1# -*- coding: UTF-8 -*- 2 3import _linkkit as _lk 4import ujson 5 6""" 7 8 9 10阿里云物联网平台提供安全可靠的设备连接通信能力,支持设备数据采集上云,规则引擎流转数据和云端数据下发设备端。此外,也提供方便快捷的设备管理能力,支持物模型定义,数据结构化存储,和远程调试、监控、运维。 基于iot模块可以简单快速的使用阿里云物联网平台能力。 11 12iot模块的主要实现是一个Device 类,通过它的构造函数获取device实例,就可以轻松设置相关回调函数和调用相关方法。阿里云物联网平台中涉及三个基本概念如下: 13 14- 属性(prop) 15 云端/设备端数据互通的通道,云端通过改变prop值,反馈到设备端,设备端修改prop值,保存到云端 16 17- 事件(event) 18 设备端到云端的事件通知 19 20- 服务(service) 21 云端到设备端的服务调用 22 23详细使用示例请参考主页”参考案例”中的云端连接/控制部分 24 25 26""" 27 28class Device(object): 29 """ 30 31 初始化物联网平台Device类,获取device实例 32 33 :param data(dict): data字典的key信息如下 34 35 .. list-table:: 36 37 * - 属性 38 - 类型 39 - 是否必填 40 - 说明 41 * - deviceName 42 - 字符串 43 - Y 44 - 物联网平台上注册的设备名称 45 * - deviceSecret 46 - 字符串 47 - Y 48 - 物联网平台上注册的deviceSecret 49 * - productKey 50 - 字符串 51 - Y 52 - 物联网平台上注册的productKey 53 * - productSecret 54 - 字符串 55 - 可选 56 - 物联网平台上注册的productSecret 57 * - region 58 - 字符串 59 - 可选 60 - 默认值是'cn-shanghai' 61 62 使用示例:: 63 64 import iot 65 66 productKey = "a1uTFk4xjko" 67 productSecret = "xxxxxxx" 68 deviceName = "mpy_001" 69 deviceSecret = "xxxxxxxxxxxxxxx" 70 key_info = { 71 'region' : 'cn-shanghai' , 72 'productKey': productKey , 73 'deviceName': deviceName , 74 'deviceSecret': deviceSecret , 75 'productSecret': productSecret 76 } 77 device = iot.Device(key_info) 78 79 80 81 """ 82 83 def __init__(self,data): 84 85 def __str_is_empty(value): 86 if value is None or value == "": 87 return True 88 else: 89 return False 90 91 if not isinstance(data,dict): 92 raise ValueError("Class Device init param must be dict") 93 94 if not 'productKey' in data: 95 raise ValueError('Device init : param must have key "productKey"') 96 elif __str_is_empty(data['productKey']): 97 raise ValueError("productKey wrong") 98 99 if not 'deviceName' in data: 100 raise ValueError('Device init : param must have key "deviceName"') 101 elif __str_is_empty(data['deviceName']): 102 raise ValueError("deviceName wrong") 103 104 if not 'deviceSecret' in data: 105 raise ValueError('Device init : param must have key "deviceSecret"') 106 elif __str_is_empty(data['deviceSecret']): 107 raise ValueError("deviceSecret wrong") 108 109 if 'productSecret' in data: 110 self.productSecret = data['productSecret'] 111 else: 112 self.productSecret = "" 113 114 if 'region' in data: 115 self.region = data['region'] 116 else: 117 self.region = "cn-shanghai" 118 119 self.data = data 120 121 # ret = _lk.init(region,data['productKey'],data['deviceName'],data['deviceSecret'],productSecret) 122 # print("init return :") 123 # print(ret) 124 # _lk.register_dyn_dev() 125 126 self._callback = {} 127 128 129 130 # def publish(self): 131 # pass 132 133 # def subscribe(self): 134 # pass 135 136 # def unsubscribe(self): 137 # pass 138 139 140 141 def on(self,event,callback): 142 143 """ 144 通过这个函数,可以设置物联网平台各种事件的处理函数,函数接收两个参数分别是事件名称和事件处理函数 145 146 :param event(str)): 需要注册的事件名称,类型是字符串 147 148 .. list-table:: 149 150 * - 事件名称 151 - 事件说明 152 * - connect 153 - 当iot设备连接到物联网平台的时候触发'connect' 事件 154 * - disconnect 155 - 当连接断开时,触发'disconnect'事件 156 * - props 157 - 当iot云端下发属性设置时,触发'props'事件 158 * - service 159 - 当iot云端调用设备service时,触发'service'事件 160 * - error 161 - 当设备跟iot平台通信过程中遇到错误时,触发'error'事件 162 163 :param callback: 回调函数 164 165 使用示例:: 166 167 def on_connect(): 168 print('linkkit is connected') 169 170 device.on('connect',on_connect) 171 172 def on_disconnect(): 173 print('linkkit is disconnected') 174 175 device.on('disconnect',on_disconnect) 176 177 def on_props(request): 178 print('clound req data is %s' %(request)) 179 180 device.on('props',on_props) 181 182 183 def on_service(id,request): 184 print('clound req id is %d , req is %s' %(id,request)) 185 186 device.on('service',on_service) 187 188 189 def on_error(err): 190 print('err msg is %s '%(err)) 191 192 device.on('error',on_error) 193 194 195 """ 196 197 # if not callable(callback): 198 # raise ValueError("the 2nd param of function on must be function") 199 200 # if (event == 'connect'): 201 # _lk.register_call_back(_lk.ON_CONNECT,callback) 202 # elif (event == 'disconnect'): 203 # _lk.register_call_back(_lk.ON_DISCONNECT,callback) 204 # elif (event == 'close'): 205 # _lk.register_call_back(_lk.ON_CLOSE,callback) 206 # elif (event == 'error'): 207 # _lk.register_call_back(_lk.ON_ERROR,callback) 208 # elif (event == 'props'): 209 # _lk.register_call_back(_lk.ON_PROPS,callback) 210 # elif (event == 'service'): 211 # _lk.register_call_back(_lk.ON_SERVICE,callback) 212 self._callback[event] = callback 213 214 def connect(self): 215 ''' 216 连接物联网平台连接函数,该函数是异步调用 217 ''' 218 219 for key in self._callback: 220 event = key 221 callback = self._callback[key] 222 print(event) 223 # if not callable(callback): 224 # raise ValueError("the 2nd param of function on must be function") 225 226 if (event == 'connect'): 227 _lk.register_call_back(_lk.ON_CONNECT,callback) 228 elif (event == 'disconnect'): 229 _lk.register_call_back(_lk.ON_DISCONNECT,callback) 230 elif (event == 'close'): 231 _lk.register_call_back(_lk.ON_CLOSE,callback) 232 elif (event == 'error'): 233 _lk.register_call_back(_lk.ON_ERROR,callback) 234 elif (event == 'props'): 235 _lk.register_call_back(_lk.ON_PROPS,callback) 236 elif (event == 'service'): 237 _lk.register_call_back(_lk.ON_SERVICE,callback) 238 239 240 ret = _lk.init(self.region,self.data['productKey'],self.data['deviceName'],self.data['deviceSecret'],self.productSecret) 241 _lk.register_dyn_dev() 242 243 _lk.connect() 244 245 def postProps(self,data): 246 """ 247 上报设备属性 248 249 250 :param data(dict): 字典的key信息如下 251 252 .. list-table:: 253 254 * - 属性 255 - 类型 256 - 是否必填 257 - 说明 258 * - params 259 - 字典 260 - Y 261 - 属性的值对应的是物联网平台的json数据 262 263 使用示例:: 264 265 data = { 266 'params': { 267 'test_prop' : 100 268 } 269 } 270 device.postProps(data) 271 272 """ 273 if not isinstance(data, dict): 274 raise ValueError("postProps func param must be dict") 275 276 if not 'params' in data: 277 raise ValueError('data must have key: "params"') 278 return _lk.post_property(ujson.dumps(data['params'])) 279 280 281 282 def postEvent(self,data): 283 """ 284 上报设备的事件 285 286 :param data(dict): 字典的key信息如下 287 288 .. list-table:: 289 290 * - 属性 291 - 类型 292 - 是否必填 293 - 说明 294 * - params 295 - 字典 296 - Y 297 - 属性的值对应的是物联网平台的json数据 298 * - id 299 - 字符串 300 - Y 301 - 事件名称,请参考物模型上定义的事件id 302 303 使用示例:: 304 305 data = { 306 'id': 'EventTest' , 307 'params': { 308 'test_event' : 100 309 } 310 } 311 device.postEvent(data) 312 313 314 """ 315 if isinstance(data, dict): 316 if not 'id' in data: 317 raise ValueError('data must have key: "id"') 318 if not 'params' in data: 319 raise ValueError('data must have key: "params"') 320 321 else: 322 raise ValueError("postEvent func param must be dict") 323 return _lk.post_event(data['id'],ujson.dumps(data['params'])) 324 325 326 def close(self): 327 ''' 328 关闭物联网设备节点,断开连接 329 ''' 330 return _lk.close() 331 332 def do_yield(self,time): 333 """ 334 激活物联网平台接收云端消息,并设置接收超时时间为:timeout, 单位是 ms.为了保证云端消息被接收到,执行了异步命令以后,需要循环执行这个方法,直到拿云端的返回 335 """ 336 _lk.do_yield(time) 337 338 339 # def __register_callback(self): 340 # _lk.register_call_back(1,self.__on_connect) 341 # _lk.register_call_back(3,self.__on_disconnect) 342 # _lk.register_call_back(5,self.__on_service_request) 343 # _lk.register_call_back(7,self.__on_prop_set) 344 # _lk.register_call_back(9,self.__on_thing_prop_post) 345 # _lk.register_call_back(10,self.__on_thing_event_post) 346 347 348# class GateWay(object): 349 350# def addTopo(self): 351# pass 352 353# def getTopo(self): 354# pass 355 356# def removeTopo(self): 357# pass 358 359# def login(self): 360# pass 361 362# def logout(self): 363# pass 364 365# def regiestSubDevice(self): 366# pass 367 368# def register(): 369 # pass 370