mirror of
https://gitee.com/qpy-solutions/tracker-v2.git
synced 2025-05-18 18:48:25 +08:00
update: 1. quec & ali cloud OTA; 2. GPS UART read; 3. module object;
This commit is contained in:
parent
fbd42c42f9
commit
08dd3afb32
@ -488,7 +488,7 @@
|
||||
},
|
||||
{
|
||||
"identifier": "user_ota_action",
|
||||
"name": "是否OTA升级",
|
||||
"name": "确认OTA升级",
|
||||
"accessMode": "rw",
|
||||
"desc": "用户操作,只写功能",
|
||||
"required": false,
|
||||
@ -506,14 +506,75 @@
|
||||
"accessMode": "r",
|
||||
"required": false,
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无升级",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
"type": "struct",
|
||||
"specs": [
|
||||
{
|
||||
"identifier": "sys_current_version",
|
||||
"name": "系统当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "sys_target_version",
|
||||
"name": "系统目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_current_version",
|
||||
"name": "应用当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_target_version",
|
||||
"name": "应用目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_module",
|
||||
"name": "当前升级模块",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "系统",
|
||||
"2": "应用"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_status",
|
||||
"name": "当前升级状态",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -531,6 +592,22 @@
|
||||
"step": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "current_speed",
|
||||
"name": "当前时速",
|
||||
"accessMode": "r",
|
||||
"required": false,
|
||||
"dataType": {
|
||||
"type": "float",
|
||||
"specs": {
|
||||
"min": "0",
|
||||
"max": "200.00",
|
||||
"unit": "km/h",
|
||||
"unitName": "千米每小时",
|
||||
"step": "0.01"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@ -975,7 +1052,7 @@
|
||||
},
|
||||
{
|
||||
"identifier": "user_ota_action",
|
||||
"name": "是否OTA升级",
|
||||
"name": "确认OTA升级",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
@ -988,14 +1065,75 @@
|
||||
"identifier": "ota_status",
|
||||
"name": "OTA升级状态",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无升级",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
"type": "struct",
|
||||
"specs": [
|
||||
{
|
||||
"identifier": "sys_current_version",
|
||||
"name": "系统当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "sys_target_version",
|
||||
"name": "系统目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_current_version",
|
||||
"name": "应用当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_target_version",
|
||||
"name": "应用目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_module",
|
||||
"name": "当前升级模块",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "系统",
|
||||
"2": "应用"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_status",
|
||||
"name": "当前升级状态",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1011,6 +1149,20 @@
|
||||
"step": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "current_speed",
|
||||
"name": "当前时速",
|
||||
"dataType": {
|
||||
"type": "float",
|
||||
"specs": {
|
||||
"min": "0",
|
||||
"max": "200.00",
|
||||
"unit": "km/h",
|
||||
"unitName": "千米每小时",
|
||||
"step": "0.01"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -1328,7 +1480,7 @@
|
||||
},
|
||||
{
|
||||
"identifier": "user_ota_action",
|
||||
"name": "是否OTA升级",
|
||||
"name": "确认OTA升级",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
@ -1375,7 +1527,8 @@
|
||||
"gps_mode",
|
||||
"user_ota_action",
|
||||
"ota_status",
|
||||
"voltage"
|
||||
"voltage",
|
||||
"current_speed"
|
||||
],
|
||||
"outputData": [
|
||||
{
|
||||
@ -1811,7 +1964,7 @@
|
||||
},
|
||||
{
|
||||
"identifier": "user_ota_action",
|
||||
"name": "是否OTA升级",
|
||||
"name": "确认OTA升级",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
@ -1824,14 +1977,75 @@
|
||||
"identifier": "ota_status",
|
||||
"name": "OTA升级状态",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无升级",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
"type": "struct",
|
||||
"specs": [
|
||||
{
|
||||
"identifier": "sys_current_version",
|
||||
"name": "系统当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "sys_target_version",
|
||||
"name": "系统目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_current_version",
|
||||
"name": "应用当前版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "app_target_version",
|
||||
"name": "应用目标版本",
|
||||
"dataType": {
|
||||
"type": "text",
|
||||
"specs": {
|
||||
"length": "1024"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_module",
|
||||
"name": "当前升级模块",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "系统",
|
||||
"2": "应用"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "upgrade_status",
|
||||
"name": "当前升级状态",
|
||||
"dataType": {
|
||||
"type": "enum",
|
||||
"specs": {
|
||||
"0": "无",
|
||||
"1": "待升级",
|
||||
"2": "升级中",
|
||||
"3": "升级成功",
|
||||
"4": "升级失败"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1847,6 +2061,20 @@
|
||||
"step": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"identifier": "current_speed",
|
||||
"name": "当前时速",
|
||||
"dataType": {
|
||||
"type": "float",
|
||||
"specs": {
|
||||
"min": "0",
|
||||
"max": "200.00",
|
||||
"unit": "km/h",
|
||||
"unitName": "千米每小时",
|
||||
"step": "0.01"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ from aLiYun import aLiYun
|
||||
from usr.logging import getLogger
|
||||
from usr.settings import settings
|
||||
from usr.settings import default_values_sys
|
||||
from usr.settings import PROJECT_VERSION
|
||||
from usr.settings import PROJECT_NAME
|
||||
from usr.settings import SYSNAME
|
||||
from usr.settings import DEVICE_FIRMWARE_VERSION
|
||||
from usr.common import numiter
|
||||
|
||||
log = getLogger(__name__)
|
||||
@ -72,6 +76,15 @@ object_model = {
|
||||
],
|
||||
}
|
||||
|
||||
_gps_read_lock = _thread.allocate_lock()
|
||||
|
||||
|
||||
def get_post_res_lock(func):
|
||||
def wrapperd_fun(*args, **kwargs):
|
||||
with _gps_read_lock:
|
||||
return func(*args, **kwargs)
|
||||
return wrapperd_fun
|
||||
|
||||
|
||||
class AliYunIotError(Exception):
|
||||
def __init__(self, value):
|
||||
@ -83,11 +96,18 @@ class AliYunIotError(Exception):
|
||||
|
||||
class AliYunIot(object):
|
||||
|
||||
def __init__(self, pk, ps, dk, ds, downlink_queue):
|
||||
def __init__(self, pk, ps, dk, ds, server, downlink_queue):
|
||||
self.pk = pk
|
||||
self.ps = ps
|
||||
self.dk = dk
|
||||
self.ds = ds
|
||||
self.server = server
|
||||
self.ali = None
|
||||
self.downlink_queue = downlink_queue
|
||||
|
||||
self.post_res = {}
|
||||
self.breack_flag = 0
|
||||
self.ali_timer = osTimer()
|
||||
self.downlink_queue = downlink_queue
|
||||
|
||||
self.id_iter = numiter()
|
||||
self.id_lock = _thread.allocate_lock()
|
||||
@ -99,20 +119,47 @@ class AliYunIot(object):
|
||||
self.ica_topic_property_query = '/sys/%s/%s/thing/service/property/query' % (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.ota_topic_device_inform = '/ota/device/inform/%s/%s' % (pk, dk)
|
||||
self.ota_topic_device_upgrade = '/ota/device/upgrade/%s/%s' % (pk, dk)
|
||||
self.ota_topic_device_progress = '/ota/device/progress/%s/%s' % (pk, dk)
|
||||
self.ota_topic_firmware_get = '/sys/%s/%s/thing/ota/firmware/get' % (pk, dk)
|
||||
self.ota_topic_firmware_get_reply = '/sys/%s/%s/thing/ota/firmware/get_reply' % (pk, dk)
|
||||
|
||||
# TODO: To Download OTA File For MQTT Association (Not Support Now.)
|
||||
self.ota_topic_file_download = '/sys/%s/%s/thing/file/download' % (pk, dk)
|
||||
self.ota_topic_file_download_reply = '/sys/%s/%s/thing/file/download_reply' % (pk, dk)
|
||||
|
||||
self.cloud_init()
|
||||
|
||||
def cloud_init(self, enforce=False):
|
||||
if enforce is False and self.ali is not None:
|
||||
if self.ali.getAliyunSta() == 0:
|
||||
return True
|
||||
else:
|
||||
self.ali.disconnect()
|
||||
|
||||
current_settings = settings.get()
|
||||
if current_settings['sys']['ali_burning_method'] == default_values_sys._ali_burning_method.one_type_one_density:
|
||||
dk = None
|
||||
self.dk = None
|
||||
elif current_settings['sys']['ali_burning_method'] == default_values_sys._ali_burning_method.one_machine_one_density:
|
||||
ps = None
|
||||
self.ali = aLiYun(pk, ps, dk, ds)
|
||||
self.clientID = dk
|
||||
setMqttres = self.ali.setMqtt(self.clientID, clean_session=False, keepAlive=60, reconn=True)
|
||||
if setMqttres == -1:
|
||||
raise AliYunIotError('setMqtt Falied!')
|
||||
self.ali.setCallback(self.ali_sub_cb)
|
||||
self.ali_subcribe_topic()
|
||||
self.ali.start()
|
||||
self.ps = None
|
||||
|
||||
self.ali = aLiYun(self.pk, self.ps, self.dk, self.ds)
|
||||
setMqttres = self.ali.setMqtt(self.dk, clean_session=False, keepAlive=current_settings['sys']['cloud_life_time'], reconn=True)
|
||||
if setMqttres != -1:
|
||||
self.ali.setCallback(self.ali_sub_cb)
|
||||
self.ali_subcribe_topic()
|
||||
self.ali.start()
|
||||
else:
|
||||
log.error('setMqtt Falied!')
|
||||
return False
|
||||
|
||||
if self.ali.getAliyunSta() == 0:
|
||||
self.device_report()
|
||||
self.ota_request()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def ali_subcribe_topic(self):
|
||||
if self.ali.subscribe(self.ica_topic_property_post, qos=0) == -1:
|
||||
@ -134,6 +181,15 @@ class AliYunIot(object):
|
||||
if self.ali.subscribe(post_reply_topic, qos=0) == -1:
|
||||
log.error('Topic [%s] Subscribe Falied.' % post_reply_topic)
|
||||
|
||||
if self.ali.subscribe(self.ota_topic_device_upgrade, qos=0) == -1:
|
||||
log.error('Topic [%s] Subscribe Falied.' % self.ota_topic_device_upgrade)
|
||||
if self.ali.subscribe(self.ota_topic_firmware_get_reply, qos=0) == -1:
|
||||
log.error('Topic [%s] Subscribe Falied.' % self.ota_topic_firmware_get_reply)
|
||||
|
||||
# TODO: To Download OTA File For MQTT Association (Not Support Now.)
|
||||
if self.ali.subscribe(self.ota_topic_file_download_reply, qos=0) == -1:
|
||||
log.error('Topic [%s] Subscribe Falied.' % self.ota_topic_file_download_reply)
|
||||
|
||||
def get_id(self):
|
||||
with self.id_lock:
|
||||
try:
|
||||
@ -147,14 +203,15 @@ class AliYunIot(object):
|
||||
def put_post_res(self, msg_id, res):
|
||||
self.post_res[msg_id] = res
|
||||
|
||||
@get_post_res_lock
|
||||
def get_post_res(self, msg_id):
|
||||
current_settings = settings.get()
|
||||
self.ali_timer.start(current_settings['sys']['checknet_timeout'] * 1000, 2, self.ali_timer_cb)
|
||||
self.ali_timer.start(current_settings['sys']['checknet_timeout'] * 1000, 0, self.ali_timer_cb)
|
||||
while self.post_res.get(msg_id) is None:
|
||||
utime.sleep_ms(200)
|
||||
if self.breack_flag:
|
||||
self.post_res[msg_id] = False
|
||||
break
|
||||
utime.sleep_ms(50)
|
||||
self.ali_timer.stop()
|
||||
self.breack_flag = 0
|
||||
res = self.post_res.pop(msg_id)
|
||||
@ -221,17 +278,104 @@ class AliYunIot(object):
|
||||
|
||||
return False
|
||||
|
||||
def device_report(self):
|
||||
self.ota_device_inform(PROJECT_VERSION, module=PROJECT_NAME)
|
||||
self.ota_device_inform(DEVICE_FIRMWARE_VERSION, module=SYSNAME)
|
||||
|
||||
def ota_request(self):
|
||||
self.ota_firmware_get(PROJECT_NAME)
|
||||
self.ota_firmware_get(SYSNAME)
|
||||
|
||||
def ota_device_inform(self, version, module='default'):
|
||||
msg_id = self.get_id()
|
||||
publish_data = {
|
||||
'id': msg_id,
|
||||
'params': {
|
||||
'version': version,
|
||||
'module': module,
|
||||
},
|
||||
}
|
||||
publish_res = self.ali.publish(self.ota_topic_device_inform, ujson.dumps(publish_data), qos=0)
|
||||
log.debug('version: %s, module: %s, publish_res: %s' % (version, module, publish_res))
|
||||
return publish_res
|
||||
|
||||
def ota_device_progress(self, step, desc, module='default'):
|
||||
msg_id = self.get_id()
|
||||
publish_data = {
|
||||
'id': msg_id,
|
||||
'params': {
|
||||
'step': step,
|
||||
'desc': desc,
|
||||
'module': module,
|
||||
}
|
||||
}
|
||||
publish_res = self.ali.publish(self.ota_topic_device_progress, ujson.dumps(publish_data), qos=0)
|
||||
if publish_res:
|
||||
return self.get_post_res(msg_id)
|
||||
else:
|
||||
log.error('ota_device_progress publish_res: %s' % publish_res)
|
||||
return False
|
||||
|
||||
def ota_firmware_get(self, module):
|
||||
msg_id = self.get_id()
|
||||
publish_data = {
|
||||
'id': msg_id,
|
||||
'version': '1.0',
|
||||
'params': {
|
||||
'module': module,
|
||||
},
|
||||
"method": "thing.ota.firmware.get"
|
||||
}
|
||||
publish_res = self.ali.publish(self.ota_topic_firmware_get, ujson.dumps(publish_data), qos=0)
|
||||
log.debug('module: %s, publish_res: %s' % (module, publish_res))
|
||||
if publish_res:
|
||||
return self.get_post_res(msg_id)
|
||||
else:
|
||||
log.error('ota_firmware_get publish_res: %s' % publish_res)
|
||||
return False
|
||||
|
||||
def ota_file_download(self, params):
|
||||
msg_id = self.get_id()
|
||||
publish_data = {
|
||||
'id': msg_id,
|
||||
'version': '1.0',
|
||||
'params': params
|
||||
}
|
||||
publish_res = self.ali.publish(self.ota_topic_file_download, ujson.dumps(publish_data), qos=0)
|
||||
if publish_res:
|
||||
return self.get_post_res(msg_id)
|
||||
else:
|
||||
log.error('ota_file_download publish_res: %s' % publish_res)
|
||||
return False
|
||||
|
||||
def ali_sub_cb(self, topic, data):
|
||||
# log.info('topic: %s, data: %s' % (topic.decode(), data.decode()))
|
||||
topic = topic.decode()
|
||||
data = ujson.loads(data)
|
||||
log.info('topic: %s, data: %s' % (topic, data))
|
||||
if topic.endswith('/post_reply'):
|
||||
log.info('topic: %s, data: %s' % (topic, data))
|
||||
self.put_post_res(data['id'], True if data['code'] == 200 else False)
|
||||
elif topic.endswith('/property/set'):
|
||||
log.info('topic: %s, data: %s' % (topic, data))
|
||||
if data['method'] == 'thing.service.property.set':
|
||||
dl_data = list(zip(data.get("params", {}).keys(), data.get("params", {}).values()))
|
||||
self.downlink_queue.put(('object_model', dl_data))
|
||||
elif topic.startswith('/ota/device/upgrade/'):
|
||||
self.put_post_res(data['id'], True if int(data['code']) == 1000 else False)
|
||||
if int(data['code']) == 1000:
|
||||
if data.get('data'):
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (data['data']['module'], 1, data['data']['version']))]))
|
||||
self.downlink_queue.put(('ota_plain', data['data']))
|
||||
elif topic.endswith('/thing/ota/firmware/get_reply'):
|
||||
self.put_post_res(data['id'], True if int(data['code']) == 200 else False)
|
||||
if data['code'] == 200:
|
||||
if data.get('data'):
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (data['data']['module'], 1, data['data']['version']))]))
|
||||
self.downlink_queue.put(('ota_plain', data['data']))
|
||||
|
||||
# TODO: To Download OTA File For MQTT Association (Not Support Now.)
|
||||
elif topic.endswith('/thing/file/download_reply'):
|
||||
self.put_post_res(data['id'], True if int(data['code']) == 200 else False)
|
||||
if data['code'] == 200:
|
||||
# self.downlink_queue.put(('ota_file_download', data['data']))
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
@ -85,18 +85,26 @@ class GPS(Singleton):
|
||||
|
||||
def uart_init(self):
|
||||
global gps_data_retrieve_queue
|
||||
gps_data_retrieve_queue = Queue(maxsize=8)
|
||||
self.uart_open()
|
||||
|
||||
def uart_open(self):
|
||||
self.uart_obj = UART(
|
||||
self.gps_cfg['UARTn'], self.gps_cfg['buadrate'], self.gps_cfg['databits'],
|
||||
self.gps_cfg['parity'], self.gps_cfg['stopbits'], self.gps_cfg['flowctl']
|
||||
)
|
||||
self.uart_obj.set_callback(gps_data_retrieve_cb)
|
||||
gps_data_retrieve_queue = Queue(maxsize=8)
|
||||
|
||||
def uart_close(self):
|
||||
self.uart_obj.close()
|
||||
|
||||
def first_gps_timer_callback(self, args):
|
||||
global gps_data_retrieve_queue
|
||||
self.__first_break = 1
|
||||
log.debug('self.__first_break: %s' % self.__first_break)
|
||||
if gps_data_retrieve_queue is not None:
|
||||
gps_data_retrieve_queue.put(0)
|
||||
log.debug('gps_data_retrieve_queue.put(0)')
|
||||
|
||||
def second_gps_timer_callback(self, args):
|
||||
global gps_data_retrieve_queue
|
||||
@ -105,13 +113,22 @@ class GPS(Singleton):
|
||||
gps_data_retrieve_queue.put(0)
|
||||
|
||||
def uart_read(self):
|
||||
self.uart_open()
|
||||
log.debug('uart_read start')
|
||||
global gps_data_retrieve_queue
|
||||
|
||||
while self.__first_break == 0:
|
||||
self.__gps_timer.start(50, 0, self.first_gps_timer_callback)
|
||||
log.debug('self.__first_break: %s' % self.__first_break)
|
||||
timer_start_res = self.__gps_timer.start(50, 0, self.first_gps_timer_callback)
|
||||
log.debug('timer_start_res: %s' % timer_start_res)
|
||||
nread = gps_data_retrieve_queue.get()
|
||||
# nread = 0
|
||||
# self.__first_break = 1
|
||||
log.debug('__first_break nread: %s' % nread)
|
||||
data = self.uart_obj.read(nread).decode()
|
||||
log.debug('__first_break data: %s' % data)
|
||||
self.__gps_timer.stop()
|
||||
log.debug('self.__first_break: %s' % self.__first_break)
|
||||
self.__first_break = 0
|
||||
|
||||
data = ''
|
||||
@ -119,8 +136,12 @@ class GPS(Singleton):
|
||||
gga_data = ''
|
||||
vtg_data = ''
|
||||
while self.__second_break == 0:
|
||||
log.debug('self.__second_break: %s' % self.__second_break)
|
||||
self.__gps_timer.start(1500, 0, self.second_gps_timer_callback)
|
||||
nread = gps_data_retrieve_queue.get()
|
||||
# nread = 0
|
||||
# self.__second_break = 1
|
||||
log.debug('__second_break nread: %s' % nread)
|
||||
if nread:
|
||||
data += self.uart_obj.read(nread).decode()
|
||||
if not rmc_data:
|
||||
@ -132,8 +153,12 @@ class GPS(Singleton):
|
||||
if rmc_data and gga_data and vtg_data:
|
||||
self.__second_break = 1
|
||||
self.__gps_timer.stop()
|
||||
log.debug('self.__second_break: %s' % self.__second_break)
|
||||
log.debug('__second_break data: %s' % data)
|
||||
self.__second_break = 0
|
||||
|
||||
log.debug('uart_read data: %s' % data)
|
||||
self.uart_close()
|
||||
return data
|
||||
|
||||
def quecgnss_read(self):
|
||||
@ -183,7 +208,6 @@ class GPS(Singleton):
|
||||
self.gps_data = self.quecgnss_read()
|
||||
else:
|
||||
self.gps_data = ''
|
||||
|
||||
return self.gps_data
|
||||
|
||||
def read_location_GxRMC(self, gps_data):
|
||||
|
14
code/main.py
14
code/main.py
@ -13,29 +13,23 @@
|
||||
# limitations under the License.
|
||||
|
||||
from usr.tracker import Tracker
|
||||
from usr.settings import settings
|
||||
from usr.settings import default_values_sys
|
||||
from usr.settings import PROJECT_NAME
|
||||
from usr.settings import PROJECT_VERSION
|
||||
from usr.settings import SYSNAME
|
||||
from usr.settings import DEVICE_FIRMWARE_VERSION
|
||||
from usr.logging import getLogger
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
def main():
|
||||
log.info('PROJECT_NAME: %s' % PROJECT_NAME)
|
||||
log.info('PROJECT_VERSION: %s' % PROJECT_VERSION)
|
||||
current_settings = settings.get()
|
||||
log.info('PROJECT_NAME: %s, PROJECT_VERSION: %s' % (PROJECT_NAME, PROJECT_VERSION))
|
||||
log.info('SYSNAME: %s, DEVICE_FIRMWARE_VERSION: %s' % (SYSNAME, DEVICE_FIRMWARE_VERSION))
|
||||
|
||||
tracker = Tracker()
|
||||
# Start Device Check
|
||||
tracker.device_check()
|
||||
|
||||
# Start OTA Check
|
||||
if current_settings['sys']['cloud'] == default_values_sys._cloud.quecIot and \
|
||||
current_settings['app']['sw_ota'] is True:
|
||||
tracker.remote.check_ota()
|
||||
|
||||
# Start PowerManage
|
||||
# Init Low Energy Work Mode
|
||||
tracker.power_manage.low_energy_init()
|
||||
|
@ -121,4 +121,6 @@ class PowerManage(Singleton):
|
||||
pm.wakelock_lock(self.lpm_fd)
|
||||
|
||||
over_speed_check_res = self.tracker.get_over_speed_check()
|
||||
log.debug('over_speed_check_res: %s' % str(over_speed_check_res))
|
||||
self.tracker.device_data_report(event_data=over_speed_check_res, msg=data)
|
||||
self.tracker.remote.check_ota()
|
||||
|
@ -11,3 +11,9 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
def OTA(object):
|
||||
|
||||
def __init__(self)
|
||||
pass
|
||||
|
@ -26,6 +26,8 @@ from queue import Queue
|
||||
|
||||
from usr.logging import getLogger
|
||||
from usr.settings import settings
|
||||
from usr.settings import PROJECT_NAME
|
||||
from usr.settings import PROJECT_VERSION
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
@ -56,8 +58,9 @@ object_model = [
|
||||
(36, ('device_module_status', 'r')),
|
||||
(37, ('gps_mode', 'r')),
|
||||
(38, ('user_ota_action', 'w')),
|
||||
(39, ('ota_status', 'r')),
|
||||
(41, ('voltage', 'r')),
|
||||
(42, ('ota_status', 'r')),
|
||||
(43, ('current_speed', 'r')),
|
||||
|
||||
# event
|
||||
(6, ('sos_alert', 'r')),
|
||||
@ -82,19 +85,27 @@ object_model_struct = {
|
||||
'gps': 1,
|
||||
'cell': 2,
|
||||
'wifi': 3,
|
||||
}
|
||||
},
|
||||
'ota_status': {
|
||||
'sys_current_version': 1,
|
||||
'sys_target_version': 2,
|
||||
'app_current_version': 3,
|
||||
'app_target_version': 4,
|
||||
'upgrade_module': 5,
|
||||
'upgrade_status': 6,
|
||||
},
|
||||
}
|
||||
|
||||
object_model_code = {i[1][0]: i[0] for i in object_model}
|
||||
|
||||
|
||||
class QuecThing(object):
|
||||
def __init__(self, pk, ps, dk, ds, downlink_queue):
|
||||
def __init__(self, pk, ps, dk, ds, server, downlink_queue):
|
||||
self.pk = pk
|
||||
self.ps = ps
|
||||
self.dk = dk
|
||||
self.ds = ds
|
||||
self.init_res = {}
|
||||
self.server = server
|
||||
self.fileSize = 0
|
||||
self.needDownloadSize = 0
|
||||
self.crcValue = 0
|
||||
@ -104,48 +115,58 @@ class QuecThing(object):
|
||||
self.downlink_queue = downlink_queue
|
||||
self.post_result_wait_queue = Queue(maxsize=16)
|
||||
self.quec_timer = osTimer()
|
||||
self.queciot_init()
|
||||
self.cloud_init()
|
||||
|
||||
fileClear = OTAFileClear()
|
||||
fileClear.file_clear()
|
||||
|
||||
def queciot_init(self):
|
||||
if quecIot.getWorkState() == 8 and quecIot.getConnmode() == 1:
|
||||
return
|
||||
def cloud_init(self, enforce=False):
|
||||
current_settings = settings.get()
|
||||
log.debug(
|
||||
'[cloud_init start] enforce: %s QuecThing Work State: %s, quecIot.getConnmode(): %s'
|
||||
% (enforce, quecIot.getWorkState(), quecIot.getConnmode())
|
||||
)
|
||||
if enforce is False:
|
||||
if quecIot.getWorkState() == 8 and quecIot.getConnmode() == 1:
|
||||
return True
|
||||
|
||||
quecIot.init()
|
||||
quecIot.setEventCB(self.eventCB)
|
||||
quecIot.setProductinfo(self.pk, self.ps)
|
||||
quecIot.setDkDs(self.dk, self.ds)
|
||||
quecIot.setServer(1, "iot-south.quectel.com:2883")
|
||||
if self.dk or self.ds:
|
||||
quecIot.setDkDs(self.dk, self.ds)
|
||||
quecIot.setServer(1, self.server)
|
||||
quecIot.setLifetime(current_settings['sys']['cloud_life_time'])
|
||||
quecIot.setMcuVersion(PROJECT_NAME, PROJECT_VERSION)
|
||||
quecIot.setConnmode(1)
|
||||
|
||||
count = 0
|
||||
while quecIot.getWorkState() != 8 and count < 10:
|
||||
if self.init_res.get('subscription') is not None:
|
||||
self.init_res.pop('subscription')
|
||||
break
|
||||
utime.sleep_ms(200)
|
||||
count += 1
|
||||
|
||||
if not self.ds and self.dk:
|
||||
count = 0
|
||||
while count < 3:
|
||||
ndk, nds = quecIot.getDkDs()
|
||||
if nds:
|
||||
dkds = quecIot.getDkDs()
|
||||
if dkds:
|
||||
self.dk, self.ds = dkds
|
||||
break
|
||||
count += 1
|
||||
utime.sleep(count)
|
||||
current_settings = settings.get()
|
||||
cloud_init_params = current_settings['sys']['cloud_init_params']
|
||||
cloud_init_params['DS'] = nds
|
||||
self.dk = ndk
|
||||
self.ds = nds
|
||||
cloud_init_params['DS'] = self.ds
|
||||
settings.set('cloud_init_params', cloud_init_params)
|
||||
settings.save()
|
||||
|
||||
log.debug('[cloud_init over] QuecThing Work State: %s, quecIot.getConnmode(): %s' % (quecIot.getWorkState(), quecIot.getConnmode()))
|
||||
if quecIot.getWorkState() == 8 and quecIot.getConnmode() == 1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_post_res(self):
|
||||
current_settings = settings.get()
|
||||
self.quec_timer.start(current_settings['sys']['checknet_timeout'] * 1000, 1, self.quec_timer_cb)
|
||||
self.quec_timer.start(5000, 0, self.quec_timer_cb)
|
||||
res = self.post_result_wait_queue.get()
|
||||
self.quec_timer.stop()
|
||||
return res
|
||||
@ -153,6 +174,7 @@ class QuecThing(object):
|
||||
def quec_timer_cb(self, args):
|
||||
# Power.powerRestart()
|
||||
self.post_result_wait_queue.put(False)
|
||||
self.quec_timer.stop()
|
||||
|
||||
@staticmethod
|
||||
def rm_empty_data(data):
|
||||
@ -161,7 +183,6 @@ class QuecThing(object):
|
||||
del data[k]
|
||||
|
||||
def post_data(self, data):
|
||||
self.queciot_init()
|
||||
res = True
|
||||
# log.debug('post_data: %s' % str(data))
|
||||
for k, v in data.items():
|
||||
@ -225,15 +246,12 @@ class QuecThing(object):
|
||||
elif event == 2:
|
||||
if errcode == 10200:
|
||||
log.info('Access succeeded.')
|
||||
self.init_res['access'] = True
|
||||
if errcode == 10450:
|
||||
log.error('Device internal error (connect failed).')
|
||||
self.init_res['access'] = False
|
||||
elif event == 3:
|
||||
if errcode == 10200:
|
||||
log.info('Subscription succeeded.')
|
||||
self.init_res['subscription'] = True
|
||||
quecIot.otaRequest(0)
|
||||
self.ota_request()
|
||||
if data != (3, 10200):
|
||||
ota_info = data.decode()
|
||||
file_info = ota_info.split(',')
|
||||
@ -243,7 +261,6 @@ class QuecThing(object):
|
||||
)
|
||||
if errcode == 10300:
|
||||
log.info('Subscription failed.')
|
||||
self.init_res['subscription'] = False
|
||||
elif event == 4:
|
||||
if errcode == 10200:
|
||||
log.info('Data sending succeeded.')
|
||||
@ -293,39 +310,39 @@ class QuecThing(object):
|
||||
"batteryLimit: %s, minSignalIntensity: %s, useSpace: %s" % tuple(file_info)
|
||||
)
|
||||
self.downlink_queue.put(('ota_plain', data))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 1)]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (data[0], 1, data[2]))]))
|
||||
elif errcode == 10701:
|
||||
log.info('The module starts to download.')
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 2)]))
|
||||
if data != (7, 10701):
|
||||
ota_info = data.decode()
|
||||
file_info = ota_info.split(',')
|
||||
self.sota_download_info(int(file_info[1]), file_info[2], int(file_info[3]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 2, None))]))
|
||||
elif errcode == 10702:
|
||||
log.info('Package download.')
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 2)]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 2, None))]))
|
||||
elif errcode == 10703:
|
||||
log.info('Package download complete.')
|
||||
if data != (7, 10703):
|
||||
ota_info = data.decode()
|
||||
file_info = ota_info.split(',')
|
||||
log.info("OTA File Info: componentNo: %s, length: %s, md5: %s, crc: %s" % tuple(file_info))
|
||||
self.sota_download_success(file_info[2], file_info[3])
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 2)]))
|
||||
self.sota_download_success(int(file_info[2]), int(file_info[3]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 2, None))]))
|
||||
elif errcode == 10704:
|
||||
log.info('Package updating.')
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 2)]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 2, None))]))
|
||||
elif errcode == 10705:
|
||||
log.info('Firmware update complete.')
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 3)]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 3, None))]))
|
||||
elif errcode == 10706:
|
||||
log.info('Failed to update firmware.')
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 4)]))
|
||||
self.downlink_queue.put(('object_model', [('ota_status', (None, 4, None))]))
|
||||
elif errcode == 10707:
|
||||
log.info('Received confirmation broadcast.')
|
||||
|
||||
def dev_info_report(self):
|
||||
quecIot.devInfoReport([i for i in range(1, 13)])
|
||||
def ota_request(self):
|
||||
quecIot.otaRequest(0)
|
||||
|
||||
def ota_action(self, val=1):
|
||||
quecIot.otaAction(val)
|
||||
@ -337,6 +354,11 @@ class QuecThing(object):
|
||||
self.update_mode = UpdateCtx()
|
||||
self.md5_value = md5_value
|
||||
|
||||
def sota_download_success(self, start, down_loaded_size):
|
||||
self.need_download_size = down_loaded_size
|
||||
self.start_addr = start
|
||||
self.read_sota_file()
|
||||
|
||||
def read_sota_file(self):
|
||||
while self.need_download_size != 0:
|
||||
readsize = 4096
|
||||
@ -354,19 +376,12 @@ class QuecThing(object):
|
||||
file_update_res = self.update_mode.file_update(self.md5_value)
|
||||
if file_update_res:
|
||||
log.debug("File Update Success, Power Restart.")
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 3)]))
|
||||
self.downlink_queue.put(('object_model', [('power_restart', 1)]))
|
||||
else:
|
||||
log.debug("File Update Failed.")
|
||||
self.downlink_queue.put(('object_model', [('ota_status', 4)]))
|
||||
self.downlink_queue.put(('object_model', [('power_restart', 1)]))
|
||||
else:
|
||||
quecIot.otaAction(2)
|
||||
|
||||
def sota_download_success(self, start, down_loaded_size):
|
||||
self.need_download_size = down_loaded_size
|
||||
self.start_addr = start
|
||||
self.read_sota_file()
|
||||
|
||||
|
||||
class UpdateCtx(object):
|
||||
def __init__(self, parent_dir="/usr/.updater/usr/"):
|
||||
|
107
code/remote.py
107
code/remote.py
@ -13,7 +13,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import uos
|
||||
import utime
|
||||
import ql_fs
|
||||
import ujson
|
||||
import _thread
|
||||
@ -81,18 +80,34 @@ class Controller(Singleton):
|
||||
elif action == 1:
|
||||
self.tracker.remote.cloud_ota_action(1)
|
||||
|
||||
def ota_status(self, perm, status=None):
|
||||
def ota_status(self, perm, upgrade_info=None):
|
||||
if perm == 'r':
|
||||
self.tracker.device_data_report()
|
||||
elif perm == 'w':
|
||||
if status is not None:
|
||||
settings.settings.set('ota_status', status)
|
||||
if upgrade_info:
|
||||
current_settings = settings.settings.get()
|
||||
ota_status_info = current_settings['sys']['ota_status']
|
||||
ota_info = {}
|
||||
if upgrade_info[0] == settings.SYSNAME:
|
||||
ota_info['upgrade_module'] = 1
|
||||
ota_info['sys_target_version'] = upgrade_info[2]
|
||||
elif upgrade_info[0] == settings.PROJECT_NAME:
|
||||
ota_info['upgrade_module'] = 2
|
||||
ota_info['app_target_version'] = upgrade_info[2]
|
||||
ota_info['upgrade_status'] = upgrade_info[1]
|
||||
ota_status_info.update(ota_info)
|
||||
settings.settings.set('ota_status', ota_status_info)
|
||||
settings.settings.save()
|
||||
|
||||
def power_restart(self, perm, flag):
|
||||
if perm == 'w':
|
||||
self.tracker.device_data_report(power_switch=False, msg='power_restart')
|
||||
|
||||
def work_cycle_period(self, perm, period):
|
||||
if perm == 'w':
|
||||
self.tracker.power_manage.rtc.enable_alarm(0)
|
||||
self.tracker.power_manage.start_rtc()
|
||||
|
||||
|
||||
class DownLinkOption(object):
|
||||
def __init__(self, tracker):
|
||||
@ -139,7 +154,14 @@ class DownLinkOption(object):
|
||||
def ota_plain(self, *args, **kwargs):
|
||||
current_settings = settings.settings.get()
|
||||
if current_settings['app']['sw_ota'] and current_settings['app']['sw_ota_auto_upgrade']:
|
||||
self.tracker.remote.cloud_ota_action()
|
||||
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot:
|
||||
self.tracker.remote.cloud_ota_action()
|
||||
elif current_settings['sys']['cloud'] == settings.default_values_sys._cloud.AliYun:
|
||||
log.debug('ota_plain args: %s' % str(args))
|
||||
log.debug('ota_plain kwargs: %s' % str(kwargs))
|
||||
|
||||
def ota_file_download(self, *args, **kwargs):
|
||||
log.debug('ota_file_download: %s' % str(args))
|
||||
|
||||
|
||||
def downlink_process(argv):
|
||||
@ -157,10 +179,11 @@ def downlink_process(argv):
|
||||
|
||||
DownLinkOptionObj = DownLinkOption(tracker=self.tracker)
|
||||
option_attr = data[0]
|
||||
args = data[1]
|
||||
args = data[1] if not isinstance(data[1], dict) else ()
|
||||
kwargs = data[1] if isinstance(data[1], dict) else {}
|
||||
if hasattr(DownLinkOptionObj, option_attr):
|
||||
option_fun = getattr(DownLinkOptionObj, option_attr)
|
||||
option_fun(*args)
|
||||
option_fun(*args, **kwargs)
|
||||
if self.remote_read_cb:
|
||||
self.remote_read_cb(*data)
|
||||
else:
|
||||
@ -185,22 +208,19 @@ def uplink_process(argv):
|
||||
# Read history data that didn't send to server intime to hist-dictionary.
|
||||
hist = self.read_history()
|
||||
try:
|
||||
if self.tracker.net_enable is False:
|
||||
if self.cloud_connect() is False:
|
||||
raise RemoteError('Net Is Disconnected.')
|
||||
for key, value in hist.items():
|
||||
# Check if non_loca data (sensor or device info data) or location gps data or location non-gps data (cell/wifi-locator data)
|
||||
if key == 'hist_data':
|
||||
for i, data in enumerate(value):
|
||||
ntry = 0
|
||||
# Try at most 3 times to post data to server.
|
||||
while not self.cloud.post_data(data):
|
||||
ntry += 1
|
||||
if ntry >= 3: # Data post failed after 3 times, maybe network error?
|
||||
if not self.cloud.post_data(data):
|
||||
self.cloud.cloud_init(enforce=True)
|
||||
if not self.cloud.post_data(data):
|
||||
raise RemoteError('Data post failed.') # Stop posting more data, go to exception handler.
|
||||
utime.sleep(1)
|
||||
else:
|
||||
value.pop(i) # Pop data from data-list after posting sueecss.
|
||||
need_refresh = True # Data in hist-dictionary changed, need to refresh history file.
|
||||
break
|
||||
value.pop(i)
|
||||
need_refresh = True # Data in hist-dictionary changed, need to refresh history file.
|
||||
except Exception as e:
|
||||
log.error('uplink_process Error: %s' % e)
|
||||
while True: # Put all data in uplink_queue to hist-dictionary.
|
||||
@ -224,10 +244,15 @@ def uplink_process(argv):
|
||||
data = self.uplink_queue.get()
|
||||
if data:
|
||||
if data[1]:
|
||||
if self.tracker.net_enable is True:
|
||||
if self.cloud_connect() is True:
|
||||
if self.cloud.post_data(data[1]):
|
||||
sys_bus.publish(data[0], 'true')
|
||||
continue
|
||||
else:
|
||||
self.cloud.cloud_init(enforce=True)
|
||||
if self.cloud.post_data(data[1]):
|
||||
sys_bus.publish(data[0], 'true')
|
||||
continue
|
||||
else:
|
||||
log.warn('Net Is Disconnected.')
|
||||
self.add_history(data[1])
|
||||
@ -250,9 +275,23 @@ class Remote(Singleton):
|
||||
current_settings = settings.settings.get()
|
||||
cloud_init_params = current_settings['sys']['cloud_init_params']
|
||||
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot:
|
||||
self.cloud = QuecThing(cloud_init_params['PK'], cloud_init_params['PS'], cloud_init_params['DK'], cloud_init_params['DS'], self.downlink_queue)
|
||||
self.cloud = QuecThing(
|
||||
cloud_init_params['PK'],
|
||||
cloud_init_params['PS'],
|
||||
cloud_init_params['DK'],
|
||||
cloud_init_params['DS'],
|
||||
cloud_init_params['SERVER'],
|
||||
self.downlink_queue
|
||||
)
|
||||
elif current_settings['sys']['cloud'] == settings.default_values_sys._cloud.AliYun:
|
||||
self.cloud = AliYunIot(cloud_init_params['PK'], cloud_init_params['PS'], cloud_init_params['DK'], cloud_init_params['DS'], self.downlink_queue)
|
||||
self.cloud = AliYunIot(
|
||||
cloud_init_params['PK'],
|
||||
cloud_init_params['PS'],
|
||||
cloud_init_params['DK'],
|
||||
cloud_init_params['DS'],
|
||||
cloud_init_params['SERVER'],
|
||||
self.downlink_queue
|
||||
)
|
||||
else:
|
||||
raise settings.SettingsError('Current cloud (0x%X) not supported!' % current_settings['sys']['cloud'])
|
||||
|
||||
@ -316,6 +355,13 @@ class Remote(Singleton):
|
||||
def clean_history(self):
|
||||
uos.remove(self._history)
|
||||
|
||||
def cloud_connect(self):
|
||||
net_check_res = self.tracker.check.net_check()
|
||||
if net_check_res == (3, 1):
|
||||
return self.cloud.cloud_init()
|
||||
else:
|
||||
return False
|
||||
|
||||
def post_data(self, topic, data):
|
||||
'''
|
||||
Data format to post:
|
||||
@ -331,21 +377,30 @@ class Remote(Singleton):
|
||||
|
||||
def check_ota(self):
|
||||
current_settings = settings.settings.get()
|
||||
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot:
|
||||
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot or \
|
||||
current_settings['sys']['cloud'] == settings.default_values_sys._cloud.AliYun:
|
||||
if current_settings['app']['sw_ota'] is True:
|
||||
log.debug('OTA Check To Report Dev Info.')
|
||||
self.cloud.dev_info_report()
|
||||
self.cloud.ota_request()
|
||||
else:
|
||||
raise settings.SettingsError('OTA Upgrade Is Disabled!')
|
||||
log.warn('OTA Upgrade Is Disabled!')
|
||||
else:
|
||||
raise settings.SettingsError('Current Cloud (0x%X) Not Supported!' % current_settings['sys']['cloud'])
|
||||
log.error('Current Cloud (0x%X) Not Supported!' % current_settings['sys']['cloud'])
|
||||
|
||||
def cloud_ota_action(self, val=1):
|
||||
current_settings = settings.settings.get()
|
||||
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot:
|
||||
self.cloud.ota_action(val)
|
||||
if val == 0:
|
||||
settings.settings.set('ota_status', 0)
|
||||
current_settings = settings.settings.get()
|
||||
ota_status_info = current_settings['sys']['ota_status']
|
||||
ota_info = {}
|
||||
ota_info['sys_target_version'] = '--'
|
||||
ota_info['app_target_version'] = '--'
|
||||
ota_info['upgrade_module'] = 0
|
||||
ota_info['upgrade_status'] = 0
|
||||
ota_status_info.update(ota_info)
|
||||
settings.settings.set('ota_status', ota_status_info)
|
||||
settings.settings.save()
|
||||
else:
|
||||
raise settings.SettingsError('Current Cloud (0x%X) Not Supported!' % current_settings['sys']['cloud'])
|
||||
log.warn('Current Cloud (0x%X) Not Supported!' % current_settings['sys']['cloud'])
|
||||
|
@ -16,14 +16,19 @@ import uos
|
||||
import ure
|
||||
import ql_fs
|
||||
import ujson
|
||||
import modem
|
||||
import _thread
|
||||
from machine import UART
|
||||
from usr.common import Singleton
|
||||
|
||||
PROJECT_NAME = 'QuecPython_Tracker'
|
||||
PROJECT_NAME = 'QuecPython-Tracker'
|
||||
|
||||
PROJECT_VERSION = '2.0.1'
|
||||
|
||||
SYSNAME = uos.uname()[0].split('=')[1]
|
||||
|
||||
DEVICE_FIRMWARE_VERSION = modem.getDevFwVersion()
|
||||
|
||||
DATA_NON_LOCA = 0x0
|
||||
DATA_LOCA_NON_GPS = 0x1
|
||||
DATA_LOCA_GPS = 0x2
|
||||
@ -47,6 +52,15 @@ DEVICE_MODULE_STATUS = {
|
||||
'mike': 6,
|
||||
}
|
||||
|
||||
OTA_STATUS = {
|
||||
'sys_current_version': 1,
|
||||
'sys_target_version': 2,
|
||||
'app_current_version': 3,
|
||||
'app_target_version': 4,
|
||||
'upgrade_module': 5,
|
||||
'upgrade_status': 6,
|
||||
}
|
||||
|
||||
DRIVE_BEHAVIOR_CODE = {
|
||||
0: 'none',
|
||||
1: 'quick_start',
|
||||
@ -128,11 +142,11 @@ class default_values_app(object):
|
||||
|
||||
work_cycle_period = 30
|
||||
|
||||
low_power_alert_threshold = 30
|
||||
low_power_alert_threshold = 20
|
||||
|
||||
low_power_shutdown_threshold = 5
|
||||
|
||||
over_speed_threshold = 60
|
||||
over_speed_threshold = 50
|
||||
|
||||
sw_ota = True
|
||||
|
||||
@ -172,13 +186,18 @@ class default_values_sys(object):
|
||||
internal = 0x1
|
||||
external = 0x2
|
||||
|
||||
class _ota_status(object):
|
||||
class _ota_upgrade_status(object):
|
||||
none = 0
|
||||
to_be_updated = 1
|
||||
updating = 2
|
||||
update_successed = 3
|
||||
update_failed = 4
|
||||
|
||||
class _ota_upgrade_module(object):
|
||||
none = 0
|
||||
sys = 1
|
||||
app = 2
|
||||
|
||||
class _ali_burning_method(object):
|
||||
one_type_one_density = 0
|
||||
one_machine_one_density = 1
|
||||
@ -194,39 +213,63 @@ class default_values_sys(object):
|
||||
|
||||
gps_mode = _gps_mode.external
|
||||
|
||||
ota_status = _ota_status.none
|
||||
ota_status = {}
|
||||
|
||||
drive_behavior_code = 0
|
||||
|
||||
cloud = _cloud.quecIot
|
||||
|
||||
cloud_life_time = 120
|
||||
|
||||
cloud_init_params = {}
|
||||
|
||||
work_mode_timeline = 3600
|
||||
|
||||
ali_burning_method = _ali_burning_method.one_machine_one_density
|
||||
|
||||
# trackdev0304
|
||||
# trackdev0304 (PROENV)
|
||||
_quecIot = {
|
||||
'PK': 'p11275',
|
||||
'PS': 'Q0ZQQndaN3pCUFd6',
|
||||
'DK': 'trackdev0304',
|
||||
'DS': '8eba9389af434974c3c846d1922d949f',
|
||||
'SERVER': 'iot-south.quectel.com:2883',
|
||||
}
|
||||
|
||||
# # trackerdemo0326
|
||||
# # trackerdemo0326 (PROENV)
|
||||
# _quecIot = {
|
||||
# 'PK': 'p11275',
|
||||
# 'PS': 'Q0ZQQndaN3pCUFd6',
|
||||
# 'DK': 'trackerdemo0326',
|
||||
# 'DS': '32d540996e32f95c58dd98f18d473d52',
|
||||
# 'SERVER': 'iot-south.quectel.com:2883',
|
||||
# }
|
||||
|
||||
# # IMEI (PROENV)
|
||||
# _quecIot = {
|
||||
# 'PK': 'p11275',
|
||||
# 'PS': 'Q0ZQQndaN3pCUFd6',
|
||||
# 'DK': '',
|
||||
# 'DS': '',
|
||||
# 'SERVER': 'iot-south.quectel.com:2883',
|
||||
# }
|
||||
|
||||
# # TrackerDevEC600NCNLC (TESTENV)
|
||||
# _quecIot = {
|
||||
# 'PK': 'p119v2',
|
||||
# 'PS': 'TXRPdVVhdkY3bU5s',
|
||||
# 'DK': 'TrackerDevEC600NCNLC',
|
||||
# 'DS': '',
|
||||
# 'SERVER': 'mqtt://220.180.239.212:8382',
|
||||
# }
|
||||
|
||||
# # IMEI (TESTENV)
|
||||
# _quecIot = {
|
||||
# 'PK': 'p119v2',
|
||||
# 'PS': 'TXRPdVVhdkY3bU5s',
|
||||
# 'DK': '',
|
||||
# 'DS': '',
|
||||
# 'SERVER': 'mqtt://220.180.239.212:8382',
|
||||
# }
|
||||
|
||||
# tracker_dev_jack
|
||||
@ -235,6 +278,7 @@ class default_values_sys(object):
|
||||
'PS': 'HQraBqtV8WsfCEuy',
|
||||
'DK': 'tracker_dev_jack',
|
||||
'DS': 'bfdfcca5075715e8309eff8597663c4b',
|
||||
"SERVER": '',
|
||||
}
|
||||
|
||||
_JTT808 = {
|
||||
@ -242,6 +286,7 @@ class default_values_sys(object):
|
||||
'PS': '',
|
||||
'DK': '',
|
||||
'DS': '',
|
||||
"SERVER": '',
|
||||
}
|
||||
|
||||
locator_init_params = {}
|
||||
@ -293,6 +338,19 @@ class default_values_sys(object):
|
||||
|
||||
return cloud_init_params
|
||||
|
||||
@staticmethod
|
||||
def _ota_status_init_params():
|
||||
ota_status = {
|
||||
'sys_current_version': SYSNAME,
|
||||
'sys_target_version': '--',
|
||||
'app_current_version': PROJECT_VERSION,
|
||||
'app_target_version': '--',
|
||||
'upgrade_module': default_values_sys._ota_upgrade_module.none,
|
||||
'upgrade_status': default_values_sys._ota_upgrade_status.none,
|
||||
}
|
||||
|
||||
return ota_status
|
||||
|
||||
|
||||
class Settings(Singleton):
|
||||
|
||||
@ -307,6 +365,7 @@ class Settings(Singleton):
|
||||
try:
|
||||
default_values_sys.locator_init_params = default_values_sys._get_locator_init_params(default_values_app.loc_method)
|
||||
default_values_sys.cloud_init_params = default_values_sys._get_cloud_init_params(default_values_sys.cloud)
|
||||
default_values_sys.ota_status = default_values_sys._ota_status_init_params()
|
||||
|
||||
default_settings_app = {k: v for k, v in default_values_app.__dict__.items() if not k.startswith('_')}
|
||||
default_settings_sys = {k: v for k, v in default_values_sys.__dict__.items() if not k.startswith('_')}
|
||||
@ -380,7 +439,13 @@ class Settings(Singleton):
|
||||
return False
|
||||
self.current_settings['app'][opt] = val
|
||||
return True
|
||||
|
||||
elif opt == 'over_speed_threshold':
|
||||
if not isinstance(val, int):
|
||||
return False
|
||||
if val < 1:
|
||||
return False
|
||||
self.current_settings['app'][opt] = val
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if opt in self.current_settings['sys']:
|
||||
@ -390,7 +455,7 @@ class Settings(Singleton):
|
||||
self.current_settings['sys'][opt] = val
|
||||
return True
|
||||
elif opt == 'ota_status':
|
||||
if not isinstance(val, int):
|
||||
if not isinstance(val, dict):
|
||||
return False
|
||||
self.current_settings['sys'][opt] = val
|
||||
return True
|
||||
|
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import pm
|
||||
import sim
|
||||
import ure
|
||||
import utime
|
||||
import _thread
|
||||
@ -122,25 +123,18 @@ def test_tracker():
|
||||
log.info('[.] sleep 10')
|
||||
utime.sleep(10)
|
||||
|
||||
# log.info('[.] tracker.power_manage.low_energy_init()')
|
||||
# tracker.power_manage.low_energy_init()
|
||||
# log.info('[.] tracker.power_manage.start_rtc()')
|
||||
# tracker.power_manage.start_rtc()
|
||||
# log.info('[.] end tracker.power_manage.start_rtc()')
|
||||
|
||||
# log.info('[.] test tracker.device_check()')
|
||||
# device_check_res = tracker.device_check()
|
||||
# log.info('[.] device_check_res:', device_check_res)
|
||||
|
||||
log.info('[.] test tracker.remote.check_ota()')
|
||||
tracker.remote.check_ota()
|
||||
log.info('[.] tracker.power_manage.low_energy_init()')
|
||||
tracker.power_manage.low_energy_init()
|
||||
log.info('[.] tracker.power_manage.start_rtc()')
|
||||
tracker.power_manage.start_rtc()
|
||||
log.info('[.] end tracker.power_manage.start_rtc()')
|
||||
|
||||
# log.info('[.] sleep 3')
|
||||
# utime.sleep(3)
|
||||
|
||||
# log.info('[.] test tracker.machine_check()')
|
||||
# machine_check_res = tracker.machine_check()
|
||||
# log.info('[.] machine_check_res:', machine_check_res)
|
||||
# log.info('[.] test tracker.remote.check_ota()')
|
||||
# check_ota_res = tracker.remote.check_ota()
|
||||
# log.info('[.] check_ota_res:', check_ota_res)
|
||||
|
||||
log.info('[x] end test_tracker')
|
||||
|
||||
@ -274,6 +268,24 @@ def test_ostimer():
|
||||
timer.start(1000, 2, timer_cb)
|
||||
|
||||
|
||||
sim_queue = Queue(maxsize=8)
|
||||
|
||||
|
||||
def sim_cb(args):
|
||||
log.debug('sim_cb args: %s' % str(args))
|
||||
sim_queue.put(args)
|
||||
|
||||
|
||||
def test_sim():
|
||||
sim_status = sim.getStatus()
|
||||
log.debug('sim_status: %s' % sim_status)
|
||||
sim.setCallback(sim_cb)
|
||||
sim.setSimDet(1, 1)
|
||||
while True:
|
||||
data = sim_queue.get()
|
||||
log.debug('sim_queue data: %s' % data)
|
||||
|
||||
|
||||
def main():
|
||||
# test_quecthing()
|
||||
# test_settings()
|
||||
@ -287,6 +299,7 @@ def main():
|
||||
# test_rtc()
|
||||
# test_gps_uart()
|
||||
# test_ostimer()
|
||||
# test_sim()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import pm
|
||||
import sim
|
||||
import utime
|
||||
import _thread
|
||||
import sys_bus
|
||||
@ -49,7 +50,7 @@ log = getLogger(__name__)
|
||||
|
||||
class Tracker(Singleton):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.net_enable = True
|
||||
sim.setSimDet(1, 0)
|
||||
self.num_iter = numiter()
|
||||
self.num_lock = _thread.allocate_lock()
|
||||
|
||||
@ -140,7 +141,6 @@ class Tracker(Singleton):
|
||||
loc_check_res = self.check.loc_check()
|
||||
sensor_check_res = self.check.sensor_check()
|
||||
|
||||
self.net_enable = True if net_check_res == (3, 1) else False
|
||||
device_module_status['net'] = 1 if net_check_res == (3, 1) else 0
|
||||
|
||||
device_module_status['location'] = 1 if loc_check_res else 0
|
||||
@ -159,15 +159,20 @@ class Tracker(Singleton):
|
||||
return alert_data
|
||||
|
||||
def get_over_speed_check(self):
|
||||
alert_data = {}
|
||||
alert_data = {
|
||||
'current_speed': 0.00
|
||||
}
|
||||
current_settings = settings.settings.get()
|
||||
if current_settings['app']['work_mode'] == settings.default_values_app._work_mode.intelligent:
|
||||
if current_settings['app']['sw_over_speed_alert'] is True:
|
||||
if self.locator.gps:
|
||||
speed = self.locator.gps.read_location_GxVTG_speed()
|
||||
gps_data = self.locator.gps.read()
|
||||
speed = self.locator.gps.read_location_GxVTG_speed(gps_data)
|
||||
if speed and float(speed) >= current_settings['app']['over_speed_threshold']:
|
||||
alert_code = 30003
|
||||
alert_info = {'local_time': self.get_local_time()}
|
||||
alert_data = self.get_alert_data(alert_code, alert_info)
|
||||
if speed:
|
||||
alert_data['current_speed'] = float(speed)
|
||||
|
||||
return alert_data
|
||||
|
||||
@ -215,8 +220,15 @@ class Tracker(Singleton):
|
||||
|
||||
# OTA Status RST
|
||||
current_settings = settings.settings.get()
|
||||
if current_settings['sys']['ota_status'] in (3, 4):
|
||||
settings.settings.set('ota_status', 0)
|
||||
ota_status_info = current_settings['sys']['ota_status']
|
||||
if ota_status_info['upgrade_status'] in (3, 4):
|
||||
ota_info = {}
|
||||
ota_info['sys_target_version'] = '--'
|
||||
ota_info['app_target_version'] = '--'
|
||||
ota_info['upgrade_module'] = 0
|
||||
ota_info['upgrade_status'] = 0
|
||||
ota_status_info.update(ota_info)
|
||||
settings.settings.set('ota_status', ota_status_info)
|
||||
settings.settings.save()
|
||||
|
||||
def device_check(self):
|
||||
@ -256,7 +268,6 @@ class Tracker(Singleton):
|
||||
def nw_callback(self, args):
|
||||
net_check_res = self.check.net_check()
|
||||
if args[1] != 1:
|
||||
self.net_enable = False
|
||||
if net_check_res[0] == 1 and net_check_res[1] != 1:
|
||||
log.warn('SIM abnormal!')
|
||||
alert_code = 30004
|
||||
@ -265,7 +276,7 @@ class Tracker(Singleton):
|
||||
self.device_data_report(event_data=alert_data, msg='sim_abnormal')
|
||||
else:
|
||||
if net_check_res == (3, 1):
|
||||
self.net_enable = True
|
||||
pass
|
||||
|
||||
|
||||
class SelfCheck(object):
|
||||
@ -276,6 +287,7 @@ class SelfCheck(object):
|
||||
checknet = checkNet.CheckNetwork(settings.PROJECT_NAME, settings.PROJECT_VERSION)
|
||||
timeout = current_settings.get('sys', {}).get('checknet_timeout', 60)
|
||||
check_res = checknet.wait_network_connected(timeout)
|
||||
log.debug('net_check res: %s' % str(check_res))
|
||||
return check_res
|
||||
|
||||
def loc_check(self):
|
||||
|
@ -2,7 +2,7 @@
|
||||
"profile":{
|
||||
"tslVersion":"1.1.0",
|
||||
"productKey":"p11275",
|
||||
"version":"20220329170419124"
|
||||
"version":"20220402191608542"
|
||||
},
|
||||
"properties":[
|
||||
{
|
||||
@ -660,50 +660,13 @@
|
||||
],
|
||||
"code":"user_ota_action",
|
||||
"dataType":"ENUM",
|
||||
"name":"是否OTA升级",
|
||||
"name":"确认OTA升级",
|
||||
"subType":"RW",
|
||||
"id":38,
|
||||
"sort":31,
|
||||
"type":"PROPERTY",
|
||||
"desc":"当OTA自动升级关闭时, 用户通过查看设备当前是否有OTA升级来进行自主选择升级或不升级"
|
||||
},
|
||||
{
|
||||
"specs":[
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"无升级",
|
||||
"value":"0"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"待升级",
|
||||
"value":"1"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级中",
|
||||
"value":"2"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级成功",
|
||||
"value":"3"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级失败",
|
||||
"value":"4"
|
||||
}
|
||||
],
|
||||
"code":"ota_status",
|
||||
"dataType":"ENUM",
|
||||
"name":"OTA升级状态",
|
||||
"subType":"R",
|
||||
"id":39,
|
||||
"sort":32,
|
||||
"type":"PROPERTY",
|
||||
"desc":""
|
||||
},
|
||||
{
|
||||
"specs":{
|
||||
"unit":"mV",
|
||||
@ -719,6 +682,127 @@
|
||||
"sort":33,
|
||||
"type":"PROPERTY",
|
||||
"desc":""
|
||||
},
|
||||
{
|
||||
"specs":[
|
||||
{
|
||||
"specs":{
|
||||
"length":"1024"
|
||||
},
|
||||
"code":"sys_current_version",
|
||||
"dataType":"TEXT",
|
||||
"name":"系统当前版本",
|
||||
"id":1
|
||||
},
|
||||
{
|
||||
"specs":{
|
||||
"length":"1024"
|
||||
},
|
||||
"code":"sys_tartget_version",
|
||||
"dataType":"TEXT",
|
||||
"name":"系统目标版本",
|
||||
"id":2
|
||||
},
|
||||
{
|
||||
"specs":{
|
||||
"length":"1024"
|
||||
},
|
||||
"code":"app_current_version",
|
||||
"dataType":"TEXT",
|
||||
"name":"应用当前版本",
|
||||
"id":3
|
||||
},
|
||||
{
|
||||
"specs":{
|
||||
"length":"1024"
|
||||
},
|
||||
"code":"app_target_version",
|
||||
"dataType":"TEXT",
|
||||
"name":"应用目标版本",
|
||||
"id":4
|
||||
},
|
||||
{
|
||||
"specs":[
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"无",
|
||||
"value":"0"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"系统",
|
||||
"value":"1"
|
||||
},
|
||||
{
|
||||
"name":"应用",
|
||||
"value":"2"
|
||||
}
|
||||
],
|
||||
"code":"upgrade_module",
|
||||
"dataType":"ENUM",
|
||||
"name":"当前升级模块",
|
||||
"id":5,
|
||||
"desc":""
|
||||
},
|
||||
{
|
||||
"specs":[
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"无",
|
||||
"value":"0"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"待升级",
|
||||
"value":"1"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级中",
|
||||
"value":"2"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级成功",
|
||||
"value":"3"
|
||||
},
|
||||
{
|
||||
"dataType":"ENUM",
|
||||
"name":"升级失败",
|
||||
"value":"4"
|
||||
}
|
||||
],
|
||||
"code":"upgrade_status",
|
||||
"dataType":"ENUM",
|
||||
"name":"当前升级状态",
|
||||
"id":6,
|
||||
"desc":""
|
||||
}
|
||||
],
|
||||
"code":"ota_status",
|
||||
"dataType":"STRUCT",
|
||||
"name":"OTA升级",
|
||||
"subType":"R",
|
||||
"id":42,
|
||||
"sort":34,
|
||||
"type":"PROPERTY",
|
||||
"desc":""
|
||||
},
|
||||
{
|
||||
"specs":{
|
||||
"unit":"km/h",
|
||||
"min":"0",
|
||||
"max":"200.00",
|
||||
"step":"0.01"
|
||||
},
|
||||
"code":"current_speed",
|
||||
"dataType":"FLOAT",
|
||||
"name":"当前时速",
|
||||
"subType":"R",
|
||||
"id":43,
|
||||
"sort":35,
|
||||
"type":"PROPERTY",
|
||||
"desc":""
|
||||
}
|
||||
],
|
||||
"events":[
|
||||
|
Loading…
x
Reference in New Issue
Block a user