本小节演示项目是如何从连接器到获取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项目,如下图:

python工业互联网监控项目实战5—Collector到opcua服务-LMLPHP

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

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

python工业互联网监控项目实战5—Collector到opcua服务-LMLPHP

 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界面等,但是总体来说服务端的架构思路是不变的,开发设计的分层(逻辑分层)是好的技术架构的重要体现。本序列文章我们更多的着重在监控界面上,没有交代业务逻辑和模型层面的知识,下一个系列笔者计划更多的着重在业务逻辑和模型层。

04-29 17:55