update: 1. settings option thread lock; 2. move cloud init params to settings; 3. down link option.

This commit is contained in:
JackSun-qc 2022-03-07 14:47:10 +08:00
parent 543010e52f
commit 2d97ba5bd8
4 changed files with 183 additions and 91 deletions

View File

@ -6,6 +6,8 @@ from usr.logging import getLogger
log = getLogger(__name__) log = getLogger(__name__)
version = '1.0.0'
tracker = None tracker = None

View File

@ -10,32 +10,32 @@ DATA_LOCA_GPS = 0x2
log = getLogger(__name__) log = getLogger(__name__)
object_model = [ object_model = [
(9, 'switch'), (9, ('switch', 'rw')),
(4, 'energy'), (4, ('energy', 'r')),
(23, 'phone_num'), (23, ('phone_num', 'rw')),
(24, 'loc_method'), (24, ('loc_method', 'rw')),
(25, 'loc_mode'), (25, ('loc_mode', 'rw')),
(26, 'loc_cycle_period'), (26, ('loc_cycle_period', 'rw')),
(19, 'local_time'), (19, ('local_time', 'r')),
(15, 'low_power_alert_threshold'), (15, ('low_power_alert_threshold', 'rw')),
(16, 'low_power_shutdown_threshold'), (16, ('low_power_shutdown_threshold', 'rw')),
(12, 'sw_ota'), (12, ('sw_ota', 'rw')),
(13, 'sw_ota_auto_upgrade'), (13, ('sw_ota_auto_upgrade', 'rw')),
(10, 'sw_voice_listen'), (10, ('sw_voice_listen', 'rw')),
(11, 'sw_voice_record'), (11, ('sw_voice_record', 'rw')),
(27, 'sw_fault_alert'), (27, ('sw_fault_alert', 'rw')),
(28, 'sw_low_power_alert'), (28, ('sw_low_power_alert', 'rw')),
(29, 'sw_over_speed_alert'), (29, ('sw_over_speed_alert', 'rw')),
(30, 'sw_sim_out_alert'), (30, ('sw_sim_out_alert', 'rw')),
(31, 'sw_disassemble_alert'), (31, ('sw_disassemble_alert', 'rw')),
(32, 'sw_drive_behavior_alert'), (32, ('sw_drive_behavior_alert', 'rw')),
(21, 'drive_behavior_code'), (21, ('drive_behavior_code', 'r')),
(6, 'sos_alert'), (6, ('sos_alert', 'rw')),
(14, 'fault_alert'), (14, ('fault_alert', 'rw')),
(17, 'low_power_alert'), (17, ('low_power_alert', 'rw')),
(18, 'sim_out_alert'), (18, ('sim_out_alert', 'rw')),
(22, 'drive_behavior_alert'), (22, ('drive_behavior_alert', 'rw')),
(20, 'disassemble_alert') (20, ('disassemble_alert', 'rw'))
] ]
@ -136,15 +136,15 @@ class QuecThing(object):
self.downlink_queue.put(('raw_data', data)) self.downlink_queue.put(('raw_data', data))
if errcode == 10210: if errcode == 10210:
log.info('Recving object model data.') log.info('Recving object model data.')
dl_data = [(dict(object_model)[k], v.decode() if isinstance(v, bytes) else v) for k, v in data.items()] dl_data = [(dict(object_model)[k][0], v.decode() if isinstance(v, bytes) else v) for k, v in data.items() if 'w' in dict(object_model)[k][1]]
self.downlink_queue.put(('set', dl_data)) self.downlink_queue.put(('object_model', dl_data))
elif errcode == 10211: elif errcode == 10211:
log.info('Recving object model query command.') log.info('Recving object model query command.')
# TODO: Check pkgId for other uses. # TODO: Check pkgId for other uses.
# log.info('pkgId: %s' % data[0]) # log.info('pkgId: %s' % data[0])
object_model_ids = data[1] object_model_ids = data[1]
object_model_val = [dict(object_model).get(i) for i in object_model_ids if object_model_ids.get(i) is not None] object_model_val = [dict(object_model)[i][0] for i in object_model_ids if dict(object_model).get(i) is not None and 'r' in dict(object_model)[i][1]]
self.downlink_queue.put(('get', object_model_val)) self.downlink_queue.put(('query', object_model_val))
elif event == 6: elif event == 6:
if errcode == 10200: if errcode == 10200:
log.info('Logout succeeded.') log.info('Logout succeeded.')

View File

