博图V19的DB块,批量导入组态王

打印 上一主题 下一主题

主题 786|帖子 786|积分 2358

最近在使用组态王做一个厂区的DCS项目,plc选用西门子1500系列。一共用了3个1500,5个io站点。整个项目下来,点位大约有5000多个。把这5000多个点位,一个一个导入到组态王,无疑是一个非常非常非常难熬的工作,不仅无聊,而且很容易出错。
一、首先,表明一下DB块。DB块是西门子S7系列的PLC,一个非常有特色的功能。大抵功能就说允许用户自己定义一个内存区域,如DB1,DB2,DB3.....DB100,等等,每个DB块,可以由用户自定义一些变量大概布局体。
试想一下,当一个PLC控制了好几条产线,假如都把这写变量,全部写到一块,维护起来就比力麻烦,固然写到一块也不是不可以。按车间大概产线,分别写到差别的DB块上,维护起来更方便。下图是博图V19导出的一个DB块内容,PDF文件。可以看到里面DB块基本信息,和布局体定义。

一样平常情况下, 对同类型的装备控制,比如皮带,风机,等。会使用相同的布局体举行定义,如下图。


 1A-CVS01和1A-CBC02。这两个装备,都是一类型的装备(说白了电机控制都一样),以是两个装备用了相同的布局体定义,差别的是,装备名字不一样,以及布局体内部各个属性对应的内存地质不一样。
他们的控制方式,就是PLC编程是一样的。同时在DCS,就是组态王画面里面,两个装备控制方式也是一样的。这两个布局体怎么才能在DCS画面控制呢?答案就是给这两个布局体在组态王变量里面也定义一下。
二、接下来就是在组态王定义布局体和变量,因为这两个布局体布局一样,以是,只需要在组态王定义一个布局类型。定义两个变量。
布局体定义按下图的步调。


布局定义完以后,就是定义变量的步调,先点左侧的变量,再点新建。如下图。变量包含了多少个属性,见下面属性下拉框。每个属性,都需要定义一地点的plc和地点。完整DB5.62.0。体现,DB块5,里面的第62个字节的,第0位。最后一个只有bit类型需要,假如是int,real不需要。

通常情况下,一个厂区,几百个电机到上千个电机,任何装备要运转,都需要电机嘛。固然也不都是同一类型的装备,也会有变频电机,软起电机,也有可以正反转的电机等等,差别的装备类型,控制肯定不一样,那么布局体定义也就不一样。
以是通常一个厂区的控制系统会包含多少个PLC,多少个DB块,十几个布局体定义,成百上千个布局体变量。几千个基本变量。如下图,其中一个DB块已经定义到了3600个字节了,假设一个布局体20个字节,也就是180个布局体定义。1000多个变量定义了。

要给这些变量,一个一个手动编辑到组态王,确实是一个非常巨大的工程,耗时耗力,还非容易出错。以是决定做一个脚本,来简化变量(点位)导入。上一篇写了一个简单的DB块导入功能,见链接DCS项目调试踩坑记载_dcs调试记载表-CSDN博客
这个文章里比力简单,得当单个DB块,并且布局体都是固定死的。并不得当多个DB块,布局体不一样的情况。
三:DB块的pdf直接天生组态王的DB文件。整个过程分为两步,第一步,解析所有pdf文件,循环所有布局体定义,提取出其中差别的布局体定义。就是全部读取,然后给布局相同的去掉。然后给布局体定义文件保存为data.json。如下图。这个文件里面包含所有布局体定义,类型,plc里面变量名称,以及组态王里面变量名称。固然这一步也可以由开辟职员自己定义,直接按下面格式编写就行。不过建议先用脚本跑一下,天生基本布局,然后开辟职员再根据个人喜欢优化一下。

第二步,读取所有的pdf文件,以及上一步定义的布局文件,循环所有pdf,所有布局体和所有变量。根据上一步定义的布局体自动天生组态王DB文件的布局体定义,如下图,模板页和模板定义页。

然后,把所有布局体变量,按规则天生组态王布局变量,如下图:

终极天生完成以后,会天生一个test.xls文件。组态王工程管理页面,点击导入,即可完成所有变量导入。见下图:

