示例#1
0
    def process_enocean_fsb61_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket

        try:
            packet.parse()
            status = Fsb61StateConverter.extract_packet(packet)
        except Exception as ex:
            self._logger.exception(ex)
            EnoceanTools.log_pickled_enocean_packet(
                self._logger.error, packet,
                "process_enocean_fsb61_message - {}".format(str(ex)))
            return

        if status.type == Fsb61StateType.UNKNOWN:
            EnoceanTools.log_pickled_enocean_packet(
                self._logger.warning, packet,
                "process_enocean_fsb61_message - unknown packet type")
            return

        self._logger.debug("process_enocean_fsb61_message: %s", status)

        # # DEBUG
        # EnoceanTools.log_pickled_enocean_packet(self._logger.debug, packet, 'process_enocean_fsb61_message')

        self._update_position(status)

        self._publish_actor_result()

        self._process_device_command2(status)  # trigger queued commands

        # prevent offline message
        self._reset_offline_refresh_timer()
        self._last_status_request_time = self._now()
示例#2
0
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return
        if packet.rorg != self._eep.rorg:
            self._logger.debug("skipped packet with rorg=%s", hex(packet.rorg))
            return

        self._reset_offline_refresh_timer()

        data = EnoceanTools.extract_packet_props(packet, self._eep)
        self._logger.debug("proceed_enocean - got: %s", data)

        try:
            value = self.extract_handle_state(data.get("WIN"))
        except DeviceException as ex:
            self._logger.exception(ex)
            value = HandleValue.ERROR

        if value == HandleValue.ERROR and self._logger.isEnabledFor(
                logging.DEBUG):
            # write ascii representation to reproduce in tests
            self._logger.debug("proceed_enocean - pickled error packet:\n%s",
                               PickleTools.pickle_packet(packet))

        since = self._determine_and_store_since(value)

        message = self._create_message(value, since)
        self._publish_mqtt(message)
示例#3
0
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return
        if packet.rorg != self._eep.rorg:
            self._logger.debug("skipped packet with rorg=%s", hex(packet.rorg))
            return

        data = EnoceanTools.extract_packet_props(packet, self._eep)
        self._logger.debug("proceed_enocean - got: %s", data)

        notification = self.extract_notification(data)
        if notification.channel != self._actor_channel:
            self._logger.debug("skip channel (%s, awaiting=%s)",
                               notification.channel, self._actor_channel)
            return

        if notification.switch_state == SwitchStatus.ERROR and self._logger.isEnabledFor(
                logging.DEBUG):
            # write ascii representation to reproduce in tests
            self._logger.debug(
                "process_enocean_message - pickled error packet:\n%s",
                PickleTools.pickle_packet(packet))

        message = self._create_json_message(notification.switch_state, None)
        self._publish_mqtt(message)
 def test_extract_release(self):
     packet = PickleTools.unpickle_packet(PACKET_RELEASE)
     device = _MockDevice()
     extracted = EnoceanTools.extract_packet_props(packet, device._eep)
     action = RockerAction(press=RockerPress.RELEASE)
     expected = RockerSwitchTools.create_props(action)
     self.assertEqual(extracted, expected)
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload
        if packet.sender_int in self._enocean_ids_skip:
            return

        packet_type = EnoceanTools.packet_type_to_string(packet.packet_type)

        if self._dump_packet and self._logger.isEnabledFor(logging.INFO):
            self._logger.info(
                "proceed_enocean - packet: %s; sender: %s; dest: %s; RORG: %s; dump:\n%s",
                packet_type, packet.sender_hex, packet.destination_hex,
                enocean_utils.to_hex_string(packet.rorg),
                PickleTools.pickle_packet(packet))
            packet.parse()
            if packet.contains_eep:
                self._logger.debug(
                    'learn received, EEP detected, RORG: 0x%02X, FUNC: 0x%02X, TYPE: 0x%02X, Manufacturer: 0x%02X'
                    % (packet.rorg, packet.rorg_func, packet.rorg_type,
                       packet.rorg_manufacturer))  # noqa: E501

        else:
            self._logger.info(
                "proceed_enocean - packet: %s; sender: %s; dest: %s; RORG: %s",
                packet_type, packet.destination_hex,
                enocean_utils.to_hex_string(packet.rorg), packet.sender_hex)
    def test_ft55(self):
        packet = PickleTools.unpickle_packet(PACKET_FT55_21L)

        # f6-02-02
        eep = Eep(rorg=0xf6, func=0x02, type=0x02)

        data = EnoceanTools.extract_props(packet, eep)
        self.assertTrue(data)
示例#7
0
    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
        )