@ -6,7 +6,6 @@ import uos
import _thread import _thread
from queue import Queue from queue import Queue
import usr.settings as settings import usr.settings as settings
import usr.dev_info as dev_info
from usr.logging import getLogger from usr.logging import getLogger
log = getLogger(__name__) log = getLogger(__name__)
@ -26,41 +25,74 @@ class RemoteError(Exception):
return repr(self.value) return repr(self.value)
class DownLinkOption(object): class Controller(object):
def __init__(self, remote_obj): def __init__(self, remote):
self.remote_obj = remote_obj self.remote = remote
def remote_post_data(self, key, val): def switch(self, perm, flag=None, *args):
# TODO: Self funtion over to post or not. if perm == 'r':
self.remote_obj.post_data(self.remote_obj.DATA_NON_LOCA, {key: val}) # TODO: PowerStatus
pass
elif perm == 'w':
if flag is True:
# TODO: PowerUp
pass
elif flag is False:
# TODO: PowerDown
pass
else:
pass
else:
raise RemoteError('Controller switch permission error %s.' % perm)
def get_switch(self, *args): def energy(self, perm, *args):
return True if perm == 'r':
# TODO: How to get energy from Power.getVbatt().
def set_switch(self, *args):
if args[0] is False:
# TODO: How to checkout msg that is posted over before power down.
pass pass
else: else:
return True raise RemoteError('Controller energy permission error %s.' % perm)
def get_energy(self, *args): def drive_behavior_code(self, perm, *args):
# TODO: How to get energy from Power.getVbatt(). if perm == 'r':
pass pass
def get_app_settings(self, *args):
return settings.current_settings['app'][args[0]]
def set_app_settings(self, *args):
if settings.set(args[0], args[1]):
settings.save()
return args[1]
else: else:
return self.get_app_settings(args[0]) raise RemoteError('Controller drive_behavior_code permission error %s.' % perm)
def get_drive_behavior_code(self, *args):
class DownLinkOption(object):
def __init__(self, remote):
self.remote = remote
self.controller = Controller(self.remote)
def row_data(self, *args, **kwargs):
pass pass
def object_model(self, *args, **kwargs):
setting_flag = 0
for arg in args:
if hasattr(settings.default_values_app, arg[0]):
set_res = settings.set(arg[0], arg[1])
log.debug('key: %s, val: %s, set_res: %s', (arg[0], arg[1], set_res))
if setting_flag == 0:
setting_flag = 1
elif hasattr(self.controller, arg[0]):
getattr(self.controller, arg[0])(*('w', arg[1]))
else:
pass
if setting_flag:
settings.save()
def query(self, *args, **kwargs):
for arg in args:
if hasattr(settings.default_values_app, arg):
settings.query(self.remote, 'app', arg)
elif hasattr(self.controller, arg):
getattr(self.controller, arg)(*('r'))
else:
pass
def downlink_process(argv): def downlink_process(argv):
self = argv self = argv
@ -73,39 +105,17 @@ def downlink_process(argv):
TODO: ===================== TODO: =====================
''' '''
data = self.downlink_queue.get() data = self.downlink_queue.get()
log.debug('downlink_queue data:', data)
DownLinkOptionObj = DownLinkOption(remote_obj=self) DownLinkOptionObj = DownLinkOption(remote=self)
for option_type, option_data in data: option_attr = data[0]
for item in option_data: args = data[1]
model_obj_name = '' if hasattr(DownLinkOptionObj, option_attr):
args = () option_fun = getattr(DownLinkOptionObj, option_attr)
option_attr = '' option_fun(*args)
if option_type == 'set': else:
model_obj_name = item[0] # TODO: Raise Error OR Conntinue
if hasattr(settings.default_values_app, model_obj_name): raise RemoteError('DownLinkOption has no accribute %s.' % option_attr)
option_attr = 'set_app_settings'
args = item
else:
option_attr = 'set_' + model_obj_name
args = (item[1],)
elif option_type == 'get':
model_obj_name = item
if hasattr(settings.default_values_app, model_obj_name):
option_attr = 'get_app_settings'
args = (item,)
else:
option_attr = 'get_' + model_obj_name
else:
# TODO: row data
pass
if hasattr(DownLinkOptionObj, option_attr):
option_fun = getattr(DownLinkOptionObj, option_attr)
option_fun_res = option_fun(*args)
self.post_data(self.DATA_NON_LOCA, {model_obj_name: option_fun_res})
else:
# TODO: Raise Error OR Conntinue
raise RemoteError('DownLinkOption has no accribute %s.' % option_fun)
''' '''
TODO: processing for settings or control commands from downlink channel TODO: processing for settings or control commands from downlink channel
''' '''
@ -203,8 +213,9 @@ class Remote(object):
def __init__(self): def __init__(self):
self.downlink_queue = Queue(maxsize=64) self.downlink_queue = Queue(maxsize=64)
self.uplink_queue = Queue(maxsize=64) self.uplink_queue = Queue(maxsize=64)
cloud_init_params = settings.current_settings['sys']['cloud_init_params']
if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot: if current_settings['sys']['cloud'] == settings.default_values_sys._cloud.quecIot:
self.cloud = QuecThing(dev_info.quecIot['PK'], dev_info.quecIot['PS'], dev_info.quecIot['DK'], dev_info.quecIot['DS'], self.downlink_queue) self.cloud = QuecThing(cloud_init_params['PK'], cloud_init_params['PS'], cloud_init_params['DK'], cloud_init_params['DS'], self.downlink_queue)
self.DATA_NON_LOCA = DATA_NON_LOCA self.DATA_NON_LOCA = DATA_NON_LOCA
self.DATA_LOCA_NON_GPS = DATA_LOCA_NON_GPS self.DATA_LOCA_NON_GPS = DATA_LOCA_NON_GPS
self.DATA_LOCA_GPS = DATA_LOCA_GPS self.DATA_LOCA_GPS = DATA_LOCA_GPS

