动作组件主要负责对各动作执行器进行控制,目前主要包括有gpio的输出控制、i2c设备控制等,当然还包括了下属各设备(目前只考虑nodeMCU参见远程PWM实验)的远程控制,还包括了定时器的启动、手机等智能前端显示状态修改等。
动作组件在有了JXPi平台的支持后实现起来是很简单的,其唯一需要考虑的是控制逻辑处理点和动作的实际执行点很可能不在同一个智能体上。考虑到上层系统处理的一致性,最终将其执行过程分为两阶段来执行:
显式触发:当控制逻辑组件决定有必要执行某动作后,由于动作的具体执行点未必就在本地,所以控制逻辑组件只对该动作的本地代理做一个显式触发,也就是下达一个要求该动作执行的命令。该动作的本地代理如何执行,控制逻辑组件就不在过问,执行结果如何,控制逻辑组件也不关心
异地执行:动作接收到执行命令后,将通过消息系统将动作执行命令下达给特定接收点(注意和消息的区别),接收方在接收到该命令后将临时创建一个动作的副本,在接收本地执行该动作,执行完毕即丢弃该副本。即便动作执行点也在控制逻辑组件所在的本地智能体上,动作执行流程都是一样的,消息系统是否短路本地消息传递过程并不在控制逻辑组件的考虑范围之内
由于底层消息的传递目前只考虑全网广播模式,所以为了降低如全开、全关、某楼层/区域全关、某类全关、所有空调设为26摄氏度等控制功能的通信量,动作组件也支持组接收。当然,由于不同种类的动作其参数是不一样的,所以同一组的动作需要为同一类型,如gpio开关和下属单片机上的gpio开关可以分到一个组内,但gpio开关和i2c端口显然无法用一个组动作命令来控制。
组接收的难点在于一条命令如何有针对性的翻译成本地的具体命令,如通用的gpio置高电平命令,如何在智能体将之翻译成本地的gpio或是下属某设备的gpio置高电平命令。目前的解决办法是标准化端口命名,但这样的弊端是动作对象的逆向构造,即具体的某gpio动作由通用的gpio动作解析出来,而通用gpio动作则由基本动作解析出来,所以需要一个工厂类来处理动作命令的正确解析。