zoukankan      html  css  js  c++  java
  • python工业互联网监控项目实战5—Collector到opcua服务

      本小节演示项目是如何从连接器到获取Tank4C9服务上的设备对象的值,并通过Connector服务的url返回给UI端请求的另外,实际项目中考虑websocket中间可能因为网络通信等原因出现中断情况,我们增加一个“心跳”设计来定时发送连接请求,确保出现冲断的情况下,能够重新连接到服务端

    1. OPCUA-Client读取OPCUA服务Tag

       现在重构Connector APP views文件里的pushCollectorData函数,通过引入OPCUA-Client来读取OPCUA服务端的Tag值,代码如下: 

    from django.shortcuts import render
    from django.http import HttpResponse
    import json
    from dwebsocket.decorators import accept_websocket
    from opcua import Client #引入 opcua-client
    @accept_websocket   
    def pushCollectorData(request):
    
        tank4C9={            
            'DeviceId': 1,
            'DeviceName':'1#反应罐',
            'Status': 0, #设备运行状态
            'OverheadFlow':0 ,#'顶流量',
            'ButtomsFlow': 0, #'低流量'
            'Power': 0, #功率
        }
        Collector={
                'CollectorId': 1,
                'CollectorName':'1#采集器',
                'Status': 0,
                'DeviceList':[tank4C9],
                } 
        Collector={
             'CollectorId': 1,
             'CollectorName':'1#采集器',
             'Status': 0,
             'DeviceList':[tank4C9],
             }  
    
        if request.is_websocket():
            #创建opcua-client
            client = Client("opc.tcp://localhost:4840/freeopcua/server/") 
            client.connect() #连接服务器
            try:
                while True:  
    
                    root = client.get_root_node() #获取OPCUA服务根节点
                    #获取Tank4C9子节点的所有变量
                    items = root.get_child(["0:Objects", "2:Tank4C9"]).get_children() 
                    for item in items:
                        #给字典赋读取opcua服务tag当前值
                        tank4C9[item.get_display_name().Text]=item.get_value() 
    
                    request.websocket.send(
                        json.dumps( {"rows":[Collector],'total':1}))
                    time.sleep(2)
     
            finally:
                client.disconnect()

       代码改动并不大,数据获取从原来的OPC DA切换到了OPC UA组件,从前面的章节起笔者就奉行迭代推进的思路,好的代码结构(组织)会让后面的升级重构非常的方便,实际项目中减少很多工作量。 

    2. 运行调试

      首先,我们在集成开发环境VS Community 2019 选择CollectorSvr项目,右键在python环境启动运行CollectorSvr项目,如下图:

       然后,F5调试默认服务端项目Tank4C9Svr。我们即可通过浏览器访问监控页面

      url:http://127.0.0.1:8090/tank4C9/ 运行效果如下图:

     3. 客户端心跳机制

      本章节我们在UI端增加一个与服务端心跳检测函数,当websocket网络通信故障或其它原因不能正常传输数据时,UI端能够重新创建连接来确保系统可靠性的手段。UI端保存一个最后更新时间的变量,心跳检测时查看当前时间-最后更新时间大于30秒时,就关闭当前连接重新创建一个新得websocket连接获取数据,这样就确保了websocket出现其它原因断开后,保证能够自动重新连接并刷新数据得机制。

      更多得看代码吧如下

    <script>
    //JQuery 代码入口
            $(document).ready(function () {
                getData()
                //设置心跳检测时间
                setInterval("heartbeat(window.ws,window.lastUpdateTime)",30000);
    
     
            });
    
    
            function heartbeat(ws,lastUpdateTime) {
                var time = new Date();
                if ((time.getTime() - lastUpdateTime > 30000)) {
                    //最后更新时间与当前检查时间大于30秒,关闭连接重新创建并获取数据
                    if(ws) 
                        ws.close();//关闭连接
    
                    getData();
                } 
            }
    
    
    
            function getData() {
               if ("WebSocket" in window) {
                   //连接server--TagCurValue
    
                    window.ws = new WebSocket("ws://127.0.0.1:8090/pushCollectorData/");
                    window.lastUpdateTime = new Date().getTime()
                    ws.onmessage = function (evt) {
                        //最后更新时间戳
                        lastUpdateTime = new Date().getTime()
                        // 接收数据
                        d = JSON.parse(evt.data);
                        collector = d.rows[0]
                        tank4C9 = collector.DeviceList[0]
    
                        $("#OverheadFlow").html(tank4C9.OverheadFlow);
                        $("#ButtomsFlow").html(tank4C9.ButtomsFlow);
                        $("#Power").html(tank4C9.Power);
    
    
                    };
    
                } 
        }
    
        </script>

    4. 小结

      本章节代码的改动不大,一个改动是切换到了OPC UA,另一个是增加了心跳检测函数,这个两个看似不大的改动,尤其心跳函数在实际项目中作用非常大,工业监控画面,如果出现长时间的数据不刷新(仅仅是插拔了一下电脑网线)画面不能自动连接到服务端刷新数据,现场管理员就看不到数据的变化,画面就不能真实的反应设备运行情况,这个在实际项目中是不能被客户接受的。OPC UA 的升级让体系可以逐步演进到新的架构下,却不会导致客户端任何调整,这个就是好的分层架构的优势,早些年笔者经历的很多项目都是从后台改到前台,并测试发布才能更新功能。

    5.后记

      python开发工业监控系列文章到本章节就告以段落了,这个系列带着大家从技术原型的探索到项目实战,从一个简单监控页面开始一步一步的也演示了项目迭代的实际过程,笔者的项目最佳实践准则:敏捷开发,有一个基本的功能蓝图后,从简设计、开发、迭代、重构、单元测试、集成测试和发布等环环相扣。同时,采用一个好的可繁可简的技术体系对持续改进非常重要,笔者转换python体系以来,越发喜欢上开源社区,互联网开发架构也会给传统企业软件开发领域带来新的机遇,尤其国家大力推进的工业互联网时代,期待python开发生态会带给我们更多的惊喜。

      这里的案例UI比较简单,实际的项目可能还会设计APP UI,或者更发杂的web 3D界面等,但是总体来说服务端的架构思路是不变的,开发设计的分层(逻辑分层)是好的技术架构的重要体现。本序列文章我们更多的着重在监控界面上,没有交代业务逻辑和模型层面的知识,下一个系列笔者计划更多的着重在业务逻辑和模型层。

  • 相关阅读:
    luogu p1268 树的重量——构造,真正考验编程能力
    luogu p2330[SCOI05] 繁忙的都市——瓶颈生成树
    生成树的个数——基尔霍夫定理(Matrix-Tree Theorem)
    子序列最大和
    有关pascal的填充语句小技巧
    P2320 [HNOI2006]鬼谷子的钱袋
    DP专题——括号序列
    简单的迷宫(bfs)noj1793
    G:献给阿尔吉侬的花束(可能超时)
    ytu 2335: 0-1背包问题
  • 原文地址:https://www.cnblogs.com/haozi0804/p/12785800.html
Copyright © 2011-2022 走看看