def execute_command(data): logging.info("execute_command") logging.info(data) interface_configuration = None interface_type = InterfaceType(int(data["interface"])) if interface_type == InterfaceType.D7ASP: id_type = IdType[data["id_type"]] id = int(data["id"]) if id_type == IdType.NOID: id = None if id_type == IdType.NBID: id = CT() # TODO convert interface_configuration = Configuration( qos=QoS(resp_mod=ResponseMode[data["qos_response_mode"]]), addressee=Addressee(access_class=int(data["access_class"]), id_type=id_type, id=id)) cmd = Command.create_with_read_file_action( interface_type=interface_type, interface_configuration=interface_configuration, file_id=int(data["file_id"]), offset=int(data["offset"]), length=int(data["length"])) logging.info("executing cmd: {}".format(cmd)) modem.execute_command_async(cmd) return { 'tag_id': cmd.tag_id, 'interface': interface_type.name, 'command_description': cmd.describe_actions() }
def add_forward_action(self, interface_type=InterfaceType.HOST, interface_configuration=None): if interface_configuration is not None and interface_type == InterfaceType.HOST: raise ValueError( "interface_configuration is not supported for interface_type HOST" ) if interface_type == InterfaceType.D7ASP: if interface_configuration is None: interface_configuration = Configuration() self.actions.append( RegularAction(operation=Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.D7ASP, interface_configuration=interface_configuration)))) elif interface_type == InterfaceType.SERIAL: self.actions.append( RegularAction(operation=Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.SERIAL)))) elif interface_type == InterfaceType.LORAWAN_ABP: self.actions.append( RegularAction(operation=Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.LORAWAN_ABP, interface_configuration=interface_configuration)))) elif interface_type == InterfaceType.LORAWAN_OTAA: self.actions.append( RegularAction(operation=Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.LORAWAN_OTAA, interface_configuration=interface_configuration)))) elif interface_type == InterfaceType.HOST: pass else: raise ValueError( "interface_type {} is not supported".format(interface_type))
def test_byte_generation(self): # TODO: use mocking framework to mock sub-objects bytes = bytearray(Configuration()) self.assertEqual(len(bytes), 3) self.assertEquals(bytes[0], int('00000000', 2)) # qos self.assertEquals(bytes[1], int('00000000', 2)) # dorm_to (CT) self.assertEquals(bytes[2], int('00010000', 2)) # addressee control BCAST
def parse_forward_action(self, b7, b6, s): if b7: raise ParseError("bit 7 is RFU") interface_id = InterfaceType(int(s.read("uint:8"))) assert(interface_id == InterfaceType.D7ASP) interface_config = Configuration.parse(s) return ForwardAction(resp=b6, operation=Forward(operand=InterfaceConfiguration(interface_id=interface_id, interface_configuration=interface_config)))
def send(self): cmd = Command.create_with_return_file_data_action( file_id=0x40, data=map(ord, list(self.command)), interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=QoS.RESP_MODE_NO), addressee=Addressee(access_class=0, id_type=IdType.BCAST))) self.modem.d7asp_fifo_flush(alp_command=cmd) self.add("me: " + self.command, curses.A_REVERSE)
def test_byte_generation(self): d7asp_config = Configuration() forward_action = Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.D7ASP, interface_configuration=d7asp_config)) bytes = bytearray(forward_action) self.assertEqual(len(bytes), len(bytearray(d7asp_config)) + 1) self.assertEqual(bytes[0], 0xD7) self.assertEqual(bytes[1:], bytearray(d7asp_config))
def test_parse(self): bytes = [0b00000000, 0, 0b00010000, 0] config = Configuration.parse(ConstBitStream(bytes=bytes)) self.assertEqual(config.qos.resp_mod, ResponseMode.RESP_MODE_NO) self.assertEqual(config.qos.retry_mod, RetryMode.RETRY_MODE_NO) self.assertEqual(config.qos.stop_on_err, False) self.assertEqual(config.qos.record, False) self.assertEqual(config.addressee.id_type, IdType.NOID) self.assertEqual(config.addressee.nls_method, NlsMethod.NONE) self.assertEqual(config.addressee.access_class, 0)
def add_forward_action(self, interface_type=InterfaceType.HOST, interface_configuration=None): if interface_configuration is not None and interface_type == InterfaceType.HOST: raise ValueError( "interface_configuration is not supported for interface_type HOST" ) if interface_type == InterfaceType.D7ASP: if interface_configuration is None: interface_configuration = Configuration() self.actions.append( RegularAction(operation=Forward(operand=InterfaceConfiguration( interface_id=InterfaceType.D7ASP, interface_configuration=interface_configuration))))
def test_parse(self): bytes = [ 0b00000000, 0, 0b00010000, 0 ] config = Configuration.parse(ConstBitStream(bytes=bytes)) self.assertEqual(config.qos.resp_mod, ResponseMode.RESP_MODE_NO) self.assertEqual(config.qos.nls, False) self.assertEqual(config.qos.stop_on_err, False) self.assertEqual(config.qos.record, False) self.assertEqual(config.addressee.id_type, IdType.NOID) self.assertEqual(config.addressee.nls_method, NlsMethod.NONE) self.assertEqual(config.addressee.access_class, 0)
def parse_forward_action(self, b7, b6, s): if b7: raise ParseError("bit 7 is RFU") interface_id = InterfaceType(int(s.read("uint:8"))) interface_config = None if (interface_id == InterfaceType.D7ASP): interface_config = Configuration.parse(s) elif (interface_id == InterfaceType.SERIAL): pass # no interface config else: assert (False) return ForwardAction(resp=b6, operation=Forward(operand=InterfaceConfiguration( interface_id=interface_id, interface_configuration=interface_config)))
def start(self): self.received_commands = defaultdict(list) payload = range(self.config.payload_size) if self.receiver_modem != None: addressee_id = int(self.receiver_modem.uid, 16) else: addressee_id = int(self.config.unicast_uid, 16) if self.transmitter_modem != None: print( "\n==> broadcast, with QoS, transmitter active access class = 0x01 ====" ) self.transmitter_modem.send_command( Command.create_with_write_file_action_system_file( DllConfigFile(active_access_class=0x01))) interface_configuration = Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ANY), addressee=Addressee( access_class=0x01, id_type=IdType.NBID, id=CT(exp=0, mant=1) # we expect one responder )) self.start_transmitting( interface_configuration=interface_configuration, payload=payload) self.wait_for_receiver(payload) print( "\n==> broadcast, no QoS, transmitter active access class = 0x01 ====" ) self.transmitter_modem.send_command( Command.create_with_write_file_action_system_file( DllConfigFile(active_access_class=0x01))) interface_configuration = Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO), addressee=Addressee(access_class=0x01, id_type=IdType.NOID)) self.start_transmitting( interface_configuration=interface_configuration, payload=payload) self.wait_for_receiver(payload) print( "\n==> unicast, with QoS, transmitter active access class = 0x01" ) interface_configuration = Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ANY), addressee=Addressee(access_class=0x01, id_type=IdType.UID, id=addressee_id)) self.start_transmitting( interface_configuration=interface_configuration, payload=payload) self.wait_for_receiver(payload) print( "\n==> unicast, no QoS, transmitter active access class = 0x01" ) interface_configuration = Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO), addressee=Addressee(access_class=0x01, id_type=IdType.UID, id=addressee_id)) self.start_transmitting( interface_configuration=interface_configuration, payload=payload) self.wait_for_receiver(payload) else: # receive only self.receiver_modem.start_reading() self.wait_for_receiver(payload)
configure_default_logger(config.verbose) modem = Modem(config.device, config.rate, unsolicited_response_received_callback=received_command_callback) modem.connect() # D7 Example interface_file = InterfaceConfigurationFile( interface_configuration=InterfaceConfiguration( interface_id=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_PREFERRED, retry_mod=RetryMode.RETRY_MODE_NO, stop_on_err=False, record=False), dorm_to=CT(), addressee=Addressee(nls_method=NlsMethod.NONE, id_type=IdType.UID, access_class=0x01, id=CT(mant=3, exp=0))))) # LORAWAN OTAA Example # interface_file = InterfaceConfigurationFile( # interface_configuration=InterfaceConfiguration( # interface_id=InterfaceType.LORAWAN_OTAA, # interface_configuration=LoRaWANInterfaceConfigurationOTAA( # adr_enabled=True, # request_ack=True, # app_port=2, # data_rate=0, # device_eui=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
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() logging.info("Executing query...") modem.execute_command_async( alp_command=Command.create_with_read_file_action( file_id=0x40, length=8, interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ALL), addressee=Addressee( access_class=0x11, id_type=IdType.NOID ) ) ) ) while True: sleep(5)
def bad(args, kwargs): Configuration(**kwargs)
def test_default_constructor(self): c = Configuration()
], file_a_offset=Offset(id=0x40, offset=Length(0)))))) # ...if the query succeeds, read the file query_sensor_file_cmd.add_action( RegularAction(operation=ReadFileData( operand=DataRequest(offset=Offset(id=0x40), length=Length(2))))) # the interface config to send the result of above action to interface_config = InterfaceConfiguration( InterfaceType.D7ASP, Configuration(qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO, retry_mod=RetryMode.RETRY_MODE_NO, stop_on_err=False, record=False), dorm_to=CT(), addressee=Addressee(access_class=0x01, id_type=IdType.NOID, id=None, nls_method=NlsMethod.NONE))) # create the command to write the action file and interface configuration file, # adapt the properties on the sensor file and forward using the downlink access profile cmd = Command() cmd.add_forward_action( InterfaceType.D7ASP, Configuration(qos=QoS(resp_mod=ResponseMode.RESP_MODE_ALL, retry_mod=RetryMode.RETRY_MODE_NO, stop_on_err=False, record=False), dorm_to=CT(),
print(list(emFile)) if not config.not_exe: modem = Modem(config.device, config.rate, unsolicited_response_received_callback=received_command_callback, rebooted_callback=rebooted_callback) modem.connect() cmd = Command() if config.forward: cmd.add_forward_action( interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_PREFERRED, retry_mod=RetryMode.RETRY_MODE_NO), addressee=Addressee( access_class=0x11, id_type=IdType.NBID, id=CT.compress(2) ) ) ) if (config.factory_gaussian != 0xFF) or (config.factory_paramp != 0xFF): if (config.factory_gaussian != 0xFF) or (config.factory_paramp != 0xFF): fact = FactorySettingsFile(gaussian=config.factory_gaussian, paramp=config.factory_paramp) elif config.factory_gaussian != 0xFF: fact = FactorySettingsFile(gaussian=config.factory_gaussian) else: fact = FactorySettingsFile(paramp=config.factory_paramp) cmd.add_action( RegularAction( operation=WriteFileData(
def on_mqtt_message(self, client, config, msg): try: payload = json.loads(msg.payload) uid = payload['device'] method = payload['data']['method'] request_id = payload['data']['id'] self.log.info( "Received RPC command of type {} for {} (request id {})". format(method, uid, request_id)) # if uid != self.modem.uid: # self.log.info("RPC command not for this modem ({}), skipping".format(self.modem.uid)) # return if method == "execute-alp-async": try: cmd = payload['data']['params'] self.log.info("Received command through RPC: %s" % cmd) self.modem.execute_command_async(cmd) self.log.info("Executed ALP command through RPC") # TODO when the command is writing local files we could read them again automatically afterwards, to make sure the digital twin is updated except Exception as e: self.log.exception("Could not deserialize: %s" % e) elif method == "alert": # TODO needs refactoring so different methods can be supported in a plugin, for now this is very specific case as an example self.log.info("Alert (payload={})".format(msg.payload)) if msg.payload != "true" and msg.payload != "false": self.log.info("invalid payload, skipping") return file_data = 0 if msg.payload == "true": file_data = 1 self.log.info("writing alert file") self.modem.execute_command_async( Command.create_with_write_file_action( file_id=0x60, offset=4, data=[file_data], interface_type=InterfaceType.D7ASP, interface_configuration=Configuration( qos=QoS(resp_mod=ResponseMode.RESP_MODE_ALL), addressee=Addressee(access_class=0x11, id_type=IdType.NOID)))) else: self.log.info("RPC method not supported, skipping") return except: exc_type, exc_value, exc_traceback = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_traceback) trace = "".join(lines) msg_info = "no msg info (missing __dict__ attribute)" # TODO because of out of date paho?? if hasattr(msg, '__dict__'): msg_info = str(msg.__dict__) self.log.error( "Exception while processing MQTT message: {} callstack:\n{}". format(msg_info, trace))
argparser.add_argument("-b", "--baudrate", help="baudrate for serial device", type=int, default=115200) config = argparser.parse_args() modem = Modem(config.serial, config.baudrate, show_logging=False) cmd = Command.create_with_return_file_data_action( file_id=0x40, data=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], interface_type=InterfaceType.D7ASP, interface_configuration=Configuration(qos=QoS(resp_mod=QoS.RESP_MODE_NO), addressee=Addressee( access_class=0, id_type=IdType.BCAST))) last_message = 0 sent = 0 received = 0 def stats(): print "sent", sent, "received", received while True: # Read from D7 modem and decode packets/commands (cmds, info) = modem.read()