示例#8
0
    def test_extract_1_off(self):
        packet = PickleTools.unpickle_packet(_PACKET_1_OFF)

        device = _MockDevice()
        data = EnoceanTools.extract_packet_props(packet,
                                                 _MockDevice.DEFAULT_EEP)

        notification = device.extract_notification(data)
        self.assertEqual(notification.channel, 1)
        self.assertEqual(notification.switch_state, SwitchStatus.OFF)
    def extract_props(cls, packet: RadioPacket) -> Dict:
        eep = cls.DEFAULT_EEP
        if packet.packet_type == PACKET.RADIO and packet.rorg == eep.rorg:
            try:
                data = EnoceanTools.extract_props(packet=packet, eep=eep)
            except AttributeError as ex:
                raise DeviceException(ex)
        else:
            data = {}

        return data
    def get_props_from_packet(cls, packet: RadioPacket) -> Dict[str, int]:
        eep = cls._EEP

        if packet.packet_type == PACKET.RADIO and packet.rorg == eep.rorg:
            try:
                props = EnoceanTools.extract_props(packet=packet, eep=eep)
            except AttributeError as ex:
                raise EepPropException(ex)
        else:
            props = {}

        return props
示例#11
0
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return

        rocker_scene = self.find_rocker_scene(packet)
        if rocker_scene:
            self.process_rocker_scene(rocker_scene)
        else:
            self._process_actor_packet(packet)
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return
        if packet.rorg != self._eep.rorg:
            self._logger.debug("skipped packet with rorg=%s", hex(packet.rorg))
            return

        message_data = self._find_rocker_command(packet)
        if message_data and message_data.topic:
            self._publish_mqtt(message_data.payload, message_data.topic)
示例#13
0
    def get_props_from_packet(cls, packet, command: Optional[Fsr61Command] = None) -> Dict[str, int]:
        eep = cls.EEP.clone()

        if packet.packet_type == PACKET.RADIO and packet.rorg == eep.rorg:
            if command is None:
                eep.command = 0
                try:
                    tmp_props = EnoceanTools.extract_props(packet=packet, eep=eep)
                    eep.command = tmp_props[Fsr61Prop.CMD.value]
                except AttributeError as ex:
                    raise EepPropException(ex)
            else:
                eep.command = command.value

            try:
                props = EnoceanTools.extract_props(packet=packet, eep=eep)
            except AttributeError as ex:
                raise EepPropException(ex)
        else:
            props = {}

        return props
示例#14
0
    def find_rocker_scene(self, packet: RadioPacket) -> Optional[RockerScene]:
        if packet.packet_type == PACKET.RADIO and packet.rorg == RockerSwitchTools.DEFAULT_EEP.rorg:
            scenes = [
                s for s in self._scenes if s.rocker_id == packet.sender_int
            ]
            if scenes:
                try:
                    rocker_action = RockerSwitchTools.extract_action_from_packet(
                        packet)
                    scenes = [
                        s for s in scenes
                        if s.rocker_key == rocker_action.button
                    ]
                except DeviceException:
                    scenes = None
                    EnoceanTools.log_pickled_enocean_packet(
                        self._logger.warning, packet,
                        "find_rocker_scene - cannot extract")

                if scenes:
                    return scenes[0]

        return None
    def test_created_switch_packet(self):
        device = _MockDevice()
        packet = device._create_switch_packet(RockerSwitchAction.ON)

        extract = EnoceanTools.extract_props(packet=packet,
                                             eep=RockerSwitchTools.DEFAULT_EEP)

        self.assertEqual(extract, {
            'R1': 1,
            'EB': 1,
            'R2': 0,
            'SA': 0,
            'T21': 1,
            'NU': 1
        })
