Esempio n. 1
0
    async def _request_raw(self,
                           obj: ZpiObject,
                           waiter_id=None,
                           expected_status=None):
        if expected_status is None:
            expected_status = [0]

        LOGGER.debug("--> %s", obj)
        frame = obj.to_unpi_frame()

        if obj.command_type == CommandType.SREQ:
            timeout = (20000 if obj.command == "bdbStartCommissioning"
                       or obj.command == "startupFromApp" else Timeouts.SREQ)
            waiter = self.wait_for(CommandType.SRSP, obj.subsystem,
                                   obj.command, {}, timeout)
            self._uart.send(frame)
            result = await waiter.wait()
            if (result and "status" in result.payload
                    and result.payload["status"] not in expected_status):
                if waiter_id is not None:
                    self._waiters.pop(waiter_id).set_result(result)

                raise CommandError(
                    result.payload["status"],
                    "SREQ '{}' failed with status '{}' (expected '{}')".format(
                        obj.command, result.payload["status"],
                        expected_status),
                )
            else:
                return result
        elif obj.command_type == CommandType.AREQ and obj.is_reset_command():
            waiter = self.wait_for(CommandType.AREQ, Subsystem.SYS, "resetInd",
                                   {}, Timeouts.reset)
            # TODO clear queue, requests waiting for lock
            self._uart.send(frame)
            return await waiter.wait()
        else:
            if obj.command_type == CommandType.AREQ:
                self._uart.send(frame)
                return None
            else:
                LOGGER.warning("Unknown type '%s'", obj.command_type)
                raise Exception("Unknown type '{}'".format(obj.command_type))
Esempio n. 2
0
    def handle_znp(self, obj: ZpiObject):
        if obj.type != t.CommandType.AREQ:
            return

        # if obj.subsystem == t.Subsystem.ZDO and obj.command == 'tcDeviceInd':
        #     nwk = obj.payload['nwkaddr']
        #     rest = obj.payload['extaddr'][2:].encode("ascii")
        #     ieee, _ = zigpy.types.EUI64.deserialize(rest)
        #     LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
        #     self.handle_join(nwk, ieee, obj.payload['parentaddr'])

        frame = obj.to_unpi_frame()

        nwk = obj.payload["srcaddr"] if "srcaddr" in obj.payload else None
        ieee = obj.payload["ieeeaddr"] if "ieeeaddr" in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "endDeviceAnnceInd":
            nwk = obj.payload["nwkaddr"]
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            # TODO TEST
            obj.sequence = 0

        # TODO bindRsp

        if obj.command in IGNORED:
            LOGGER.debug("message ignored: %s", obj.command)
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "permitJoinInd":
            # if obj.payload["duration"] == 0:
            #     loop = asyncio.get_event_loop()
            #     loop.create_task(self.permit_ncp())
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                LOGGER.warning("missing tsn from %s, maybe not a reply",
                               obj.command)
                return
            LOGGER.info("REPLY for %d %s", obj.sequence, obj.command)
            cluster_id, prefix_length = REQUESTS[obj.command]
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == "incomingMsg"
                                                  or obj.command
                                                  == "incomingMsgExt"):
            # ZCL commands
            cluster_id = obj.payload["clusterid"]
            src_ep = obj.payload["srcendpoint"]
            dst_ep = obj.payload["dstendpoint"]
            data = obj.payload["data"]
            lqi = obj.payload["linkquality"]

        else:
            LOGGER.warning("Unhandled message: %s %s",
                           t.Subsystem(obj.subsystem), obj.command)
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.warning("Received frame from unknown device: %s",
                           ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)
        # if obj.subsystem == t.Subsystem.ZDO:
        #     pass
        LOGGER.info("handle_message %s", obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep,
                            data)
Esempio n. 3
0
    def handle_znp(self, obj: ZpiObject):
        if obj.command_type != t.CommandType.AREQ:
            return

        frame = obj.to_unpi_frame()

        nwk = obj.payload["srcaddr"] if "srcaddr" in obj.payload else None
        ieee = obj.payload["ieeeaddr"] if "ieeeaddr" in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "endDeviceAnnceInd":
            nwk = obj.payload["nwkaddr"]
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            obj.sequence = 0

        if obj.command in IGNORED:
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "mgmtPermitJoinRsp":
            self.set_led(LedMode.On)

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "permitJoinInd":
            self.set_led(LedMode.Off if obj.payload["duration"] ==
                         0 else LedMode.On)
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                return
            LOGGER.debug("REPLY for %d %s", obj.sequence, obj.command)
            cluster_id, prefix_length = REQUESTS[obj.command]
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == "incomingMsg"
                                                  or obj.command
                                                  == "incomingMsgExt"):
            # ZCL commands
            cluster_id = obj.payload["clusterid"]
            src_ep = obj.payload["srcendpoint"]
            dst_ep = obj.payload["dstendpoint"]
            data = obj.payload["data"]
            lqi = obj.payload["linkquality"]

        else:
            LOGGER.warning(
                "Unhandled message: %s %s %s",
                t.CommandType(obj.command_type),
                t.Subsystem(obj.subsystem),
                obj.command,
            )
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.warning("Received frame from unknown device: %s",
                           ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)

        LOGGER.info("handle_message %s", obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep,
                            data)
Esempio n. 4
0
    def handle_znp(self, obj: ZpiObject):
        if obj.type != t.CommandType.AREQ:
            return

        # if obj.subsystem == t.Subsystem.ZDO and obj.command == 'tcDeviceInd':
        #     nwk = obj.payload['nwkaddr']
        #     rest = obj.payload['extaddr'][2:].encode("ascii")
        #     ieee, _ = zigpy.types.EUI64.deserialize(rest)
        #     LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
        #     self.handle_join(nwk, ieee, obj.payload['parentaddr'])

        frame = obj.to_unpi_frame()

        nwk = obj.payload['srcaddr'] if 'srcaddr' in obj.payload else None
        ieee = obj.payload['ieeeaddr'] if 'ieeeaddr' in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == 'endDeviceAnnceInd':
            nwk = obj.payload['nwkaddr']
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            # TODO TEST
            obj.sequence = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                LOGGER.warning("missing tsn from %s, maybe not a reply", obj.command)
                return
            cluster_id, prefix_length = REQUESTS[obj.command]
            LOGGER.info("REPLY for %d %s", obj.sequence, obj.command)
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == 'incomingMsg' or obj.command == 'incomingMsgExt'):
            # ZCL commands
            cluster_id = obj.payload['clusterid']
            src_ep = obj.payload['srcendpoint']
            dst_ep = obj.payload['dstendpoint']
            data = obj.payload['data']
            lqi = obj.payload['linkquality']

        elif obj.command == 'stateChangeInd':
            LOGGER.info("State changed to: %s", obj.payload['state'])
            return

        else:
            LOGGER.warning("Unhandled message: %s %s", obj.subsystem, obj.command)
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.debug("Received frame from unknown device: %s", ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)
        if obj.subsystem == t.Subsystem.ZDO:
            pass
        LOGGER.info('handle_message %s', obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep, data)