本文讲解4.0版的jxTMS中python服务的内置自动机,整个系列的文章请查看:docker版jxTMS使用指南:4.0版升级内容
docker版本的使用,请参考:docker版jxTMS使用指南
4.0版jxTMS中python服务是一个采集前端数据的接口机。其自建了两个自动机:
-
跟踪设备状态的_devSM
-
解析vrs20设备所接收到的文本消息的vrs20SM
后者则定义在app/policy_vrs20.py文件中,所以我们主要讲解_devSM。
_devSM
状态图为:
该自动机有四个状态:
-
init,自动机刚启动所处状态
-
normal,正常工作状态
-
disconnect,失去连接状态
-
error,接收错误状态
三种事件【本自动机非常简单,每种事件都对应跃迁到相应状态并执行对应的操作】:
-
received,正确接收到数据,状态跃迁到normal,并执行changeNormal函数
-
timeOut,未接收到数据的时间超时,状态跃迁到timeOut,并执行changeDisconnect函数
-
error,接收错误,状态跃迁到error,并执行changeError函数
响应函数的定义为:
def changeNormal(devObj, param):
devObj.setState('数据接收','info','ok', 'receive', '正确接收到数据')
def changeError(devObj, param):
devObj.setState('数据接收','error','error', 'receive', f'接收数据[{param}]解析错误')
def changeDisconnect(devObj, param):
devObj.setState('数据接收','error','error', 'disconnect', '连接超时')
devObj.warn('连接超时','设备失连','失去连接')
所以状态机的定义就非常简单了:
_devSM = jxLocalStateMachine('devSM','init')
_devSM.addTrans('init','timeOut','disconnect',changeDisconnect)
_devSM.addTrans('init','received','normal',changeNormal)
_devSM.addTrans('init','error','error',changeError)
_devSM.addTrans('normal','error','error',changeError)
_devSM.addTrans('normal','timeOut','disconnect',changeDisconnect)
_devSM.addTrans('disconnect','received','normal',changeNormal)
_devSM.addTrans('error','received','normal',changeNormal)
事件触发点有两个:
1、超时检查
管理设备的dev类在声明后,会启动一个超时检查【apscheduler的BackgroundScheduler,执行间隔由timeOutCheckInterval指定】,当其被触发时有两种情况被认为已经超时:
-
尚未接收到数据,即启动后的timeOutCheckInterval时间内都没有接收到数据
-
自上次接收到数据以来,timeOutCheckInterval时间内再没有接收到数据
当检测到这两种情况时,触发timeOut事件:
self.happen('timeOut')
2、接收到数据
设备的receive函数负责接收数据。该函数被调用,就意味着设备接收到了数据。此时有三种情况:
-
本设备的解析策略对接收到的数据没有解析成功,则认为是接收错误
-
本设备的解析策略对接收到的数据解析成功,则认为是接收正确
-
本函数的执行出现错误,则认为是接收错误
接收正确,则触发received事件:
self.happen('received')
接收错误,则触发error事件:
self.happen('error',param=msg)
由于changeError函数需要打印接收到的错误消息,所以error事件被触发时需要送入导致错误的msg。
vrs20SM
app/policy_vrs20.py文件中说明了vrs20型设备发送消息的格式。大家对照该格式和vrs20SM的定义应该可以更深刻的理解状态机是如何工作的了。
状态机的最大优点就是简单可靠,只要我们定义对了,其基本不会出现问题。
此外,在定义了vrs20SM后,我们需要定义一个消息解析策略将其打包起来,并将该策略以设备类型为名进行注册,这样当设备创建后就可以根据设备类型设置恰当的消息解析策略了。
参考资料:
jxTMS设计思想
jxTMS编程手册
下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:
如何用jxTMS开发一个功能
下面的系列文章讲述了jxTMS的一些基本开发能力:
jxTMS的HelloWorld