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

python工业互联网监控项目实战5—Collector到opcua服务的更多相关文章

  1. python工业互联网监控项目实战4—python opcua

    前面章节我们采用OPC作为设备到上位的信息交互的协议,本章我们介绍跨平台的OPC UA.OPC作为早期的工业通信规范,是基于COM/DCOM的技术实现的,用于设备和软件之间交换数据,最初,OPC标准仅 ...

  2. python工业互联网监控项目实战2—OPC

    OPC(OLE for Process Control)定义:指为了给工业控制系统应用程序之间的通信建立一个接口标准,在工业控制设备与控制软件之间建立统一的数据存取规范.它给工业控制领域提供了一种标准 ...

  3. Python工业互联网监控项目实战3—websocket to UI

    本小节继续演示如何在Django项目中采用早期websocket技术原型来实现把OPC服务端数据实时推送到UI端,让监控页面在另一种技术方式下,实时显示现场设备的工艺数据变化情况.本例我们仍然采用比较 ...

  4. Python爬虫开发与项目实战

    Python爬虫开发与项目实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1MFexF6S4No_FtC5U2GCKqQ 提取码:gtz1 复制这段内容后打开百度 ...

  5. Python爬虫开发与项目实战pdf电子书|网盘链接带提取码直接提取|

    Python爬虫开发与项目实战从基本的爬虫原理开始讲解,通过介绍Pthyon编程语言与HTML基础知识引领读者入门,之后根据当前风起云涌的云计算.大数据热潮,重点讲述了云计算的相关内容及其在爬虫中的应 ...

  6. python工业互联网应用实战2—从需求开始

    前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...

  7. python工业互联网应用实战3—模型层构建

    本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...

  8. python工业互联网应用实战1—SQL与ORM

    从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...

  9. python工业互联网应用实战8—django-simpleui

    笔者也使用过一段时间adminx组件,后来由于adminx停更,又遇到更简单的django-simpleui后,现在基本上只使用simpleui了,使用simpleui的几个好处,笔者认为排在第一位的 ...

随机推荐

  1. AssociatedObject

    在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量,值得庆幸的是,我们可以通过 Associated Objects 来弥补这一不足. 在阅读本文 ...

  2. Material Design 组件之 FloatingActionButton

    Material Design 设计规范在 Google I/O 2014 推出,这种设计理念一经推出就受到广大开发者的喜爱,主要侧重于纸墨化创作和突出设计的实体感,使得设计更接近于真实世界,力求平滑 ...

  3. git原理,git命令使用详解,github使用 --有此图文并茂原来如此简单

    一.Git分布式控制系统原理:git有三个区,被管理的代码或文件是从:工作区-->暂存区-->本地版本库. 二.GitHub创建线上仓库GitHub是一个面向开源及私有软件项目的托管平台, ...

  4. UITextField - 为正文设置缩进

    实现思路: 把UITextField的leftView当做填充位置,这样就实现了文字偏移. 代码: UILabel *label = [[[UILabelalloc] initWithFrame:CG ...

  5. JDK12不包含JAXB-API

    ##用JDK12环境下 做EUREKA的的时候 报错如下 java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not ...

  6. rem布局和使用js rem动态改变字体大小,自适应

    解决rem文字动态改变字体大小: <script> console.log(window.devicePixelRatio); var iScale = 1; iScale = iScal ...

  7. 在vue+elementUI项目中使用分页功能

    HTML: <div class="mRttt">         <!-- 分页 -->          <el-pagination       ...

  8. js 数组 随机排序

    方法一: function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } fu ...

  9. 1049 Counting Ones (30分)

    The task is simple: given any positive integer N, you are supposed to count the total number of 1's ...

  10. 1012 The Best Rank (25 分)

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...