【问题标题】:Two issue about python OpenOPC library关于 python OpenOPC 库的两个问题
【发布时间】:2014-02-13 12:38:16
【问题描述】:

问题描述和环境

OpenOPC 库友好且易于使用,api 也很简单,但我在开发用于记录实时 OPC 项目数据的工具时发现了两个问题。

  1. 开发环境为:Window 8.1、Python 2.7.6、wxpython 2.8 unicode
  2. 测试环境为:Window XP SP3, Python 2.7.6, wxpython 2.8 unicode, Rockwell's soft logix as OPC Server
  3. 部署环境为:Window XP SP3,连接罗克韦尔真实PLC,安装RSLogix 5000和RSLinx Classic Gateway

问题

  1. opc.list 函数没有列出测试和工作站环境中指定节点的所有项目。问题是如何从 opc 服务器列出“t”?
    • 在 soft_1 范围内使用 RS logix 5000 添加了一个 int 数组 'dint100' 和一个 dint 't'
    • 使用来自 Rockwell 的默认 OPC 客户端测试工具,它可以列出新添加的“t”
    • 使用 OpenOPC 库,我不知道如何列出项目 't',但我可以通过 opc.read('[soft_1]t') 及其标签读取它的值。
    • 如果可以列出“t”,则可以将其添加到我的工具的 IO 树中。
  2. opc.servers 函数在部署环境中会遇到 OPCError,但客户端可以直接使用服务器名称连接“RSLinx OPC Server”。 opc.servers 的功能是否依赖于某些特殊的 dll 或服务?

    任何建议将不胜感激!提前致谢!

【问题讨论】:

    标签: python opc


    【解决方案1】:

    考虑到浏览问题(“opc.list”)可能不在您这边。 RSLinx 因其破坏性的 OPC 浏览而臭名昭著。尝试使用其他供应商的一些测试/模拟服务器来测试这个假设。

    【讨论】:

      【解决方案2】:

      我意识到我玩这个游戏真的迟到了。我找到了导致这个问题的原因。 OpenOPC.py 假定在同一级别上不能同时存在“叶子”和“分支”。将函数 ilist 替换为:

      def ilist(self, paths='*', recursive=False, flat=False, include_type=False):
        """Iterable version of list()"""
      
        try:
           self._update_tx_time()
           pythoncom.CoInitialize()
           
           try:
              browser = self._opc.CreateBrowser()
           # For OPC servers that don't support browsing
           except:
              return
      
           paths, single, valid = type_check(paths)
           if not valid:
              raise TypeError("list(): 'paths' parameter must be a string or a list of strings")
      
           if len(paths) == 0: paths = ['*']
           nodes = {}
      
           for path in paths:
              
              if flat:
                 browser.MoveToRoot()
                 browser.Filter = ''
                 browser.ShowLeafs(True)
      
                 pattern = re.compile('^%s$' % wild2regex(path) , re.IGNORECASE)
                 matches = filter(pattern.search, browser)
                 if include_type:  matches = [(x, node_type) for x in matches]
      
                 for node in matches: yield node
                 continue
                 
              queue = []
              queue.append(path)
      
              while len(queue) > 0:
                 tag = queue.pop(0)
              
                 browser.MoveToRoot()
                 browser.Filter = ''
                 pattern = None
      
                 path_str = '/'
                 path_list = tag.replace('.','/').split('/')
                 path_list = [p for p in path_list if len(p) > 0]
                 found_filter = False
                 path_postfix = '/'
      
                 for i, p in enumerate(path_list):
                    if found_filter:
                       path_postfix += p + '/'
                    elif p.find('*') >= 0:
                       pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
                       found_filter = True
                    elif len(p) != 0:
                       pattern = re.compile('^.*$')
                       browser.ShowBranches()
      
                       # Branch node, so move down
                       if len(browser) > 0:
                          try:
                             browser.MoveDown(p)
                             path_str += p + '/'
                          except:
                             if i < len(path_list)-1: return
                             pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
      
                       # Leaf node, so append all remaining path parts together
                       # to form a single search expression
                       else:
                          ###################################### JG Edit - Flip the next two rows comment/uncommented
                          p = '.'.join(path_list[i:])
                          # p = string.join(path_list[i:], '.')
                          pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
                          break
           
                 
                 ###################################### JG Edit - Comment this to return to original
      
                 browser.ShowBranches()
                 
                 node_types = ['Branch','Leaf']
      
                 if len(browser) == 0:
                    lowest_level = True
                    node_types.pop(0)
                 else:
                    lowest_level = False
      
                 for node_type in node_types:
                    if node_type=='Leaf':
                       browser.ShowLeafs(False)
      
                    matches = filter(pattern.search, browser)
                    
                    if not lowest_level and recursive:
                       queue += [path_str + x + path_postfix for x in matches]
                    else:
                       ###################################### JG Edit - Flip the next two rows comment/uncommented
                       if lowest_level or node_type=='Leaf':  matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
                       # if lowest_level:  matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
                       if include_type:  matches = [(x, node_type) for x in matches]
                       for node in matches:
                          if not node in nodes: yield node
                          nodes[node] = True
      
                 ###################################### Uncomment this to return to original
      
                 # browser.ShowBranches()
      
                 # if len(browser) == 0:
                 #    browser.ShowLeafs(False)
                 #    lowest_level = True
                 #    node_type = 'Leaf'
                 # else:
                 #    lowest_level = False
                 #    node_type = 'Branch'
      
                 # matches = filter(pattern.search, browser)
                 
                 # if not lowest_level and recursive:
                 #    queue += [path_str + x + path_postfix for x in matches]
                 # else:
                 #    if lowest_level:  matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
                 #    if include_type:  matches = [(x, node_type) for x in matches]
                 #    for node in matches:
                 #       if not node in nodes: yield node
                 #       nodes[node] = True
      
        except pythoncom.com_error as err:
           error_msg = 'list: %s' % self._get_error_str(err)
           raise OPCError(error_msg)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 2018-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多