├── Readme.txt ├── data_transfer.js ├── dynamic_register.py ├── model_raw.json ├── mqtt_connect_TCP.py ├── mqtt_connect_TLS.py ├── mqtt_sub_pub_on.py ├── thing_alink.py ├── thing_custom.py └── tsl.json /Readme.txt: -------------------------------------------------------------------------------- 1 | # 阿里云物联网平台 (项目示例) 2 | 3 | > aliyun-iot-linkkit-examples 4 | 5 | 6 | * dynamic_register.py 动态获取deviceScret 7 | * mqtt_connect_TCP.py 通过TCP方式建立MQTT连接 8 | * mqtt_connect_TLS.py 通过TLS加密方式建立MQTT连接 9 | * mqtt_sub_pub_on.py 展示mqtt订阅,发布,接收消息 10 | * thing_alink.py 通过透传协议,展示物模型能力,进行属性上报,属性设置,事件上报,服务响应 11 | * tsl.json thing_alink.py使用的物模型文件 12 | * thing_custom.py 通过用户自定义协议进行展示属性设置及属性上报 13 | * model_raw.json thing_custom.py 使用的物模型文件 14 | * data_transfer.js thing_custom.py 对应云端的数据解析脚本 15 | -------------------------------------------------------------------------------- /data_transfer.js: -------------------------------------------------------------------------------- 1 | var COMMAND_REPORT = 0x00; 2 | var COMMAND_SET = 0x01; 3 | var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //标准ALink JSON格式topic, 设备 上传属性数据到 云端 4 | var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //标准ALink JSON格式topic, 云端 下发属性控制指令 到设备端 5 | /* 6 | 示例数据: 7 | 传入参数 -> 8 | 0x00002233441232013fa00000 9 | 输出结果 -> 10 | {"method":"thing.event.property.post","id":"2241348", 11 | "params":{"prop_float":1.25,"prop_int16":4658,"prop_bool":1}, 12 | "version":"1.0"} 13 | */ 14 | function rawDataToProtocol(bytes) { 15 | var uint8Array = new Uint8Array(bytes.length); 16 | for (var i = 0; i < bytes.length; i++) { 17 | uint8Array[i] = bytes[i] & 0xff; 18 | } 19 | var dataView = new DataView(uint8Array.buffer, 0); 20 | var jsonMap = new Object(); 21 | var fHead = uint8Array[0]; // command 22 | if (fHead == COMMAND_REPORT) { 23 | jsonMap['method'] = ALINK_PROP_REPORT_METHOD; //ALink JSON格式 - 属性上报topic 24 | jsonMap['version'] = '1.0'; //ALink JSON格式 - 协议版本号固定字段 25 | jsonMap['id'] = '' + dataView.getInt32(1); //ALink JSON格式 - 标示该次请求id值 26 | var params = {}; 27 | params['prop_int16'] = dataView.getInt16(5); //对应产品属性中 prop_int16 28 | jsonMap['params'] = params; //ALink JSON格式 - params标准字段 29 | } 30 | return jsonMap; 31 | //return {"method": "thing.event.property.post","id": "1234567","params": {"prop_float": 1.11,"prop_int16": 1234,"prop_bool": 1},"version": "1.0"} 32 | } 33 | /* 34 | 示例数据: 35 | 传入参数 -> 36 | {"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}} 37 | 输出结果 -> 38 | 0x0100003039014d0142f6e76d 39 | */ 40 | function protocolToRawData(json) { 41 | var method = json['method']; 42 | var id = json['id']; 43 | var version = json['version']; 44 | var payloadArray = []; 45 | if (method == ALINK_PROP_SET_METHOD) // 属性设置 46 | { 47 | var params = json['params']; 48 | var prop_float = params['prop_float']; 49 | var prop_int16 = params['prop_int16']; 50 | var prop_bool = params['prop_bool']; 51 | //按照自定义协议格式拼接 rawdata 52 | payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SET)); // command字段 53 | payloadArray = payloadArray.concat(buffer_int32(parseInt(12345))); // ALink JSON格式 'id' 54 | payloadArray = payloadArray.concat(buffer_int16(prop_int16)); // 属性'prop_int16'的值 55 | } else { 56 | /* 回复上行的请求 */ 57 | var code = json['code']; 58 | payloadArray = payloadArray.concat(buffer_int16(code)); /* 填充payload的值 */ 59 | } 60 | return payloadArray; 61 | } 62 | //以下是部分辅助函数 63 | function buffer_uint8(value) { 64 | var uint8Array = new Uint8Array(1); 65 | var dv = new DataView(uint8Array.buffer, 0); 66 | dv.setUint8(0, value); 67 | return [].slice.call(uint8Array); 68 | } 69 | function buffer_int16(value) { 70 | var uint8Array = new Uint8Array(2); 71 | var dv = new DataView(uint8Array.buffer, 0); 72 | dv.setInt16(0, value); 73 | return [].slice.call(uint8Array); 74 | } 75 | function buffer_int32(value) { 76 | var uint8Array = new Uint8Array(4); 77 | var dv = new DataView(uint8Array.buffer, 0); 78 | dv.setInt32(0, value); 79 | return [].slice.call(uint8Array); 80 | } 81 | function buffer_float32(value) { 82 | var uint8Array = new Uint8Array(4); 83 | var dv = new DataView(uint8Array.buffer, 0); 84 | dv.setFloat32(0, value); 85 | return [].slice.call(uint8Array); 86 | } -------------------------------------------------------------------------------- /dynamic_register.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import logging 4 | 5 | # config log 6 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 7 | logging.basicConfig(format=__log_format) 8 | 9 | lk = linkkit.LinkKit( 10 | host_name="cn-shanghai", 11 | product_key="xxxxxxxxxxx", 12 | device_name="device-name", 13 | device_secret="", 14 | product_secret="yyyyyyyyyyyyyyyy") 15 | 16 | lk.enable_logger(logging.DEBUG) 17 | 18 | 19 | def on_device_dynamic_register(rc, value, userdata): 20 | if rc == 0: 21 | print("dynamic register device success, rc:%d, value:%s" % (rc, value)) 22 | else: 23 | print("dynamic register device fail,rc:%d, value:%s" % (rc, value)) 24 | 25 | 26 | def on_connect(session_flag, rc, userdata): 27 | print("on_connect:%d,rc:%d,userdata:" % (session_flag, rc)) 28 | pass 29 | 30 | 31 | def on_disconnect(rc, userdata): 32 | print("on_disconnect:rc:%d,userdata:" % rc) 33 | 34 | 35 | def on_topic_message(topic, payload, qos, userdata): 36 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 37 | pass 38 | 39 | 40 | def on_subscribe_topic(mid, granted_qos, userdata): 41 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 42 | (mid, str(','.join('%s' % it for it in granted_qos)))) 43 | pass 44 | 45 | 46 | def on_unsubscribe_topic(mid, userdata): 47 | print("on_unsubscribe_topic mid:%d" % mid) 48 | pass 49 | 50 | 51 | def on_publish_topic(mid, userdata): 52 | print("on_publish_topic mid:%d" % mid) 53 | 54 | 55 | lk.on_device_dynamic_register = on_device_dynamic_register 56 | lk.on_connect = on_connect 57 | lk.on_disconnect = on_disconnect 58 | lk.on_topic_message = on_topic_message 59 | lk.on_subscribe_topic = on_subscribe_topic 60 | lk.on_unsubscribe_topic = on_unsubscribe_topic 61 | lk.on_publish_topic = on_publish_topic 62 | lk.connect_async() 63 | 64 | 65 | while True: 66 | try: 67 | msg = input() 68 | except KeyboardInterrupt: 69 | sys.exit() 70 | else: 71 | if msg == "1": 72 | lk.disconnect() 73 | elif msg == "2": 74 | lk.connect_async() 75 | else: 76 | sys.exit() 77 | -------------------------------------------------------------------------------- /model_raw.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema":"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json", 3 | "profile":{ 4 | "productKey":"xxxxxxxxx" 5 | }, 6 | "services":[ 7 | { 8 | "outputData":[ 9 | 10 | ], 11 | "identifier":"set", 12 | "inputData":[ 13 | { 14 | "identifier":"prop_float", 15 | "dataType":{ 16 | "specs":{ 17 | "min":"0", 18 | "max":"10000", 19 | "step":"0.001" 20 | }, 21 | "type":"float" 22 | }, 23 | "name":"prop_float_name" 24 | }, 25 | { 26 | "identifier":"prop_int16", 27 | "dataType":{ 28 | "specs":{ 29 | "min":"0", 30 | "max":"10000", 31 | "step":"1" 32 | }, 33 | "type":"int" 34 | }, 35 | "name":"prop_int16_name" 36 | }, 37 | { 38 | "identifier":"prop_bool", 39 | "dataType":{ 40 | "specs":{ 41 | "0":"off", 42 | "1":"on" 43 | }, 44 | "type":"bool" 45 | }, 46 | "name":"prop_bool_name" 47 | } 48 | ], 49 | "method":"thing.service.property.set", 50 | "name":"set", 51 | "required":true, 52 | "callType":"async", 53 | "desc":"属性设置" 54 | }, 55 | { 56 | "outputData":[ 57 | { 58 | "identifier":"prop_float", 59 | "dataType":{ 60 | "specs":{ 61 | "min":"0", 62 | "max":"10000", 63 | "step":"0.001" 64 | }, 65 | "type":"float" 66 | }, 67 | "name":"prop_float_name" 68 | }, 69 | { 70 | "identifier":"prop_int16", 71 | "dataType":{ 72 | "specs":{ 73 | "min":"0", 74 | "max":"10000", 75 | "step":"1" 76 | }, 77 | "type":"int" 78 | }, 79 | "name":"prop_int16_name" 80 | }, 81 | { 82 | "identifier":"prop_bool", 83 | "dataType":{ 84 | "specs":{ 85 | "0":"off", 86 | "1":"on" 87 | }, 88 | "type":"bool" 89 | }, 90 | "name":"prop_bool_name" 91 | } 92 | ], 93 | "identifier":"get", 94 | "inputData":[ 95 | "prop_float", 96 | "prop_int16", 97 | "prop_bool" 98 | ], 99 | "method":"thing.service.property.get", 100 | "name":"get", 101 | "required":true, 102 | "callType":"async", 103 | "desc":"属性获取" 104 | } 105 | ], 106 | "properties":[ 107 | { 108 | "identifier":"prop_float", 109 | "dataType":{ 110 | "specs":{ 111 | "min":"0", 112 | "max":"10000", 113 | "step":"0.001" 114 | }, 115 | "type":"float" 116 | }, 117 | "name":"prop_float_name", 118 | "accessMode":"rw", 119 | "required":false 120 | }, 121 | { 122 | "identifier":"prop_int16", 123 | "dataType":{ 124 | "specs":{ 125 | "min":"0", 126 | "max":"10000", 127 | "step":"1" 128 | }, 129 | "type":"int" 130 | }, 131 | "name":"prop_int16_name", 132 | "accessMode":"rw", 133 | "required":false 134 | }, 135 | { 136 | "identifier":"prop_bool", 137 | "dataType":{ 138 | "specs":{ 139 | "0":"off", 140 | "1":"on" 141 | }, 142 | "type":"bool" 143 | }, 144 | "name":"prop_bool_name", 145 | "accessMode":"rw", 146 | "required":false 147 | } 148 | ], 149 | "events":[ 150 | { 151 | "outputData":[ 152 | { 153 | "identifier":"prop_float", 154 | "dataType":{ 155 | "specs":{ 156 | "min":"0", 157 | "max":"10000", 158 | "step":"0.001" 159 | }, 160 | "type":"float" 161 | }, 162 | "name":"prop_float_name" 163 | }, 164 | { 165 | "identifier":"prop_int16", 166 | "dataType":{ 167 | "specs":{ 168 | "min":"0", 169 | "max":"10000", 170 | "step":"1" 171 | }, 172 | "type":"int" 173 | }, 174 | "name":"prop_int16_name" 175 | }, 176 | { 177 | "identifier":"prop_bool", 178 | "dataType":{ 179 | "specs":{ 180 | "0":"off", 181 | "1":"on" 182 | }, 183 | "type":"bool" 184 | }, 185 | "name":"prop_bool_name" 186 | } 187 | ], 188 | "identifier":"post", 189 | "method":"thing.event.property.post", 190 | "name":"post", 191 | "type":"info", 192 | "required":true, 193 | "desc":"属性上报" 194 | } 195 | ] 196 | } 197 | -------------------------------------------------------------------------------- /mqtt_connect_TCP.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import logging 4 | 5 | # config log 6 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 7 | logging.basicConfig(format=__log_format) 8 | 9 | lk = linkkit.LinkKit( 10 | host_name="cn-shanghai", 11 | product_key="xxxxxxxxxxx", 12 | device_name="device-name", 13 | device_secret="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") 14 | 15 | lk.enable_logger(logging.DEBUG) 16 | 17 | 18 | def on_device_dynamic_register(rc, value, userdata): 19 | if rc == 0: 20 | print("dynamic register device success, rc:%d, value:%s" % (rc, value)) 21 | else: 22 | print("dynamic register device fail,rc:%d, value:%s" % (rc, value)) 23 | 24 | 25 | def on_connect(session_flag, rc, userdata): 26 | print("on_connect:%d,rc:%d,userdata:" % (session_flag, rc)) 27 | pass 28 | 29 | 30 | def on_disconnect(rc, userdata): 31 | print("on_disconnect:rc:%d,userdata:" % rc) 32 | 33 | 34 | def on_topic_message(topic, payload, qos, userdata): 35 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 36 | pass 37 | 38 | 39 | def on_subscribe_topic(mid, granted_qos, userdata): 40 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 41 | (mid, str(','.join('%s' % it for it in granted_qos)))) 42 | pass 43 | 44 | 45 | def on_unsubscribe_topic(mid, userdata): 46 | print("on_unsubscribe_topic mid:%d" % mid) 47 | pass 48 | 49 | 50 | def on_publish_topic(mid, userdata): 51 | print("on_publish_topic mid:%d" % mid) 52 | 53 | 54 | lk.on_device_dynamic_register = on_device_dynamic_register 55 | lk.on_connect = on_connect 56 | lk.on_disconnect = on_disconnect 57 | lk.on_topic_message = on_topic_message 58 | lk.on_subscribe_topic = on_subscribe_topic 59 | lk.on_unsubscribe_topic = on_unsubscribe_topic 60 | lk.on_publish_topic = on_publish_topic 61 | lk.config_mqtt(secure="") 62 | lk.connect_async() 63 | 64 | 65 | while True: 66 | try: 67 | msg = input() 68 | except KeyboardInterrupt: 69 | sys.exit() 70 | else: 71 | if msg == "1": 72 | lk.disconnect() 73 | elif msg == "2": 74 | lk.connect_async() 75 | else: 76 | sys.exit() 77 | -------------------------------------------------------------------------------- /mqtt_connect_TLS.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import logging 4 | 5 | # config log 6 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 7 | logging.basicConfig(format=__log_format) 8 | 9 | lk = linkkit.LinkKit( 10 | host_name="cn-shanghai", 11 | product_key="xxxxxxxxxxx", 12 | device_name="device-name", 13 | device_secret="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") 14 | 15 | lk.enable_logger(logging.DEBUG) 16 | 17 | 18 | def on_device_dynamic_register(rc, value, userdata): 19 | if rc == 0: 20 | print("dynamic register device success, rc:%d, value:%s" % (rc, value)) 21 | else: 22 | print("dynamic register device fail,rc:%d, value:%s" % (rc, value)) 23 | 24 | 25 | def on_connect(session_flag, rc, userdata): 26 | print("on_connect:%d,rc:%d,userdata:" % (session_flag, rc)) 27 | pass 28 | 29 | 30 | def on_disconnect(rc, userdata): 31 | print("on_disconnect:rc:%d,userdata:" % rc) 32 | 33 | 34 | def on_topic_message(topic, payload, qos, userdata): 35 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 36 | pass 37 | 38 | 39 | def on_subscribe_topic(mid, granted_qos, userdata): 40 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 41 | (mid, str(','.join('%s' % it for it in granted_qos)))) 42 | pass 43 | 44 | 45 | def on_unsubscribe_topic(mid, userdata): 46 | print("on_unsubscribe_topic mid:%d" % mid) 47 | pass 48 | 49 | 50 | def on_publish_topic(mid, userdata): 51 | print("on_publish_topic mid:%d" % mid) 52 | 53 | 54 | lk.on_device_dynamic_register = on_device_dynamic_register 55 | lk.on_connect = on_connect 56 | lk.on_disconnect = on_disconnect 57 | lk.on_topic_message = on_topic_message 58 | lk.on_subscribe_topic = on_subscribe_topic 59 | lk.on_unsubscribe_topic = on_unsubscribe_topic 60 | lk.on_publish_topic = on_publish_topic 61 | lk.connect_async() 62 | 63 | 64 | while True: 65 | try: 66 | msg = input() 67 | except KeyboardInterrupt: 68 | sys.exit() 69 | else: 70 | if msg == "1": 71 | lk.disconnect() 72 | elif msg == "2": 73 | lk.connect_async() 74 | else: 75 | sys.exit() 76 | -------------------------------------------------------------------------------- /mqtt_sub_pub_on.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import threading 4 | import traceback 5 | import inspect 6 | import time 7 | import logging 8 | 9 | # config log 10 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 11 | logging.basicConfig(format=__log_format) 12 | 13 | lk = linkkit.LinkKit( 14 | host_name="cn-shanghai", 15 | product_key="xxxxxxxxxxx", 16 | device_name="device-name", 17 | device_secret="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") 18 | lk.enable_logger(logging.DEBUG) 19 | 20 | 21 | def on_device_dynamic_register(rc, value, userdata): 22 | if rc == 0: 23 | print("dynamic register device success, value:" + value) 24 | else: 25 | print("dynamic register device fail, message:" + value) 26 | 27 | 28 | def on_connect(session_flag, rc, userdata): 29 | print("on_connect:%d,rc:%d" % (session_flag, rc)) 30 | pass 31 | 32 | 33 | def on_disconnect(rc, userdata): 34 | print("on_disconnect:rc:%d,userdata:" % rc) 35 | 36 | 37 | def on_topic_message(topic, payload, qos, userdata): 38 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 39 | pass 40 | 41 | 42 | def on_subscribe_topic(mid, granted_qos, userdata): 43 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 44 | (mid, str(','.join('%s' % it for it in granted_qos)))) 45 | pass 46 | 47 | 48 | def on_unsubscribe_topic(mid, userdata): 49 | print("on_unsubscribe_topic mid:%d" % mid) 50 | pass 51 | 52 | 53 | def on_publish_topic(mid, userdata): 54 | print("on_publish_topic mid:%d" % mid) 55 | 56 | 57 | lk.on_device_dynamic_register = on_device_dynamic_register 58 | lk.on_connect = on_connect 59 | lk.on_disconnect = on_disconnect 60 | lk.on_topic_message = on_topic_message 61 | lk.on_subscribe_topic = on_subscribe_topic 62 | lk.on_unsubscribe_topic = on_unsubscribe_topic 63 | lk.on_publish_topic = on_publish_topic 64 | 65 | 66 | lk.config_device_info("Eth|03ACDEFF0032|Eth|03ACDEFF0031") 67 | lk.connect_async() 68 | lk.start_worker_loop() 69 | 70 | while True: 71 | try: 72 | msg = input() 73 | except KeyboardInterrupt: 74 | sys.exit() 75 | else: 76 | if msg == "1": 77 | lk.disconnect() 78 | elif msg == "2": 79 | lk.connect_async() 80 | elif msg == "3": 81 | rc, mid = lk.subscribe_topic(lk.to_full_topic("user/test")) 82 | if rc == 0: 83 | print("subscribe topic success:%r, mid:%r" % (rc, mid)) 84 | else: 85 | print("subscribe topic fail:%d" % rc) 86 | elif msg == "4": 87 | rc, mid = lk.unsubscribe_topic(lk.to_full_topic("user/test")) 88 | if rc == 0: 89 | print("unsubscribe topic success:%r, mid:%r" % (rc, mid)) 90 | else: 91 | print("unsubscribe topic fail:%d" % rc) 92 | elif msg == "5": 93 | rc, mid = lk.publish_topic(lk.to_full_topic("user/pub"), "123") 94 | if rc == 0: 95 | print("publish topic success:%r, mid:%r" % (rc, mid)) 96 | else: 97 | print("publish topic fail:%d" % rc) 98 | elif msg == "6": 99 | rc, mid = lk.subscribe_topic([(lk.to_full_topic("user/test2"), 1), 100 | (lk.to_full_topic("user/test"), 1), 101 | (lk.to_full_topic("user/sub"), 1)]) 102 | if rc == 0: 103 | print("subscribe multiple topics success:%r, mid:%r" % (rc, mid)) 104 | else: 105 | print("subscribe multiple topics fail:%d" % rc) 106 | elif msg == "7": 107 | rc, mid = lk.unsubscribe_topic([lk.to_full_topic("user/test2"), lk.to_full_topic("user/test")]) 108 | if rc == 0: 109 | print("unsubscribe multiple topics success:%r, mid:%r" % (rc, mid)) 110 | else: 111 | print("unsubscribe multiple topics fail:%d" % rc) 112 | elif msg == "8": 113 | ret = lk.dump_user_topics() 114 | print("user topics:%s", str(ret)) 115 | elif msg == "9": 116 | lk.destruct() 117 | print("destructed") 118 | else: 119 | sys.exit() 120 | -------------------------------------------------------------------------------- /thing_alink.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import threading 4 | import traceback 5 | import inspect 6 | import time 7 | import logging 8 | 9 | # config log 10 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 11 | logging.basicConfig(format=__log_format) 12 | 13 | 14 | class CustomerThing(object): 15 | def __init__(self): 16 | self.__linkkit = linkkit.LinkKit( 17 | host_name="cn-shanghai", 18 | product_key="xxxxxxxxxxx", 19 | device_name="device-name", 20 | device_secret="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") 21 | self.__linkkit.enable_logger(logging.DEBUG) 22 | self.__linkkit.on_device_dynamic_register = self.on_device_dynamic_register 23 | self.__linkkit.on_connect = self.on_connect 24 | self.__linkkit.on_disconnect = self.on_disconnect 25 | self.__linkkit.on_topic_message = self.on_topic_message 26 | self.__linkkit.on_subscribe_topic = self.on_subscribe_topic 27 | self.__linkkit.on_unsubscribe_topic = self.on_unsubscribe_topic 28 | self.__linkkit.on_publish_topic = self.on_publish_topic 29 | self.__linkkit.on_thing_enable = self.on_thing_enable 30 | self.__linkkit.on_thing_disable = self.on_thing_disable 31 | self.__linkkit.on_thing_event_post = self.on_thing_event_post 32 | self.__linkkit.on_thing_prop_post = self.on_thing_prop_post 33 | self.__linkkit.on_thing_prop_changed = self.on_thing_prop_changed 34 | self.__linkkit.on_thing_call_service = self.on_thing_call_service 35 | self.__linkkit.on_thing_raw_data_post = self.on_thing_raw_data_post 36 | self.__linkkit.on_thing_raw_data_arrived = self.on_thing_raw_data_arrived 37 | self.__linkkit.thing_setup("tsl.json") 38 | self.__linkkit.config_device_info("Eth|03ACDEFF0032|Eth|03ACDEFF0031") 39 | self.__call_service_request_id = 0 40 | 41 | def on_device_dynamic_register(self, rc, value, userdata): 42 | if rc == 0: 43 | print("dynamic register device success, value:" + value) 44 | else: 45 | print("dynamic register device fail, message:" + value) 46 | 47 | def on_connect(self, session_flag, rc, userdata): 48 | print("on_connect:%d,rc:%d,userdata:" % (session_flag, rc)) 49 | 50 | def on_disconnect(self, rc, userdata): 51 | print("on_disconnect:rc:%d,userdata:" % rc) 52 | 53 | def on_topic_message(self, topic, payload, qos, userdata): 54 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 55 | pass 56 | 57 | def on_subscribe_topic(self, mid, granted_qos, userdata): 58 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 59 | (mid, str(','.join('%s' % it for it in granted_qos)))) 60 | pass 61 | 62 | def on_unsubscribe_topic(self, mid, userdata): 63 | print("on_unsubscribe_topic mid:%d" % mid) 64 | pass 65 | 66 | def on_publish_topic(self, mid, userdata): 67 | print("on_publish_topic mid:%d" % mid) 68 | 69 | def on_thing_prop_changed(self, params, userdata): 70 | print("on_thing_prop_changed params:" + str(params)) 71 | 72 | def on_thing_enable(self, userdata): 73 | print("on_thing_enable") 74 | 75 | def on_thing_disable(self, userdata): 76 | print("on_thing_disable") 77 | 78 | def on_thing_event_post(self, event, request_id, code, data, message, userdata): 79 | print("on_thing_event_post event:%s,request id:%s, code:%d, data:%s, message:%s" % 80 | (event, request_id, code, str(data), message)) 81 | pass 82 | 83 | def on_thing_prop_post(self, request_id, code, data, message,userdata): 84 | print("on_thing_prop_post request id:%s, code:%d, data:%s message:%s" % 85 | (request_id, code, str(data), message)) 86 | 87 | def on_thing_raw_data_arrived(self, payload, userdata): 88 | print("on_thing_raw_data_arrived:%s" % str(payload)) 89 | 90 | def on_thing_raw_data_post(self, payload, userdata): 91 | print("on_thing_raw_data_post: %s" % str(payload)) 92 | 93 | def on_thing_call_service(self, identifier, request_id, params, userdata): 94 | print("on_thing_call_service identifier:%s, request id:%s, params:%s" % 95 | (identifier, request_id, params)) 96 | self.__call_service_request_id = request_id 97 | pass 98 | 99 | def user_loop(self): 100 | self.__linkkit.connect_async() 101 | tips = "1: disconnect\n" +\ 102 | "2 connect&loop\n" +\ 103 | "3 subscribe topic\n" + \ 104 | "4 unsubscribe topic\n" + \ 105 | "5 public topic\n" +\ 106 | "" 107 | while True: 108 | try: 109 | msg = input() 110 | except KeyboardInterrupt: 111 | sys.exit() 112 | else: 113 | if msg == "1": 114 | event_data = { 115 | "power": 10, 116 | "power_style": 1 117 | } 118 | self.__linkkit.thing_trigger_event(("power_state", event_data)) 119 | elif msg == "2": 120 | prop_data = { 121 | "abs_speed": 11, 122 | "power_stage": 10 123 | } 124 | self.__linkkit.thing_post_property(prop_data) 125 | elif msg == "3": 126 | # power_stage value max than tsl define 127 | prop_data = { 128 | "abs_speed": 11, 129 | "power_stage": 120 130 | } 131 | self.__linkkit.thing_post_property(prop_data) 132 | elif msg == "4": 133 | self.__linkkit.thing_answer_service("attack", self.__call_service_request_id, 200, {}) 134 | else: 135 | sys.exit() 136 | 137 | 138 | if __name__ == "__main__": 139 | custom_thing = CustomerThing() 140 | custom_thing.user_loop() 141 | -------------------------------------------------------------------------------- /thing_custom.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from linkkit import linkkit 3 | import threading 4 | import traceback 5 | import inspect 6 | import time 7 | import logging 8 | 9 | # config log 10 | __log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s' 11 | logging.basicConfig(format=__log_format) 12 | 13 | 14 | class CustomerThing(object): 15 | def __init__(self): 16 | self.__linkkit = linkkit.LinkKit( 17 | host_name="cn-shanghai", 18 | product_key="xxxxxxxxxxx", 19 | device_name="device-name", 20 | device_secret="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") 21 | self.__linkkit.enable_logger(logging.DEBUG) 22 | self.__linkkit.on_device_dynamic_register = self.on_device_dynamic_register 23 | self.__linkkit.on_connect = self.on_connect 24 | self.__linkkit.on_disconnect = self.on_disconnect 25 | self.__linkkit.on_topic_message = self.on_topic_message 26 | self.__linkkit.on_subscribe_topic = self.on_subscribe_topic 27 | self.__linkkit.on_unsubscribe_topic = self.on_unsubscribe_topic 28 | self.__linkkit.on_publish_topic = self.on_publish_topic 29 | self.__linkkit.on_thing_enable = self.on_thing_enable 30 | self.__linkkit.on_thing_disable = self.on_thing_disable 31 | self.__linkkit.on_thing_raw_data_post = self.on_thing_raw_data_post 32 | self.__linkkit.on_thing_raw_data_arrived = self.on_thing_raw_data_arrived 33 | self.__linkkit.thing_setup() 34 | self.__linkkit.config_device_info("Eth|03ACDEFF0032|Eth|03ACDEFF0031") 35 | 36 | def on_device_dynamic_register(self, rc, value, userdata): 37 | if rc == 0: 38 | print("dynamic register device success, value:" + value) 39 | else: 40 | print("dynamic register device fail, message:" + value) 41 | 42 | def on_connect(self, session_flag, rc, userdata): 43 | print("on_connect:%d,rc:%d,userdata:" % (session_flag, rc)) 44 | 45 | def on_disconnect(self, rc, userdata): 46 | print("on_disconnect:rc:%d,userdata:" % rc) 47 | 48 | def on_topic_message(self, topic, payload, qos, userdata): 49 | print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos)) 50 | pass 51 | 52 | def on_subscribe_topic(self, mid, granted_qos, userdata): 53 | print("on_subscribe_topic mid:%d, granted_qos:%s" % 54 | (mid, str(','.join('%s' % it for it in granted_qos)))) 55 | pass 56 | 57 | def on_unsubscribe_topic(self, mid, userdata): 58 | print("on_unsubscribe_topic mid:%d" % mid) 59 | pass 60 | 61 | def on_publish_topic(self, mid, userdata): 62 | print("on_publish_topic mid:%d" % mid) 63 | 64 | def on_thing_enable(self, userdata): 65 | print("on_thing_enable") 66 | 67 | def on_thing_disable(self, userdata): 68 | print("on_thing_disable") 69 | 70 | def on_thing_raw_data_arrived(self, payload, userdata): 71 | print("on_thing_raw_data_arrived:%r" % payload) 72 | print("prop data:%r" % self.rawDataToProtocol(payload)) 73 | 74 | def on_thing_raw_data_post(self, payload, userdata): 75 | print("on_thing_raw_data_post: %s" % str(payload)) 76 | 77 | def rawDataToProtocol(self, byte_data): 78 | alink_data = {} 79 | head = byte_data[0] 80 | if head == 0x01: 81 | alink_data["method"] = "thing.service.property.set" 82 | alink_data["version"] = "1.0" 83 | alink_data["id"] = int.from_bytes(byte_data[1:5], "big") 84 | params = {} 85 | params["prop_int16"] = int.from_bytes(byte_data[5:7], "big") 86 | alink_data["params"] = params 87 | return alink_data 88 | 89 | def protocolToRawData(self, params): 90 | # command set 91 | payload_bytes = b'\x00' 92 | # id 93 | payload_bytes += b'\x00' 94 | payload_bytes += b'\x00' 95 | payload_bytes += b'\x00' 96 | payload_bytes += b'\x01' 97 | # prop_int16 big en 98 | prop_int16 = params["prop_int16"] 99 | payload_bytes += bytes([prop_int16 // 256]) 100 | payload_bytes += bytes([prop_int16 % 256]) 101 | return payload_bytes 102 | 103 | def user_loop(self): 104 | self.__linkkit.connect_async() 105 | tips = "1: disconnect\n" +\ 106 | "2 connect&loop\n" +\ 107 | "3 subscribe topic\n" + \ 108 | "4 unsubscribe topic\n" + \ 109 | "5 public topic\n" +\ 110 | "" 111 | while True: 112 | try: 113 | msg = input() 114 | except KeyboardInterrupt: 115 | sys.exit() 116 | else: 117 | if msg == "1": 118 | params = { 119 | "prop_int16": 11 120 | } 121 | payload = self.protocolToRawData(params) 122 | print("payload:%r" % payload.hex()) 123 | self.__linkkit.thing_raw_post_data(payload) 124 | pass 125 | else: 126 | sys.exit() 127 | 128 | 129 | if __name__ == "__main__": 130 | custom_thing = CustomerThing() 131 | custom_thing.user_loop() 132 | -------------------------------------------------------------------------------- /tsl.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "schema": "https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json", 4 | "profile": { 5 | "productKey": "xxxxxxxxxx" 6 | }, 7 | "services": [ 8 | { 9 | "outputData": [], 10 | "identifier": "set", 11 | "inputData": [ 12 | { 13 | "identifier": "abs_speed", 14 | "dataType": { 15 | "specs": { 16 | "unit": "m/s", 17 | "min": "1", 18 | "max": "300000000", 19 | "step": "1" 20 | }, 21 | "type": "int" 22 | }, 23 | "name": "绝对速度" 24 | } 25 | ], 26 | "method": "thing.service.property.set", 27 | "name": "set", 28 | "required": true, 29 | "callType": "async", 30 | "desc": "属性设置" 31 | }, 32 | { 33 | "outputData": [ 34 | { 35 | "identifier": "abs_speed", 36 | "dataType": { 37 | "specs": { 38 | "unit": "m/s", 39 | "min": "1", 40 | "max": "300000000", 41 | "step": "1" 42 | }, 43 | "type": "int" 44 | }, 45 | "name": "绝对速度" 46 | } 47 | ], 48 | "identifier": "get", 49 | "inputData": [ 50 | "abs_speed" 51 | ], 52 | "method": "thing.service.property.get", 53 | "name": "get", 54 | "required": true, 55 | "callType": "async", 56 | "desc": "属性获取" 57 | }, 58 | { 59 | "outputData": [], 60 | "identifier": "attack", 61 | "inputData": [ 62 | { 63 | "identifier": "count", 64 | "dataType": { 65 | "specs": { 66 | "unit": "kW", 67 | "min": "1", 68 | "max": "1000", 69 | "step": "1" 70 | }, 71 | "type": "int" 72 | }, 73 | "name": "发射次数" 74 | } 75 | ], 76 | "method": "thing.service.attack", 77 | "name": "攻击", 78 | "required": false, 79 | "callType": "async", 80 | "desc": "质子攻击" 81 | } 82 | ], 83 | "properties": [ 84 | { 85 | "identifier": "abs_speed", 86 | "dataType": { 87 | "specs": { 88 | "unit": "m/s", 89 | "min": "1", 90 | "max": "300000000", 91 | "step": "1" 92 | }, 93 | "type": "int" 94 | }, 95 | "name": "绝对速度", 96 | "accessMode": "rw", 97 | "required": false, 98 | "desc": "运动的绝对速度" 99 | } 100 | ], 101 | "events": [ 102 | { 103 | "outputData": [ 104 | { 105 | "identifier": "abs_speed", 106 | "dataType": { 107 | "specs": { 108 | "unit": "m/s", 109 | "min": "1", 110 | "max": "300000000", 111 | "step": "1" 112 | }, 113 | "type": "int" 114 | }, 115 | "name": "绝对速度" 116 | } 117 | ], 118 | "identifier": "post", 119 | "method": "thing.event.property.post", 120 | "name": "post", 121 | "type": "info", 122 | "required": true, 123 | "desc": "属性上报" 124 | }, 125 | { 126 | "outputData": [ 127 | { 128 | "identifier": "power", 129 | "dataType": { 130 | "specs": { 131 | "min": "1", 132 | "max": "100", 133 | "step": "1" 134 | }, 135 | "type": "int" 136 | }, 137 | "name": "能量" 138 | }, 139 | { 140 | "identifier": "power_style", 141 | "dataType": { 142 | "specs": { 143 | "1": "sine", 144 | "2": "triangle", 145 | "3": "const", 146 | "4": "peak" 147 | }, 148 | "type": "enum" 149 | }, 150 | "name": "能量方式" 151 | } 152 | ], 153 | "identifier": "power_state", 154 | "method": "thing.event.power_state.post", 155 | "name": "能量状态", 156 | "type": "info", 157 | "required": false, 158 | "desc": "能量大小" 159 | } 160 | ] 161 | } 162 | --------------------------------------------------------------------------------