From d19a5554e132d397f363b81994808bc77058beba Mon Sep 17 00:00:00 2001 From: JackSun-qc Date: Fri, 18 Mar 2022 17:53:46 +0800 Subject: [PATCH] add: aliyunIot.py --- code/aliyunIot.py | 180 ++++++++++++++++++++++++++++++++++++++++++++++ code/common.py | 10 +++ code/quecthing.py | 26 +++---- code/settings.py | 8 +-- 4 files changed, 208 insertions(+), 16 deletions(-) create mode 100644 code/aliyunIot.py diff --git a/code/aliyunIot.py b/code/aliyunIot.py new file mode 100644 index 0000000..1e84ead --- /dev/null +++ b/code/aliyunIot.py @@ -0,0 +1,180 @@ +import utime +import _thread +import osTimer + +from aLiYun import aLiYun + +from usr.logging import getLogger +from usr.settings import settings +from usr.common import numiter +from usr.common import power_restart + +log = getLogger(__name__) + +PROPERTY = 0x0 +EVENT = 0x1 +SERVICE = 0x2 + +object_model = { + 'event': [ + 'sos_alert', + 'fault_alert', + 'low_power_alert', + 'sim_out_alert', + 'disassemble_alert', + 'drive_behavior_alert', + 'over_speed_alert', + ], + 'property': [ + 'power_switch', + 'energy', + 'phone_num', + 'loc_method', + 'loc_mode', + 'loc_cycle_period', + 'local_time', + 'low_power_alert_threshold', + 'low_power_shutdown_threshold', + 'sw_ota', + 'sw_ota_auto_upgrade', + 'sw_voice_listen', + 'sw_voice_record', + 'sw_fault_alert', + 'sw_low_power_alert', + 'sw_over_speed_alert', + 'sw_sim_out_alert', + 'sw_disassemble_alert', + 'sw_drive_behavior_alert', + 'drive_behavior_code', + 'power_restart', + 'over_speed_threshold', + 'fault_code', + 'gps_mode', + 'user_ota_action', + 'ota_status', + ], +} + + +class AliYunIot(object): + + def __init__(self, pk, ps, dk, ds): + self.ali = aLiYun(pk, ps, dk, ds) + clientID = dk + self.ali.setMqtt(clientID, clean_session=False, keeyAlive=60, reconn=True) + self.ali.setCallback(self.ali_sub_cb) + + self.ica_topic_property_post = 'sys/%s/%s/thing/event/property/post' % (pk, dk) + self.ica_topic_property_post_reply = 'sys/%s/%s/thing/event/property/post_reply' % (pk, dk) + self.ica_topic_property_set = 'sys/%s/%s/thing/service/property/set' % (pk, dk) + self.ica_topic_event_post = 'sys/%s/%s/thing/event/{}/post' % (pk, dk) + self.ica_topic_event_post_reply = 'sys/%s/%s/thing/event/{}/post_reply' % (pk, dk) + self.ali_subcribe_topic() + self.post_res = {} + self.ali_timer = osTimer() + + self.id_iter = numiter() + self.id_lock = _thread.allocate_lock() + + self.ali.start() + + def ali_subcribe_topic(self): + self.ali.subcribute(self.ica_topic_property_post, qos=0) + self.ali.subcribute(self.ica_topic_property_post_reply, qos=0) + self.ali.subcribute(self.ica_topic_property_set, qos=0) + for tsl_event_identifier in object_model['event']: + self.ali.subcribute(self.ica_topic_event_post.format(tsl_event_identifier), qos=0) + self.ali.subcribute(self.ica_topic_event_post_reply.format(tsl_event_identifier), qos=0) + + def get_id(self): + with self.id_lock: + try: + msg_id = next(self.id_iter) + except StopIteration: + self.id_iter = numiter() + msg_id = next(self.id_iter) + + return str(msg_id) + + def put_post_res(self, msg_id, res): + self.post_res[msg_id] = res + + def get_post_res(self, msg_id): + current_settings = settings.get() + self.ali_timer.start(current_settings['sys']['cloud_timeout'] * 1000, 2, power_restart) + while self.post_res.get(msg_id) is None: + utime.sleep_ms(200) + self.ali_timer.stop() + res = self.post_res.pop(msg_id) + return res + + def post_data(self, data_type, data): + msg_ids = [] + if self.ali.getAliyunSta() == 0: + try: + property_params = {} + event_params = {} + # Format Publish Params. + for k, v in data.items(): + if k in object_model['property']: + property_params[k] = { + 'value': v, + 'time': utime.mktime(utime.localtime()) * 1000 + } + elif k in object_model['event']: + event_params[k] = { + 'value': v, + 'time': utime.mktime(utime.localtime()) * 1000 + } + else: + log.error('Publish Key [%s] is not in property and event' % k) + # Publish Property Data. + if property_params: + msg_id = self.get_id() + publish_data = { + 'id': msg_id, + 'version': '1.0', + 'sys': { + 'ack': 1 + }, + 'params': property_params, + 'method': 'thing.event.property.post' + } + pub_res = self.ali.publish(self.ica_topic_property_post, publish_data, qos=0) + if pub_res == 0: + msg_ids.append(msg_id) + else: + return False + # Publish Event Data. + if event_params: + for event in event_params.keys(): + topic = self.ica_topic_event_post.format(event) + msg_id = self.get_id() + publish_data = { + 'id': msg_id, + 'version': '1.0', + 'sys': { + 'ack': 1 + }, + 'params': event_params[event], + 'method': 'thing.event.%s.post' % event + } + pub_res = self.ali.publish(topic, publish_data, qos=0) + if pub_res == 0: + msg_ids.append(msg_id) + else: + return False + + pub_res = [self.get_post_res(msg_id) for msg_id in msg_ids] + return True if False not in pub_res else False + except Exception: + log.error('AliYun publish topic %s failed. data: %s' % (data.get('topic'), data.get('data'))) + + return False + + def ali_sub_cb(self, topic, data): + log.info('topic: %s, data: %s' % (topic, data)) + if topic.endswith('/post_reply'): + self.put_post_res(data['id'], True if data['code'] == 200 else False) + else: + pass diff --git a/code/common.py b/code/common.py index 221d737..3540eee 100644 --- a/code/common.py +++ b/code/common.py @@ -1,4 +1,5 @@ import _thread +from misc import Power class Singleton(object): @@ -17,3 +18,12 @@ class Singleton(object): Singleton.instance_dict[str(cls)] = _instance return Singleton.instance_dict[str(cls)] + + +def numiter(): + for i in range(99999): + yield i + + +def power_restart(): + Power.powerRestart() diff --git a/code/quecthing.py b/code/quecthing.py index 701836d..b18c037 100644 --- a/code/quecthing.py +++ b/code/quecthing.py @@ -1,9 +1,11 @@ import osTimer import quecIot -from misc import Power + from queue import Queue + from usr.logging import getLogger from usr.settings import settings +from usr.common import power_restart DATA_NON_LOCA = 0x0 DATA_LOCA_NON_GPS = 0x1 @@ -12,6 +14,7 @@ DATA_LOCA_GPS = 0x2 log = getLogger(__name__) object_model = [ + # property (9, ('power_switch', 'rw')), (4, ('energy', 'r')), (23, ('phone_num', 'rw')), @@ -32,19 +35,21 @@ object_model = [ (31, ('sw_disassemble_alert', 'rw')), (32, ('sw_drive_behavior_alert', 'rw')), (21, ('drive_behavior_code', 'r')), - (6, ('sos_alert', 'rw')), - (14, ('fault_alert', 'rw')), - (17, ('low_power_alert', 'rw')), - (18, ('sim_out_alert', 'rw')), - (22, ('drive_behavior_alert', 'rw')), - (20, ('disassemble_alert', 'rw')), (33, ('power_restart', 'w')), (34, ('over_speed_threshold', 'rw')), - (35, ('over_speed_alert', 'rw')), (36, ('fault_code', 'r')), (37, ('gps_mode', 'r')), (38, ('user_ota_action', 'w')), (39, ('ota_status', 'r')), + + # event + (6, ('sos_alert', 'r')), + (14, ('fault_alert', 'r')), + (17, ('low_power_alert', 'r')), + (18, ('sim_out_alert', 'r')), + (20, ('disassemble_alert', 'r')), + (22, ('drive_behavior_alert', 'r')), + (35, ('over_speed_alert', 'r')), ] object_model_code = {i[1][0]: i[0] for i in object_model} @@ -65,14 +70,11 @@ class QuecThing(object): def get_post_res(self): current_settings = settings.get() - self.quec_timer.start(current_settings['sys']['quecIot_timeout'] * 1000, 2, self.quec_timer_callback) + self.quec_timer.start(current_settings['sys']['cloud_timeout'] * 1000, 2, power_restart) res = self.post_result_wait_queue.get() self.quec_timer.stop() return res - def quec_timer_callback(self): - Power.powerRestart() - @staticmethod def rm_empty_data(data): for k, v in data.items(): diff --git a/code/settings.py b/code/settings.py index c34ec79..6d3a76e 100644 --- a/code/settings.py +++ b/code/settings.py @@ -185,10 +185,10 @@ class default_values_sys(object): } _AliYun = { - 'PK': '', - 'PS': '', - 'DK': '', - 'DS': '', + 'PK': 'guqqtu3edVY', + 'PS': 'xChL7HREtPyYCtPM', + 'DK': 'TrackerEC600N', + 'DS': 'a3153ed0c2f68db6e2f47e0769f966a2', } _JTT808 = {