2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
import ure
|
2022-03-08 17:12:38 +08:00
|
|
|
import utime
|
2022-03-03 09:53:51 +08:00
|
|
|
import _thread
|
2022-03-04 13:21:48 +08:00
|
|
|
import cellLocator
|
|
|
|
import usr.settings as settings
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
from queue import Queue
|
2022-03-04 13:21:48 +08:00
|
|
|
from machine import UART
|
2022-03-09 13:17:33 +08:00
|
|
|
from usr.logging import getLogger
|
|
|
|
from usr.common import Singleton
|
|
|
|
from wifilocator import wifilocator
|
2022-03-03 09:53:51 +08:00
|
|
|
|
2022-03-11 14:05:06 +08:00
|
|
|
try:
|
|
|
|
import quecgnns
|
|
|
|
except ImportError:
|
|
|
|
quecgnns = None
|
|
|
|
|
2022-03-04 17:25:28 +08:00
|
|
|
log = getLogger(__name__)
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
gps_data_retrieve_queue = None
|
|
|
|
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-11 14:05:06 +08:00
|
|
|
class LocationError(Exception):
|
|
|
|
def __init__(self, value):
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return repr(self.value)
|
|
|
|
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
def gps_data_retrieve_cb(para_list):
|
2022-03-04 13:21:48 +08:00
|
|
|
'''
|
|
|
|
GPS data retrieve callback from UART
|
|
|
|
When data comes, send a message to queue of data length
|
|
|
|
'''
|
2022-03-03 09:53:51 +08:00
|
|
|
global gps_data_retrieve_queue
|
|
|
|
toRead = para_list[2]
|
|
|
|
if toRead:
|
|
|
|
gps_data_retrieve_queue.put(toRead)
|
|
|
|
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
def gps_data_retrieve_thread(argv):
|
2022-03-04 13:21:48 +08:00
|
|
|
'''
|
|
|
|
GPS data retrieve thread
|
|
|
|
Receive a message from queue of data length.
|
|
|
|
Then read the corresponding length of data from UART into self.gps_data.
|
|
|
|
So self.gps_data will be updated immediately once the data comes to UART that
|
|
|
|
the self.gps_data could keep the latest data.
|
|
|
|
'''
|
2022-03-03 09:53:51 +08:00
|
|
|
global gps_data_retrieve_queue
|
|
|
|
self = argv
|
|
|
|
|
|
|
|
while True:
|
|
|
|
toRead = gps_data_retrieve_queue.get()
|
|
|
|
if toRead:
|
|
|
|
self.gps_data = self.uart_read(toRead).decode()
|
|
|
|
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-09 13:17:33 +08:00
|
|
|
class GPS(Singleton):
|
2022-03-03 09:53:51 +08:00
|
|
|
def __init__(self, gps_cfg):
|
2022-03-11 14:05:06 +08:00
|
|
|
self.gps_data = ''
|
|
|
|
self.gps_cfg = gps_cfg
|
|
|
|
current_settings = settings.settings.get()
|
|
|
|
if current_settings['app']['gps_mode'] & settings.default_values_app._gps_mode.external:
|
|
|
|
self.uart_init()
|
|
|
|
elif current_settings['app']['gps_mode'] & settings.default_values_app._gps_mode.internal:
|
|
|
|
if quecgnns:
|
|
|
|
quecgnns.init()
|
|
|
|
else:
|
|
|
|
raise LocationError('quecgnns import error.')
|
|
|
|
self.quecgnns_init()
|
|
|
|
|
|
|
|
def uart_init(self):
|
2022-03-03 09:53:51 +08:00
|
|
|
global gps_data_retrieve_queue
|
2022-03-04 17:25:28 +08:00
|
|
|
self.uart_obj = UART(
|
2022-03-11 14:05:06 +08:00
|
|
|
self.gps_cfg['UARTn'], self.gps_cfg['buadrate'], self.gps_cfg['databits'],
|
|
|
|
self.gps_cfg['parity'], self.gps_cfg['stopbits'], self.gps_cfg['flowctl']
|
2022-03-04 17:25:28 +08:00
|
|
|
)
|
|
|
|
self.uart_obj.set_callback(gps_data_retrieve_cb)
|
2022-03-03 09:53:51 +08:00
|
|
|
gps_data_retrieve_queue = Queue(maxsize=8)
|
|
|
|
_thread.start_new_thread(gps_data_retrieve_thread, (self,))
|
|
|
|
|
|
|
|
def uart_read(self, nread):
|
2022-03-04 17:25:28 +08:00
|
|
|
return self.uart_obj.read(nread).decode()
|
2022-03-03 09:53:51 +08:00
|
|
|
|
2022-03-11 14:05:06 +08:00
|
|
|
def quecgnns_read(self):
|
|
|
|
if quecgnns.get_state() == 0:
|
|
|
|
quecgnns.gnssEnable(1)
|
|
|
|
|
|
|
|
data = quecgnns.read(4096)
|
|
|
|
self.gps_data = data[1].decode()
|
|
|
|
|
|
|
|
return self.gps_data
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
def read(self):
|
|
|
|
return self.gps_data
|
|
|
|
|
|
|
|
def read_location_GxRMC(self):
|
|
|
|
gps_data = self.read()
|
|
|
|
rmc_re = ure.search(
|
|
|
|
r"\$G[NP]RMC,[0-9]+\.[0-9]+,A,[0-9]+\.[0-9]+,[NS],[0-9]+\.[0-9]+,[EW],[0-9]+\.[0-9]+,[0-9]+\.[0-9]+,[0-9]+,,,[ADE],[SCUV]\*[0-9]+",
|
|
|
|
gps_data)
|
|
|
|
if rmc_re:
|
|
|
|
return rmc_re.group(0)
|
|
|
|
else:
|
|
|
|
return ""
|
|
|
|
|
|
|
|
def read_location_GxGGA(self):
|
|
|
|
gps_data = self.read()
|
|
|
|
gga_re = ure.search(
|
|
|
|
r"\$G[BLPN]GGA,[0-9]+\.[0-9]+,[0-9]+\.[0-9]+,[NS],[0-9]+\.[0-9]+,[EW],[126],[0-9]+,[0-9]+\.[0-9]+,-*[0-9]+\.[0-9]+,M,-*[0-9]+\.[0-9]+,M,,\*[0-9]+",
|
|
|
|
gps_data)
|
|
|
|
if gga_re:
|
|
|
|
return gga_re.group(0)
|
|
|
|
else:
|
|
|
|
return ""
|
|
|
|
|
2022-03-04 17:25:28 +08:00
|
|
|
def read_location_GxVTG(self):
|
|
|
|
gps_data = self.read()
|
2022-03-04 18:06:05 +08:00
|
|
|
vtg_re = ure.search(r"\$G[NP]VTG,[0-9]+\.[0-9]+,T,([0-9]+\.[0-9]+)??,M,[0-9]+\.[0-9]+,N,[0-9]+\.[0-9]+,K,[ADEN]\*\w*", gps_data)
|
|
|
|
if vtg_re:
|
|
|
|
return vtg_re.group(0)
|
|
|
|
else:
|
|
|
|
return ""
|
|
|
|
|
|
|
|
def read_location_GxVTG_speed(self):
|
2022-03-04 18:15:27 +08:00
|
|
|
vtg_data = self.read_location_GxVTG()
|
|
|
|
if vtg_data:
|
|
|
|
speed_re = ure.search(r",N,[0-9]+\.[0-9]+,K,", vtg_data)
|
2022-03-04 18:06:05 +08:00
|
|
|
if speed_re:
|
2022-03-04 18:19:10 +08:00
|
|
|
return speed_re.group(0)[3:-3]
|
2022-03-04 18:15:27 +08:00
|
|
|
|
|
|
|
return ""
|
2022-03-04 17:25:28 +08:00
|
|
|
|
2022-03-04 13:21:48 +08:00
|
|
|
|
|
|
|
class CellLocator(object):
|
2022-03-03 09:53:51 +08:00
|
|
|
def __init__(self, cellLocator_cfg):
|
|
|
|
self.cellLocator_cfg = cellLocator_cfg
|
|
|
|
|
|
|
|
def read(self):
|
2022-03-09 15:14:03 +08:00
|
|
|
return ['LBS']
|
|
|
|
|
|
|
|
def get_location(self):
|
2022-03-04 13:21:48 +08:00
|
|
|
return cellLocator.getLocation(
|
|
|
|
self.cellLocator_cfg['serverAddr'],
|
|
|
|
self.cellLocator_cfg['port'],
|
|
|
|
self.cellLocator_cfg['token'],
|
|
|
|
self.cellLocator_cfg['timeout'],
|
|
|
|
self.cellLocator_cfg['profileIdx']
|
|
|
|
)
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
|
2022-03-04 19:29:23 +08:00
|
|
|
class WiFiLocator(object):
|
2022-03-03 09:53:51 +08:00
|
|
|
def __init__(self, wifiLocator_cfg):
|
2022-03-04 19:29:23 +08:00
|
|
|
self.wifilocator_obj = wifilocator(wifiLocator_cfg['token'])
|
2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
def read(self):
|
2022-03-09 15:14:03 +08:00
|
|
|
return []
|
|
|
|
|
|
|
|
def get_location(self):
|
2022-03-04 19:29:23 +08:00
|
|
|
return self.wifilocator_obj.getwifilocator()
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
def loc_worker(argv):
|
|
|
|
self = argv
|
|
|
|
while True:
|
|
|
|
trigger = self.trigger_queue.get()
|
|
|
|
if trigger:
|
2022-03-08 17:12:38 +08:00
|
|
|
data = None
|
|
|
|
retry = 0
|
|
|
|
while retry < 3:
|
|
|
|
data = self.read()
|
|
|
|
if data:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
retry += 1
|
|
|
|
utime.sleep(1)
|
|
|
|
log.debug('location data info:', data)
|
2022-03-11 09:49:24 +08:00
|
|
|
if data and self.loc_read_cb:
|
|
|
|
self.loc_read_cb(data)
|
2022-03-03 09:53:51 +08:00
|
|
|
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-09 13:17:33 +08:00
|
|
|
class Location(Singleton):
|
2022-03-08 17:12:38 +08:00
|
|
|
gps = None
|
|
|
|
cellLoc = None
|
|
|
|
wifiLoc = None
|
2022-03-03 09:53:51 +08:00
|
|
|
|
2022-03-11 09:49:24 +08:00
|
|
|
def __init__(self, loc_read_cb):
|
|
|
|
self.loc_read_cb = loc_read_cb
|
2022-03-08 17:12:38 +08:00
|
|
|
self.trigger_queue = Queue(maxsize=64)
|
|
|
|
_thread.start_new_thread(loc_worker, (self,))
|
|
|
|
|
|
|
|
def _locater_init(self):
|
|
|
|
current_settings = settings.settings.get()
|
|
|
|
locator_init_params = current_settings['sys']['locator_init_params']
|
2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
if current_settings['app']['loc_method'] & settings.default_values_app._loc_method.gps:
|
2022-03-08 17:12:38 +08:00
|
|
|
if self.gps is None:
|
|
|
|
if 'gps_cfg' in locator_init_params:
|
|
|
|
self.gps = GPS(locator_init_params['gps_cfg'])
|
|
|
|
else:
|
|
|
|
raise ValueError('Invalid gps init parameters.')
|
|
|
|
else:
|
|
|
|
self.gps = None
|
2022-03-04 13:21:48 +08:00
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
if current_settings['app']['loc_method'] & settings.default_values_app._loc_method.cell:
|
2022-03-08 17:12:38 +08:00
|
|
|
if self.cellLoc is None:
|
|
|
|
if 'cellLocator_cfg' in locator_init_params:
|
|
|
|
self.cellLoc = CellLocator(locator_init_params['cellLocator_cfg'])
|
|
|
|
else:
|
|
|
|
raise ValueError('Invalid cell-locator init parameters.')
|
|
|
|
else:
|
|
|
|
self.cellLoc = None
|
2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
if current_settings['app']['loc_method'] & settings.default_values_app._loc_method.wifi:
|
2022-03-08 17:12:38 +08:00
|
|
|
if self.wifiLoc is None:
|
|
|
|
if 'wifiLocator_cfg' in locator_init_params:
|
|
|
|
self.wifiLoc = WiFiLocator(locator_init_params['wifiLocator_cfg'])
|
|
|
|
else:
|
|
|
|
raise ValueError('Invalid wifi-locator init parameters.')
|
|
|
|
else:
|
|
|
|
self.wifiLoc = None
|
2022-03-03 09:53:51 +08:00
|
|
|
|
|
|
|
def read(self):
|
2022-03-08 17:12:38 +08:00
|
|
|
self._locater_init()
|
|
|
|
|
|
|
|
if self.gps:
|
2022-03-03 09:53:51 +08:00
|
|
|
data = []
|
2022-03-08 17:12:38 +08:00
|
|
|
r = self.gps.read_location_GxRMC()
|
2022-03-03 09:53:51 +08:00
|
|
|
if r:
|
|
|
|
data.append(r)
|
|
|
|
|
2022-03-08 17:12:38 +08:00
|
|
|
r = self.gps.read_location_GxGGA()
|
2022-03-03 09:53:51 +08:00
|
|
|
if r:
|
|
|
|
data.append(r)
|
|
|
|
|
2022-03-11 14:05:06 +08:00
|
|
|
r = self.gps.read_location_GxVTG()
|
|
|
|
if r:
|
|
|
|
data.append(r)
|
|
|
|
|
2022-03-03 09:53:51 +08:00
|
|
|
if len(data):
|
|
|
|
return (settings.default_values_app._loc_method.gps, data)
|
|
|
|
|
2022-03-08 17:12:38 +08:00
|
|
|
if self.cellLoc:
|
|
|
|
data = self.cellLoc.read()
|
2022-03-03 09:53:51 +08:00
|
|
|
if data:
|
|
|
|
return (settings.default_values_app._loc_method.cell, data)
|
|
|
|
|
2022-03-08 17:12:38 +08:00
|
|
|
if self.wifiLoc:
|
|
|
|
data = self.wifiLoc.read()
|
2022-03-03 09:53:51 +08:00
|
|
|
if data:
|
|
|
|
return (settings.default_values_app._loc_method.wifi, data)
|
|
|
|
|
|
|
|
return ()
|
|
|
|
|
|
|
|
def trigger(self):
|
|
|
|
self.trigger_queue.put(True)
|