def on(self): """Turns on device.""" if hasattr(self, "gpio"): self.gpio.on() # set pin to off utils.status_table[self.name] = 1 utils.log_file("{} => ON".format(self.name), constants.LOG_LEVEL) # return
def _is_ready(self): """Waits for modem get ready. Returns: True or False """ utils.log_file("{} => starting up...".format(__name__), constants.LOG_LEVEL, False) for _ in range(constants.TIMEOUT): rx_buff = [] self.uart.write("AT\r") t0 = utime.time() while True: if utime.time() - t0 > 5: # Waits 5 sec for response. break if self.uart.any(): byte = self.uart.read(1) if byte == b"\n": continue elif byte == b"\r": rx = "".join(rx_buff) if rx: if rx == "ERROR": break if rx == "OK": return True rx_buff = [] else: rx_buff.append(chr(ord(byte))) utime.sleep(1) utils.log_file("{} => unavailable ".format(__name__), constants.LOG_LEVEL, True) return False
def data_transfer(self): """Sends files over the gsm network.""" if not self.init_uart(): return self.sending = True self.led_on() print("########################################") print("# #") print("# YMODEM SENDER V1.1 #") print("# #") print("########################################") self.connected = False self.sending = False self.sent = False error_count = 0 while True: if error_count == int(self.call_attempt): utils.log_file("{} => connection unavailable, aborting...".format(self.__qualname__), constants.LOG_LEVEL, True) break elif not self.connected: if not self._call(): error_count += 1 utime.sleep(self.call_delay) continue error_count = 0 elif not self.sent: self._send() else: if not self._hangup(): error_count += 1 continue break self.led_on() # self.deinit_uart() DEBUG Restore before deploy??? return
def _set_usr_cfg(self): """Uploads a deployment config to the instrument and sets up the device Activation_Rate and Warmup_Duration parameters according to the current deployment constants.""" start = utime.time() while True: if self._timeout(start): break if self._break(): try: with open(self.config["Adcp"]["Deployment_Config"], "rb") as pdc: cfg = pdc.read() rate = int.from_bytes(cfg[38:40], "little") self.config["Activation_Rate"] = rate self.config[ "Warmup_Duration"] = rate - self.config["Samples"] usr_cfg = cfg[0:48] + self._set_start() + cfg[54:510] checksum = self._calc_checksum(usr_cfg) tx = usr_cfg + ubinascii.unhexlify( hex(checksum)[-2:] + hex(checksum)[2:4]) self.uart.write(b"\x43\x43") self.uart.write(tx) utils.verbose("=> CC", constants.VERBOSE) rx = self._get_reply() if self._ack(rx): utils.log_file( "{} => uploaded deployment config".format( self.__qualname__)) # DEBUG return True except: break utils.log_file("{} => unable to upload deployment config".format( self.__qualname__)) # DEBUG return False
def _set_auto_answer(self): """Initializes modem with auto answer. Returns: True or False """ if not self._is_ready(): return False else: utils.log_file("{} => initialization sequence".format(__name__), constants.LOG_LEVEL, True) for at in ["AT\r","AT+CREG=0\r","AT+CBST=7,0,1\r","ATS0=2\r","ATS0?\r"]: self.uart.write(at) rx_buff = [] t = utime.time() while True: if utime.time() - t == self.call_timeout: print("TIMEOUT OCCURRED") return False if self.uart.any(): byte = self.uart.read(1) if byte == b"\n": continue elif byte == b"\r": rx = "".join(rx_buff) if rx: print(rx) if rx == "OK": break rx_buff = [] else: rx_buff.append(chr(ord(byte))) utime.sleep(self.ats_delay) return True
def _get_cfg(self): """Reads complete configuration data Reads the currently used hardware configuration, the head configuration, and the deployment configuration from the instrument. """ start = utime.time() while True: if self._timeout(start): break if self._break(): utils.verbose("=> GA", constants.VERBOSE) self.uart.write("GA") rx = self._get_reply() if self._ack(rx) and self.verify_checksum( rx[0:48]) and self.verify_checksum( rx[48:272]) and self.verify_checksum(rx[272:784]): try: with open("config/adcp.cfg", "wb") as cfg: cfg.write(rx) utils.log_file( "{} => retreived instrument config".format( self.__qualname__)) # DEBUG return True except: break utils.log_file("{} => unable to retreive instrument config".format( self.__qualname__)) # DEBUG return False
def main(self): """Captures instrument data.""" if not self.init_uart(): return utils.log_file("{} => acquiring data...".format( self.__qualname__)) # DEBUG self.led_on() sample = "" new_line = False start = utime.time() while True: if utime.time( ) - start > self.config["Samples"] // self.config["Sample_Rate"]: utils.log_file("{} => no data coming from serial".format( self.__qualname__)) # DEBUG break if self.uart.any(): byte = self.uart.read(1) if byte == b"\n": new_line = True elif byte == b"\r" and new_line: break elif new_line: sample += byte.decode("utf-8") utils.log_data(self._format_data(sample)) self.led_on() return
def _set_clock(self): """Sets up the instrument RTC. mm ss DD hh YY MM (3 words of 2 bytes each) """ start = utime.time() while True: if self._timeout(start): utils.log_file("{} => unable to sync clock".format( self.__qualname__)) # DEBUG return False if self._break(): now = utime.localtime() tx = "{:02d}{:02d}{:02d}{:02d}{:02d}{:02d}".format( now[4], now[5], now[2], now[3], int(str(now[0])[2:]), now[1]) self.uart.write("SC") self.uart.write(ubinascii.unhexlify(tx)) utils.verbose("=> SC" + str(tx), constants.VERBOSE) if self._ack(self._get_reply()): utils.log_file( "{} => clock synced (dev: {} board: {})".format( self.__qualname__, self._get_clock(), utils.time_string(utime.mktime(now)))) # DEBUG return True
def init_gpio(self): """Creates the device pin object.""" if "Ctrl_Pin" in self.config: try: self.gpio = pyb.Pin(self.config["Ctrl_Pin"], pyb.Pin.OUT) except (ValueError) as err: utils.log_file("{} => {}.".format(self.name, err), constants.LOG_LEVEL)
def init_led(self): """Creates the device led object.""" try: self.led = pyb.LED(constants.LEDS["RUN"]) self.led.off() except ValueError as err: utils.log_file("{} => {}.".format(self.name, err), constants.LOG_LEVEL)
def _break(self): utils.log_file("{} => waiting for instrument getting ready...".format( self.__qualname__)) # DEBUG while True: self._flush_uart() self.uart.write(b"\x03") # <CTRL+C> if self._get_prompt(120): return True
def off(self): """Turns off device.""" if hasattr(self, "gpio"): self.gpio.off() # set pin to off utils.status_table[self.name] = 0 utils.log_file("{} => OFF".format(self.name), constants.LOG_LEVEL) # DEBUG return
def main(self): """Gets data from internal sensors.""" utils.log_file("{} => checking up system status...".format(self.name), constants.LOG_LEVEL) core_temp = 0 core_vbat = 0 core_vref = 0 vref = 0 battery_level = 0 current_level = 0 ambient_temperature = 0 self.data = [] channels = [] for key in self.config["Adc"]["Channels"].keys(): channels.append(self.config["Adc"]["Channels"][key]["Ch"]) adcall = pyb.ADCAll(int(self.config["Adc"]["Bit"]), self.adcall_mask(channels)) for i in range( int(self.config["Samples"]) * int(self.config["Sample_Rate"])): core_temp += adcall.read_core_temp() core_vbat += adcall.read_core_vbat() core_vref += adcall.read_core_vref() vref += adcall.read_vref() battery_level += adcall.read_channel( self.config["Adc"]["Channels"]["Battery_Level"]["Ch"]) current_level += adcall.read_channel( self.config["Adc"]["Channels"]["Current_Level"]["Ch"]) ambient_temperature += adcall.read_channel( self.config["Adc"]["Channels"]["Ambient_Temperature"]["Ch"]) i += 1 core_temp = core_temp / i core_vbat = core_vbat / i core_vref = core_vref / i vref = vref / i battery_level = battery_level / i * vref / pow( 2, int(self.config["Adc"]["Bit"])) current_level = current_level / i * vref / pow( 2, int(self.config["Adc"]["Bit"])) ambient_temperature = ambient_temperature / i * vref / pow( 2, int(self.config["Adc"]["Bit"])) battery_level = self.battery_level(battery_level) current_level = self.current_level(current_level) ambient_temperature = self.ad22103(ambient_temperature, vref) epoch = utime.time() self.data.append(self.config["String_Label"]) self.data.append(str(utils.unix_epoch(epoch))) # unix timestamp self.data.append(utils.datestamp(epoch)) # YYMMDD self.data.append(utils.timestamp(epoch)) # hhmmss self.data.append("{:.4f}".format(battery_level)) self.data.append("{:.4f}".format(current_level)) self.data.append("{:.4f}".format(ambient_temperature)) self.data.append("{:.4f}".format(core_temp)) self.data.append("{:.4f}".format(core_vbat)) self.data.append("{:.4f}".format(core_vref)) self.data.append("{:.4f}".format(vref)) return True
def _start_logging(self): if self._get_prompt(): self.uart.write("SET SCAN LOGGING\r") if self._get_prompt(): utils.log_file("{} => logging started".format( self.__qualname__)) # DEBUG return True utils.log_file("{} => unable to start logging".format( self.__qualname__)) # DEBUG return False
def get_config(self): """Gets the device configuration.""" try: self.config = utils.read_config( self.config_file)[self.__qualname__][self.instance] return self.config except: utils.log_file("{} => unable to load configuration.".format( self.name), constants.LOG_LEVEL) # DEBUG return False
def _set_clock(self): """Syncs the intrument clock.""" if self._set_date() and self._set_time(): utils.log_file("{} => clock synced (dev: {} {} board: {})".format( self.__qualname__, self._get_date(), self._get_time(), utils.time_string(utime.mktime(utime.localtime())))) # DEBUG return True utils.log_file("{} => unable to sync clock".format( self.__qualname__)) # DEBUG return False
def deinit_uart(self): """Deinitializes the uart bus.""" try: self.uart.deinit() except: utils.log_file( "{} => unable to deinitialize uart {}".format( self.__qualname__, self.config["Uart"]["Bus"]), constants.LOG_LEVEL) return False return True
def _set_sample_rate(self): """Sets intrument sampling rate.""" if self._get_prompt(): self.uart.write("SET S {:0d} S\r".format( self.config["Sample_Rate"])) if self._get_reply() == self.prompt: self._get_sample_rate() return True utils.log_file("{} => unable to set sampling rate".format( self.__qualname__)) # DEBUG return False
def _format_recorder(self): """Erase all recorded data if it reached the maximum allowed files number (31)""" start = utime.time() while True: if self._timeout(start): utils.log_file("{} => unable to format recorder".format( self.__qualname__)) # DEBUG return False if self._break(): utils.verbose("=> FO", constants.VERBOSE) self.uart.write(b"\x46\x4F\x12\xD4\x1E\xEF") if self._ack(self._get_reply()): utils.log_file("{} => recorder formatted".format( self.__qualname__)) # DEBUG return True
def verify_checksum(self, checksum, sentence): """Verifies the NMEA sentence integrity. Params: checksum(hex) sentence(list) """ calculated_checksum = 0 for char in ",".join(map(str, sentence)): calculated_checksum ^= ord(char) if "{:02X}".format(calculated_checksum) != checksum: utils.log_file("NMEA invalid checksum calculated: {:02X} got: {}".format(calculated_checksum, checksum), constants.LOG_LEVEL) return False else: return True
def manage_task(self, device, tasks): """Manages the device status after a event event. |--OFF--> ON--> WARMING UP--> READY-->|--OFF--|-> Params: task(str) """ if "on" in tasks: utils.create_device(device, tasks=["on"]) elif "off" in tasks: utils.create_device(device, tasks=["off"]) else: utils.status_table[device] = 2 # Sets device ready. _thread.start_new_thread(utils.execute, (device, tasks,)) utils.log_file("{} => {}".format(device, constants.DEVICE_STATUS[utils.status_table[device]]), constants.LOG_LEVEL)
def init_devices(self): """ Initializes all configured devices. """ utils.log_file("Initializing devices...", constants.LOG_LEVEL) for file in uos.listdir(constants.CONFIG_PATH): f_name = file.split(".")[0] f_ext = file.split(".")[1] if f_ext == constants.CONFIG_TYPE: # and f_name.split("_")[0] == "dev" cfg = utils.read_config(file) for key in cfg.keys(): for obj in cfg[key]: if cfg[key][obj]["Device"]: try: utils.create_device(f_name + "." + key + "_" + obj, tasks=["start_up"]) except ImportError: pass
def _acquire_data(self): """Starts a single measurement based on the current configuration of the instrument without storing data to the recorder. Instrument enters Power Down Mode when measurement has been made. """ utils.log_file("{} => acquiring 1 sample...".format( self.__qualname__)) # DEBUG start = utime.time() while True: if self._timeout(start): return False if self._break(): utils.verbose("=> AD", constants.VERBOSE) self.uart.write("AD") if self._ack(self._get_reply()): rx = self._get_reply() if self.verify_checksum(rx): return rx
def _get_head_cfg(self): """Retreives the current head config from the instrument.""" start = utime.time() while True: if self._timeout(start): utils.log_file("{} => unable to retreive head config".format( self.__qualname__)) # DEBUG return False if self._break(): utils.verbose("=> GH", constants.VERBOSE) self.uart.write("GH") rx = self._get_reply() if self._ack(rx): if self.verify_checksum(rx[:-2]): self.head_cfg = self._parse_head_cfg(rx) utils.log_file("{} => retreived head config".format( self.__qualname__)) # DEBUG return True
def _parse_cfg(self): """Parses configuration data.""" try: with open("config/adcp.cfg", "rb") as cfg: bytes = cfg.read() self.hw_cfg = self._parse_hw_cfg( bytes[0:48]) # Hardware config (48 bytes) self.head_cfg = self._parse_head_cfg( bytes[48:272]) # Head config (224 bytes) self.usr_cfg = self._parse_usr_cfg( bytes[272:784]) # Deployment config (512 bytes) utils.log_file("{} => parsed instrument config".format( self.__qualname__)) # DEBUG return True except: utils.log_file("{} => unable to parse instrument config".format( self.__qualname__)) # DEBUG return False
def init_uart(self): """Initializes the uart bus.""" try: self.uart = pyb.UART(int(self.config["Uart"]["Bus"]), int(self.config["Uart"]["Baudrate"])) self.uart.init( int(self.config["Uart"]["Baudrate"]), bits=int(self.config["Uart"]["Bits"]), parity=eval(self.config["Uart"]["Parity"]), stop=int(self.config["Uart"]["Stop"]), timeout=int(self.config["Uart"]["Timeout"]), flow=int(self.config["Uart"]["Flow_Control"]), timeout_char=int(self.config["Uart"]["Timeout_Char"]), read_buf_len=int(self.config["Uart"]["Read_Buf_Len"])) return True except (ValueError) as err: utils.log_file("{} => {}.".format(self.name, err), constants.LOG_LEVEL) return False
def _set_start(self): """Computes the measurement starting time to be synced with scheduler.""" now = utime.time() - self.config["Activation_Delay"] next = now - now % self.config["Activation_Rate"] + self.config[ "Activation_Rate"] if now % self.config["Activation_Rate"] > self.config[ "Activation_Rate"] - self.config["Samples"] // self.config[ "Sample_Rate"] - self.config["Adcp"]["Start_Delay"]: next += self.config["Activation_Rate"] next += -self.config["Samples"] // self.config[ "Sample_Rate"] // 2 - self.config["Adcp"]["Start_Delay"] next += self.config["Activation_Delay"] start = utime.localtime(next) start = ubinascii.unhexlify( "{:02d}{:02d}{:02d}{:02d}{:02d}{:02d}".format( start[4], start[5], start[2], start[3], int(str(start[0])[2:]), start[1])) utils.log_file("{} => set start at {}".format( self.__qualname__, utils.time_string(next))) # DEBUG return start
def last_fix(self): """Stores last gps valid position and utc.""" if self.is_valid_gprmc(): utils.log_file("{} => saving last gps fix...".format(self.name), constants.LOG_LEVEL) utc_time = self.sentence[1] utc_date = self.sentence[9] lat = "{}{}".format(self.sentence[3], self.sentence[4]) lon = "{}{}".format(self.sentence[5], self.sentence[6]) utc = "{}-{}-{} {}:{}:{}".format("20" + utc_date[4:6], utc_date[2:4], utc_date[0:2], utc_time[0:2], utc_time[2:4], utc_time[4:6]) speed = "{}".format(self.sentence[7]) heading = "{}".format(self.sentence[8]) utils.gps = (utc, lat, lon, speed, heading) utils.log_file( "{} => last fix (UTC: {} POSITION: {} {}, SPEED: {}, HEADING: {})" .format(self.name, utc, lat, lon, speed, heading), constants.LOG_LEVEL) # DEBUG return
def init_uart(self): """Initializes the uart bus.""" if "Uart" in self.config: try: self.uart = pyb.UART( int(constants.UARTS[constants.DEVICES[self.__qualname__ + "_" + self.instance]]), int(self.config["Uart"]["Baudrate"])) self.uart.init( int(self.config["Uart"]["Baudrate"]), bits=int(self.config["Uart"]["Bits"]), parity=eval(self.config["Uart"]["Parity"]), stop=int(self.config["Uart"]["Stop"]), timeout=int(self.config["Uart"]["Timeout"]), flow=int(self.config["Uart"]["Flow_Control"]), timeout_char=int(self.config["Uart"]["Timeout_Char"]), read_buf_len=int(self.config["Uart"]["Read_Buf_Len"])) except (ValueError) as err: utils.log_file("{} => {}.".format(self.name, err), constants.LOG_LEVEL)
def sync_rtc(self): """Synchronizes rtc with gps data.""" if self.is_valid_gprmc(): utils.log_file("{} => syncyng rtc...".format(self.name), constants.LOG_LEVEL) utc_time = self.sentence[1] utc_date = self.sentence[9] rtc = pyb.RTC() try: rtc.datetime( (int("20" + utc_date[4:6]), int(utc_date[2:4]), int(utc_date[0:2]), 0, int(utc_time[0:2]), int(utc_time[2:4]), int(utc_time[4:6]), float(utc_time[6:]) )) # rtc.datetime(yyyy, mm, dd, 0, hh, ii, ss, sss) utils.log_file( "{} => rtc successfully synchronized (UTC: {})".format( self.name, utils.time_string(utime.time())), constants.LOG_LEVEL) except: utils.log_file( "{} => unable to synchronize rtc".format( self.name, utils.time_string(utime.time())), constants.LOG_LEVEL) return