def test_temperature(): TEMPERATURE = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x00, 0x00, 0x55, 0x08, 0x01, 0x81, 0xB7, 0x44, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x5C ]) packet = RadioPacket.create(rorg=RORG.BS4, rorg_func=0x02, rorg_type=0x05, sender=[0x01, 0x81, 0xB7, 0x44], TMP=26.66666666666666666666666666666666666666666667) packet_serialized = packet.build() assert len(packet_serialized) == len(TEMPERATURE) assert list(packet_serialized) == list(TEMPERATURE) assert packet.learn is False TEMPERATURE = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x00, 0x00, 0x55, 0x00, 0x01, 0x81, 0xB7, 0x44, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0 ]) packet = RadioPacket.create(rorg=RORG.BS4, rorg_func=0x02, rorg_type=0x05, sender=[0x01, 0x81, 0xB7, 0x44], learn=True, TMP=26.66666666666666666666666666666666666666666667) packet_serialized = packet.build() assert len(packet_serialized) == len(TEMPERATURE) assert packet.learn is True
def test_packets_with_destination(): TEMPERATURE = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x00, 0x00, 0x55, 0x08, 0x01, 0x81, 0xB7, 0x44, 0x00, 0x03, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x5F ]) packet = RadioPacket.create(rorg=RORG.BS4, rorg_func=0x02, rorg_type=0x05, sender=[0x01, 0x81, 0xB7, 0x44], destination=[0xDE, 0xAD, 0xBE, 0xEF], TMP=26.66666666666666666666666666666666666666666667) packet_serialized = packet.build() assert len(packet_serialized) == len(TEMPERATURE) assert list(packet_serialized) == list(TEMPERATURE) assert packet.learn is False assert packet.sender_int == 25278276 assert packet.destination_int == 3735928559 MAGNETIC_SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xD5, 0x08, 0x01, 0x82, 0x5D, 0xAB, 0x00, 0x03, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0xB9 ]) packet = RadioPacket.create(rorg=RORG.BS1, rorg_func=0x00, rorg_type=0x01, sender=[0x01, 0x82, 0x5D, 0xAB], destination=[0xDE, 0xAD, 0xBE, 0xEF], CO='open') packet_serialized = packet.build() assert len(packet_serialized) == len(MAGNETIC_SWITCH) assert list(packet_serialized) == list(MAGNETIC_SWITCH) assert packet.learn is False
def test_magnetic_switch(): MAGNETIC_SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xD5, 0x08, 0x01, 0x82, 0x5D, 0xAB, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBA ]) packet = RadioPacket.create(rorg=RORG.BS1, rorg_func=0x00, rorg_type=0x01, sender=[0x01, 0x82, 0x5D, 0xAB], CO='open') packet_serialized = packet.build() assert len(packet_serialized) == len(MAGNETIC_SWITCH) assert list(packet_serialized) == list(MAGNETIC_SWITCH) assert packet.learn is False MAGNETIC_SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xD5, 0x00, 0x01, 0x82, 0x5D, 0xAB, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x06 ]) packet = RadioPacket.create(rorg=RORG.BS1, rorg_func=0x00, rorg_type=0x01, sender=[0x01, 0x82, 0x5D, 0xAB], learn=True, CO='open') packet_serialized = packet.build() assert len(packet_serialized) == len(MAGNETIC_SWITCH) assert list(packet_serialized) == list(MAGNETIC_SWITCH) assert packet.learn is True MAGNETIC_SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xD5, 0x09, 0x01, 0x82, 0x5D, 0xAB, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2E ]) packet = RadioPacket.create(rorg=RORG.BS1, rorg_func=0x00, rorg_type=0x01, sender=[0x01, 0x82, 0x5D, 0xAB], CO='closed') packet_serialized = packet.build() assert len(packet_serialized) == len(MAGNETIC_SWITCH) assert list(packet_serialized) == list(MAGNETIC_SWITCH) assert packet.learn is False MAGNETIC_SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xD5, 0x01, 0x01, 0x82, 0x5D, 0xAB, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x92 ]) packet = RadioPacket.create(rorg=RORG.BS1, rorg_func=0x00, rorg_type=0x01, sender=[0x01, 0x82, 0x5D, 0xAB], learn=True, CO='closed') packet_serialized = packet.build() assert len(packet_serialized) == len(MAGNETIC_SWITCH) assert list(packet_serialized) == list(MAGNETIC_SWITCH) assert packet.learn is True
def test_switch(): SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xF6, 0x50, 0x00, 0x29, 0x89, 0x79, 0x30, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x61 ]) # test also enum setting by integer value with EB0 packet = RadioPacket.create(rorg=RORG.RPS, rorg_func=0x02, rorg_type=0x02, sender=[0x00, 0x29, 0x89, 0x79], SA='No 2nd action', EB=1, R1='Button BI', T21=True, NU=True, ) packet_serialized = packet.build() assert len(packet_serialized) == len(SWITCH) assert list(packet_serialized) == list(SWITCH) SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xF6, 0x00, 0x00, 0x29, 0x89, 0x79, 0x20, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xD2 ]) packet = RadioPacket.create(rorg=RORG.RPS, rorg_func=0x02, rorg_type=0x02, sender=[0x00, 0x29, 0x89, 0x79], SA='No 2nd action', EB='released', T21=True, NU=False, ) packet_serialized = packet.build() assert len(packet_serialized) == len(SWITCH) assert list(packet_serialized) == list(SWITCH)
def test_switch(): SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xF6, 0x50, 0x00, 0x29, 0x89, 0x79, 0x30, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x61 ]) p = RadioPacket.create(rorg=RORG.RPS, func=0x02, type=0x02, sender=[0x00, 0x29, 0x89, 0x79], SA='No 2nd action', EBO='pressed', R1='Button BI', T21=True, NU=True, ) packet_serialized = p.build() assert len(packet_serialized) == len(SWITCH) assert list(packet_serialized) == list(SWITCH) SWITCH = bytearray([ 0x55, 0x00, 0x07, 0x07, 0x01, 0x7A, 0xF6, 0x00, 0x00, 0x29, 0x89, 0x79, 0x20, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xD2 ]) p = RadioPacket.create(rorg=RORG.RPS, func=0x02, type=0x02, sender=[0x00, 0x29, 0x89, 0x79], SA='No 2nd action', EBO='released', T21=True, NU=False, ) packet_serialized = p.build() assert len(packet_serialized) == len(SWITCH) assert list(packet_serialized) == list(SWITCH)
def create_packet(cls, eep: Eep, destination=None, sender=None, learn=False, **kwargs): destination_id = destination or 0xffffffff if type(destination_id) == int: destination_id = EnoceanTools.int_to_byte_list(destination_id) sender_id = sender or cls._sender_id if type(sender_id) == int: sender_id = EnoceanTools.int_to_byte_list(sender_id) return RadioPacket.create( eep.rorg, eep.func, eep.type, direction=eep.direction, command=eep.command, destination=destination_id, sender=sender_id, learn=learn, **kwargs )
def _reply_packet(self, in_packet, sensor): '''send enocean message as a reply to an incoming message''' # prepare addresses destination = in_packet.sender # prepare packet if 'direction' in sensor: # we invert the direction in this reply direction = 1 if sensor['direction'] == 2 else 2 else: direction = None packet = RadioPacket.create(RORG.BS4, sensor['func'], sensor['type'], direction=direction, sender=self.enocean_sender, destination=destination, learn=in_packet.learn) # assemble data based on packet type (learn / data) if not in_packet.learn: # data packet received # start with default data packet.data[1:5] = [(sensor['default_data'] >> i & 0xff) for i in (24, 16, 8, 0)] # do we have specific data to send? if 'data' in sensor: # override with specific data settings packet.set_eep(sensor['data']) else: # what to do if we have no data to send yet? logging.warn('sending default data as answer to %s', sensor['name']) else: # learn request received # copy EEP and manufacturer ID packet.data[1:5] = in_packet.data[1:5] # update flags to acknowledge learn request packet.data[4] = 0xf0 # send it logging.info('sending: {}'.format(packet)) self.enocean.send(packet)
def test_vld(): SWITCH = bytearray([ 0x55, 0x00, 0x09, 0x07, 0x01, 0x56, 0xD2, 0x01, 0x1E, 0x64, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x5A ]) packet = RadioPacket.create(rorg=RORG.VLD, rorg_func=0x01, rorg_type=0x01, command=1, DV=0, IO=0x1E, OV=0x64) packet_serialized = packet.build() assert len(packet_serialized) == len(SWITCH) assert list(packet_serialized) == list(SWITCH) assert packet.parsed['CMD']['raw_value'] == 0x01 assert packet.parsed['IO']['raw_value'] == 0x1E assert packet.parsed['IO']['value'] == 'All output channels supported by the device' assert packet.parsed['DV']['value'] == 'Switch to new output value' assert packet.parsed['OV']['value'] == 'Output value 100% or ON'
def send_command(message, learn=False, immediate=False): kwargs = {} command = None generic = '' direction = None delay = False learn = False type = '' raw = '' sender = globals.COMMUNICATOR.base_id commandRorg = int(message['profile']['rorg'], 16) commandFunc = utils.from_hex_string(message['profile']['func']) commandType = utils.from_hex_string(message['profile']['type']) commandDestination = utils.destination_sender_to_list(message['dest']) for data in message['command']: if data == 'command': command = int(message['command'][data]) elif data == 'direction': direction = int(message['command'][data]) elif data == 'type': type = message['command'][data] elif data == 'delay': delay = message['command'][data] elif data == 'profil': profil = message['command'][data] else: try: kwargs[data] = int(message['command'][data]) except: kwargs[data] = message['command'][data] logging.debug( str(kwargs) + ' on command ' + str(command) + ' ' + str(commandRorg) + ' ' + str(commandFunc) + ' ' + str(commandType)) globals.COMMUNICATOR.send( RadioPacket.create(rorg=commandRorg, rorg_func=commandFunc, rorg_type=commandType, destination=commandDestination, sender=sender, learn=learn, command=command, direction=direction, **kwargs))
def unpickle_packet(cls, text): unpickled = pickle.loads(codecs.decode(text.encode(), "base64")) packet_type = unpickled["packet_type"] data = unpickled["data"] opt_data = unpickled["optional"] # copied from: enocean/protocol/packet.py if packet_type == PACKET.RADIO_ERP1: # Need to handle UTE Teach-in here, as it's a separate packet type... if data[0] == RORG.UTE: packet = UTETeachInPacket(packet_type, data, opt_data) else: packet = RadioPacket(packet_type, data, opt_data) elif packet_type == PACKET.RESPONSE: packet = ResponsePacket(packet_type, data, opt_data) elif packet_type == PACKET.EVENT: packet = EventPacket(packet_type, data, opt_data) else: packet = Packet(packet_type, data, opt_data) return packet
def _reply_packet(self, in_packet, sensor): '''send enocean message as a reply to an incoming message''' # prepare addresses destination = in_packet.sender # prepare packet if 'direction' in sensor: # we invert the direction in this reply direction = 1 if sensor['direction'] == 2 else 2 else: direction = None packet = RadioPacket.create(RORG.BS4, sensor['func'], sensor['type'], direction=direction, sender=self.enocean_sender, destination=destination, learn=in_packet.learn) # assemble data based on packet type (learn / data) if not in_packet.learn: # data packet received # start with default data packet.data[1:5] = [ (sensor['default_data'] >> i & 0xff) for i in (24,16,8,0) ] # do we have specific data to send? if 'data' in sensor: # override with specific data settings packet.set_eep(sensor['data']) else: # what to do if we have no data to send yet? logging.warn('sending default data as answer to %s', sensor['name']) else: # learn request received # copy EEP and manufacturer ID packet.data[1:5] = in_packet.data[1:5] # update flags to acknowledge learn request packet.data[4] = 0xf0 # send it logging.info('sending: {}'.format(packet)) self.enocean.send(packet)
def test_illegal_eep_enum2(): RadioPacket.create(rorg=RORG.RPS, rorg_func=0x02, rorg_type=0x02, sender=[0x00, 0x29, 0x89, 0x79], EB=2)
def send_command(message, learn=False, immediate=False): kwargs = {} command = None generic = '' direction = None delay = False learn = False type = '' raw = '' sender = globals.COMMUNICATOR.base_id commandRorg = int(message['profile']['rorg'], 16) commandFunc = utils.from_hex_string(message['profile']['func']) commandType = utils.from_hex_string(message['profile']['type']) commandDestination = utils.destination_sender_to_list(message['dest']) for data in message['command']: if data == 'command': command = int(message['command'][data]) elif data == 'direction': direction = int(message['command'][data]) elif data == 'type': type = message['command'][data] elif data == 'delay': delay = message['command'][data] elif data == 'generic': generic = message['command'][data] elif data == 'learn': learn = message['command'][data] elif data == 'profil': profil = message['command'][data] elif data == 'raw': raw = message['command'][data] else: try: kwargs[data] = int(message['command'][data]) except: kwargs[data] = message['command'][data] if learn <> False and learn <> '1': send_learn(learn, message) return if learn == '1': learn = True if delay and not immediate: globals.STORAGE_MESSAGE[message['dest']] = message logging.debug('Storing message') return logging.debug( str(kwargs) + ' on command ' + str(command) + ' ' + str(commandRorg) + ' ' + str(commandFunc) + ' ' + str(commandType)) if generic <> '': if type == 'switch': sender = utils.destination_sender_to_list(generic) commandDestination = None globals.COMMUNICATOR.send( RadioPacket.create(rorg=commandRorg, rorg_func=commandFunc, rorg_type=commandType, destination=commandDestination, sender=sender, learn=learn, command=command, direction=direction, EB=1, **kwargs)) globals.COMMUNICATOR.send( RadioPacket.create(rorg=commandRorg, rorg_func=commandFunc, rorg_type=commandType, destination=commandDestination, sender=sender, learn=learn, command=command, direction=direction, EB=0, **kwargs)) return else: sender = utils.destination_sender_to_list(generic) commandDestination = None if raw <> '': rawhandler.send(commandRorg, raw, sender) return globals.COMMUNICATOR.send( RadioPacket.create(rorg=commandRorg, rorg_func=commandFunc, rorg_type=commandType, destination=commandDestination, sender=sender, learn=learn, command=command, direction=direction, **kwargs))
def assemble_radio_packet(transmitter_id): return RadioPacket.create(rorg=RORG.BS4, rorg_func=0x20, rorg_type=0x01, sender=transmitter_id, CV=50, TMP=21.5, ES='true')
def test_packet_assembly(): PACKET_CONTENT_1 = bytearray([ 0x55, 0x00, 0x0A, 0x00, 0x01, 0x80, 0xA5, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x18 ]) PACKET_CONTENT_2 = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE4 ]) PACKET_CONTENT_3 = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x32, 0x20, 0x89, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x43 ]) PACKET_CONTENT_4 = bytearray([ 0x55, 0x00, 0x0A, 0x07, 0x01, 0xEB, 0xA5, 0x32, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80 ]) # manually assemble packet packet = Packet(PACKET.RADIO_ERP1) packet.rorg = RORG.BS4 sender_bytes = [(0xdeadbeef >> i & 0xff) for i in (24, 16, 8, 0)] data = [0, 0, 0, 0] packet.data = [packet.rorg] + data + sender_bytes + [0] # test content packet_serialized = packet.build() assert len(packet_serialized) == len(PACKET_CONTENT_1) assert list(packet_serialized) == list(PACKET_CONTENT_1) # set optional data sub_tel_num = 3 destination = [255, 255, 255, 255] # broadcast dbm = 0xff security = 0 packet.optional = [sub_tel_num] + destination + [dbm] + [security] # test content packet_serialized = packet.build() assert len(packet_serialized) == len(PACKET_CONTENT_2) assert list(packet_serialized) == list(PACKET_CONTENT_2) # update data based on EEP packet.select_eep(0x20, 0x01, 1) prop = { 'CV': 50, 'TMP': 21.5, 'ES': 'true', } packet.set_eep(prop) # test content packet_serialized = packet.build() assert len(packet_serialized) == len(PACKET_CONTENT_3) assert list(packet_serialized) == list(PACKET_CONTENT_3) assert packet.rorg_func == 0x20 assert packet.rorg_type == 0x01 # Test the easier method of sending packets. packet = Packet.create(PACKET.RADIO_ERP1, rorg=RORG.BS4, rorg_func=0x20, rorg_type=0x01, learn=True, direction=1, **prop) packet_serialized = packet.build() assert len(packet_serialized) == len(PACKET_CONTENT_3) assert list(packet_serialized) == list(PACKET_CONTENT_3) assert packet.rorg_func == 0x20 assert packet.rorg_type == 0x01 # Test creating RadioPacket directly. packet = RadioPacket.create(rorg=RORG.BS4, rorg_func=0x20, rorg_type=0x01, learn=True, direction=2, SP=50) packet_serialized = packet.build() assert len(packet_serialized) == len(PACKET_CONTENT_4) assert list(packet_serialized) == list(PACKET_CONTENT_4) assert packet.rorg_func == 0x20 assert packet.rorg_type == 0x01
def send_command(destination, output_value): global communicator communicator.send( RadioPacket.create(rorg=RORG.VLD, rorg_func=0x01, rorg_type=0x01, destination=destination, sender=communicator.base_id, command=1, IO=0x1E, OV=output_value) )
def test_illegal_eep_enum1(): RadioPacket.create(rorg=RORG.RPS, func=0x02, type=0x02, sender=[0x00, 0x29, 0x89, 0x79], EBO='inexisting')
def send(rorg, raw, sender): logging.debug('Sending Raw message ' + str(raw)) data = [rorg] + utils.destination_sender_to_list(raw) + sender + [0] optional = [0x03] + [0xFF, 0xFF, 0xFF, 0xFF] + [0xFF, 0x00] globals.COMMUNICATOR.send( RadioPacket(PACKET.RADIO, data=data, optional=optional))
def create_enocean_teach_in(sender): packet_response = RadioPacket.create(RORG.BS4, 0x20, 0x1, sender=sender) packet_response.data[1:5] = [0x40, 0x18, 0x2d, 0x80] packet_response.parsed = OrderedDict({}) return packet_response
def _send_packet(self, sensor, destination, command=None, negate_direction=False, learn_data=None): '''triggers sending of an enocean packet''' # determine direction indicator if 'direction' in sensor: direction = sensor['direction'] if negate_direction: # we invert the direction in this reply direction = 1 if direction == 2 else 2 else: direction = None # is this a response to a learn packet? is_learn = learn_data is not None # Add possibility for the user to indicate a specific sender address # in sensor configuration using added 'sender' field. # So use specified sender address if any if 'sender' in sensor: sender = [(sensor['sender'] >> i*8) & 0xff for i in reversed(range(4))] else: sender = self.enocean_sender try: # Now pass command to RadioPacket.create() packet = RadioPacket.create(sensor['rorg'], sensor['func'], sensor['type'], direction=direction, command=command, sender=sender, destination=destination, learn=is_learn) except ValueError as err: logging.error("Cannot create RF packet: %s", err) return # assemble data based on packet type (learn / data) if not is_learn: # data packet received # start with default data # Initialize packet with default_data if specified if 'default_data' in sensor: packet.data[1:5] = [(sensor['default_data'] >> i*8) & 0xff for i in reversed(range(4))] # do we have specific data to send? if 'data' in sensor: # override with specific data settings logging.debug("sensor data: %s", sensor['data']) packet.set_eep(sensor['data']) packet.parse_eep() # ensure that the logging output of packet is updated else: # what to do if we have no data to send yet? logging.warning('sending only default data as answer to %s', sensor['name']) else: # learn request received # copy EEP and manufacturer ID packet.data[1:5] = learn_data[1:5] # update flags to acknowledge learn request packet.data[4] = 0xf0 # send it logging.info("sending: %s", packet) self.enocean.send(packet)
def set_position(destination, percentage): global communicator communicator.send( RadioPacket.create(rorg=RORG.VLD, rorg_func=0x05, rorg_type=0x00, destination=destination, sender=communicator.base_id, command=1, POS=percentage) )