def __parse_route(self, data): """ Parses the given bytearray and returns a route. Args: data (bytearray): Bytearray with data to parse. Returns: :class:`.Route`: The route or ``None`` if not found. """ # Bytes 0 - 1: 16-bit destination address (little endian) # Byte 2: Setting byte: # * Bits 0 - 2: Route status # * Bit 3: Low-memory concentrator flag # * Bit 4: Destination is a concentrator flag # * Bit 5: Route record message should be sent prior to next transmission flag # Bytes 3 - 4: 16 bit next hop address (little endian) return Route( XBee16BitAddress.from_bytes(data[1], data[0]), XBee16BitAddress.from_bytes(data[4], data[3]), RouteStatus.get( utils.get_int_from_byte(data[2], self.__class__.__ST_FIELD_OFFSET, self.__class__.__ST_FIELD_LEN)), utils.is_bit_enabled(data[2], self.__class__.__MEM_FIELD_OFFSET), utils.is_bit_enabled(data[2], self.__class__.__M2O_FIELD_OFFSET), utils.is_bit_enabled(data[2], self.__class__.__RR_FIELD_OFFSET))
def my_data_received_callback(self,xbee_message): address = xbee_message.remote_device.get_64bit_addr() data = xbee_message.data.decode("utf8") print("Received data from %s: %s" % (address, data)) #remote_dev = RemoteXBeeDevice(self.device, address) #self.device.send_data(remote_dev, "Hello XBee!") threading.Thread(target=self.append, args=[address,data]).start() ATcommand1 = RemoteATCommandPacket(1,address,XBee16BitAddress.from_hex_string("FFFE"),2,"P2",bytearray([0x05])) #raw1 = bytearray([0x7E,0x00,0x10,0x17,0x01,0x00,0x13,0xA2,0x00,0x41,0x47,0x9E,0xC1,0xFF,0xFE,0x02,0x50,0x32,0x05,0xC5]) #ATpacket1 = RemoteATCommandPacket.create_packet(raw1, OperatingMode.API_MODE) #self.device.send_packet(ATcommand1) #raw2 = bytearray([0x7E,0x00,0x10,0x17,0x01,0x00,0x13,0xA2,0x00,0x41,0x47,0x9E,0xC1,0xFF,0xFE,0x02,0x50,0x32,0x04,0xC6]) #ATpacket2 = RemoteATCommandPacket.create_packet(raw2, OperatingMode.API_MODE) ATcommand2 = RemoteATCommandPacket(1,address,XBee16BitAddress.from_hex_string("FFFE"),2,"P2",bytearray([0x04])) #self.device.send_packet(ATcommand2) ATcommand3 = RemoteATCommandPacket(1,address,XBee16BitAddress.from_hex_string("FFFE"),2,"D4",bytearray([0x05])) ATcommand4 = RemoteATCommandPacket(1,address,XBee16BitAddress.from_hex_string("FFFE"),2,"D4",bytearray([0x04])) for i in range(10): self.device.send_packet(ATcommand1) self.device.send_packet(ATcommand4) time.sleep(1) self.device.send_packet(ATcommand2) self.device.send_packet(ATcommand3) time.sleep(1)
def _is_valid_remote_at_response(self, packet): """ Checks if the provided packet is the remote AT command response packet that matches the sent package. Args: packet (:class:`.XBeeAPIPacket`): Packet to check. Returns: Boolean: `True` if packet is the remote AT command response packet corresponding to the sent package, `False` otherwise. """ # If the sent packet is a remote AT command, verify that the received # one is a remote AT command response and their commands match. return ( packet.get_frame_type() == ApiFrameType.REMOTE_AT_COMMAND_RESPONSE and self._packet.command.upper() == packet.command.upper() and (not XBee64BitAddress.is_known_node_addr( self._packet.x64bit_dest_addr) or self._packet.x64bit_dest_addr == packet.x64bit_source_addr) and (not XBee16BitAddress.is_known_node_addr( self._packet.x16bit_dest_addr) or not XBee16BitAddress.is_known_node_addr(packet.x16bit_source_addr) or self._packet.x16bit_dest_addr == packet.x16bit_source_addr))
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.CreateSourceRoutePacket`. Raises: InvalidPacketException: If the bytearray length is less than 18. (start delim. + length (2 bytes) + frame type + frame id + 64-bit addr. + 16-bit addr. + Route command options + num of addrs + hops 16-bit addrs + checksum = 18 bytes). InvalidPacketException: If the length field of `raw` is different from its real length. (length field: bytes 1 and 3) InvalidPacketException: If the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: If the calculated checksum is different from the checksum field value (last byte). InvalidPacketException: If the frame type is not :attr:`.ApiFrameType.CREATE_SOURCE_ROUTE`. InvalidPacketException: If the number of hops does not match with the number of 16-bit addresses. InvalidOperatingModeException: If `operating_mode` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode not in (OperatingMode.ESCAPED_API_MODE, OperatingMode.API_MODE): raise InvalidOperatingModeException(operating_mode.name + " is not supported.") XBeeAPIPacket._check_api_packet( raw, min_length=CreateSourceRoutePacket.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.CREATE_SOURCE_ROUTE.code: raise InvalidPacketException( "This packet is not a Create Source Route packet.") hops = [ XBee16BitAddress(raw[i:i + 2]) for i in range(17, len(raw) - 1, 2) ] if raw[16] != len(hops): raise InvalidPacketException("Specified number of hops does not" "match with the length of addresses.") return CreateSourceRoutePacket(raw[4], XBee64BitAddress(raw[5:13]), XBee16BitAddress(raw[13:15]), raw[15], hops, op_mode=operating_mode)
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.RouteRecordIndicatorPacket`. Raises: InvalidPacketException: If the bytearray length is less than 17. (start delim. + length (2 bytes) + frame type + 64bit addr. + 16bit addr. + Receive options + num of addrs + checksum = 17 bytes). InvalidPacketException: If the length field of `raw` is different from its real length. (length field: bytes 1 and 3) InvalidPacketException: If the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: If the calculated checksum is different from the checksum field value (last byte). InvalidPacketException: If the frame type is not :attr:`.ApiFrameType.ROUTE_RECORD_INDICATOR`. InvalidPacketException: If the number of hops does not match with the number of 16-bit addresses. InvalidOperatingModeException: If `operating_mode` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode not in (OperatingMode.ESCAPED_API_MODE, OperatingMode.API_MODE): raise InvalidOperatingModeException(operating_mode.name + " is not supported.") XBeeAPIPacket._check_api_packet( raw, min_length=RouteRecordIndicatorPacket.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.ROUTE_RECORD_INDICATOR.code: raise InvalidPacketException( "This packet is not a Route Record Indicator packet.") hops = [ XBee16BitAddress(raw[i:i + 2]) for i in range(16, len(raw) - 1, 2) ] if raw[15] != len(hops): raise InvalidPacketException("Specified number of hops does not" "match with the length of addresses.") return RouteRecordIndicatorPacket(XBee64BitAddress(raw[4:12]), XBee16BitAddress(raw[12:14]), raw[14], hops, op_mode=operating_mode)
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.TX16Packet`. Raises: InvalidPacketException: if the bytearray length is less than 9. (start delim. + length (2 bytes) + frame type + frame id + 16bit addr. + transmit options + checksum = 9 bytes). InvalidPacketException: if the length field of 'raw' is different than its real length. (length field: bytes 2 and 3) InvalidPacketException: if the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: if the calculated checksum is different than the checksum field value (last byte). InvalidPacketException: if the frame type is different than :attr:`.ApiFrameType.TX_16`. InvalidOperatingModeException: if ``operating_mode`` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode != OperatingMode.ESCAPED_API_MODE and operating_mode != OperatingMode.API_MODE: raise InvalidOperatingModeException(op_mode=operating_mode) XBeeAPIPacket._check_api_packet( raw, min_length=TX16Packet.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.TX_16.code: raise InvalidPacketException( message="This packet is not a TX 16 packet.") return TX16Packet(raw[4], XBee16BitAddress(raw[5:7]), raw[7], rf_data=raw[8:-1])
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.RX16Packet`. Raises: InvalidPacketException: if the bytearray length is less than 9. (start delim. + length (2 bytes) + frame type + 16bit addr. + rssi + receive options + checksum = 9 bytes). InvalidPacketException: if the length field of 'raw' is different than its real length. (length field: bytes 2 and 3) InvalidPacketException: if the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: if the calculated checksum is different than the checksum field value (last byte). InvalidPacketException: if the frame type is different than :attr:`.ApiFrameType.RX_16`. InvalidOperatingModeException: if ``operating_mode`` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode != OperatingMode.ESCAPED_API_MODE and operating_mode != OperatingMode.API_MODE: raise InvalidOperatingModeException(operating_mode.name + " is not supported.") raw = XBeeAPIPacket._unescape_data( raw) if operating_mode == OperatingMode.ESCAPED_API_MODE else raw XBeeAPIPacket._check_api_packet( raw, min_length=RX16Packet.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.RX_16.code: raise InvalidPacketException("This packet is not an RX 16 Packet") return RX16Packet(XBee16BitAddress(raw[4:6]), raw[6], raw[7], raw[8:-1])
def reset(self): self.id = "unknown" self.address = XBee16BitAddress.from_hex_string("0x0000") self.received_count = 0 self.sent_count = 0 self.remote = None self.runtime = 0
def _refresh_if_cached(self, node, parameter, value, apply=True): """ Refreshes the proper cached parameter depending on `parameter` value. If `parameter` is not a cached parameter, this method does nothing. Args: node (:class:`.AbstractXBeeDevice`): The XBee to refresh. parameter (String): the parameter to refresh its value. value (Bytearray): the new value of the parameter. apply (Boolean, optional, default=`True`): `True` to apply immediately, `False` otherwise. """ updated = False param = parameter.upper() key = str(node.get_64bit_addr()) if key not in self._future_apply: self._future_apply[key] = {} node_fut_apply = self._future_apply.get(key, {}) # Node identifier if param == ATStringCommand.NI.command: node_id = str(value, encoding='utf8', errors='ignore') changed = node.get_node_id() != node_id updated = changed and apply if updated: node._node_id = node_id node_fut_apply.pop(param, None) elif changed: node_fut_apply.update({param: value}) # 16-bit address elif param == ATStringCommand.MY.command: x16bit_addr = XBee16BitAddress(value) changed = node.get_16bit_addr() != x16bit_addr updated = changed and apply if updated: node._16bit_addr = x16bit_addr node_fut_apply.pop(param, None) elif changed: node_fut_apply.update({param: value}) elif not node.is_remote(): updated = self._refresh_serial_params(node, param, value, apply=apply) if updated: network = node.get_local_xbee_device().get_network() if node.is_remote() \ else node.get_network() if (network and (not node.is_remote() or network.get_device_by_64(node.get_64bit_addr()) or network.get_device_by_16(node.get_16bit_addr()))): from digi.xbee.devices import NetworkEventType, NetworkEventReason network._network_modified(NetworkEventType.UPDATE, NetworkEventReason.READ_INFO, node=node)
def __init__(self, port_name, remote_addr, callback_var): self.con_device = XBD.XBeeDevice(port_name, BAUD_RATE) self.remote_device = XBD.RemoteXBeeDevice(self.con_device, XBee16BitAddress.from_hex_string(remote_addr)) self.callback = callback_var self.running = False self.con_device.open() self.con_device.flush_queues()
def mandar_mensage(self, dir_64, msg=PING, dir_16=None) -> TransmitStatusPacket: """ Manda el mensaje al destinatario por defecto. """ ack = None # Transformamos el mensaje recibido en un string tratable msg = str(msg) # Recuperamos la dirección del dispositivo remoto en formato de 64 bits high = None try: dir_64 = XBee64BitAddress.from_hex_string(dir_64) high = dir_64 or self.remote_zigbee.get_64bit_addr() except: high = XBee64BitAddress.UNKNOWN_ADDRESS # Recuperamos la dirección del dispositivo remoto en 16 bits o la marcamos como desconocida low = None try: low = XBee16BitAddress.from_hex_string( dir_16) or self.remote_zigbee.get_16bit_addr() except: low = XBee16BitAddress.UNKNOWN_ADDRESS try: # Intentamos mandar el mensaje ## Versión fragmentando el paquete ## Versión sin fragmentar el paquete ack = super().send_data_64_16(high, low, msg) # self.logger.debug(format(ack)) if ack.transmit_status is not TransmitStatus.SUCCESS: self.logger.warning( "Algo no fue bien mandando el mensaje:\n{}\nError:\t{}". format(msg, ack)) except Exception as e: error = "Se ha encontrado un error al mandar el mensaje\n\t" + str( e) self.logger.error(error) raise EOFError(error) # ack = super().send_data_64_16(high, low, msg) # Añadir código para el reintento else: # TODO Borrar esta traza de control self.logger.debug("Mandado mensaje:\t" + msg) return ack
def hops(self, hops): """ Sets the hops of the route (excluding source and destination). Args: hops (List): List of `XBee16BitAddress`. .. seealso:: | :class:`.XBee16BitAddress` """ if hops is None: self.__hops = None else: self.__hops = \ [XBee16BitAddress(hops[i].address) for i in range(len(hops))]
def __parse_neighbor(self, data): """ Parses the given bytearray and returns a neighbor. Args: data (bytearray): Bytearray with data to parse. Returns: :class:`.Neighbor`: The neighbor or ``None`` if not found. """ # Bytes 0 - 7: Extended PAN ID (little endian) # Bytes 8 - 15: 64-bit neighbor address (little endian) # Bytes 16 - 17: 16-bit neighbor address (little endian) # Byte 18: First setting byte: # * Bit 0 - 1: Neighbor role # * Bit 2 - 3: Receiver on when idle (indicates if the neighbor's receiver is # enabled during idle times) # * Bit 4 - 6: Relationship of this neighbor with the node # * Bit 7: Reserved # Byte 19: Second setting byte: # * Bit 0 - 1: Permit joining (indicates if the neighbor accepts join requests) # * Bit 2 - 7: Reserved # Byte 20: Depth (Tree depth of the neighbor. A value of 0 indicates the neighbor is the # coordinator) # Byte 21: LQI (The estimated link quality of data transmissions from this neighbor) x64 = XBee64BitAddress.from_bytes(*data[8:16][::-1]) x16 = XBee16BitAddress.from_bytes(data[17], data[16]) role = Role.get( utils.get_int_from_byte(data[18], self.__class__.__ROLE_FIELD_OFFSET, self.__class__.__ROLE_FIELD_LEN)) relationship = NeighborRelationship.get( utils.get_int_from_byte(data[18], self.__class__.__RELATIONSHIP_FIELD_OFFSET, self.__class__.__RELATIONSHIP_FIELD_LEN)) depth = int(data[20]) lqi = int(data[21]) if not self._xbee.is_remote(): xb = self._xbee else: xb = self._xbee.get_local_xbee_device() # Create a new remote node n_xb = RemoteZigBeeDevice(xb, x64bit_addr=x64, x16bit_addr=x16) n_xb._role = role return Neighbor(n_xb, relationship, depth, lqi)
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.OTAFirmwareUpdateStatusPacket`. Raises: InvalidPacketException: if the bytearray length is less than 17. (start delim. + length (2 bytes) + frame type + source 64bit addr. (8 bytes) + updater 16bit addr. (2 bytes) + receive options + bootloader message type + block number + source 64bit addr. (8 bytes) + checksum = 27 bytes). InvalidPacketException: if the length field of 'raw' is different from its real length. (length field: bytes 1 and 3) InvalidPacketException: if the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: if the calculated checksum is different from the checksum field value (last byte). InvalidPacketException: if the frame type is not :attr:`.ApiFrameType.OTA_FIRMWARE_UPDATE_STATUS`. InvalidOperatingModeException: if `operating_mode` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode not in (OperatingMode.ESCAPED_API_MODE, OperatingMode.API_MODE): raise InvalidOperatingModeException(operating_mode.name + " is not supported.") XBeeAPIPacket._check_api_packet( raw, min_length=OTAFirmwareUpdateStatusPacket.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.OTA_FIRMWARE_UPDATE_STATUS.code: raise InvalidPacketException( "This packet is not an OTA Firmware Update Status packet.") return OTAFirmwareUpdateStatusPacket(XBee64BitAddress(raw[4:12]), XBee16BitAddress(raw[12:14]), raw[14], EmberBootloaderMessageType.get( raw[15]), raw[16], XBee64BitAddress(raw[17:25]), op_mode=operating_mode)
def _parse_data(self, data): """ Override. .. seealso:: | :meth:`.__ZDOCommand._parse_data` """ # Ensure the 16-bit address received matches the address of the device x16 = XBee16BitAddress.from_bytes(data[1], data[0]) if x16 != self._xbee.get_16bit_addr(): return False # Role field: 3 bits (0, 1, 2) of the next byte role = Role.get(utils.get_int_from_byte(data[2], 0, 3)) # Complex descriptor available: next bit (3) of the same byte complex_desc_available = utils.is_bit_enabled(data[2], 3) # User descriptor available: next bit (4) of the same byte user_desc_available = utils.is_bit_enabled(data[2], 4) # Frequency band: 5 bits of the next byte freq_band = NodeDescriptorReader.__to_bits(data[3])[-5:] # MAC capabilities: next byte mac_capabilities = NodeDescriptorReader.__to_bits(data[4]) # Manufacturer code: next 2 bytes manufacturer_code = utils.bytes_to_int([data[6], data[5]]) # Maximum buffer size: next byte max_buffer_size = int(data[7]) # Maximum incoming transfer size: next 2 bytes max_in_transfer_size = utils.bytes_to_int([data[9], data[8]]) # Maximum outgoing transfer size: next 2 bytes max_out_transfer_size = utils.bytes_to_int([data[13], data[12]]) # Maximum outgoing transfer size: next byte desc_capabilities = NodeDescriptorReader.__to_bits(data[14]) self.__node_descriptor = NodeDescriptor(role, complex_desc_available, user_desc_available, freq_band, mac_capabilities, manufacturer_code, max_buffer_size, max_in_transfer_size, max_out_transfer_size, desc_capabilities) return True
def hops(self): """ Returns the list of intermediate hops starting from the closest to destination hop and finishing with the closest to the source (excluding source and destination). Returns: List: The list of 16-bit addresses of intermediate hops. .. seealso:: | :class:`.XBee16BitAddress` """ if not self.__hops: return [] return [ XBee16BitAddress(self.__hops[i].address) for i in range(len(self.__hops)) ]
def create_packet(raw, operating_mode): """ Override method. Returns: :class:`.RX16IOPacket`. Raises: InvalidPacketException: if the bytearray length is less than 14. (start delim. + length (2 bytes) + frame type + 16bit addr. + rssi + receive options + rf data (5 bytes) + checksum = 14 bytes). InvalidPacketException: if the length field of 'raw' is different from its real length. (length field: bytes 2 and 3) InvalidPacketException: if the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: if the calculated checksum is different from the checksum field value (last byte). InvalidPacketException: if the frame type is different from :attr:`.ApiFrameType.RX_IO_16`. InvalidOperatingModeException: if `operating_mode` is not supported. .. seealso:: | :meth:`.XBeePacket.create_packet` | :meth:`.XBeeAPIPacket._check_api_packet` """ if operating_mode not in (OperatingMode.ESCAPED_API_MODE, OperatingMode.API_MODE): raise InvalidOperatingModeException(op_mode=operating_mode) XBeeAPIPacket._check_api_packet( raw, min_length=RX16IOPacket.__MIN_PACKET_LENGTH) if raw[3] != ApiFrameType.RX_IO_16.code: raise InvalidPacketException( message="This packet is not an RX 16 IO packet.") return RX16IOPacket(XBee16BitAddress(raw[4:6]), raw[6], raw[7], raw[8:-1], op_mode=operating_mode)
''' Created on Feb 18, 2019 @author: Jake ''' from digi.xbee.devices import XBeeDevice, RemoteXBeeDevice import RobotInstruction from builtins import input from digi.xbee.models.address import XBee16BitAddress, XBee64BitAddress COMport = 'COM9' baud_rate = 9600 remote_address = '0008' transmitDevice = XBeeDevice(COMport,baud_rate) remoteDevice = RemoteXBeeDevice(transmitDevice, XBee64BitAddress.from_hex_string(remote_address), XBee16BitAddress.from_hex_string(remote_address)) def main(): transmitDevice.close() print('transmitting to: ') print(remoteDevice.get_16bit_addr()) cont = 'y' while(cont != 'q'): try: transmitDevice.open() instruction = getCommand() #print(hex(instruction)) sendInstructions(instruction)
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from digi.xbee.devices import RemoteXBeeDevice, XBeeDevice from digi.xbee.models.address import XBee64BitAddress, XBee16BitAddress # TODO: Replace with the serial port where your local module is connected to. PORT = "COM1" # TODO: Replace with the baud rate of your local module. BAUD_RATE = 9600 ADDR_64_REMOTE_A = XBee64BitAddress.from_hex_string("0013A200AAAAAAAA") ADDR_64_REMOTE_B = XBee64BitAddress.from_hex_string("0013A200BBBBBBBB") ADDR_16_REMOTE_A = XBee16BitAddress.from_hex_string("AAAA") ADDR_16_REMOTE_A_2 = XBee16BitAddress.from_hex_string("BBBB") NODE_ID_REMOTE_A = "TEST" def main(): print(" +---------------------------------+") print(" | Add Devices to the Network Test |") print(" +---------------------------------+\n") device = XBeeDevice(PORT, BAUD_RATE) try: device.open()
from digi.xbee.models.message import XBeeMessage from digi.xbee.models.address import XBee16BitAddress, XBee64BitAddress from DisplayManager import DisplayManager import sys try: COMport = sys.argv[1] except IndexError: COMport = 'COM9' baud_rate = 9600 remote_address = '0010' transmitDevice = XBeeDevice(COMport, baud_rate) remoteDevice = RemoteXBeeDevice( transmitDevice, XBee64BitAddress.from_hex_string(remote_address), XBee16BitAddress.from_hex_string(remote_address)) def main(): xbeeCommunication() def xbeeCommunication(): transmitDevice.close() print('transmitting to: ') print(remoteDevice.get_16bit_addr()) cont = 'y' pb = PB.PathBuilder() while (cont != 'n'):
def run_server(): """ Xbee Server :return: """ # INIT SERVER print("starting run_server...") UpdaWear.reset() MessageBuffer.clear() server = Raw802Device(PORT, BAUD_RATE) UpdaWear.id = "UPDA-WEAR-1" UpdaWear.address = XBee16BitAddress.from_hex_string(WEAR_16B_ADDR) UpdaWear.remote = RemoteRaw802Device(server, UpdaWear.address) instance_manager = None exit_message = bytearray([0x05, 0x00]) try: # might not want this if not os.path.exists('./data'): print("unable to find './data' to store information") raise KeyboardInterrupt # get data count to make a new file num_patients = len([name for name in os.listdir('./data')]) instance_manager = InstanceLoader(num_patients) instance_manager.start() # start the thread server.open() def msg_callback(message): UpdaWear.received_count = UpdaWear.received_count + 1 # register the device # print("{} >> {}".format(server.get_16bit_addr(), message.data.decode())) # pass information off to a buffer # store the data (byte array) with BufferLock: MessageBuffer.append(message.data) server.add_data_received_callback(msg_callback) print("press enter to stop run_server...") input() except KeyboardInterrupt: print() # add a space so everything is nearly on a different line except serial.serialutil.SerialException: print("Unable to open {}".format(PORT)) finally: if instance_manager is not None: # close instance manager with BufferLock: MessageBuffer.append(exit_message) instance_manager.join() if server is not None and server.is_open(): server.close() print("closing run_server...")