From: d15521469561 Date: Wed, 22 Mar 2023 04:01:47 +0000 (+0800) Subject: 代码提交 X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=4f112a160c13c3fe10fbd61d125294b2ed719f6f;p=mirrors%2FASR1603_G5.git 代码提交 --- diff --git a/3.code/1.watch/2.code/location.py b/3.code/1.watch/2.code/location.py new file mode 100644 index 00000000..dad14903 --- /dev/null +++ b/3.code/1.watch/2.code/location.py @@ -0,0 +1,1024 @@ +# Copyright (c) Quectel Wireless Solution, Co., Ltd.All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + +import ure +import net +import math +import utime +import osTimer +import _thread +import wifiScan +import cellLocator + +from queue import Queue +from machine import UART, Pin + +try: + from wifilocator import wifilocator +except: + wifilocator = None + +from log import getLogger + +try: + import quecgnss +except ImportError: + quecgnss = None + +log = getLogger(__name__) + +_gps_read_lock = _thread.allocate_lock() +_gps_data_set_lock = _thread.allocate_lock() + +EE = 0.00669342162296594323 +EARTH_RADIUS = 6378.137 # Approximate Earth Radius(km) +M_PI = math.pi + + +class _loc_method(object): + gps = 0x1 + cell = 0x2 + wifi = 0x4 + + +class _gps_mode(object): + none = 0x0 + internal = 0x1 + external = 0x2 + + +def transformLat(x, y): + ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(math.fabs(x)) + ret += (20.0 * math.sin(6.0 * x * M_PI) + 20.0 * math.sin(2.0 * x * M_PI)) * 2.0 / 3.0 + ret += (20.0 * math.sin(y * M_PI) + 40.0 * math.sin(y / 3.0 * M_PI)) * 2.0 / 3.0 + ret += (160.0 * math.sin(y / 12.0 * M_PI) + 320 * math.sin(y * M_PI / 30.0)) * 2.0 / 3.0 + return ret + + +def transformLon(x, y): + ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(math.fabs(x)) + ret += (20.0 * math.sin(6.0 * x * M_PI) + 20.0 * math.sin(2.0 * x * M_PI)) * 2.0 / 3.0 + ret += (20.0 * math.sin(x * M_PI) + 40.0 * math.sin(x / 3.0 * M_PI)) * 2.0 / 3.0 + ret += (150.0 * math.sin(x / 12.0 * M_PI) + 300.0 * math.sin(x / 30.0 * M_PI)) * 2.0 / 3.0 + return ret + + +def WGS84ToGCJ02(lon, lat): + dLat = transformLat(lon - 105.0, lat - 35.0) + dLon = transformLon(lon - 105.0, lat - 35.0) + radLat = lat / 180.0 * M_PI + magic = math.sin(radLat) + magic = 1 - magic * magic * EE + sqrtMagic = math.sqrt(magic) + + dLat = (dLat * 180.0) / ((EARTH_RADIUS * 1000 * (1 - EE)) / (magic * sqrtMagic) * M_PI) + dLon = (dLon * 180.0) / (EARTH_RADIUS * 1000 / sqrtMagic * math.cos(radLat) * M_PI) + lon02 = lon + dLon + lat02 = lat + dLat + + return lon02, lat02 + + +class GPSMatch(object): + """This class is match gps NEMA 0183""" + + def GxRMC(self, gps_data): + """Match Recommended Minimum Specific GPS/TRANSIT Data(RMC) + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: RMC NMEA string. + """ + if gps_data: + rmc_re = ure.search( + r"\$G[NP]RMC,\d*\.*\d*,*[AV],*\d*\.*\d*,*[NS],*\d*\.*\d*,*[EW],*\d*\.*\d*,*\d*\.*\d*,*\d*,*\d*\.*\d*,*[EW]*,*[ADEN]*,*[SCUV]*\**(\d|\w)*", + gps_data) + if rmc_re: + return rmc_re.group(0) + return "" + + def GxGGA(self, gps_data): + """Match Global Positioning System Fix Data(GGA) + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: GGA NMEA string. + """ + if gps_data: + gga_re = ure.search( + r"\$G[BLPN]GGA,\d*\.*\d*,*\d*\.*\d*,*[NS],*\d*\.*\d*,*[EW],*[0126],*\d*,*\d*\.*\d*,*-*\d*\.*\d*,*M,*-*\d*\.*\d*,*M,*\d*,*\**(\d|\w)*", + gps_data) + if gga_re: + return gga_re.group(0) + return "" + + def GxVTG(self, gps_data): + """Match Track Made Good and Ground Speed(VTG) + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: VTG NMEA string. + """ + if gps_data: + vtg_re = ure.search(r"\$G[NP]VTG,\d*\.*\d*,*T,*\d*\.*\d*,*M,*\d*\.*\d*,*N,*\d*\.*\d*,*K,*[ADEN]*\*(\d|\w)*", + gps_data) + if vtg_re: + return vtg_re.group(0) + return "" + + def GxGSV(self, gps_data): + """Mactch GPS Satellites in View(GSV) + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: GSV NMEA string. + """ + if gps_data: + gsv_re = ure.search( + r"\$G[NP]GSV,\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*\**(\d|\w)*", + gps_data) + if gsv_re: + return gsv_re.group(0) + return "" + + def GxGLL(self, gps_data): + """Geographic Position + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: GLL NMEA string. + """ + if gps_data: + gll_re = ure.search(r"\$G[NP]GLL,\d*\.*\d*,*[NS]*,*\d*\.*\d*,*[EW]*,*\d*\.*\d*,*[AV]*,*[ADEN]*\**(\d|\w)*", + gps_data) + if gll_re: + return gll_re.group(0) + + def GxGSA(self, gps_data): + """GNSS DOP and Active Satellites + + Args: + gps_data(str): GPS NMEA string. + + Returns: + str: GSA NMEA string. + """ + if gps_data: + gsa_re = ure.search( + r"\$G[NP]GSA,[MA]*,*[123]*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*\.*\d*,*\d*\.*\d*,*\d*\.*\d*,*(\d|\w)*\**(\d|\w)*", + gps_data) + if gsa_re: + return gsa_re.group(0) + + +class GPSParse(object): + """Parse details from gps data""" + + def GxGGA_satellite_num(self, gga_data): + """Parse satellite num from GGA""" + if gga_data: + satellite_num_re = ure.search(r",[EW],[0126],\d+,", gga_data) + if satellite_num_re: + return satellite_num_re.group(0).split(",")[-2] + return "" + + def GxGGA_latitude(self, gga_data): + """Parse latitude from GGA""" + if gga_data: + latitude_re = ure.search(r",[0-9]+\.[0-9]+,[NS],", gga_data) + if latitude_re: + latitude = latitude_re.group(0)[1:-3] + return str(float(latitude[:2]) + float(latitude[2:]) / 60) + return "" + + def GxGGA_longitude(self, gga_data): + """Parse longitude from GGA""" + if gga_data: + longitude_re = ure.search(r",[0-9]+\.[0-9]+,[EW],", gga_data) + if longitude_re: + longitude = longitude_re.group(0)[1:-3] + return str(float(longitude[:3]) + float(longitude[3:]) / 60) + return "" + + def GxGGA_altitude(self, gga_data): + """Parse altitude from GGA""" + if gga_data: + altitude_re = ure.search(r",-*[0-9]+\.[0-9]+,M,", gga_data) + if altitude_re: + return altitude_re.group(0)[1:-3] + return "" + + def GxVTG_speed(self, vtg_data): + """Parse speed from VTG""" + if vtg_data: + speed_re = ure.search(r",N,\d+\.\d+,K,", vtg_data) + if speed_re: + return speed_re.group(0)[3:-3] + return "" + + def GxGSV_satellite_num(self, gsv_data): + """Parse satellite num from GSV""" + if gsv_data: + satellite_num_re = ure.search(r"\$G[NP]GSV,\d+,\d+,\d+,", gsv_data) + if satellite_num_re: + return satellite_num_re.group(0).split(",")[-2] + return "" + + def GxRMC_loc_status(self, rmc_data): + if rmc_data: + loc_status_re = ure.search(r"\$G[NP]RMC,\d*\.*\d*,[AV],", rmc_data) + if loc_status_re: + loc_status = loc_status_re.group(0).split(",")[-2] + return True if loc_status == "A" else False + return False + + def __nmea_parse(self, nmea): + return tuple(nmea[1:].split("*")[0].split(",")) if nmea else () + + def GxRMC(self, rmc_data): + return self.__nmea_parse(rmc_data) + + def GxGGA(self, gga_data): + return self.__nmea_parse(gga_data) + + def GxGSV(self, gsv_data): + return self.__nmea_parse(gsv_data) + + def GxGSA(self, gsa_data): + return self.__nmea_parse(gsa_data) + + def GxVTG(self, vtg_data): + return self.__nmea_parse(vtg_data) + + def GxGLL(self, gll_data): + return self.__nmea_parse(gll_data) + + +class GPS(object): + """This class if for reading gps data. + + Now support external gps and internal gps. + + Sleep power consumption: + power off < backup < standby + """ + + __RMC = 0 + __GGA = 1 + __GSV = 2 + __GSA = 3 + __VTG = 4 + __GLL = 5 + __NMEA = 0b010111 + + def __init__(self, UARTn, buadrate, databits, parity, stopbits, flowctl, PowerPin, StandbyPin, BackupPin, gps_mode): + """Init GPS module + + [description] + + Args: + UARTn(int): UART No. + buadrate(int): baud rate + databits(int): data bits (5 ~ 8) + parity(int): parity (0 – NONE,1 – EVEN,2 - ODD) + stopbits(int): stop bit + flowctl(int): hardware control flow (0 – FC_NONE, 1 – FC_HW) + PowerPin(int): Power GIPO Pin + StandbyPin(int): Standby GPIO Pin + BackupPin(int): Back GPIO Pin + gps_mode(int): GPS mode + 0 - None + 1 - internal GPS + 2 - external GPS + """ + self.__UARTn = UARTn + self.__buadrate = buadrate + self.__databits = databits + self.__parity = parity + self.__stopbits = stopbits + self.__flowctl = flowctl + self.__PowerPin = PowerPin + self.__StandbyPin = StandbyPin + self.__BackupPin = BackupPin + self.__gps_mode = gps_mode + + self.__external_obj = None + self.__internal_obj = quecgnss + self.__gps_match = GPSMatch() + self.__gps_parse = GPSParse() + self.__gps_power_gpio = None + self.__gps_standby_gpio = None + self.__gps_backup_gpio = None + + self.__external_retrieve_queue = None + self.__queue_size = 2 + self.__first_break = 0 + self.__break = 0 + self.__gps_data = "" + self.__rmc_data = "" + self.__gga_data = "" + self.__vtg_data = "" + self.__gsv_data = "" + self.__gps_timer = osTimer() + self.__gps_data_check_timer = osTimer() + + if self.__gps_mode & _gps_mode.external: + self.__external_init() + elif self.__gps_mode & _gps_mode.internal: + self.__internal_init() + #print("GPS:__init__%d",self.__gps_mode) + def __gps_power_control(self, GPIOn, onoff, method): + if method == "power_switch": + if self.__gps_power_gpio is None: + self.__gps_power_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff) + gpio_obj = self.__gps_power_gpio + elif method == "standby": + if self.__gps_standby_gpio is None: + self.__gps_standby_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff) + gpio_obj = self.__gps_standby_gpio + elif method == "backup": + if self.__gps_backup_gpio is None: + self.__gps_backup_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff) + gpio_obj = self.__gps_backup_gpio + else: + raise TypeError("Param method %s is not compare." % method) + + if gpio_obj.read() != onoff: + gpio_obj.write(onoff) + if gpio_obj.read() != onoff: + return False + return True + + def __reverse_gps_data(self, this_gps_data): + """Reverse GPS data for regular match get the latest data""" + log.debug("this_gps_data: \n%s" % this_gps_data) + delimiter = "\r\n" + if this_gps_data: + _gps_data = self.__get_gps_data() + if _gps_data: + _gps_data = delimiter.join(_gps_data.split(delimiter)[::-1]) + _gps_data += this_gps_data.strip().replace("\r", "").replace("\n", "").replace("$", delimiter + "$") + _gps_data = delimiter.join(_gps_data.split(delimiter)[::-1]) + self.__set_gps_data(_gps_data) + + def __read_latitude(self, gps_data): + """Read latitude from gps data""" + return self.__gps_parse.GxGGA_latitude(self.__gps_match.GxGGA(gps_data)) + + def __read_longitude(self, gps_data): + """Read longitude from gps data""" + return self.__gps_parse.GxGGA_longitude(self.__gps_match.GxGGA(gps_data)) + + def __read_altitude(self, gps_data): + """Read altitude from gps data""" + return self.__gps_parse.GxGGA_altitude(self.__gps_match.GxGGA(gps_data)) + + def __set_gps_data(self, gps_data): + self.__gps_data = gps_data + + def __get_gps_data(self): + return self.__gps_data + + def __gps_timer_callback(self, args): + """GPS read timer callback + When over time to get uart data, break queue wait + """ + self.__break = 1 + if self.__external_retrieve_queue is not None: + self.__external_retrieve_queue.put(False) + + def __gps_data_check_callback(self, args): + """GPS read old data clean timer callback + When GPS read over time, clean old gps data, wait to read new gps data. + """ + clean = False + if "" in (self.__rmc_data, self.__gga_data, self.__gsv_data): + clean = True + else: + if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data: + clean = True + elif self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data: + clean = True + elif self.__nmea_statement_exist(self.__GLL) and not self.__gll_data: + clean = True + + if clean: + self.__gps_nmea_data_clean() + + def __external_init(self): + """External GPS init""" + self.__external_retrieve_queue = Queue(maxsize=self.__queue_size) + + def __external_open(self): + """External GPS start, UART init""" + self.power_switch(1) + self.__external_obj = UART( + self.__UARTn, + self.__buadrate, + self.__databits, + self.__parity, + self.__stopbits, + self.__flowctl + ) + self.__external_obj.set_callback(self.__external_retrieve_cb) + + def __external_close(self): + """External GPS close, UART close, NOT GPS stop""" + self.__external_obj.close() + + def __external_retrieve_cb(self, args): + """ + GPS data retrieve callback from UART + When data comes, send a message to queue of data length + """ + # log.debug("GPS __external_retrieve_cb args: %s" % str(args)) + if self.__external_retrieve_queue.size() >= self.__queue_size: + self.__external_retrieve_queue.get() + self.__external_retrieve_queue.put(True) + + def __internal_init(self): + """Internal GPS init""" + if self.__internal_obj: + if self.__internal_obj.init() != 0: + self.__internal_open() + log.error("GNSS INIT Failed.") + else: + log.debug("GNSS INIT Success.") + else: + log.error("Module quecgnss Import Error.") + + def __internal_open(self): + """Internal GPS enable""" + if self.__internal_obj.get_state() == 0: + return True if self.__internal_obj.gnssEnable(1) == 0 else False + else: + return True + + def __internal_close(self): + """Internal GPS close""" + return True if self.__internal_obj.gnssEnable(0) == 0 else False + + def __nmea_statement_exist(self, nmea_item): + return (self.__NMEA & (0b1 << nmea_item)) >> nmea_item + + def __gps_nmea_data_clean(self): + self.__set_gps_data("") + self.__rmc_data = "" + self.__gga_data = "" + self.__gsv_data = "" + self.__gsa_data = "" + self.__vtg_data = "" + self.__gll_data = "" + + def __check_gps_valid(self, gps_data): + self.__reverse_gps_data(gps_data) + + if not self.__rmc_data: + self.__rmc_data = self.__gps_match.GxRMC(self.__get_gps_data()) + loc_status = self.__gps_parse.GxRMC_loc_status(self.__rmc_data) + + if self.__rmc_data and loc_status: + if self.__nmea_statement_exist(self.__GGA) and not self.__gga_data: + self.__gga_data = self.__gps_match.GxGGA(self.__get_gps_data()) + if self.__nmea_statement_exist(self.__GSV) and not self.__gsv_data: + self.__gsv_data = self.__gps_match.GxGSV(self.__get_gps_data()) + if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data: + self.__gsa_data = self.__gps_match.GxGSA(self.__get_gps_data()) + if self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data: + self.__vtg_data = self.__gps_match.GxVTG(self.__get_gps_data()) + if self.__nmea_statement_exist(self.__GLL) and not self.__gll_data: + self.__gll_data = self.__gps_match.GxGLL(self.__get_gps_data()) + + if self.__nmea_statement_exist(self.__GGA) and not self.__gga_data: + return False + if self.__nmea_statement_exist(self.__GSV) and not self.__gsv_data: + return False + if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data: + return False + if self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data: + return False + if self.__nmea_statement_exist(self.__GLL) and not self.__gll_data: + return False + return True + + return False + + def __external_read(self): + """Read external GPS data + + Return: + $GPTXT,01,01,02,ANTSTATUS=OPEN*2B + $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07 + $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22 + $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56 + $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02 + $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03 + $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54 + $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58 + $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B + $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71 + $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71 + $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70 + $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78 + $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72 + $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E + """ + self.__external_open() + log.debug("__external_read start") + + while self.__break == 0: + self.__gps_timer.start(50, 0, self.__gps_timer_callback) + signal = self.__external_retrieve_queue.get() + log.debug("[first] signal: %s" % signal) + if signal: + to_read = self.__external_obj.any() + log.debug("[first] to_read: %s" % to_read) + if to_read > 0: + self.__set_gps_data(self.__external_obj.read(to_read).decode()) + self.__gps_timer.stop() + self.__break = 0 + + self.__gps_nmea_data_clean() + self.__gps_data_check_timer.start(2000, 1, self.__gps_data_check_callback) + cycle = 0 + while self.__break == 0: + self.__gps_timer.start(1500, 0, self.__gps_timer_callback) + signal = self.__external_retrieve_queue.get() + log.debug("[second] signal: %s" % signal) + if signal: + to_read = self.__external_obj.any() + log.debug("[second] to_read: %s" % to_read) + if to_read > 0: + if self.__check_gps_valid(self.__external_obj.read(to_read).decode()): + self.__break = 1 + + self.__gps_timer.stop() + cycle += 1 + if cycle >= self.__retry: + self.__break = 1 + if self.__break != 1: + utime.sleep(1) + self.__gps_data_check_timer.stop() + self.__break = 0 + + # To check GPS data is usable or not. + self.__gps_data_check_callback(None) + self.__external_close() + log.debug("__external_read data: %s" % self.__get_gps_data()) + return self.__get_gps_data() + + def __internal_read(self): + from ext import EventMesh + log.debug("__internal_read start.") + """Read internal GPS data + + Return: + $GPTXT,01,01,02,ANTSTATUS=OPEN*2B + $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07 + $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22 + $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56 + $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02 + $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03 + $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54 + $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58 + $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B + $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71 + $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71 + $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70 + $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78 + $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72 + $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E + """ + + #self.__gps_nmea_data_clean() + + cycle = 0 + #while self.__break == 0: + gnss_data = quecgnss.read(1024*3) + #print("__internal_read") + #print(gnss_data) + if gnss_data and gnss_data[1]: + this_gps_data = gnss_data[1].decode() if len(gnss_data) > 1 and gnss_data[1] else "" + _gps_valid = self.__check_gps_valid(this_gps_data) + log.debug("_gps_valid: %s" % _gps_valid) + + #print("_gps_valid:",_gps_valid) + #print(str(_gps_valid),self.__get_gps_data()) + if _gps_valid == True : + #EventMesh.publish("time", [self.__get_gps_data(),"0",str(_gps_valid),"0"]) + return self.__get_gps_data() + else : + EventMesh.publish("time", [self.__get_gps_data(),"0",str(_gps_valid),"0"]) + return "" + + def read(self, retry=30): + """For user to read gps data + + Return: (res_code, gps_data) + res_code: + - 0: Success + - -1: Failed + gps_data: + $GPTXT,01,01,02,ANTSTATUS=OPEN*2B + $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07 + $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22 + $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56 + $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02 + $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03 + $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54 + $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58 + $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B + $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71 + $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71 + $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70 + $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78 + $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72 + $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E + """ + self.__retry = retry + gps_data = "" + if self.__gps_mode & _gps_mode.external: + gps_data = self.__external_read() + elif self.__gps_mode & _gps_mode.internal: + gps_data = self.__internal_read() + + res = 0 if gps_data else -1 + return (res, gps_data) + + def read_coordinates(self, gps_data): + """Read positioning coordinates. + + Params: + gps_data: read gps data. + map_coordinate_system: `WGS84` or GCJ02 + + Return: + (longitude, latitude, altitude) + """ + latitude = self.__read_latitude(gps_data) + latitude = float(latitude) if latitude else latitude + longitude = self.__read_longitude(gps_data) + longitude = float(longitude) if longitude else longitude + altitude = self.__read_altitude(gps_data) + altitude = float(altitude) if altitude else altitude + return (longitude, latitude, altitude) + + def power_switch(self, onoff): + """GPS module power switch + + Params: + onoff: 0 -- off, 1 -- on + """ + if self.__gps_mode & _gps_mode.external: + if self.__PowerPin is not None: + return self.__gps_power_control(self.__PowerPin, onoff, "power_switch") + else: + return False + elif self.__gps_mode & _gps_mode.internal: + # TODO: Interal GNSS power down will not be used this api. + if onoff == 0: + return self.__internal_close() + else: + return self.__internal_open() + + def backup(self, onoff): + """GPS module low enery mode backup + + Params: + onoff: 0 -- off, 1 -- on + """ + if self.__BackupPin is not None: + return self.__gps_power_control(self.__BackupPin, onoff, "backup") + else: + return False + + def standby(self, onoff): + """GPS module low enery mode standby + + Params: + onoff: 0 -- off, 1 -- on + """ + if self.__StandbyPin is not None: + return self.__gps_power_control(self.__StandbyPin, onoff, "standby") + else: + return False + + def set_nmea_statement(self, nmea_statement): + """Set NMEA statement to check gps info valid + + RMC, GGA, GSV must be required. + + Args: + nmea_statement(int): + RMC - 0b1 << 0 (bit0), 0 - off, 1 - on + GGA - 0b1 << 1 (bit1), 0 - off, 1 - on + GSV - 0b1 << 2 (bit2), 0 - off, 1 - on + GSA - 0b1 << 3 (bit3), 0 - off, 1 - on + VTG - 0b1 << 4 (bit4), 0 - off, 1 - on + GLL - 0b1 << 5 (bit5), 0 - off, 1 - on + + Returns: + bool: True - success, False - falied. + """ + if nmea_statement >= 0b111: + self.__NMEA = nmea_statement + return True + return False + + +class CellLocator(object): + """This class is for reading cell location data""" + + def __init__(self, serverAddr, port, token, timeout, profileIdx): + self.__serverAddr = serverAddr + self.__port = port + self.__token = token + self.__timeout = timeout + self.__profileIdx = profileIdx + + def read(self): + read_loc_res = self.__read_loc() + read_cell_res = self.__read_cell() + res = 0 if read_loc_res[0] == 0 or read_cell_res[0] == 0 else -1 + return (res, read_loc_res[1], read_cell_res[1]) + + def __read_loc(self): + """Read cell location data. + + Return: (res_code, loc_data) + res_code: + - 0: Success + - -1: Initialization failed + - -2: The server address is too long (more than 255 bytes) + - -3: Wrong key length, must be 16 bytes + - -4: The timeout period is out of range, the supported range is (1 ~ 300) s + - -5: The specified PDP network is not connected, please confirm whether the PDP is correct + - -6: Error getting coordinates + loc_data: + (117.1138, 31.82279, 550) + """ + res = -1 + loc_data = cellLocator.getLocation( + self.__serverAddr, + self.__port, + self.__token, + self.__timeout, + self.__profileIdx + ) + if isinstance(loc_data, tuple) and len(loc_data) == 3: + res = 0 + else: + res = loc_data + loc_data = () + + return (res, loc_data) + + def __read_cell(self): + res = -1 + near_cell = [] + server_cell = [] + + near_cells = net.getCi() + if near_cells != -1 and isinstance(near_cells, list): + near_cell = list(map(str, near_cells)) + + server_cells = net.getCellInfo() + if server_cells != -1 and isinstance(server_cells, tuple): + server_cell = server_cells + + res = 0 if near_cell or server_cell else -1 + return (res, {"near_cell": near_cell, "server_cell": server_cell}) + + +class WiFiLocator(object): + """This class is for reading wifi location data""" + + def __init__(self, token): + self.__wifilocator_obj = wifilocator(token) + + def read(self): + read_loc_res = self.__read_loc() + read_mac_res = self.__read_mac() + res = 0 if read_loc_res[0] == 0 or read_mac_res[0] == 0 else -1 + return (res, read_loc_res[1], read_mac_res[1]) + + def __read_loc(self): + """Read wifi location data. + + Return: (res_code, loc_data) + res_code: + - 0: Success + - -1: The current network is abnormal, please confirm whether the dial-up is normal + - -2: Wrong key length, must be 16 bytes + - -3: Error getting coordinates + loc_data: + (117.1138, 31.82279, 550) + """ + res = -1 + loc_data = self.__wifilocator_obj.getwifilocator() + if isinstance(loc_data, tuple) and len(loc_data) == 3: + res = 0 + else: + res = loc_data + loc_data = () + + return (res, loc_data) + + def __read_mac(self): + res = -1 + macs = [] + if wifiScan.support(): + if wifiScan.control(1) == 0: + if wifiScan.getState(): + wifisacn_start = wifiScan.start() + if wifisacn_start != -1 and wifisacn_start[0] > 0: + macs = [i[0] for i in wifisacn_start[1]] + res = 0 + wifiScan.control(0) + return (res, macs) + + +class Location(object): + """This class is for reading location data from gps, cell, wifi""" + gps = None + cellLoc = None + wifiLoc = None + + def __init__(self, loc_method, locator_init_params): + """Init Location module + + 1. If loc_method include gps then init gps module; + 2. If loc_method inculde cell then init cell module; + 3. If loc_method Include wifi then init wifi module; + + Args: + loc_method(int): + 1 - gps + 2 - cell + 3 - cell & gps + 4 - wifi + 5 - wifi & gps + 6 - wifi & cell + 7 - wifi & cell & gps + locator_init_params(dict): + gps_cfg(dict):GPS module init args + cell_cfg(dict):CELL module init args + wifi_cfg(dict):WIFI module init args + """ + self.__loc_method = loc_method + self.__locator_init_params = locator_init_params + self.__locater_init() + + def __locater_init(self): + """Init gps, cell, wifi by loc_method""" + + if self.__loc_method & _loc_method.gps: + if self.gps is None: + _gps_cfg = self.__locator_init_params.get("gps_cfg", {}) + if _gps_cfg: + self.gps = GPS(**_gps_cfg) + if _gps_cfg.get("nmea_cfg") is not None: + self.gps.set_nmea_statement(_gps_cfg.get("nmea_cfg")) + else: + raise ValueError("Invalid gps init parameters.") + else: + self.gps = None + + if self.__loc_method & _loc_method.cell: + if self.cellLoc is None: + _cell_cfg = self.__locator_init_params.get("cell_cfg") + if _cell_cfg: + self.cellLoc = CellLocator(**_cell_cfg) + else: + raise ValueError("Invalid cell-locator init parameters.") + else: + self.cellLoc = None + + if self.__loc_method & _loc_method.wifi: + if self.wifiLoc is None: + _wifi_cfg = self.__locator_init_params.get("wifi_cfg") + if _wifi_cfg: + self.wifiLoc = WiFiLocator(**_wifi_cfg) + else: + raise ValueError("Invalid wifi-locator init parameters.") + else: + self.wifiLoc = None + + def __read_gps(self, retry): + """Read loction data from gps module + + Return: + $GPTXT,01,01,02,ANTSTATUS=OPEN*2B + $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07 + $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22 + $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56 + $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02 + $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03 + $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54 + $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58 + $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B + $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71 + $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71 + $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70 + $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78 + $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72 + $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E + """ + if self.gps: + return self.gps.read(retry)[1] + return "" + + def __read_cell(self): + """Read loction data from cell module + + Return: + (117.1138, 31.82279, 550) or () + """ + if self.cellLoc: + cell_loc_data = self.cellLoc.read() + return (cell_loc_data[1], cell_loc_data[2]) + return () + + def __read_wifi(self): + """Read loction data from wifi module + + Return: + (117.1138, 31.82279, 550) or () + """ + if self.wifiLoc: + wifi_loc_data = self.wifiLoc.read() + return (wifi_loc_data[1], wifi_loc_data[2]) + return () + + def read(self, retry=30): + """Read location data + + args: + retry(int): gps read uart data retry count. + + Returns: + dict: + key: + 1 - GPS data + 2 - CELL data + 4 - WIFI data + .e.g: + { + 1: "$GPGGA,XXX", + 2: (0.00, 0.00, 0.00), + 4: (0.00, 0.00, 0.00), + } + """ + loc_data = {} + + if self.__loc_method & _loc_method.gps: + loc_data[_loc_method.gps] = self.__read_gps(retry) + + if self.__loc_method & _loc_method.cell: + loc_data[_loc_method.cell] = self.__read_cell() + + if self.__loc_method & _loc_method.wifi: + loc_data[_loc_method.wifi] = self.__read_wifi() + + return loc_data + + def wgs84togcj02(self, Longitude, Latitude): + return WGS84ToGCJ02(Longitude, Latitude) + + +if __name__ == '__main__': + _gps_cfg = { + "UARTn": UART.UART1, + "buadrate": 115200, + "databits": 8, + "parity": 0, + "stopbits": 1, + "flowctl": 0, + "PowerPin": Pin.GPIO2, + "StandbyPin": Pin.GPIO3, + "BackupPin": None, + "gps_mode": 0x01, + } + gps = GPS(**_gps_cfg) + print("read {}".format(gps.read(300))) diff --git a/3.code/1.watch/2.code/static/APP/alipay/1_11_1.jpg b/3.code/1.watch/2.code/static/APP/alipay/1_11_1.jpg new file mode 100644 index 00000000..88c0c4b7 Binary files /dev/null and b/3.code/1.watch/2.code/static/APP/alipay/1_11_1.jpg differ diff --git a/3.code/1.watch/2.code/static/APP/alipay/1_12_1_1.jpg b/3.code/1.watch/2.code/static/APP/alipay/1_12_1_1.jpg new file mode 100644 index 00000000..3b304a66 Binary files /dev/null and b/3.code/1.watch/2.code/static/APP/alipay/1_12_1_1.jpg differ diff --git a/3.code/1.watch/2.code/static/APP/alipay/1_1_1.jpg b/3.code/1.watch/2.code/static/APP/alipay/1_1_1.jpg new file mode 100644 index 00000000..40fdf420 Binary files /dev/null and b/3.code/1.watch/2.code/static/APP/alipay/1_1_1.jpg differ diff --git a/3.code/1.watch/2.code/static/APP/alipay/1_2_1.jpg b/3.code/1.watch/2.code/static/APP/alipay/1_2_1.jpg new file mode 100644 index 00000000..d54e4b17 Binary files /dev/null and b/3.code/1.watch/2.code/static/APP/alipay/1_2_1.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_APP_QR_CODE.jpg b/3.code/1.watch/2.code/static/IMAGE_APP_QR_CODE.jpg new file mode 100644 index 00000000..ca88cccf Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_APP_QR_CODE.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_HEART_ONLY_TEST_DONE.jpg b/3.code/1.watch/2.code/static/IMAGE_HEART_ONLY_TEST_DONE.jpg new file mode 100644 index 00000000..8f30f367 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_HEART_ONLY_TEST_DONE.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY0_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY0_ICON.jpg new file mode 100644 index 00000000..0a5fbbb4 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY0_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY1_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY1_ICON.jpg new file mode 100644 index 00000000..35e08c11 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY1_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY2_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY2_ICON.jpg new file mode 100644 index 00000000..7500ae70 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY2_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY3_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY3_ICON.jpg new file mode 100644 index 00000000..8783cfa8 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY3_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY4_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY4_ICON.jpg new file mode 100644 index 00000000..90d2a3ee Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY4_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY5_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY5_ICON.jpg new file mode 100644 index 00000000..c66444d0 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY5_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY6_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY6_ICON.jpg new file mode 100644 index 00000000..43450ece Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY6_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY7_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY7_ICON.jpg new file mode 100644 index 00000000..c4087a55 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY7_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY8_ICON.jpg b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY8_ICON.jpg new file mode 100644 index 00000000..e979dc92 Binary files /dev/null and b/3.code/1.watch/2.code/static/IMAGE_NUMBER_KEY8_ICON.jpg differ diff --git a/3.code/1.watch/2.code/static/lightrain.jpg b/3.code/1.watch/2.code/static/lightrain.jpg new file mode 100644 index 00000000..b23ac858 Binary files /dev/null and b/3.code/1.watch/2.code/static/lightrain.jpg differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu1/4-1.jpg b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-1.jpg new file mode 100644 index 00000000..ebd1ccc6 Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-1.jpg differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu1/4-2.jpg b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-2.jpg new file mode 100644 index 00000000..4b78c8e9 Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-2.jpg differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu1/4-3.jpg b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-3.jpg new file mode 100644 index 00000000..fbefbce2 Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-3.jpg differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu1/4-4.jpg b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-4.jpg new file mode 100644 index 00000000..86e9a902 Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu1/4-4.jpg differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu1/IMAGE_MAINMENU_WECHAT.png b/3.code/1.watch/2.code/static/main_menu/main_menu1/IMAGE_MAINMENU_WECHAT.png new file mode 100644 index 00000000..8414d97c Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu1/IMAGE_MAINMENU_WECHAT.png differ diff --git a/3.code/1.watch/2.code/static/main_menu/main_menu2/IMAGE_ONE_PAGE_SPO2_DETECT.jpg b/3.code/1.watch/2.code/static/main_menu/main_menu2/IMAGE_ONE_PAGE_SPO2_DETECT.jpg new file mode 100644 index 00000000..8a7690b6 Binary files /dev/null and b/3.code/1.watch/2.code/static/main_menu/main_menu2/IMAGE_ONE_PAGE_SPO2_DETECT.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_app_qrcode.jpg b/3.code/1.watch/2.code/static/menu_app_qrcode.jpg new file mode 100644 index 00000000..e4b9eccd Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_app_qrcode.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_bright.jpg b/3.code/1.watch/2.code/static/menu_bright.jpg new file mode 100644 index 00000000..d5072f0b Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_bright.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_theme_switch.jpg b/3.code/1.watch/2.code/static/menu_theme_switch.jpg new file mode 100644 index 00000000..55112318 Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_theme_switch.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_time.jpg b/3.code/1.watch/2.code/static/menu_time.jpg new file mode 100644 index 00000000..7d4f722c Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_time.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_upgrade.jpg b/3.code/1.watch/2.code/static/menu_upgrade.jpg new file mode 100644 index 00000000..8332b8ce Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_upgrade.jpg differ diff --git a/3.code/1.watch/2.code/static/menu_volume.jpg b/3.code/1.watch/2.code/static/menu_volume.jpg new file mode 100644 index 00000000..064581d3 Binary files /dev/null and b/3.code/1.watch/2.code/static/menu_volume.jpg differ diff --git a/3.code/1.watch/2.code/static/mpsignal1.jpg b/3.code/1.watch/2.code/static/mpsignal1.jpg new file mode 100644 index 00000000..520bd7fb Binary files /dev/null and b/3.code/1.watch/2.code/static/mpsignal1.jpg differ diff --git a/3.code/1.watch/2.code/static/mpsignal2.jpg b/3.code/1.watch/2.code/static/mpsignal2.jpg new file mode 100644 index 00000000..dd915c88 Binary files /dev/null and b/3.code/1.watch/2.code/static/mpsignal2.jpg differ diff --git a/3.code/1.watch/2.code/static/mpsignal3.jpg b/3.code/1.watch/2.code/static/mpsignal3.jpg new file mode 100644 index 00000000..05baf08a Binary files /dev/null and b/3.code/1.watch/2.code/static/mpsignal3.jpg differ diff --git a/3.code/1.watch/2.code/static/mpsignal4.jpg b/3.code/1.watch/2.code/static/mpsignal4.jpg new file mode 100644 index 00000000..deeaffa8 Binary files /dev/null and b/3.code/1.watch/2.code/static/mpsignal4.jpg differ diff --git a/3.code/1.watch/2.code/static/off_icon.jpg b/3.code/1.watch/2.code/static/off_icon.jpg new file mode 100644 index 00000000..9f019e31 Binary files /dev/null and b/3.code/1.watch/2.code/static/off_icon.jpg differ diff --git a/3.code/1.watch/2.code/static/reduce_btn.jpg b/3.code/1.watch/2.code/static/reduce_btn.jpg new file mode 100644 index 00000000..2d76ae23 Binary files /dev/null and b/3.code/1.watch/2.code/static/reduce_btn.jpg differ diff --git a/3.code/1.watch/2.code/static/stopwatch_reset.jpg b/3.code/1.watch/2.code/static/stopwatch_reset.jpg new file mode 100644 index 00000000..013ff61f Binary files /dev/null and b/3.code/1.watch/2.code/static/stopwatch_reset.jpg differ diff --git a/3.code/1.watch/2.code/static/stopwatch_stop.jpg b/3.code/1.watch/2.code/static/stopwatch_stop.jpg new file mode 100644 index 00000000..4b4a9982 Binary files /dev/null and b/3.code/1.watch/2.code/static/stopwatch_stop.jpg differ diff --git a/3.code/1.watch/2.code/static/sunny.jpg b/3.code/1.watch/2.code/static/sunny.jpg new file mode 100644 index 00000000..f49510e5 Binary files /dev/null and b/3.code/1.watch/2.code/static/sunny.jpg differ diff --git a/3.code/1.watch/2.code/static/time_up.jpg b/3.code/1.watch/2.code/static/time_up.jpg new file mode 100644 index 00000000..441aa09d Binary files /dev/null and b/3.code/1.watch/2.code/static/time_up.jpg differ diff --git a/3.code/1.watch/2.code/static/update.jpg b/3.code/1.watch/2.code/static/update.jpg new file mode 100644 index 00000000..3ce99f03 Binary files /dev/null and b/3.code/1.watch/2.code/static/update.jpg differ diff --git a/3.code/1.watch/2.code/static/vbat_0.jpg b/3.code/1.watch/2.code/static/vbat_0.jpg new file mode 100644 index 00000000..511db7c3 Binary files /dev/null and b/3.code/1.watch/2.code/static/vbat_0.jpg differ diff --git a/3.code/1.watch/2.code/static/vbat_100.jpg b/3.code/1.watch/2.code/static/vbat_100.jpg new file mode 100644 index 00000000..c8b4259d Binary files /dev/null and b/3.code/1.watch/2.code/static/vbat_100.jpg differ diff --git a/3.code/1.watch/2.code/static/vbat_80.jpg b/3.code/1.watch/2.code/static/vbat_80.jpg new file mode 100644 index 00000000..31bee1df Binary files /dev/null and b/3.code/1.watch/2.code/static/vbat_80.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/step.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/step.jpg new file mode 100644 index 00000000..f16ef9cc Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/step.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/0.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/0.jpg new file mode 100644 index 00000000..62e72ad3 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/0.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/1.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/1.jpg new file mode 100644 index 00000000..7f84eca3 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/1.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/2.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/2.jpg new file mode 100644 index 00000000..137d2098 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/2.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/3.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/3.jpg new file mode 100644 index 00000000..b00537d0 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/3.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/4.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/4.jpg new file mode 100644 index 00000000..00d38374 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/4.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/5.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/5.jpg new file mode 100644 index 00000000..51870ff3 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/5.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/6.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/6.jpg new file mode 100644 index 00000000..d5bd2f2b Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/6.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/7.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/7.jpg new file mode 100644 index 00000000..17a9fbc2 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/7.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/8.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/8.jpg new file mode 100644 index 00000000..e06aff66 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/8.jpg differ diff --git a/3.code/1.watch/2.code/static/watch_plate/style_1/time/colon.jpg b/3.code/1.watch/2.code/static/watch_plate/style_1/time/colon.jpg new file mode 100644 index 00000000..621c9333 Binary files /dev/null and b/3.code/1.watch/2.code/static/watch_plate/style_1/time/colon.jpg differ