四:代码分享。解析布局体代码如下
  1. import pdfplumber
  2. import os
  3. import json
  4. path='./'
  5. arr=[]  #存储结构体的数组
  6. #plc变量名称和组态王变量名称的映射关系,如果不定义这个,会直接使用plc里面的变量名称
  7. varNames={'iinf':'状态字','balm':'报警','disysj':'运行时长','rdianliu_fankui':'电流','rpinlv_fankui':'频率','bstate_run_fw':'正向运行',
  8.           'bstate_run_bw':'反向运行','bstate_fault':'故障','bstate_ready':'备妥','fengjiyunxing':'风机运行','chuchenqirukouyali':'入口压力',
  9.           'panglu':'旁路运行','rm1dianliu_fankui':'M1电流','rm2dianliu_fankui':'M2电流','rrt_pos':'开度','fankuizhuansu':'转速',
  10.           'bstate_open_done':'开到位','bstate_close_done':'关到位','zhengxiangxianwei':'正限位','fanxingxianwei':'负限位',
  11.           'bstate_runz':'正向运行','bstate_runf':'反向运行','bstopallowed':'停止许可',
  12.           'bstart':'启动','bstop':'停止','startallowed':'启动许可','stopallowed':'停止许可','rpinlv_geiding':'手动频率','rpinlv_geiding_a':'自动频率',
  13.           'ma':'模式','breset':'复位','em':'急停','bopen':'手动开','bclose':'手动关','bstop':'手动停','bopen_a':'自动开','bclose_a':'自动关','bstop_a':'自动停',
  14.           'zhengxiangqidong':'正向启动','fanxiangqidong':'反向启动','tingzhi':'停止',
  15.           'bstartz':'正向启动','bstartf':'反向启动','bstartzallowed':'正向启动许可','bstartfallowed':'反向启动许可','wendu1':'温度1','wendu2':'温度2','wendu3':'温度3'
  16.           }
  17. #有时候plc定义变量名称会敲错,这个功能是给敲错的单词转换一下,例如chukou拼写成cukou,这里定义一下'cukou':'chukou'
  18. wordTrans={'chuchanqirukouyali':'chuchenqirukouyali','zhaunsufankui':'fankuizhuansu','zhuansufankui':'fankuizhuansu','bstate_ready_1':'bstate_ready','bstate_fault_1':'bstate_fault'} #有些拼错的,使用这个转换一下
  19. #获取变量在组态王的名称
  20. def getVarName(s):
  21.     if s in varNames.keys():
  22.         return varNames[s]
  23.     return s
  24. #转换名称
  25. def transName(nm):
  26.     if nm in wordTrans.keys():
  27.         print(nm+" ===== " +wordTrans[nm])
  28.         return wordTrans[nm]
  29.     return nm
  30. #读取pdf里面的db块号
  31. def getDBNum(pdf):                                  #解析DB块号
  32.     tb=pdf.pages[0].extract_tables()[1]             #获取第一页
  33.     name=tb[2][1]                                   #DB块注释
  34.     dbNum=tb[2][3]                                  #DB块号
  35.     print(name,dbNum)
  36.     return 'DB' +dbNum
  37. #比较两个结构体是否一样
  38. #a1是数组,a2是map
  39. def compStruct(a1,a2) :
  40.     for nm in a1:
  41.        if nm not in a2.keys():
  42.            return False
  43.     return True
  44.    
  45. #检查是否有重复的结构体,如果没有就增加上去
  46. def checkStruct(s):
  47.     #print('check struct',s)
  48.     if s=={} :return #无效的结构体
  49.     f = False
  50.     l1=len(s['attrs'])
  51.     for o in arr:
  52.         l2= len ( o['attrs'].keys() )
  53.         if l2!=l1 : continue                #属性数量不一样,直接跳过
  54.         f=compStruct(s['attrs'],o['attrs'])
  55.         if f == True: return                #找到一样的,不用再找了
  56.          
  57.     if f==False :
  58.         arr.append(s)
  59.     return
  60. #----------------------------------------------------------------------------------------------------
  61. def formatStr(s):
  62.     s1=s.replace(' ','').replace('\r','').replace('\n','').lower()
  63.     #print(s,s1)
  64.     return s1
  65. #读取pdf,并解析
  66. def readPDF(fname):
  67.     if fname.find('.pdf')==-1 :
  68.         return
  69.     pdf=pdfplumber.open(fname)
  70.     DB=getDBNum(pdf)
  71.     print("dbname",DB)
  72.     plc=fname.split('_')[0]
  73.     mode='只读'                                     #默认读写模式
  74.     if fname.find("write") !=-1:
  75.         mode='只写'                                 #只写
  76.     ss={}                                           #临时结构体
  77.     for pg in pdf.pages:                            #循环所有页
  78.         data =pg.extract_table()                    #获取表格
  79.         for r in data :                             #循环所有行
  80.             #print(r)
  81.             name=transName(formatStr(r[0]))                    #名称
  82.             type=formatStr(r[1])                              #类型
  83.             add=formatStr(r[2])                               #地址
  84.             remark=formatStr(r[13])                            #备注信息
  85.             # print(name,type,remark)
  86.             if  name=='名称' or name=='w' or name.find('备用')!=-1:            #跳过无用的行
  87.                 #print('skip  '+name)
  88.                 continue
  89.             #print(name,type)
  90.             if type == 'struct' :                   #如果是Struct ,可能是结构体开头
  91.                 checkStruct(ss)                     #添加到结构体
  92.                 if name.find('static') ==-1:
  93.                     ss={'name':remark,'DB':DB,'mode':mode,'attrs':{},'plc':plc}
  94.                 else:
  95.                     ss={}                           #无效的结构体,直接跳过
  96.                 continue                            #结构体开头行
  97.             if name.find('static')==-1 and 'attrs' in ss.keys():                    #如果是一般列,并且有属性
  98.                 ss['attrs'][name]={'type':type,'add':add,'name':getVarName(name)}    #添加到属性集合,var是组态王里面的名称
  99. #-----------------------------------------------------------------------------------------------------------------------------------
  100. # 遍历当前目录
  101. for file_name in os.listdir(path):
  102.     # 处理目录中的文件或子目录
  103.     full_path = os.path.join(path, file_name)  # 拼接文件或子目录的完整路径
  104.     if os.path.isfile(full_path):  # 判断是否为文件
  105.         print("文件:", file_name)
  106.         readPDF(file_name)
  107.     elif os.path.isdir(full_path):  # 判断是否为子目录
  108.         print("子目录:", file_name)
  109. print('------------------------------------------------------------')
  110. print(arr)
  111.    
  112. # 打开文件
  113. with open("data.json", "w",encoding="utf-8") as file:
  114.     # 使用json.dump将数据写入文件
  115.     json.dump(arr, file,ensure_ascii=False)
