docker版jxTMS使用指南:数据源之modbus

本文详细介绍了如何在4.2版jxTMS中使用数据源访问modbus设备,主要涉及modbus连接初始化、数据拉取、异常处理以及数据源的注册和使用。示例代码展示了如何通过modbus_tcp.TcpMaster进行通信,并在python脚本中处理数据。
摘要由CSDN通过智能技术生成

本文讲解4.2版jxTMS如何用数据源访问modbus设备,整个系列的文章请查看:docker版jxTMS使用指南:4.2版升级内容

docker版本的使用,请参考docker版jxTMS使用指南

4.0版jxTMS的说明,请查看:4.0版升级内容

在docker镜像的/home/tms/python/app/module/目录下,笔者提供了dataSource_modbus.py文件,该文件就实现了用modbus来拉取数据。看完大家会发现,数据源和modbus的结合,简直简单到了极点。

继承自数据源的dataSource_modbus使用modbus_tk来执行modbus操作,核心就做了四件事:

1、初始化modbus连接:

self._master = modbus_tcp.TcpMaster(ip, port)

2、重载pull函数:

def pull(self, t):
    #从机地址
    s = t[2]
    #功能码
    f = t[3]
    #希望访问的寄存器号
    r = t[4]
    #希望访问的数量
    n = t[5]
    try:
        #读取寄存器
        return self._master.execute(s, f, r, n)
    except ConnectionRefusedError:
        #失联
        jxGo.log('warn',self._disConnectionMsg)
    except:
        pr = traceback.format_exc()
        jxGo.log('warn',f'modbus pull [{t[0]}.{t[1]}] error:{pr}')
	#执行到这里一定是出现了错误
    if self._errorNum < 3:
        #3次错误才动作
        self._errorNum = self._errorNum + 1
    else:
        self._errorNum = 0
        #错误不可避免,所以终止继续访问,等待下一个周期继续
        self.clearWandQueue()
    return None

3、增加一个start函数以封装setPullMode:

def start(self):
    #延迟10秒后执行以分散处理压力
    self.setPullMode(delayExec_seconds=10,
        taskInterval_milliseconds=self._taskInterval_milliseconds,
        interval_seconds=self._interval_seconds)

4、注册modbus类型的数据源:

def _newModbusDataSource(*args, **kw):
    return dataSource_modbus(*args, **kw)

dataSource.register('modbus',_newModbusDataSource)
使用modbus数据源

注册后,在需要时执行下述命令即可:

self._dataSource = dataSource.New('modbus',afterPullDual=self._afterPull,
	informDual=self._setData,ip=sp30h_ip,port=sp30h_port,
	taskInterval_milliseconds=500,
	interval_seconds=300)

在docker镜像的/home/tms/python/app/sinosoarSP30H/目录下的site.py文件中sp30h_slave站点就是如此定义了自己的数据源。

其指定了_afterPull函数来执行拉取到数据的后处理:

def _afterPull(self, t, tv):
    if tv is None:
        return None
    #数据类型,在jxUtils中定义
    dt = t[6]
	#modbus读到的是一个元组
    v = tv[0]
    if dt == dataType_int16:
        if v >= 32767:
            #16位带符号整数
            v = jxUtils.trans2short(v)
    elif dt == dataType_uint32:
        #32位无符号整数
        v = jxUtils.trans2u32(v)
	#缩放倍率【modbus的寄存器使用16位无符号数,精度可能不够,所以有时需要使用倍率来进行缩放】
    rate = t[7]
    if rate > 0:
        return v * rate
    return v

sp30h_slave还封装了数据源的addWantReceiveOver、addWantReceive两函数:

def addWantReceiveOver(self, dn, receiveFunc):
    #为数据源支流添加访问入口
    return self._dataSource.addWantReceiveOver(dn, receiveFunc)

def addWantReceive(self, dn, vn, slave, readFn, regid, num, dataType, rate, productStatement, compareStatement):
    #为数据源支流添加访问入口
    t = (dn,vn,slave,readFn,regid,num,dataType,rate)
    self._dataSource.addWantReceive(t,productStatement=productStatement,compareStatement=compareStatement)

现在只需要添加待拉取的数据点即可。这部分代码在docker镜像的/home/tms/python/app/sinosoarSP30H/目录下的几个device文件中,都是根据设备厂家提供的产品手册查到需要的寄存器信息依次调用即可,大家根据注释读下代码就可以理解了。

注:可能有同学说,怎么好像没有定义数据策略呢?原因很简单,数据源中拉取到的数据,先是根据拉取参数元组中的dn【设备名】、vn【变量名】已经存放到dict中了,然后又经过afterDual将其转换为合适的数据格式和精度了,所以各设备接收到的数据就已经是符合要求的数据了,自然就不再需要数据策略进行解析和转换了

参考资料:

jxTMS设计思想

jxTMS编程手册

下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:

如何用jxTMS开发一个功能

下面的系列文章讲述了jxTMS的一些基本开发能力:

jxTMS的HelloWorld

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值