Beispiel #1
0
    async def _update_subscriptions(self, characteristics, ev):
        """Subscribe or unsubscribe to characteristics."""
        status = {}
        # We do one aid at a time to match what iOS does
        # even though its inefficient
        # https://github.com/home-assistant/core/issues/37996
        #
        # Prebuild the payloads to avoid the set size changing
        # between await calls
        char_payloads = [
            [{"aid": aid, "iid": iid, "ev": ev} for aid, iid in aid_iids]
            for _, aid_iids in groupby(characteristics, key=itemgetter(0))
        ]
        for char_payload in char_payloads:
            response = await self.connection.put_json(
                "/characteristics",
                {"characteristics": char_payload},
            )
            if response:
                # An empty body is a success response
                for row in response.get("characteristics", []):
                    status[(row["aid"], row["iid"])] = {
                        "status": row["status"],
                        "description": to_status_code(row["status"]).description,
                    }

        return status
Beispiel #2
0
def format_characteristic_list(data):
    tmp = {}
    for c in data["characteristics"]:
        key = (c["aid"], c["iid"])
        del c["aid"]
        del c["iid"]

        if "status" in c and c["status"] == 0:
            del c["status"]
        if "status" in c and c["status"] != 0:
            c["description"] = to_status_code(c["status"]).description
        tmp[key] = c
    return tmp
Beispiel #3
0
    async def identify(self):
        await self._ensure_connected()

        response = await self.connection.post_json("/identify", {})

        if not response:
            return True

        code = to_status_code(response["code"])

        raise AlreadyPairedError(
            "Identify failed because: {reason} ({code}).".format(
                reason=code.description,
                code=code.value,
            ))

        return True
Beispiel #4
0
    async def put_characteristics(self, characteristics):
        """
        Update the values of writable characteristics. The characteristics have to be identified by accessory id (aid),
        instance id (iid). If do_conversion is False (the default), the value must be of proper format for the
        characteristic since no conversion is done. If do_conversion is True, the value is converted.

        :param characteristics: a list of 3-tupels of accessory id, instance id and the value
        :param do_conversion: select if conversion is done (False is default)
        :return: a dict from (aid, iid) onto {status, description}
        :raises FormatError: if the input value could not be converted to the target type and conversion was
                             requested
        """
        await self._ensure_connected()

        if "accessories" not in self.pairing_data:
            await self.list_accessories_and_characteristics()

        data = []
        characteristics_set = set()
        for characteristic in characteristics:
            aid = characteristic[0]
            iid = characteristic[1]
            value = characteristic[2]
            characteristics_set.add(f"{aid}.{iid}")
            data.append({"aid": aid, "iid": iid, "value": value})
        data = {"characteristics": data}

        response = await self.connection.put_json("/characteristics", data)
        if response:
            data = {
                (d["aid"], d["iid"]): {
                    "status": d["status"],
                    "description": to_status_code(d["status"]).description,
                }
                for d in response["characteristics"]
            }
            return data

        return {}
Beispiel #5
0
async def test_normalized_statuscodes():
    """Verify we account for quirks in HAP implementations."""
    assert to_status_code(70411) == HapStatusCode.INSUFFICIENT_AUTH
    assert to_status_code(-70411) == HapStatusCode.INSUFFICIENT_AUTH