复制代码
天生组态王DB文件代码如下:
  1. import pdfplumber
  2. import os
  3. import json
  4. from openpyxl import Workbook   #用于写入excel,如果没有需要pip install openpyxl
  5. from openpyxl import load_workbook
  6. #创建组态王结构体声明   
  7. def createStruct(dat):
  8.     print("data length ",len(dat))
  9.     startId=1                                                           #默认从编号1开始
  10.     st1 = wb.create_sheet("模板页")                                         #结构体变量模板
  11.     st2 = wb.create_sheet("模板定义页")
  12.     st1.append(['说明:本页为数据词典中所有模板定义  请不要编辑此行'])
  13.     varId=21                                                      #变量id,21开始
  14.     for o in dat:
  15.         #print(o)
  16.         st1.append(['[模板]','模板ID','模板名称','模板使用记数','注释'])    #结构体行
  17.         st1.append(['',startId,o['name'],-2,''])                               #结构体名称
  18.         st1.append(['','[成员]',        '成员ID','成员名称','成员类型'])         #结构体开始
  19.         id=1                                                                #属性开始
  20.         startId=startId+1
  21.         
  22.         for k in o['attrs'].keys() :
  23.             o['attrs'][k]['varid']=varId      
  24.             tp=o['attrs'][k]['type']                                  #变量id
  25.             varId=varId+1                                               #增加一个
  26.             st1.append(['','',id,o['attrs'][k]['name'],types[tp]])
  27.             id=id+1
  28.     ###下面是输出模板定义地方
  29.     st2.append(['说明:本页为数据词典中所有基本变量  请不要编辑此行'])
  30.     st2.append(['[内存整型]'])
  31.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  32.     #st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  33.     st2.append([])
  34.     st2.append(['[内存实型]'])
  35.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  36.     st2.append([])
  37.     st2.append(['[内存离散]'])
  38.     st2.append(['变量ID','变量名','变量使用记数','初始值','是否保存值','是否保存参数','报警组','优先级','是否产生报警','报警类型(开/关/变位)','关报警文本','开报警文本','开到关报警文本','关到开报警文本','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  39.     st2.append([])
  40.     st2.append(['[内存字符串]'])
  41.     st2.append(['变量ID','变量名','变量使用记数','初始字符串(<127字节)','是否保存值','是否保存参数','安全区','注释','变量签名属性'])
  42.     st2.append([])
  43.     st2.append(['[IO整型]'])
  44.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','最小原始值','最大原始值','是否保存值','是否保存参数','设备名','寄存器名称','数据类型','读写属性','采集频率(毫秒)','转换方式','高级转换方式','线性表名称','最小累计值','最大累计值','是否允许DDE访问','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录/每次采集记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  45.     for o in dat:
  46.         print(o)
  47.         sname=o['name']
  48.         db=o['DB']+"."
  49.         for k in o['attrs'].keys():
  50.             tp=o['attrs'][k]['type']
  51.             if tp=='dint' :
  52.                 name=o['attrs'][k]['name']
  53.                 id=o['attrs'][k]['varid']
  54.                 add=o['attrs'][k]['add'].split('.')[0]
  55.                 add=db+add
  56.                 st2.append([id,sname+"."+name,-2,0,0,-10000,999999999,-1000,999999999,'否','否',o['plc'],add,'LONG',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','','',144])
  57.                 # st2.append([id,        sname+"."+name,0,0,0,-10000,999999999,-10000,999999999,'否','否',o['plc'],add,'LONG',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','',144,''])
  58.             if tp=='int' :
  59.                 name=o['attrs'][k]['name']
  60.                 id=o['attrs'][k]['varid']
  61.                 add=o['attrs'][k]['add'].split('.')[0]
  62.                 add=db+add
  63.                 st2.append([id,sname+"."+name,-2,0,0,-10000,999999999,-1000,999999999,'否','否',o['plc'],add,'SHORT',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','','',144])
  64.                 #st2.append([id,        sname+"."+name,0,0,0,-10000,999999999,-10000,999999999,'否','否',o['plc'],add,'SHORT',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','',144,''])
  65.     st2.append([])
  66.     st2.append(['[IO实型]'])
  67.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','最小原始值','最大原始值','是否保存值','是否保存参数','设备名','寄存器名称','数据类型','读写属性','采集频率(毫秒)','转换方式','高级转换方式','线性表名称','最小累计值','最大累计值','是否允许DDE访问','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录/每次采集记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  68.     for o in dat:
  69.         sname=o['name']
  70.         db=o['DB']+"."
  71.         for k in o['attrs'].keys():
  72.             tp=o['attrs'][k]['type']
  73.             if tp=='real' :
  74.                 name=o['attrs'][k]['name']
  75.                 id=o['attrs'][k]['varid']
  76.                 add=o['attrs'][k]['add'].split('.')[0]
  77.                 add=db+add
  78.                 st2.append([id,sname+"."+name,-2,0,0,-10000,999999999,-1000,999999999,'否','否',o['plc'],add,'FLOAT',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','','',144])
  79.                 #st2.append([id,        sname+"."+name,0,0,0,-10000,999999999,-10000,999999999,'否','否',o['plc'],add,'FLOAT',o['mode'],1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无','',144,''])
  80.             
  81.     st2.append([])
  82.     st2.append(['[IO离散]'])
  83.     st2.append(['变量ID','变量名','变量使用记数','初始值','是否保存值','是否保存参数','设备名','寄存器名称','数据类型','读写属性','采集频率(毫秒)','是否允许DDE访问','报警组','优先级','是否产生报警','报警类型(开/关/变位)','关报警文本','开报警文本','开到关报警文本','关到开报警文本','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录/每次采集记录)','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  84.     #st2.append(['变量ID','变量名','变量使用记数','初始值','是否保存值','是否保存参数','报警组','优先级','是否产生报警','报警类型(开/关/变位)','关报警文本','开报警文本','开到关报警文本','关到开报警文本','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  85.     for o in dat:
  86.         sname=o['name']
  87.         db=o['DB']+"."
  88.         for k in o['attrs'].keys():
  89.             tp=o['attrs'][k]['type']
  90.             if tp=='bool' :
  91.                 name=o['attrs'][k]['name']
  92.                 id=o['attrs'][k]['varid']
  93.                 add=db+o['attrs'][k]['add']
  94.                 #st2.append([id,sname+"."+name,0,'关','否','否',o['plc'],add,'Bit',o['mode'],1000,'否','',1,'否','','','','','','','','不记录','','否','无','',144,''])
  95.                 st2.append([id,sname+"."+name,-2,'关','否','否',o['plc'],add,'Bit',o['mode'],1000,'否','',1,'否','','','','','','','','不记录','','否','无','',144])
  96.     st2.append([])
  97.     st2.append(['[IO字符串]'])
  98.     st2.append(['变量ID','变量名','变量使用记数','初始字符串(<127字节)','是否保存值','是否保存参数','设备名','寄存器名称','数据类型','读写属性','采集频率(毫秒)','是否允许DDE访问','安全区','注释','变量签名属性'])
  99.     st2.append([])
  100.     return varId
  101. #------------------------------------------------------------------------------------------------------
  102. #比较两个结构体是否一样
  103. def compStruct(a1,a2) :
  104.     for nm in a1['attrs']:
  105.        if nm['name'] not in a2['attrs'].keys():
  106.            return False
  107.     return True
  108.    
  109. #匹配结构体定义
  110. def getStruct(obj):
  111.     #print('get struct',obj)
  112.    
  113.     if 'attrs' not in obj.keys(): return None
  114.     l1 = len(obj['attrs'])                                      #当前结构体属性数量
  115.     for o in arr:
  116.         l2=len(o['attrs'].keys())                              #目标结构体属性数量
  117.         #print("@@",obj['name'],o['name'],l1,l2)
  118.         if l1!=l2 : continue                                    #数量不匹配直接跳过
  119.         if compStruct(obj,o) :                                 #如果比较成功了
  120.             return o
  121.          
  122.     return None
  123. #--------------------------------------------------------------------
  124. # 解析对象的属性到已经定义的结构名称
  125. # obj 是要转换的对象
  126. # s 是已经定义的结构体
  127. def transStruct(obj,s):
  128.     for o in obj['attrs']:
  129.         o['var']=s['attrs'][o['name']]['name']    #结构体变量名称
  130.     return
  131. #------------------------------------------------------------
  132. #转换特定的名称,防止DB块里面拼写错误
  133. def transName(nm):
  134.     if nm in wordTrans.keys():
  135.         return wordTrans[nm]
  136.     return nm.replace('-','_').replace('#','_')
  137. #----------------------------------------------------------
  138. def formatStr(s):
  139.     s1=s.replace(' ','').replace('\r','').replace('\n','').lower()
  140.     #print(s,s1)
  141.     return s1
  142. #解析PDF
  143. def readPDF(fname):
  144.     if fname.find('.pdf')==-1 :
  145.         return
  146.     plc=fname.split("_")[0]
  147.     pdf=pdfplumber.open(fname)
  148.     DB=getDBNum(pdf)
  149.     print("dbname",DB)                              #结构体名称
  150.     ss={}                                           #临时结构体
  151.     for pg in pdf.pages:                            #循环所有页
  152.         data =pg.extract_table()                    #获取表格
  153.         for r in data :                             #循环所有行
  154.             #print(r)
  155.             name=transName(formatStr(r[0]))                    #名称,转换后的
  156.             type=formatStr(r[1])                               #类型
  157.             add=formatStr(r[2])                               #地址
  158.             remark=r[13][0:35]                            #备注信息
  159.             # print(name,type,remark)
  160.             if name=='名称' or name=='w' or name.find('备用')!=-1:            #跳过无用的行
  161.                 #print('skip  '+name)
  162.                 continue
  163.             
  164.             #print(name,type)
  165.             if type == 'struct':                    #如果是Struct ,可能是结构体开头
  166.                 structDef=getStruct(ss)             #寻找匹配的结构体
  167.                 #print("structDef",structDef)
  168.                 if  structDef != None :
  169.                     #print(" found struct",ss)
  170.                     transStruct(ss,structDef)       #转换到定义的名称
  171.                     ss['struct']=structDef['name']  #结构体变量名称
  172.                     ss['mode']=structDef['mode']    #读写属性
  173.                     objects.append(ss)              #添加到对象里面
  174.                 else :
  175.                     others.append(ss)               #添加到另外一个列表
  176.                 if name.find('static')!=-1:         #没有名字的结构体,跳过
  177.                     ss={}
  178.                 else :
  179.                     ss={'name':name,'remark':remark,'DB':DB,'plc':plc,'attrs':[]} #重置当前结构体
  180.                 continue                            #结构体开头行
  181.             if name.find('static')==-1 and  'attrs' in ss.keys():                #如果存在这个属性,认为是一个合理的结构体
  182.                 ss['attrs'].append({'name':name,'type':type,'add':add,'remark':remark}) #增加一个属性
  183.     return                                          #解析PDF结束
  184. #-----------------------------------------------------------------------------------------------------------
  185. #创建结构体变量
  186. def createVar(objs,varId):
  187.     print("struct len ",len(objs))
  188.     startId=1   
  189.     st1=wb.create_sheet("结构变量页")
  190.     st2=wb.create_sheet("基本变量页")
  191.     st1.append(['说明:本页为数据词典中所有结构变量  请不要编辑此行'])
  192.     st2.append(['说明:本页为数据词典中所有基本变量  请不要编辑此行'])
  193.     st2.append(['[内存整型]'])
  194.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  195.     st2.append([''])
  196.     st2.append(['[内存实型]'])
  197.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  198.     st2.append([''])
  199.     st2.append(['[内存离散]'])
  200.     st2.append(['变量ID','变量名','变量使用记数','初始值','是否保存值','是否保存参数','报警组','优先级','是否产生报警','报警类型(开/关/变位)','关报警文本','开报警文本','开到关报警文本','关到开报警文本','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  201.     st2.append([''])
  202.     st2.append(['[内存字符串]'])
  203.     st2.append(['变量ID','变量名','变量使用记数','初始字符串(<127字节)','是否保存值','是否保存参数','安全区','注释','变量签名属性'])
  204.     st2.append([''])
  205.     for o in objs:                                                                  #循环输出结构体变量页
  206.         m='R'
  207.         if o['mode']=='只写':m="W"
  208.         sname=m+o['name'].upper()
  209.         st1.append(['[结构变量]','变量ID','变量名','变量类型','变量使用记数','注释'])   #列
  210.         st1.append(['',startId,sname,o['struct'],0,o['remark']])                #结构体
  211.         st1.append(['','[成员]','成员名称','成员基本变量ID'])                              #成员变量列
  212.         startId=startId+1
  213.         sname=sname+"."
  214.         for a in o['attrs']:
  215.             a['varid']=varId
  216.             st1.append(['','',sname+a['var'].upper(),varId])                              #成员变量列
  217.             varId=varId+1                                                     #变量id增加1个
  218.     #################################################################
  219.     st2.append(['[IO整型]'])
  220.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  221.     for o in objs:                                                            #循环输出整数
  222.         plc=o['plc']
  223.         DB=o['DB']+"."
  224.         struct=o['struct']
  225.         mode=o['mode']
  226.         m='R'
  227.         if mode=='只写':m="W"
  228.         sname=m+o['name'].upper()+"."
  229.         for  a in o['attrs']:
  230.              if a['type'] == 'int' or a['type']=='dint' :
  231.                 add=DB+a['add'].split(".")[0]
  232.                 tp='SHORT'
  233.                 if a['type']=='dint' : tp='LONG'
  234.                 st2.append([a['varid'],sname+a['var'].upper(),0,0,0,-10000,999999999,-10000,999999999,'否','否',plc,add,tp,mode,1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无',a['remark'],144,''])
  235.     st2.append([''])
  236.     #################################################################
  237.     st2.append(['[IO实型]'])
  238.     st2.append(['变量ID','变量名','变量使用记数','变化灵敏度','初始值','最小值','最大值','是否保存值','是否保存参数','报警组','优先级','低低限值','低低报警文本','低限值','低报警文本','高限值','高报警文本','高高限值','高高报警文本','越限死区','报警延时','变化率%','变化率单位','目标值','小偏差','大偏差','偏差死区','扩展域1','扩展域2','历史记录方式(不记录/变化记录/定时记录)','历史记录变化灵敏度','记录间隔(分)','是否生成操作事件','安全区','注释','变量签名属性'])
  239.     for o in objs:                                                            #循环输出整数
  240.         plc=o['plc']
  241.         DB=o['DB']+"."
  242.         struct=o['struct']
  243.         mode=o['mode']
  244.         m='R'
  245.         if mode=='只写':m="W"
  246.         sname=m+o['name'].upper()+"."
  247.         for  a in o['attrs']:
  248.              if a['type'] == 'real':
  249.                 add=DB+a['add'].split(".")[0]
  250.                 tp='FLOAT'
  251.                 st2.append([a['varid'],sname+a['var'].upper(),0,0,0,-10000,999999999,-10000,999999999,'否','否',plc,add,tp,mode,1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无',a['remark'],144,''])
  252.    
  253.     st2.append([''])
  254.     #################################################################
  255.     st2.append(['[IO离散]'])
  256.     st2.append(['变量ID','变量名','变量使用记数','初始字符串(<127字节)','是否保存值','是否保存参数','安全区','注释','变量签名属性'])
  257.     for o in objs:                                                            #循环输出整数
  258.         plc=o['plc']
  259.         DB=o['DB']+"."
  260.         struct=o['struct']
  261.         mode=o['mode']
  262.         m='R'
  263.         if mode=='只写':m="W"
  264.         sname=m+o['name'].upper()+"."
  265.         for  a in o['attrs']:
  266.              if a['type'] == 'bool' :
  267.                 add=DB+a['add']     
  268.                 st2.append([a['varid'],sname+a['var'].upper(),0,'关','否','否',plc,add,'Bit',mode,1000,'否','',1,'否','','','','','','','','不记录','','否','无',a['remark'],144,''])
  269.     st2.append([''])
  270.     return
  271. #---------------------------------------------------------------
  272. path='./'
  273. arr=[]      #存储定义好的结构体
  274. objects=[]  #所有数据
  275. others=[]   #没有写进去的
  276. wb =Workbook()                              #用于导出excel文件
  277. types={'bool':'离散型','int':'整型','dint':'整型','real':'实型'}
  278. wordTrans={'chuchanqirukouyali':'chuchenqirukouyali','zhaunsufankui':'fankuizhuansu','zhuansufankui':'fankuizhuansu','bstate_ready_1':'bstate_ready','bstate_fault_1':'bstate_fault'} #有些拼错的,使用这个转换一下
  279. def getDBNum(pdf):                                  #解析DB块号
  280.     tb=pdf.pages[0].extract_tables()[1]             #获取第一页
  281.     name=tb[2][1]                                   #DB块注释
  282.     dbNum=tb[2][3]                                  #DB块号
  283.     print(name,dbNum)
  284.     return 'DB' +dbNum
  285. # 打开JSON文件
  286. with open('data.json', 'r',encoding='utf-8') as f:
  287.     # 读取文件内容
  288.     arr = json.load(f)
  289.    
  290. # 创建结构体定义
  291. varId=createStruct(arr)
  292. # 遍历当前目录
  293. for file_name in os.listdir(path):
  294.     # 处理目录中的文件或子目录
  295.     full_path = os.path.join(path, file_name)  # 拼接文件或子目录的完整路径
  296.     if os.path.isfile(full_path):  # 判断是否为文件
  297.         print("文件:", file_name)
  298.         readPDF(file_name)
  299.         #print(objects)
  300.     elif os.path.isdir(full_path):  # 判断是否为子目录
  301.         print("子目录:", file_name)
  302. #创建变量定义
  303. createVar(objects,varId)
  304. wb.save('test.xls')  
  305. print(others)
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表