示例#16
0
    def test_packet_roundtrip(self):
        props_in = {'R1': 1, 'EB': 1, 'R2': 0, 'SA': 0, 'T21': 1, 'NU': 1}

        eep = Eep(rorg=0xf6, func=0x02, type=0x02)
        packet_in = EnoceanPacketFactory.create_packet(
            eep=eep,
            destination=EnoceanTools.int_to_byte_list(0xffffffff),
            learn=False,
            **props_in
        )

        text = PickleTools.pickle_packet(packet_in)
        packet_out = PickleTools.unpickle_packet(text)

        self.assertEqual(packet_out, packet_in)
    def test_extract_press(self):
        loop_data = [
            (PACKET_0_PRESS, RockerButton.ROCK0),
            (PACKET_1_PRESS, RockerButton.ROCK1),
            (PACKET_2_PRESS, RockerButton.ROCK2),
            (PACKET_3_PRESS, RockerButton.ROCK3),
        ]

        for i in range(0, 3):
            packet = PickleTools.unpickle_packet(loop_data[i][0])
            device = _MockDevice()
            extracted = EnoceanTools.extract_packet_props(packet, device._eep)
            action = RockerAction(press=RockerPress.PRESS_SHORT,
                                  button=loop_data[i][1])
            expected = RockerSwitchTools.create_props(action)
            self.assertEqual(extracted, expected)
    def extract_packet(cls, packet: RadioPacket) -> Fsb61State:

        status = Fsb61State()

        status.rssi = packet.dBm

        status.sender = packet.sender_int
        status.destination = packet.destination_int

        if Fsb61CommandConverter.is_command_packet(
                packet):  # packet.rorg == 0xa5
            command = Fsb61CommandConverter.extract_packet(packet)
            if command.type == Fsb61CommandType.CLOSE:
                status.type = Fsb61StateType.CLOSED
                status.time = command.time
            elif command.type == Fsb61CommandType.OPEN:
                status.type = Fsb61StateType.OPENED
                status.time = command.time
            elif command.type == Fsb61CommandType.STOP:
                status.type = Fsb61StateType.STOPPED
                status.time = 0
            else:
                raise EepPropException("Invalid command type!")

        elif packet.rorg == cls._EEP.rorg:
            props = EnoceanTools.extract_props(packet, cls._EEP)
            r2 = props["R2"]  # R2 (Rocker 2nd action)
            sa = props["SA"]  # 2nd action valid
            if sa == 1:
                if r2 == 0:  # 0: Button AI: "Switch light on" or "Dim light up" or "Move blind open"
                    status.type = Fsb61StateType.OPENING
                elif r2 == 1:  # 1: Button A0: "switch light off" or "Dim light down" or "Move blind closed"
                    status.type = Fsb61StateType.CLOSING

            elif sa == 0:
                if r2 == 1:  # 1: Button A0: "switch light off" or "Dim light down" or "Move blind closed"
                    status.type = Fsb61StateType.CLOSING
                else:
                    status.type = Fsb61StateType.STOPPED

            if status.type is None:
                raise EepPropException("Invalid data ({})!".format(props))

        else:
            status.type = Fsb61StateType.UNKNOWN

        return status
示例#19
0
    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return

        if packet.rorg == RockerSwitchTools.DEFAULT_EEP.rorg:
            props = RockerSwitchTools.extract_props(packet)
            self._logger.debug("proceed_enocean - got=%s", props)
            action = RockerSwitchTools.extract_action(
                props)  # type: RockerAction

            if action.button == RockerButton.ROCK3:
                self._current_switch_state = SwitchStatus.ON
            elif action.button == RockerButton.ROCK2:
                self._current_switch_state = SwitchStatus.OFF
            else:
                self._current_switch_state = SwitchStatus.ERROR
        else:
            self._current_switch_state = SwitchStatus.ERROR

        if self._current_switch_state not in [
                SwitchStatus.ON, SwitchStatus.OFF
        ]:
            if self._logger.isEnabledFor(logging.DEBUG):
                self._logger.debug(
                    "proceed_enocean - pickled error packet:\n%s",
                    PickleTools.pickle_packet(packet))

        self._logger.debug("proceed_enocean - switch_state=%s",
                           self._current_switch_state)

        self._last_status_request = self._now()
        self._reset_offline_refresh_timer()

        message = self._create_json_message(self._current_switch_state)
        self._publish_mqtt(message)
    def test_open(self):
        packet = PickleTools.unpickle(PACKET_WIN_OPEN)

        comp = {'WIN': 2, 'T21': 1, 'NU': 0}
        data = EnoceanTools.extract_packet_props(packet, self.eep)
        self.assertEqual(data, comp)
示例#21
0
 def test_packet_type_text(self):
     self.assertEqual(EnoceanTools.packet_type_to_string(PACKET.RADIO), "RADIO")
     self.assertEqual(EnoceanTools.packet_type_to_string(int(PACKET.RADIO)), "RADIO")
     self.assertEqual(EnoceanTools.packet_type_to_string(None), "None")
示例#22
0
 def set_sender_id(cls, sender_id):
     if type(sender_id) == int:
         cls._sender_id = EnoceanTools.int_to_byte_list(sender_id)
     else:
         cls._sender_id = copy.deepcopy(sender_id)
示例#23
0
 def test_int_to_byte_list(self):
     value = 0x034567af
     byte_list = EnoceanTools.int_to_byte_list(value)
     result = enocean.utils.combine_hex(byte_list)
     self.assertEqual(result, value)