在另一篇文章讲述了client API设计(IOT command (based on sip)client API设计 for java )。
前段时间梳理了command设计及框架,其实狭义上即设备控制、管理,即可以家庭局域网内进行管理,也可以远程管理(通过开源的sip server: opensips),当然也包含了设备联动规则的原型实现(即物联网的ITTT).
command包含两部分:即client和server(eg. 手机上的client app,gateway上的server)
流程如下图所示:
1. 手机发送远程请求:对房间内hue开灯
2. 物联网cloud平台接收到请求转发给相应的gateway
3. command_svr接收,解析发送给hue模块,hue模块进行本设备类型协议的通信,实现开灯请求
4-5. command_svr将操作结果发送回去,由opensips转发给client, client获知开灯成功结果。
client主要功能:
1. 请求gateway的设备列表,设备功能,状态
2. 发送设备操作请求,并接收设备操作结果
3. 订阅, 接收设备消息通知
sever主要功能:
1. 管理接入到gateway的不同设备类型列表,设备插件以动态库形式接入,方便第三方接入。
2. 接收client的设备操作请求,转发给相应的设备模块(eg 上图ip_camera),由该模块进行协议转换,进行实际的设备控制,然后接收操作结果,并将其转换为command协议,返回给client response.
3. 接收设备模块的主动推送的消息,并推送给相应的client.
4. ittt功能:接收并存储client制定的设备联动规则,检查client的设备控制请求,如符合if, 则触发then的设备控制。
目前command的实现是基于sip来实现的,对sip的方法进行扩展,即增加一个定制的方法sip-command,并在其基础上实现
设备控制层,command在pjsip开源库基础上实现,而远程管理借助开源的opensips服务器,达到快速原型目的; 另外一个原因是项目中流媒体传输播放需求是基于sip/rtp来实现,统一在sip下,减少学习投入成本,尽快出原型。
下图是一个command框架图,底层是sip层,在pjsip基础上增加了command方法;cmd_mng定义了两个主要接口(cmd_send_inf, cmd_recv_inf)来和sip层进行通信, 考虑将来方便替换或兼容不同的协议,达到模块间松耦合。cmd_mng上层分别是dev_mng和iot_cmd_proc两个模块,dev_mng包含了
command server端的管理、加载设备插件,即设备的function功能和设备元数据文件解析导入(通过定义plugin_interface接口,提供给第三方开发为gateway接入新设备类型),以及供client查询设备元信息的内部接口。iot_cmd_proc模块则包含了client, server的收发command消息的处理框架,和提供给第三方开发client端的接口(即开头讲到的client API设计)。
1. 下面介绍server端的供第三方接入新设备类型开发的接口定义(第三方实现,并以动态库的方式提供给gateway command-svr)
plugin_interface接口:
typedef struct dev_func { const char * funcname; int (* dev_method)(cmd_arg * param_list[], uint8_t plist_size); }dev_func; typedef struct dev_plugin { char dev_pluginname[NAME_MAXSIZE]; //设备类型名称,具有唯一性 const dev_func * pt_func_array; //函数列表,设备实际执行函数,供command-svr回调。 char dev_metafile[NAME_MAXSIZE]; //设备元数据文件 }dev_plugin; typedef int (* init_devplugin)(dev_plugin * pt_plugin, dev_cmd_interface * pt_inf);
command-svr通过init_devplugin函数,会读取到该设备插件的上面信息, gateway便知晓该设备类型具有的属性和功能。
(后续还需要有设备插件的热更新,删除,运行时加载等功能)
2. 下面介绍iot_cmd_proc模块,它是command的逻辑处理核心
以client端为例,
采用内存消息队列形式(使用mini_mq)来解耦业务层(cli_proxy),command层(cmdhandler_proc),承载msg的协议层(sip_proxy)
原型开发完后,总结了下开发,使用时碰到的各种问题:
1. command的设备控制设计,是以设备的动作为目标,如下test设备类型的元数据定义
<device type="test_plugin"> <method name="test1"> <param name="a" type="int" direction="IN"/> <param name="b" type="string" direction="IN"/> <param name="c" type="float" direction="OUT"/> <param name="d" type="string" direction="OUT"/> </method> </device>
如果加入设备propery属性,可以很好的契合下个阶段command的协议采用http的restful风格,以设备资源属性为目标,简单通过
set, get来实现对设备的操作(当然正如不是所有的web服务都能完美的采用restful, 设备控制操作可以采用属性,动作均定义的方式)。
2. 正如上面描述到的,我考虑command的协议采用http,在gateway使用web服务方式,client端就采用hybrid方式,即避免command
的client, server更新问题,又使用原生来避免web的不足,目前已经在调研中。
3. 设计一个的iot_cloud原型,暂定功能主要为方便用户远程管理设备,以及存储用户设备数据,及简单的数据分析。