View File

@ -3,6 +3,8 @@ import ql_fs
import ujson import ujson
import uos import uos
import ure import ure
import _thread
import quecIot
from machine import UART from machine import UART
from usr.logging import getLogger from usr.logging import getLogger
@ -14,6 +16,23 @@ current_settings = {}
current_settings_app = {} current_settings_app = {}
current_settings_sys = {} current_settings_sys = {}
_settings_lock = _thread.allocate_lock()
def settings_lock(func):
def wrapperd_fun(*args, **kwargs):
if not _settings_lock.locked():
if _settings_lock.acquire():
source_fun = func(*args, **kwargs)
_settings_lock.release()
return source_fun
else:
log.warn('%s for _settings_lock acquire falied. args: %s' % (func.__name__, args))
else:
log.warn('%s for _settings_lock is locked. args: %s' % (func.__name__, args))
return wrapperd_fun
class default_values_app(object): class default_values_app(object):
''' '''
@ -97,6 +116,29 @@ class default_values_sys(object):
cloud = _cloud.quecIot cloud = _cloud.quecIot
cloud_init_params = {}
_quecIot = {
'PK': 'p11275',
'PS': 'Q0ZQQndaN3pCUFd6',
'DK': 'trackdev0304',
'DS': '8eba9389af434974c3c846d1922d949f',
}
_AliYun = {
'PK': '',
'PS': '',
'DK': '',
'DS': '',
}
_JTT808 = {
'PK': '',
'PS': '',
'DK': '',
'DS': '',
}
locator_init_params = {} locator_init_params = {}
_gps_cfg = { _gps_cfg = {
@ -134,11 +176,39 @@ class default_values_sys(object):
return locator_init_params return locator_init_params
@staticmethod
def _get_cloud_init_params(cloud):
global current_settings
cloud_init_params = current_settings.get('sys', {}).get('cloud_init_params', {})
if cloud & default_values_sys._cloud.quecIot:
cloud_init_params = default_values_sys._quecIot
cloud_init_params = default_values_sys._quecIot_init_params(cloud_init_params)
if cloud & default_values_sys._cloud.AliYun:
cloud_init_params = default_values_sys._AliYun
if cloud & default_values_sys._cloud.JTT808:
cloud_init_params = default_values_sys._JTT808
return cloud_init_params
@staticmethod
def _quecIot_init_params(cloud_init_params):
if not cloud_init_params['DK'] or not cloud_init_params['DS']:
if quecIot.init():
if quecIot.setProductinfo(pk, ps):
if quecIot.setDkDs(dk, ds):
ndk, nds = quecIot.getDkDs()
cloud_init_params['DK'] = ndk
cloud_init_params['DS'] = nds
return cloud_init_params
@settings_lock
def init(): def init():
global current_settings global current_settings
default_values_sys.locator_init_params = default_values_sys._get_locator_init_params(default_values_app.loc_method) 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_settings_app = {k: v for k, v in default_values_app.__dict__.items() if not k.startswith('_')} 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('_')} default_settings_sys = {k: v for k, v in default_values_sys.__dict__.items() if not k.startswith('_')}
@ -153,11 +223,19 @@ def init():
current_settings = ujson.load(f) current_settings = ujson.load(f)
@settings_lock
def get(): def get():
global current_settings global current_settings
return current_settings return current_settings
@settings_lock
def query(remote, set_type, set_key):
global current_settings
remote.post_data(remote.DATA_NON_LOCA, {set_key: current_settings.get(set_type, {}).get(set_key)})
@settings_lock
def set(opt, val): def set(opt, val):
global current_settings global current_settings
@ -216,16 +294,17 @@ def set(opt, val):
else: else:
return False return False
else: else:
return False return False
@settings_lock
def save(): def save():
with open(tracker_settings_file, 'w') as f: with open(tracker_settings_file, 'w') as f:
ujson.dump(current_settings, f) ujson.dump(current_settings, f)
@settings_lock
def reset(): def reset():
uos.remove(tracker_settings_file) uos.remove(tracker_settings_file)