# IOTOSDK-Python **Repository Path**: tynice/IOTOSDK-Python ## Basic Information - **Project Name**: IOTOSDK-Python - **Description**: IOTOS Python版本SDK,自带原生接口和采集引擎 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: http://docs.aiotos.net/docs/iotos/iotos-1db943sp5npaf - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 21 - **Created**: 2023-06-01 - **Last Updated**: 2023-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## IOTOS物联中台 vs 常见物联网平台 - 侧重面向集成项目、存量设备子系统接入 **vs** 面向消费端智能硬件、增量设备接入 - 降低接口协议驱动的开发门槛 **vs** 新产品的创建和连接管理 - 强调工具化,驱动由项目实施人员来配置交付项目 **vs** 实现硬件设备出厂直接接入IoT平台 ## 历史版本说明 ### 4.0.1.220928_release 升级驱动类的setValue()方法,在端侧支持数据点上报自动创建机制 ### 4.0.1.220501_release #### 驱动命名规则: - 初步拟订驱动命名规则,以dr_开头为普通接口协议层驱动,以drl_开头为通信连接层驱动。 - 两类型驱动可以通过同一个网关下组合,不同设备间的本地发布订阅来使用 ### 驱动类(用于开发编写驱动包) ```python #!coding:utf8 import json import sys sys.path.append("..") from driver import * class TemplateDriver(IOTOSDriverI): ''' 驱动派生类模板,直接编写设备子系统接入相关的接口协议转换代码 1.属性: 1.1 String sysId 设备实例全局标识 1.2 Json sysAttrs 设备实例配置属性 1.3 Json data2attrs 数据点与属性配置键值对 1.4 Json data2subs 数据点与被订阅设备列表键值对 1.5 Json name2dataId 数据点名称与对应标识键值对 2.方法 2.1 String getSysId() 获取设备标识(参见1.1) 2.2 Json getSysAttrs() 获取设备配置(参见1.2) 2.3 Json getData2attrs() 获取数据点配置(参见1.3) 2.4 Json getData2subs() 获取数据被订阅信息(参见1.4) 2.5 String id(String name) 数据点名称转标识(参见1.5),将名称标识(方便阅读和修改的)换成ID标识(保证唯一性,方便驱动代码复用) 注意,支持"[数据点名称]"或"[设备名称].[数据点名]",暂不支持"全名称"("[网关名称].[设备名称].[数据点名称]") 2.6 String name(String id) 数据点标识转名称,将标识ID转成名称 注意,支持"[数据点标识]"或"[设备标识].[数据点标识]",暂不支持"全ID标识"("[网关标识].[设备标识].[数据点标识]") 2.7 None setPauseCollect(Bool enable=True) 传入True或False,设置3.3中Collecting()是否停止采集循环遍历,默认不启动。调用并传入False将启动采集循环(线程), 按顺序自动从数据点表第一个到最后一个进行遍历传入,详见3.3。 2.8 None setCollectingOneCircle(Bool enable=True) 在2.7设置启用采集循环前提下,传入True或False,设置3.3中采集循环是周期循环遍历,还是初始化遍历完数据点表一次就退出(默认) 2.9 String pointId(String dataId) 根据当前设备下数据点由ID标识,获取带网关、设备的"全ID标识"("[网关标识].[设备标识].[数据点标识]") @param dataId: String 数据点ID标识,如"0b2e" @return String 全ID标识,如'9003f858c85011ecbb02525400ffc252.e2c4f6fe.0b2e' 2.10 String(Json) setValue(String name=None,id=None, Bool/String/Int/Float value, Timestamp timestamp=time.time(), Bool auto_created=False) 上报当前设备下单个数据点的值。注意name、id保证有任一传入即可,不要都传入。 @param name: String 数据点名称 id: String 数据点ID标识 value: Bool/String/Int/Float 数据点上报值 @return String Json字符串:{"code": 0, "msg":"", "data":""},返回格式及错误码详见README.md 2.11 String(Json) setValues(Json data_values) 批量上报数据点值。 @param data_values: Json 多个数据点与值组成的json数组,比如[{"id": "数据点ID", "value": "数据点value"}, {"id": "数据点ID", "value": "数据点value"}] @return String 多个返回结构Json数组字符串,比如[{"code": 0, "msg":"", "data":""},{"code": 0, "msg":"", "data":""}],返回格式及错误码详见README.md 2.12 Bool/String/Int/Float valueTyped(String dataId,String strValue) 将字符串类型的值按照点表类型转换成实际类型 @param dataId: String 数据点ID标识 strValue: String 数据点值对应的字符串 @return Bool/String/Int/Float 根据数据点的实际类型将字符串数值转换成实际类型 2.13 Bool/String/Int/Float value(String name,String param='',String source='memory') 获取数据点的当前值,包含从采集引擎缓存、平台数据库、以及设备当下最新这三种方式 @param name: String 数据点名称 param: String 查询条件, source: String 有'memory'、'device'、'platfrom'三个来源参数,简写m/M,d/D,p/P,分别是上次采集到引擎的数据、设备当前数据、上报到平台的数据三类 @return Bool/String/Int/Float 按照实际类型返回数据点当前值 2.14 String(Json) subscribers(self, dataId) 订阅了当前设备指定监测点的外部设备ID标识列表 @param dataId: String 数据点ID标识 @return String 返回Json数组字符串,比如["d8540013","36cb7dd8","82591776"] 2.15 String(Json) online(Bool state) 上报平台设备上下线状态 @param state: Bool 上线(True)/下线(False) @return String 参见详见README.md,通用数据返回结构 ''' ''' 3.服务(引擎回调,需用户重写实现的驱动代码) 3.1 通信初始化:Bool InitComm(Json attrs) 3.2 通信连接状态回调(非必要,结合jcomm.py):None connectEvent(Bool state): 3.3 循环采集:Dict/Array Collecting(String dataId): 3.4 平台下发广播:String(Json) Event_customBroadcast(String fromUuid,String type,String data): 3.5 平台下发查询:String(Json) Event_getData(String dataId, string condition): 3.6 平台下发控制:String(Json) Event_setData(String dataId, Bool/String/Int/Float value): 3.7 订阅数据上报:String(Json) Event_syncPubMsg(String point, Bool/String/Int/Float value): ''' #3.1 通信初始化 def InitComm(self,attrs): ''' 需要用户实现的设备通信初始化。 Parameter attrs: dict 点表json加载并补全(参见parent指向)后,当前设备下包括数据的部分,示例如下: { "id": 11, "device_oid": "d8540013", "gateway_uuid": null, "gateway_id": 8, "uid": 28, "config": { "driver": "python/dr_pingshanshuiwu.ZSWDriver" }, "name": "水位尺", "type": "", "description": "河道水文监测站-水位尺", "timestamp": 1650774553.0, "on": false, "tpl_id": 9, "data": { "20bf": { "id": 877, "name": "msgId", "description": "流水号(累加)", "config": {}, "defaultvalue": "", "readwrite": "1", "timestamp": 1651338138724, "valuetype": "STRING", "maxvalue": "999", "minvalue": "0", "sensibility": "0.1", "refreshcycle": "0", "unit": null, "tpl_id": 9, "regexp": "english", "value": null, "data_date": null, "data_oid": "20bf" }, } } Return bool: True/False ''' ''' TODO #self.setPauseCollect(True) #self.setCollectingOneCircle(False) #self.online(True) #self.setValue(u'demo_device.热水供水泵控制', True) '''' return True #3.3 循环采集 def Collecting(self, dataId): ''' 对点表自动遍历的采集循环,可开启或关闭(对于主动上报,不存在遍历采集的情况) Parameter dataId: string 当前数据点全局标识id,示例如"0b2e" Return tuple: () 元组类型返回,多个不同类型数据的顺序组合,比如modbus批量采集数据后多个值的返回。 [*]应该支持多类型返回,常规数值类型,或元组都可以,目前直接返回dataId,报错;返回(dataId)报错;返回[dataId]才可以! ''' ''' TODO '''' return () #3.4 平台下发广播 def Event_customBroadcast(self, fromUuid, type, data): ''' 高级用途,广播事件回调,其他操作访问,详略 ''' ''' TODO ''' return json.dumps({'code':0, 'msg':'', 'data':''}) #3.5 平台下发查询 def Event_getData(self, dataId, condition): ''' 查询事件回调,数据点查询访问 Parameter dataId: string 当前数据点全局标识id,示例如"0b2e" condition: string 结合驱动支持下发的自定义查询条件 Return string: 查询结果转成string类型返回 ''' ''' TODO ''' return json.dumps({'code':0, 'msg':'', 'data':''}) #3.6 平台下发控制 def Event_setData(self, dataId, value): ''' 控制事件回调,数据点控制访问 Parameter dataId: string 当前数据点全局标识id,示例如"0b2e" value: 下发设备控制或写入的值,由数据点自身属性来决定类型,通常为Bool或String Return string: 执行结果转成string类型返回 ''' ''' TODO ''' return json.dumps({'code':0, 'msg':'', 'data':''}) #3.7 订阅数据上报 def Event_syncPubMsg(self, point, value): ''' 数据订阅的事件回调。通常是同一个网关下不同设备上报的数据(兼容高级用途跨网关远程数据点订阅,略),常见订阅规则如下, 在当下驱动对应的设备实例驱动根配置中,param.sub以数组形式订阅同一个网关下其他一个或多个设备上报到平台的数据,以 [设备全局标识].[数据点全局标识],其中数据点全局标识可以指定也可以用*代替,表明指定设备所有setValue上报的数据都会 被订阅过来,在这里做数据处理,通过业务逻辑加工(常见是报文协议解析)后再做上报。 { "driver": "python/dr_xxx.xxxDriver", "param": { "sub": [ "1bcd6b35.*" ], } } Parameter point: string 当前数据点全ID(网关标识.设备标识.数据点标识),示例如"9003f858c85011ecbb02525400ffc252.e2c4f6fe.0b2e",id难以辨别可通过self.name()转换 value: 上报对应的值,由数据点自身属性来决定类型,通常为Bool/String/Int/Float Return string: string类型返回。注意同网关下不同设备的订阅为异步,可以默认返回或不返。兼容高级用途跨网关远程数据点订阅,返回值解释略 ''' ''' TODO ''' return json.dumps({'code':0, 'msg':'', 'data':''}) ``` ### 通用返回格式 ``` { "code": 0, //0表示调用成功;非0则标识异常,具体见"错误码定义" "msg" :"ok", //code为0时,为描述信息;非0则对应错误码定义中的英文内容 "data":null, //code为0时,由具体业务接口返回数据而定,接口无返回则data为null,有返回则data为数据的字符串格式; //code不为0时,通常存放程序捕获的异常信息字符串 } ``` ### 驱动根配置 参考配置格式如下: { "parentid": null, "driver": "python/drl_tcp.TCPDriver", "param": { "port": 3883, "sub": [] //本地设备间的数据发布和订阅 }, "datahub": "", //连同下面display,设置组态页面连接 "display": "", //同上 "bind": {} } 关于param.sub,本地设备间的数据发布和订阅: > 同一个网关下,多个设备实例比如A、B、C。其中A在正常从设备到平台数据点setValue上报过程中,设备B和C也需要该数据,那么可以在设备B、C的设备驱动配置中param.sub中订阅A的数据。 > 指定“[设备ID].[数据点ID]”(其中数据点ID可以用*号代替,表明订阅全部A中的数据!),那么对应A中被订阅的数据点上报时就会通过B、C的Event_syncPubMsg()事件函数传递过来! > 常规IoT平台的方式:创建产品、设备(选择传输协议、消息协议),创建网关、网络组件。目前版本暂不支持这种方式配置(后续版本会提供)。 >相对应地提供本地设备间数据的发布与订阅功能,一方面可实现常规传输协议与接口或报文协议组合,另一方面能实现本地联动调度以及算法服务类的虚拟设备接入,专用于数据处理。 >上面本地发布订阅做到监听获取上行数据,那么订阅方的驱动怎么复用下行通道呢:setValue([设备名].[数据点名],val)即可!没有特殊机制! ### 错误码定义 #### 数值范围对应错误源 ``` 0~99: 通信路由返回 100~499: 数据后台返回 500~999: 采集引擎返回 ``` #### 错误码详细参照表 | 错误码 | Enum定义(data) | 中文描述 | 错误信息返回(msg) | | ---- | ---- | ---- | ---- | | 0 | Sucess | 没有错误(返回成功) | Success | | 101 | Unknown | 未知失败 | Unknow error(当内部调用第三方库返回错误时,将库的反馈错误信息原样返回) | | 2 | SelfOffline | 自己掉线 | self offline! | | 3 | ObjectOffline | 网络错误 | Network error | | 504 | NetError | 没有错误(返回成功) | Success | | 105 | ArgError | 参数错误 | Argument error | | 105 | ArgError | 参数错误 | Argument error | |6 | NoWebSer | 没有WEB服务接入 | No webserver online!| | 107 | AccountNotRegister | 用户名或密码错误,或登录失效 | Account invalid | | 108 | IONodeNotExist | 接入网关不存在 | Object not exists | | 109 | DeviceNotExist | 设备不存在 | Device not exits | | 110 | DataNotExist | 数据点不存在 | Data not exists | | 111 | PointNotExist | 点不存在 | Point not exists | | 112 | ObjectNotAuth | 对象没有授权,目前指没有订阅相关接入网关 | Object has no authority | |513 | FileNotExist| 文件不存在 | File not exists | | 514 | TableNotValid | 点表格式不正确 | Table format invalid | | 515 | PropertyNotValid | 属性非法操作 | Property access invalid | | 516 | TypeNotValid | 监测点类型不匹配 | Point type mismatching | | 517 | RuleNotRecognized | 监测点条件规则未识别 | Table format not recognized | | 518 | ThreadNotDestoryed | 采集线程创建失败,存在未释放的 | Inner resource not released | | 519 | Timeout | 接口请求超时 | Timeout | | 521 | DataNameInvalid | 数据点名称不正确 | DataName not exist | | 522 | TypeNotSupport | 参数类型不正确 | type not support | | 1000 |Reserved | 以内的系统保留,大于的为用户服务自定义码| user customed|