def on_read_local_system_file(data): cmd = Command.create_with_read_file_action_system_file( SystemFiles.files[SystemFileIds(int(data['system_file_id']))]) logging.info("executing cmd: {}".format(cmd)) modem.execute_command_async(cmd) return {'tag_id': cmd.tag_id}
def read_uid(self): self.send_command(Command.create_with_read_file_action_system_file(UidFile())) while True: # TODO timeout commands, info = self.read() for command in commands: for action in command.actions: if type(action) is RegularAction \ and type(action.operation) is ReturnFileData \ and action.operand.offset.id == SystemFileIds.UID: return struct.unpack(">Q", bytearray(action.operand.data))[0]
def read_uid(self): self.send_command( Command.create_with_read_file_action_system_file(UidFile())) while True: # TODO timeout commands, info = self.read() for command in commands: for action in command.actions: if type(action) is RegularAction \ and type(action.operation) is ReturnFileData \ and action.operand.offset.id == SystemFileIds.UID: return struct.unpack(">Q", bytearray(action.operand.data))[0]
def connect(self): if self.connected: return read_modem_info_action = Command.create_with_read_file_action_system_file( UidFile()) read_modem_info_action.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=Length( 0)), # TODO offset size length=FirmwareVersionFile().length)))) if self.skip_alp_parsing: self.log.info( "Running in skip_alp_parsing mode, not checking if we can receive the modem's UID" ) self.connected = True self.execute_command_async(read_modem_info_action) return True resp_cmd = self.execute_command(read_modem_info_action, timeout_seconds=10) if len(resp_cmd) == 0: self.log.warning("Timed out reading node information") return False for action in resp_cmd[0].actions: if type(action) is RegularAction and type( action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = '{:x}'.format( struct.unpack(">Q", str(bytearray(action.operand.data)))[0]) if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse( ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: self.connected = True if self.connected: self.log.info( "connected to {}, node UID {} running D7AP v{}, application \"{}\" with git sha1 {}" .format(self.config["device"], self.uid, self.firmware_version.d7ap_version, self.firmware_version.application_name, self.firmware_version.git_sha1)) return True else: return False
def _connect_serial_modem(self): self.dev = serial.Serial( port=self.config["device"], baudrate=self.config["baudrate"], timeout=None, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, xonxoff=False, rtscts=False, dsrdtr=False, exclusive=True, ) self.dev.flush() # ignore possible buffered data self.start_reading() read_modem_info_action = Command.create_with_read_file_action_system_file( UidFile()) read_modem_info_action.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=Length( 0)), # TODO offset size length=FirmwareVersionFile().length)))) resp_cmd = self.execute_command(read_modem_info_action, timeout_seconds=60) if len(resp_cmd) == 0: self.log.warning("Timed out reading node information") return False for action in resp_cmd[0].actions: if type(action) is RegularAction and type( action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = '{:x}'.format( struct.unpack(">Q", bytearray(action.operand.data))[0]) if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse( ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: return True return False
def _connect_serial_modem(self): self.dev = serial.Serial( port=self.config["device"], baudrate=self.config["baudrate"], timeout=0.5, ) read_modem_info_action = Command.create_with_read_file_action_system_file( UidFile()) read_modem_info_action.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=0), # TODO offset size length=FirmwareVersionFile().length)))) self.send_command(read_modem_info_action) # read thread not yet running here, read sync start_time = datetime.now() timeout = False while not timeout: commands, info = self.read() for command in commands: for action in command.actions: if type(action) is RegularAction and type( action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = '{:x}'.format( struct.unpack(">Q", bytearray( action.operand.data))[0]) if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse( ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: return True if (datetime.now() - start_time).total_seconds() > 2: timeout = True self.log("Timed out reading node information") return False
def _connect_serial_modem(self): self.dev = serial.Serial( port = self.config["device"], baudrate = self.config["baudrate"], timeout = 0.5, ) read_modem_info_action = Command.create_with_read_file_action_system_file(UidFile()) read_modem_info_action.add_action( RegularAction( operation=ReadFileData( operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=0), # TODO offset size length=FirmwareVersionFile().length ) ) ) ) self.send_command(read_modem_info_action) # read thread not yet running here, read sync start_time = datetime.now() timeout = False while not timeout: commands, info = self.read() for command in commands: for action in command.actions: if type(action) is RegularAction and type(action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = struct.unpack(">Q", bytearray(action.operand.data))[0] if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse(ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: return True if (datetime.now() - start_time).total_seconds() > 2: timeout = True self.log("Timed out reading node information") return False
def received_command_callback(cmd): print cmd argparser = argparse.ArgumentParser() argparser.add_argument("-d", "--device", help="serial device /dev file modem", default="/dev/ttyUSB0") argparser.add_argument("-r", "--rate", help="baudrate for serial device", type=int, default=115200) argparser.add_argument("-v", "--verbose", help="verbose", default=False, action="store_true") config = argparser.parse_args() modem = Modem(config.device, config.rate, receive_callback=received_command_callback, show_logging=config.verbose) modem.d7asp_fifo_flush( alp_command=Command.create_with_read_file_action_system_file( file=UidFile(), interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ALL), addressee=Addressee( access_class=0, id_type=IdType.NOID ) ) ) ) modem.start_reading() while True: pass
def on_read_local_system_file(data): print("read local system file") modem.send_command( Command.create_with_read_file_action_system_file(SystemFiles.files[SystemFileIds(int(data['system_file_id']))]) )
def __init__(self): argparser = argparse.ArgumentParser() argparser.add_argument("-d", "--device", help="serial device /dev file modem", default="/dev/ttyACM0") argparser.add_argument("-r", "--rate", help="baudrate for serial device", type=int, default=115200) argparser.add_argument("-v", "--verbose", help="verbose", default=False, action="store_true") argparser.add_argument("-t", "--token", help="Access token for the TB gateway", required=True) argparser.add_argument("-tb", "--thingsboard", help="Thingsboard hostname/IP", default="localhost") argparser.add_argument("-p", "--plugin-path", help="path where plugins are stored", default="") argparser.add_argument("-bp", "--broker-port", help="mqtt broker port", default="1883") argparser.add_argument( "-l", "--logfile", help="specify path if you want to log to file instead of to stdout", default="") argparser.add_argument( "-k", "--keep-data", help= "Save data locally when Thingsboard is disconnected and send it when connection is restored.", default=True) argparser.add_argument( "-b", "--save-bandwidth", help="Send data in binary format to save bandwidth", action="store_true") argparser.add_argument("-sf", "--skip-system-files", help="Do not read system files on boot", action="store_true") self.bridge_count = 0 self.next_report = 0 self.config = argparser.parse_args() self.log = logging.getLogger() formatter = logging.Formatter( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') if self.config.logfile == "": handler = logging.StreamHandler() else: handler = logging.FileHandler(self.config.logfile) handler.setFormatter(formatter) self.log.addHandler(handler) self.log.setLevel(logging.INFO) if self.config.verbose: self.log.setLevel(logging.DEBUG) self.tb = Thingsboard(self.config.thingsboard, self.config.token, self.on_mqtt_message, persistData=self.config.keep_data) if self.config.plugin_path != "": self.load_plugins(self.config.plugin_path) self.modem = Modem(self.config.device, self.config.rate, self.on_command_received, self.config.save_bandwidth) connected = self.modem.connect() while not connected: try: self.log.warning("Not connected to modem, retrying ...") time.sleep(1) connected = self.modem.connect() except KeyboardInterrupt: self.log.info("received KeyboardInterrupt... stopping") self.tb.disconnect() exit(-1) except: exc_type, exc_value, exc_traceback = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_traceback) trace = "".join(lines) self.log.error( "Exception while connecting modem: \n{}".format(trace)) # switch to continuous foreground scan access profile self.modem.execute_command( Command.create_with_write_file_action_system_file( DllConfigFile(active_access_class=0x01)), timeout_seconds=1) if self.config.save_bandwidth: self.log.info("Running in save bandwidth mode") if self.config.plugin_path is not "": self.log.warning( "Save bandwidth mode is enabled, plugin files will not be used" ) # update attribute containing git rev so we can track revision at TB platform git_sha = subprocess.check_output(["git", "describe", "--always"]).strip() ip = self.get_ip() self.tb.sendGwAttributes({ 'UID': self.modem.uid, 'git-rev': git_sha, 'IP': ip, 'save bw': str(self.config.save_bandwidth) }) self.log.info("Running on {} with git rev {} using modem {}".format( ip, git_sha, self.modem.uid)) # read all system files on the local node to store as attributes on TB if not self.config.skip_system_files: self.log.info("Reading all system files ...") for file in SystemFiles().files.values(): self.modem.execute_command_async( Command.create_with_read_file_action_system_file(file))
from util.logger import configure_default_logger def received_command_callback(cmd): logging.info(cmd) if cmd.execution_completed: sys.exit(0) argparser = argparse.ArgumentParser() argparser.add_argument("-d", "--device", help="serial device /dev file modem", default="/dev/ttyUSB0") argparser.add_argument("-r", "--rate", help="baudrate for serial device", type=int, default=115200) argparser.add_argument("-v", "--verbose", help="verbose", default=False, action="store_true") config = argparser.parse_args() configure_default_logger(config.verbose) modem = Modem(config.device, config.rate, unsolicited_response_received_callback=received_command_callback) modem.connect() answers = modem.execute_command( alp_command=Command.create_with_read_file_action_system_file( file=PhyStatusFile(channel_status_list_length=10) ) ) for answer in answers: logging.info("answer is {}".format(answer.__str__()))
def __init__(self): argparser = argparse.ArgumentParser() argparser.add_argument("-d", "--device", help="serial device /dev file modem", default="/dev/ttyACM0") argparser.add_argument("-r", "--rate", help="baudrate for serial device", type=int, default=115200) argparser.add_argument("-v", "--verbose", help="verbose", default=False, action="store_true") argparser.add_argument("-b", "--broker", help="mqtt broker hostname", default="localhost") argparser.add_argument("-bp", "--broker-port", help="mqtt broker port", default="1883") argparser.add_argument("-p", "--plugin-path", help="path where plugins are stored", default="") argparser.add_argument( "-l", "--logfile", help="specify path if you want to log to file instead of to stdout", default="") self.bridge_count = 0 self.next_report = 0 self.mq = None self.mqtt_topic_incoming_alp = "" self.connected_to_mqtt = False self.config = argparser.parse_args() self.log = logging.getLogger() formatter = logging.Formatter( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') if self.config.logfile == "": handler = logging.StreamHandler() else: handler = logging.FileHandler(self.config.logfile) handler.setFormatter(formatter) self.log.addHandler(handler) self.log.setLevel(logging.INFO) if self.config.verbose: self.log.setLevel(logging.DEBUG) if self.config.plugin_path != "": self.load_plugins(self.config.plugin_path) self.modem = Modem(self.config.device, self.config.rate, self.on_command_received) self.connect_to_mqtt() # update attribute containing git rev so we can track revision at TB platform git_sha = subprocess.check_output(["git", "describe", "--always"]).strip() ip = self.get_ip() # TODO ideally this should be associated with the GW device itself, not with the modem in the GW # not clear how to do this using TB-GW self.publish_to_topic( "/gateway-info", jsonpickle.json.dumps({ "git-rev": git_sha, "ip": ip, "device": self.modem.uid })) # make sure TB knows the modem device is connected. TB considers the device connected as well when there is regular # telemetry data. This is fine for remote nodes which will be auto connected an disconnected in this way. But for the # node in the gateway we do it explicitly to make sure it always is 'online' even when there is no telemetry to be transmitted, # so that we can reach it over RPC self.publish_to_topic( "sensors/connect", jsonpickle.json.dumps({"serialNumber": self.modem.uid})) self.log.info("Running on {} with git rev {} using modem {}".format( ip, git_sha, self.modem.uid)) # read all system files on the local node to store as attributes on TB self.log.info("Reading all system files ...") for file in SystemFiles().files.values(): self.modem.execute_command_async( Command.create_with_read_file_action_system_file(file))
help="serial device /dev file modem", default="/dev/ttyACM1") argparser.add_argument("-r", "--rate", help="baudrate for serial device", type=int, default=115200) argparser.add_argument("-v", "--verbose", help="verbose", default=False, action="store_true") config = argparser.parse_args() modem = Modem(config.device, config.rate, receive_callback=received_command_callback, show_logging=config.verbose) modem.d7asp_fifo_flush( alp_command=Command.create_with_read_file_action_system_file( file=UidFile(), interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ALL), addressee=Addressee(access_class=0x01, id_type=IdType.NOID)))) modem.start_reading() while True: pass