def test_byte_generation(self): expected = [ 0, # channel_header 16, 0, # channel_id 70, # rxlevel (- dBm) 80, # link budget 80, # target rx level 0, # status 100, # fifo token 0, # seq 20, # response timeout 16 # addressee ctrl (BCAST) ] bytes = bytearray(Status( channel_header=0, channel_index=16, rx_level=70, link_budget=80, target_rx_level=80, nls=False, missed=False, retry=False, unicast=False, fifo_token=100, seq_nr=0, response_to=CT(0, 20), addressee=Addressee() )) self.assertEqual(len(bytes), 11) for i in xrange(10): self.assertEqual(expected[i], bytes[i]) bytes = bytearray(Status( channel_header=0, channel_index=16, rx_level=70, link_budget=80, target_rx_level=80, unicast=False, fifo_token=100, seq_nr=0, response_to=CT(0, 20), addressee=Addressee(), nls=True, missed=True, retry=True)) expected[6] = int('11100000', 2) # nls, missed, retry, ucast self.assertEqual(len(bytes), 11) for i in xrange(10): self.assertEqual(expected[i], bytes[i])
def set_gps(GPS): characters = [0x80, 0x81] # 0 = GPS off -> 0x30, 1 = GPS on -> 0x31 cmd = Command.create_with_return_file_data_action( 0x40, [0x0A, 0x32, characters[GPS], 0X0D], InterfaceType.D7ASP, D7Config(addressee=Addressee(access_class=0x11, id_type=IdType.NOID))) execute_rpc_command("<gateway ID>", cmd) debug("GPS was set to " + str(GPS) + " through RPC") push_to_tb({"gps": GPS}) for i in range(0, 20): cmd = Command.create_with_return_file_data_action( 0x40, [0x0A, 0x32, characters[GPS], 0X0D], InterfaceType.D7ASP, D7Config( addressee=Addressee(access_class=0x11, id_type=IdType.NOID))) time.sleep(0.5)
def parse_alp_interface_status_d7asp(self, s): channel_header = s.read("uint:8") # TODO parse channel_index = struct.unpack(">h", s.read("bytes:2"))[0] rx_level = s.read("int:8") link_budget = s.read("uint:8") target_rx_level = s.read("uint:8") nls = s.read("bool") missed = s.read("bool") retry = s.read("bool") unicast = s.read("bool" ) _ = s.read("pad:4") fifo_token = s.read("uint:8") seq_nr = s.read("uint:8") response_to = CT.parse(s) addressee = Addressee.parse(s) status = Status(channel_header=channel_header, channel_index=channel_index, rx_level=rx_level, link_budget=link_budget, target_rx_level=target_rx_level, nls=nls, missed=missed, retry=retry, unicast=unicast, fifo_token=fifo_token, seq_nr=seq_nr, response_to=response_to, addressee=addressee) return InterfaceStatus( operand=InterfaceStatusOperand(interface_id=0xd7, interface_status=status) )
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 run(self): # cmd = Command.create_with_return_file_data_action(file_id, data, interface_type=InterfaceType.HOST,interface_configuration=None) cmd = Command.create_with_return_file_data_action( file_id=40, data=[0x31, 0x41, 0x45], interface_type=InterfaceType.D7ASP, interface_configuration=D7config( qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO), addressee=Addressee(access_class=0x11, id_type=IdType.NOID))) # cmd = {0x32, 0xd7, 0x01, 0x00, 0x10, 0x01, 0x20, 0x01, 0x00} # cmd = {0x011} self.execute_rpc_command(self.config.device, cmd) print("Send 1") self.update_progress(0) sleep(1) self.update_progress(20) sleep(1) self.update_progress(40) sleep(1) self.update_progress(60) sleep(1) self.update_progress(80) sleep(1) self.update_progress(100) self.execute_rpc_command(self.config.device, cmd) print() print("Send 2")
def parse_alp_interface_status_d7asp(self, s): channel_header = ChannelHeader.parse(s) channel_index = struct.unpack(">h", s.read("bytes:2"))[0] rx_level = s.read("int:8") link_budget = s.read("uint:8") target_rx_level = s.read("uint:8") nls = s.read("bool") missed = s.read("bool") retry = s.read("bool") unicast = s.read("bool") _ = s.read("pad:4") fifo_token = s.read("uint:8") seq_nr = s.read("uint:8") response_to = CT.parse(s) addressee = Addressee.parse(s) status = Status(channel_header=channel_header, channel_index=channel_index, rx_level=rx_level, link_budget=link_budget, target_rx_level=target_rx_level, nls=nls, missed=missed, retry=retry, unicast=unicast, fifo_token=fifo_token, seq_nr=seq_nr, response_to=response_to, addressee=addressee) return InterfaceStatus(operand=InterfaceStatusOperand( interface_id=0xd7, interface_status=status))
def execute_rpc_command(device_id, data): json_alp_cmd = Command.create_with_return_file_data_action( file_id=40, data=data, interface_type=InterfaceType.D7ASP, interface_configuration=D7config( qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO), addressee=Addressee(access_class=0x11, id_type=IdType.NOID))) # we will do it by a manual POST to /api/plugins/rpc/oneway/ , which is the route specified # in the documentation cmd = { "method": "execute-alp-async", "params": jsonpickle.encode(json_alp_cmd), "timeout": 500 } path_params = {'deviceId': device_id} query_params = {} header_params = {} header_params['Accept'] = api_client.select_header_accept(['*/*']) header_params['Content-Type'] = api_client.select_header_content_type( ['application/json']) # Authentication setting auth_settings = ['X-Authorization'] return api_client.call_api('/api/plugins/rpc/oneway/{deviceId}', 'POST', path_params, query_params, header_params, body=cmd, post_params=[], files={}, response_type='DeferredResultResponseEntity', auth_settings=auth_settings, async=False)
def test_simple_received_return_file_data_command(self): cmd = Command( generate_tag_request_action=False, actions=[ RegularAction(operation=ReturnFileData( operand=Data(data=list(bytearray("Hello world")), offset=Offset(id=0x51)))), StatusAction( status_operand_extension=StatusActionOperandExtensions. INTERFACE_STATUS, operation=InterfaceStatus(operand=InterfaceStatusOperand( interface_id=0xD7, interface_status=D7ASpStatus(channel_header=0, channel_index=16, rx_level=70, link_budget=80, target_rx_level=80, nls=False, missed=False, retry=False, unicast=False, fifo_token=200, seq_nr=0, response_to=CT(mant=20), addressee=Addressee())))) ]) expected = [ 0x62, # Interface Status action 0xD7, # D7ASP interface 0, # channel header 16, 0, # channel_id 70, # rxlevel (- dBm) 80, # link budget 80, # target rx level 0, # status 200, # fifo token 0, # seq 20, # response timeout 16, # addressee ctrl (BCAST) 0x20, # action=32/ReturnFileData 0x51, # File ID 0x00, # offset 0x0b, # length 0x48, 0x65, 0x6c, 0x6c, 0x6f, # Hello 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 # World ] bytes = bytearray(cmd) self.assertEqual(len(bytes), len(expected)) for i in xrange(len(expected)): self.assertEqual(bytes[i], expected[i])
def parse(s): channel_header = ChannelHeader.parse(s) channel_index = s.read("uint:16") rx_level = s.read("int:8") link_budget = s.read("uint:8") target_rx_level = s.read("uint:8") nls = s.read("bool") missed = s.read("bool") retry = s.read("bool") unicast = s.read("bool") _ = s.read("pad:4") fifo_token = s.read("uint:8") seq_nr = s.read("uint:8") response_to = CT.parse(s) addressee = Addressee.parse(s) return Status(channel_header=channel_header, channel_index=channel_index, rx_level=rx_level, link_budget=link_budget, target_rx_level=target_rx_level, nls=nls, missed=missed, retry=retry, unicast=unicast, fifo_token=fifo_token, seq_nr=seq_nr, response_to=response_to, addressee=addressee)
def test_byte_generation(self): tests = [ (Addressee(), '00010000'), # NOID (Addressee(id_type=IdType.NBID, id=CT(0)), '00000000'), (Addressee(id_type=IdType.VID, id=0), '00110000'), (Addressee(id_type=IdType.UID, id=0), '00100000'), (Addressee(id_type=IdType.NBID, id=CT(0), nls_method=NlsMethod.AES_CTR), '00000001') ] for test in tests: addressee_ctrl = bytearray(test[0])[0] self.assertEqual(addressee_ctrl, int(test[1], 2)) bs = bytearray(Addressee(id_type=IdType.VID, id=0x1234, access_class=5)) self.assertEqual(len(bs), 4) self.assertEqual(bs[0], int('00110000', 2)) self.assertEqual(bs[1], 5) self.assertEqual(bs[2], int('00010010', 2)) self.assertEqual(bs[3], int('00110100', 2)) bs = bytearray( Addressee(id_type=IdType.UID, id=0x1234567890123456, access_class=5)) self.assertEqual(len(bs), 10) self.assertEqual(bs[0], int('00100000', 2)) self.assertEqual(bs[1], 5) self.assertEqual(bs[2], int('00010010', 2)) self.assertEqual(bs[3], int('00110100', 2)) self.assertEqual(bs[4], int('01010110', 2)) self.assertEqual(bs[5], int('01111000', 2)) self.assertEqual(bs[6], int('10010000', 2)) self.assertEqual(bs[7], int('00010010', 2)) self.assertEqual(bs[8], int('00110100', 2)) self.assertEqual(bs[9], int('01010110', 2)) bs = bytearray( Addressee(id_type=IdType.NOID, access_class=5, nls_method=NlsMethod.AES_CBC_MAC_128)) self.assertEqual(len(bs), 2) self.assertEqual(bs[0], int('00010010', 2)) self.assertEqual(bs[1], 5) bs = bytearray(Addressee(id_type=IdType.NBID, id=CT.compress(100))) self.assertEqual(len(bs), 3) self.assertEqual(bs[0], int('00000000', 2)) self.assertEqual(bs[1], 0) self.assertEqual(bs[2], 0x39)
def test_byte_generation_with_overload(self): indirect_forward_action = IndirectForward( operand=IndirectInterfaceOperand( interface_file_id=0x40, interface_configuration_overload=Addressee())) bytes = bytearray(indirect_forward_action) self.assertEqual(len(bytes), 3) self.assertEqual(bytes[0], 0x40)
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): tests = [(Addressee(), '00010000'), (Addressee(id_type=IdType.VID, id=0), '00110000'), (Addressee(id_type=IdType.UID, id=0), '00100000'), (Addressee(id_type=IdType.VID, id=0, access_class=15), '00111111')] for test in tests: addressee_ctrl = bytearray(test[0])[0] self.assertEqual(addressee_ctrl, int(test[1], 2)) bs = bytearray(Addressee(id_type=IdType.VID, id=0x1234)) self.assertEqual(len(bs), 3) self.assertEqual(bs[0], int('00110000', 2)) self.assertEqual(bs[1], int('00010010', 2)) self.assertEqual(bs[2], int('00110100', 2)) bs = bytearray(Addressee(id_type=IdType.UID, id=0x1234567890123456)) self.assertEqual(len(bs), 9) self.assertEqual(bs[0], int('00100000', 2)) self.assertEqual(bs[1], int('00010010', 2)) self.assertEqual(bs[2], int('00110100', 2)) self.assertEqual(bs[3], int('01010110', 2)) self.assertEqual(bs[4], int('01111000', 2)) self.assertEqual(bs[5], int('10010000', 2)) self.assertEqual(bs[6], int('00010010', 2)) self.assertEqual(bs[7], int('00110100', 2)) self.assertEqual(bs[8], int('01010110', 2))
def parse_indirect_forward_action(self, b7, b6, s): interface_file_id = int(s.read("uint:8")) overload = b7 overload_config = None if overload: # TODO we are assuming D7ASP interface here overload_config = Addressee.parse(s) return IndirectForwardAction( overload=overload, resp=b6, operation=IndirectForward(operand=IndirectInterfaceOperand( interface_file_id=interface_file_id, interface_configuration_overload=overload_config)))
def test_get_short_channel_string(self): s = Status(channel_header=self.valid_channel_header, channel_index=16, rx_level=70, link_budget=80, target_rx_level=80, nls=False, missed=False, retry=False, unicast=False, fifo_token=100, seq_nr=0, response_to=CT(0, 20), addressee=Addressee()) self.assertEqual(s.get_short_channel_string(), "433N016")
def run(self): # cmd = Command.create_with_return_file_data_action(file_id, data, interface_type=InterfaceType.HOST,interface_configuration=None) cmd = Command.create_with_return_file_data_action(file_id=40, data=[0x03], interface_type=InterfaceType.D7ASP, interface_configuration=D7config( qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO), addressee=Addressee(access_class=0x11, id_type=IdType.NOID))) #cmd = {0x32, 0xd7, 0x01, 0x00, 0x10, 0x01, 0x20, 0x01, 0x00} # cmd = {0x011} for x in range(5): print("Alert {} to node".format(x)) try: ThingsBoard.execute_rpc_command(self.config.gateway1, [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31]) except: print("Gateway {} not reached.".format(self.config.gateway1)) sleep(0.5) try: ThingsBoard.execute_rpc_command(self.config.gateway2, [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31]) except: print("Gateway {} not reached.".format(self.config.gateway2)) sleep(0.5) try: ThingsBoard.execute_rpc_command(self.config.gateway3, [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31]) except: print("Gateway {} not reached.".format(self.config.gateway3)) sleep(0.5) try: ThingsBoard.execute_rpc_command(self.config.gateway4, [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31]) except: print("Gateway {} not reached.".format(self.config.gateway4)) sleep(1)
def test_id_type_property(self): addr = Addressee() self.assertEqual(addr.id_type, IdType.NOID)
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], # app_eui=[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01], # app_key=[0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F] # )
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)
def __init__(self, qos=QoS(), dorm_to=CT(), addressee=Addressee()): self.qos = qos self.dorm_to = dorm_to self.addressee = addressee super(Configuration, self).__init__()
def parse(s): qos = QoS.parse(s) dorm_to = CT.parse(s) addressee = Addressee.parse(s) return Configuration(qos=qos, dorm_to=dorm_to, addressee=addressee)
def test_simple_received_return_file_data_command_with_tag_request(self): cmd = Command( tag_id=25, actions=[ RegularAction(operation=ReturnFileData( operand=Data(data=list(bytearray("Hello world")), offset=Offset(id=0x51)))), StatusAction( status_operand_extension=StatusActionOperandExtensions. INTERFACE_STATUS, operation=InterfaceStatus(operand=InterfaceStatusOperand( interface_id=0xD7, interface_status=D7ASpStatus(channel_id=ChannelID( channel_header=ChannelHeader( channel_band=ChannelBand.BAND_433, channel_class=ChannelClass.LO_RATE, channel_coding=ChannelCoding.PN9), channel_index=16), rx_level=70, link_budget=80, target_rx_level=80, nls=False, missed=False, retry=False, unicast=False, fifo_token=200, seq_nr=0, response_to=CT(mant=20), addressee=Addressee())))) ]) expected = [ 0xB4, # tag request with send response bit set 25, # tag ID 0x62, # Interface Status action 0xD7, # D7ASP interface 32, # channel header 0, 16, # channel_id 70, # rxlevel (- dBm) 80, # link budget 80, # target rx level 0, # status 200, # fifo token 0, # seq 20, # response timeout 0x10, # addressee ctrl (NOID) 0, # access class 0x20, # action=32/ReturnFileData 0x51, # File ID 0x00, # offset 0x0b, # length 0x48, 0x65, 0x6c, 0x6c, 0x6f, # Hello 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 # World ] bytes = bytearray(cmd) self.assertEqual(len(bytes), len(expected)) for i in xrange(len(expected)): self.assertEqual(bytes[i], expected[i])
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)
pprint(command.as_dict()) print("serial frame:") print(binascii.hexlify(serial_frame).decode("ascii")) output_serial_frame( "Return file data, with QoS, unicast", 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=ResponseMode.RESP_MODE_ALL), addressee=Addressee( access_class=0, id_type=IdType.UID, id=2656824718681607041 # TODO hex string )))) output_serial_frame( "Return file data, with QoS, broadcast", 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=ResponseMode.RESP_MODE_ALL), addressee=Addressee(access_class=2, id_type=IdType.NOID)))) output_serial_frame( "Return file data, without QoS, broadcast",
def test_id_length_of_virtual_id(self): addr = Addressee(id_type=IdType.VID, id=0x0) self.assertEqual(addr.id_length, 2)
def test_id_length_of_noid(self): addr = Addressee(id_type=IdType.NOID, id=None) self.assertEqual(addr.id_length, 0)
def bad(): addr = Addressee(id_type=IdType.NOID, id=CT(0))
def bad(): addr = Addressee(id_type=IdType.VID, id=-1)
def test_id_property(self): addr = Addressee(id_type=IdType.VID, id=0x1234) self.assertEqual(addr.id, 0x1234)
def test_access_class_property(self): addr = Addressee(access_class=0xF) self.assertEqual(addr.access_class, 0xF)
def test_id_length_of_universal_id(self): addr = Addressee(id_type=IdType.UID, id=0x0) self.assertEqual(addr.id_length, 8)