docker版jxTMS使用指南:python服务之jxLocalStateMachine

本文讲解4.0版jxTMS中python服务的jxLocalStateMachine模块,整个系列的文章请查看:docker版jxTMS使用指南:4.0版升级内容

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

jxLocalStateMachine提供了一个简单可靠的有限状态自动机。之所以叫做local,是因为jxTMS的python服务原本为了配合智能硬件工作,还提供了一个jxStateMachine的有限状态自动机【参考用jxTMS开发智能转运箱】。jxStateMachine是从智能硬件接收事件来驱动的,而jxLocalStateMachine则是本地手动触发事件来驱动的。

jxLocalStateMachine的几个概念:

  • 状态,一个稳定的、可识别的阶段

  • 初始状态,自动机启动后所处的第一个状态

  • 跃迁,从一个状态切换到另一个状态

  • 事件,外部对自动机的触发,事件可能导致自动机跃迁,也可能不跃迁,事件所起到的作用,首先取决于事件发生时状态机所处的状态。某状态时,如果指定接收到某事件时的处理,该事件就叫做此状态下的期望事件;某状态所有期望事件之外的事件,叫做该状态的非期望事件,也就是异常事件

  • 响应,当跃迁发生时,自动机需要执行的动作,一般就是一个函数

  • 跌落,某状态下出现非期望事件时跃迁到某个预设状态

有限状态自动机的工作机制是:

  • 某状态时触发了某事件,如果该事件是此状态的期望事件,则跃迁到指定的状态【该状态可以是本状态】并执行响应动作

  • 非期望事件发生时如果定义了跌落,则跃迁到跌落状态,并执行对应的异常处理

  • 非期望事件发生时未定义跌落,则不做任何响应

jxLocalStateMachine提供的自动机包括三个部分:

  • 状态跃迁图,定义自动机的状态、跃迁、事件、跌落等

  • 响应函数,当响应时需要执行的处理函数

  • 自动机实例,保存当前状态的、实际运行中的自动机。需要状态跟踪的对象一般都被定义为自动机实例,这会比较自然,如device中跟踪设备状态

定义状态机

引用:

from jx.jxLocalStateMachine import jxLocalStateMachine

状态机的定义需要先创建一个jxLocalStateMachine对象。其初始化函数为:

class jxLocalStateMachine:
    def __init__(self,name, initState):
    ...

其中:

name:状态机的名字
initState:状态机的初始状态

如用于设备状态跟踪的自动机:

_devSM = jxLocalStateMachine('devSM','init')

状态机的对象函数有:

addTrans(self, state, event, toState, dual)

定义一个跃迁

参数:
	 state:当前状态
	 event:事件
	 toState:跃迁到的状态,也可以是当前状态
	 dual:响应函数,None则不执行
返回值:
	无
示例:
	#当前状态为idel时,发生了start事件,则跃迁到mi状态,并执行receiveStart函数
	vrs20SM.addTrans('idel','start','mi',receiveStart)
说明:
	某个状态下,所有用addSMTrans定义的事件,就是本状态的期望事件;期望事件之外的事件,就是非期望事件。如果没有给当前的状态定义跌落,那么所有的非期望事件都不做任何动作

addFall(self, state, elseState,elseDual)

定义一个跌落

参数:
	 state:当前状态
	 fallState:跌落到的状态
	 fallDual:响应函数,None则不执行
返回值:
	无
示例:
	#当前状态为init时,发生了非期望事件,则跃迁到idel状态并执行errorDual函数
	vrs20SM.addFall('range','idel',errorDual)
说明:
	本状态下出现了非期望的意外事件时的行为

如果一个状态,没有定义跌落,则出现非期望事件时不做任何动作,只是默默丢弃事件。

那么,如果给某状态用addTrans定义了出现某事件后跃迁回本状态,那和不用addFall定义该事件的跌落有什么区别呢?!两点:

1、addTrans如果定义了,则命中时,不管跃迁到哪个状态,都会执行响应函数

2、没用addTrans定义某事件跃迁回自己,如果定义了addFall,则会出现跌落

这样一来,在某状态时,【用addTrans定义了发生某事件后跃迁回本状态,但响应函数为None,虽然没有意义,但打开debug时可以跟踪状态机的运行情况】等价于【没有定义addFall,同时也没有用addTrans定义某事件的跃迁】。

状态机实例

状态机实例是定义好的自动机的具体应用,其在初始化时需要指定是哪个自动机的实例。

引用:

from jx.jxLocalStateMachine import SMInstance

目标对象继承自动机实例,并在初始化时声明其由哪个自动机衍生即可。如设备:

class device(SMInstance):
    def __init__(self, name,...创建设备所需的参数):
        super(device , self).__init__(_devSM,name=name)
    ...

这样一来,每台设备都可以跟踪自己的状态变化。

又如vrs20SM设备解析数据的自动机:

class vrs20(SMInstance):
    def __init__(self, ...参数表):
        super(vrs20 , self).__init__(vrs20SM)
    ...

则vrs20就可以绑定给一台设备来解析其接收到的消息。

状态机实例的对象函数:

happen(self,event,param=None)

触发一个事件

参数:
	 event:事件
	 param:事件参数
返回值:
	无
示例:
	#设备超时
	self.happen('timeOut')

currentState(self)

获取当前状态

参数:
	 无
返回值:
	当前状态

name(self)

获取自动机实例的名字,如果创建实例时给出了实例名,则实例的全名是:{自动机名}.{实例名},否则就只是:{自动机名}

参数:
	 无
返回值:
	自动机实例的名字

debug(self, bv)

设置本自动机示例的运行跟踪,如果打开,则happen事件时会对自动机的运行过程进行全面跟踪,打印到日志中,包括没动作的情况

参数:
	 bv:是否跟踪,bool
返回值:
	无

响应函数

响应函数的示例:

def errorDual(SMInstanceObj, param):
    ...

SMInstanceObj就是调用的happen触发事件的自动机实例,param就是调用happen送入的参数

大家可以参考app目录中的policy_vrs20.py文件中vrs20SM的定义和使用。

参考资料:

jxTMS设计思想

jxTMS编程手册

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

如何用jxTMS开发一个功能

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

jxTMS的HelloWorld

你可能感兴趣的:(jxTMS,python,docker,SaaS,jxTMS)