aioamazondevices 6.2.9__py3-none-any.whl → 6.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of aioamazondevices might be problematic. Click here for more details.
- aioamazondevices/__init__.py +1 -1
- aioamazondevices/api.py +187 -67
- aioamazondevices/const.py +1 -6
- aioamazondevices/query.py +47 -54
- {aioamazondevices-6.2.9.dist-info → aioamazondevices-6.4.1.dist-info}/METADATA +2 -3
- aioamazondevices-6.4.1.dist-info/RECORD +12 -0
- aioamazondevices-6.2.9.dist-info/RECORD +0 -12
- {aioamazondevices-6.2.9.dist-info → aioamazondevices-6.4.1.dist-info}/WHEEL +0 -0
- {aioamazondevices-6.2.9.dist-info → aioamazondevices-6.4.1.dist-info}/licenses/LICENSE +0 -0
aioamazondevices/__init__.py
CHANGED
aioamazondevices/api.py
CHANGED
|
@@ -53,6 +53,7 @@ from .const import (
|
|
|
53
53
|
SAVE_PATH,
|
|
54
54
|
SENSORS,
|
|
55
55
|
URI_DEVICES,
|
|
56
|
+
URI_DND,
|
|
56
57
|
URI_NEXUS_GRAPHQL,
|
|
57
58
|
URI_SIGNIN,
|
|
58
59
|
)
|
|
@@ -63,7 +64,7 @@ from .exceptions import (
|
|
|
63
64
|
CannotRetrieveData,
|
|
64
65
|
WrongMethod,
|
|
65
66
|
)
|
|
66
|
-
from .query import
|
|
67
|
+
from .query import QUERY_DEVICE_DATA, QUERY_SENSOR_STATE
|
|
67
68
|
from .utils import obfuscate_email, scrub_fields
|
|
68
69
|
|
|
69
70
|
|
|
@@ -74,6 +75,8 @@ class AmazonDeviceSensor:
|
|
|
74
75
|
name: str
|
|
75
76
|
value: str | int | float
|
|
76
77
|
error: bool
|
|
78
|
+
error_type: str | None
|
|
79
|
+
error_msg: str | None
|
|
77
80
|
scale: str | None
|
|
78
81
|
|
|
79
82
|
|
|
@@ -141,6 +144,12 @@ class AmazonEchoApi:
|
|
|
141
144
|
self._list_for_clusters: dict[str, str] = {}
|
|
142
145
|
|
|
143
146
|
self._session = client_session
|
|
147
|
+
self._final_devices: dict[str, AmazonDevice] = {}
|
|
148
|
+
self._endpoints: dict[str, str] = {} # endpoint ID to serial number map
|
|
149
|
+
|
|
150
|
+
initial_time = datetime.now(UTC) - timedelta(days=2) # force initial refresh
|
|
151
|
+
self._last_devices_refresh: datetime = initial_time
|
|
152
|
+
self._last_endpoint_refresh: datetime = initial_time
|
|
144
153
|
|
|
145
154
|
_LOGGER.debug("Initialize library v%s", __version__)
|
|
146
155
|
|
|
@@ -336,7 +345,7 @@ class AmazonEchoApi:
|
|
|
336
345
|
self,
|
|
337
346
|
method: str,
|
|
338
347
|
url: str,
|
|
339
|
-
input_data: dict[str, Any] | None = None,
|
|
348
|
+
input_data: dict[str, Any] | list[dict[str, Any]] | None = None,
|
|
340
349
|
json_data: bool = False,
|
|
341
350
|
) -> tuple[BeautifulSoup, ClientResponse]:
|
|
342
351
|
"""Return request response context data."""
|
|
@@ -572,17 +581,21 @@ class AmazonEchoApi:
|
|
|
572
581
|
_LOGGER.info("Register device: %s", scrub_fields(login_data))
|
|
573
582
|
return login_data
|
|
574
583
|
|
|
575
|
-
async def
|
|
576
|
-
self,
|
|
577
|
-
) -> dict[str, Any]:
|
|
578
|
-
"""Get
|
|
579
|
-
payload =
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
"
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
584
|
+
async def _get_sensors_state(
|
|
585
|
+
self, endpoint_id_list: list[str]
|
|
586
|
+
) -> dict[str, Any] | list[dict[str, Any]]:
|
|
587
|
+
"""Get sensor State."""
|
|
588
|
+
payload = [
|
|
589
|
+
{
|
|
590
|
+
"operationName": "getEndpointState",
|
|
591
|
+
"variables": {
|
|
592
|
+
"endpointId": endpoint_id,
|
|
593
|
+
"latencyTolerance": "LOW",
|
|
594
|
+
},
|
|
595
|
+
"query": QUERY_SENSOR_STATE,
|
|
596
|
+
}
|
|
597
|
+
for endpoint_id in endpoint_id_list
|
|
598
|
+
]
|
|
586
599
|
|
|
587
600
|
_, raw_resp = await self._session_request(
|
|
588
601
|
method=HTTPMethod.POST,
|
|
@@ -593,52 +606,52 @@ class AmazonEchoApi:
|
|
|
593
606
|
|
|
594
607
|
return await self._response_to_json(raw_resp)
|
|
595
608
|
|
|
596
|
-
async def _get_sensors_states(
|
|
597
|
-
self, devices: dict[str, Any]
|
|
598
|
-
) -> tuple[dict[str, dict[str, Any]], dict[str, dict[str, AmazonDeviceSensor]]]:
|
|
609
|
+
async def _get_sensors_states(self) -> dict[str, dict[str, AmazonDeviceSensor]]:
|
|
599
610
|
"""Retrieve devices sensors states."""
|
|
600
|
-
devices_state = await self._get_devices_state()
|
|
601
611
|
devices_sensors: dict[str, dict[str, AmazonDeviceSensor]] = {}
|
|
602
|
-
devices_endpoints: dict[str, dict[str, Any]] = {}
|
|
603
|
-
|
|
604
|
-
if error := devices_state.get("errors"):
|
|
605
|
-
if isinstance(error, list):
|
|
606
|
-
error = error[0]
|
|
607
|
-
msg = error.get("message", "Unknown error")
|
|
608
|
-
path = error.get("path", "Unknown path")
|
|
609
|
-
_LOGGER.error("Error retrieving devices state: %s for path %s", msg, path)
|
|
610
|
-
return {}, {}
|
|
611
|
-
|
|
612
|
-
if not (data := devices_state.get("data")) or not data.get("listEndpoints"):
|
|
613
|
-
_LOGGER.error("Malformed devices state data received: %s", devices_state)
|
|
614
|
-
return {}, {}
|
|
615
612
|
|
|
616
|
-
endpoints
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
if
|
|
624
|
-
|
|
625
|
-
|
|
613
|
+
# batch endpoints into groups of 3 to reduce number of requests
|
|
614
|
+
endpoint_ids = list(self._endpoints.keys())
|
|
615
|
+
batches = [endpoint_ids[i : i + 3] for i in range(0, len(endpoint_ids), 3)]
|
|
616
|
+
for endpoint_id_batch in batches:
|
|
617
|
+
sensors_state = await self._get_sensors_state(endpoint_id_batch)
|
|
618
|
+
_LOGGER.debug("Sensor data - %s", sensors_state)
|
|
619
|
+
|
|
620
|
+
if not isinstance(sensors_state, list) and (
|
|
621
|
+
error := sensors_state.get("errors")
|
|
622
|
+
):
|
|
623
|
+
if isinstance(error, list):
|
|
624
|
+
error = error[0]
|
|
625
|
+
msg = error.get("message", "Unknown error")
|
|
626
|
+
path = error.get("path", "Unknown path")
|
|
627
|
+
_LOGGER.error(
|
|
628
|
+
"Error retrieving devices state: %s for path %s", msg, path
|
|
626
629
|
)
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
+
return {}
|
|
631
|
+
|
|
632
|
+
for endpoint_data in sensors_state:
|
|
633
|
+
if (
|
|
634
|
+
not isinstance(endpoint_data, dict)
|
|
635
|
+
or not (data := endpoint_data.get("data"))
|
|
636
|
+
or not (endpoint := data.get("endpoint"))
|
|
637
|
+
):
|
|
638
|
+
_LOGGER.error(
|
|
639
|
+
"Malformed sensor state data received: %s", endpoint_data
|
|
640
|
+
)
|
|
641
|
+
return {}
|
|
642
|
+
serial_number = self._endpoints[endpoint.get("endpointId")]
|
|
643
|
+
|
|
644
|
+
if serial_number in self._final_devices:
|
|
645
|
+
devices_sensors[serial_number] = self._get_device_sensor_state(
|
|
646
|
+
endpoint, serial_number
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
return devices_sensors
|
|
630
650
|
|
|
631
651
|
def _get_device_sensor_state(
|
|
632
652
|
self, endpoint: dict[str, Any], serial_number: str
|
|
633
653
|
) -> dict[str, AmazonDeviceSensor]:
|
|
634
654
|
device_sensors: dict[str, AmazonDeviceSensor] = {}
|
|
635
|
-
if endpoint_dnd := endpoint.get("settings", {}).get("doNotDisturb"):
|
|
636
|
-
device_sensors["dnd"] = AmazonDeviceSensor(
|
|
637
|
-
name="dnd",
|
|
638
|
-
value=endpoint_dnd.get("toggleValue"),
|
|
639
|
-
error=bool(endpoint_dnd.get("error")),
|
|
640
|
-
scale=None,
|
|
641
|
-
)
|
|
642
655
|
for feature in endpoint.get("features", {}):
|
|
643
656
|
if (sensor_template := SENSORS.get(feature["name"])) is None:
|
|
644
657
|
# Skip sensors that are not in the predefined list
|
|
@@ -653,7 +666,11 @@ class AmazonEchoApi:
|
|
|
653
666
|
|
|
654
667
|
value: str | int | float = "n/a"
|
|
655
668
|
scale: str | None = None
|
|
656
|
-
|
|
669
|
+
|
|
670
|
+
api_error = feature_property.get("error", {})
|
|
671
|
+
error = bool(api_error)
|
|
672
|
+
error_type = api_error.get("type")
|
|
673
|
+
error_msg = api_error.get("message")
|
|
657
674
|
if not error:
|
|
658
675
|
try:
|
|
659
676
|
value_raw = feature_property[sensor_template["key"]]
|
|
@@ -683,15 +700,55 @@ class AmazonEchoApi:
|
|
|
683
700
|
feature_property,
|
|
684
701
|
repr(exc),
|
|
685
702
|
)
|
|
703
|
+
if error:
|
|
704
|
+
_LOGGER.debug(
|
|
705
|
+
"error in sensor %s - %s - %s", name, error_type, error_msg
|
|
706
|
+
)
|
|
686
707
|
device_sensors[name] = AmazonDeviceSensor(
|
|
687
708
|
name,
|
|
688
709
|
value,
|
|
689
710
|
error,
|
|
711
|
+
error_type,
|
|
712
|
+
error_msg,
|
|
690
713
|
scale,
|
|
691
714
|
)
|
|
692
715
|
|
|
693
716
|
return device_sensors
|
|
694
717
|
|
|
718
|
+
async def _get_devices_endpoint_data(self) -> dict[str, dict[str, Any]]:
|
|
719
|
+
"""Get Devices endpoint data."""
|
|
720
|
+
payload = {
|
|
721
|
+
"operationName": "getDevicesBaseData",
|
|
722
|
+
"query": QUERY_DEVICE_DATA,
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
_, raw_resp = await self._session_request(
|
|
726
|
+
method=HTTPMethod.POST,
|
|
727
|
+
url=f"https://alexa.amazon.{self._domain}{URI_NEXUS_GRAPHQL}",
|
|
728
|
+
input_data=payload,
|
|
729
|
+
json_data=True,
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
endpoint_data = await self._response_to_json(raw_resp)
|
|
733
|
+
|
|
734
|
+
if not (data := endpoint_data.get("data")) or not data.get("listEndpoints"):
|
|
735
|
+
_LOGGER.error("Malformed endpoint data received: %s", endpoint_data)
|
|
736
|
+
return {}
|
|
737
|
+
|
|
738
|
+
endpoints = data["listEndpoints"]
|
|
739
|
+
devices_endpoints: dict[str, dict[str, Any]] = {}
|
|
740
|
+
for endpoint in endpoints.get("endpoints"):
|
|
741
|
+
# save looking up sensor data on apps
|
|
742
|
+
if endpoint.get("alexaEnabledMetadata", {}).get("category") == "APP":
|
|
743
|
+
continue
|
|
744
|
+
|
|
745
|
+
if endpoint.get("serialNumber"):
|
|
746
|
+
serial_number = endpoint["serialNumber"]["value"]["text"]
|
|
747
|
+
devices_endpoints[serial_number] = endpoint
|
|
748
|
+
self._endpoints[endpoint["endpointId"]] = serial_number
|
|
749
|
+
|
|
750
|
+
return devices_endpoints
|
|
751
|
+
|
|
695
752
|
async def _response_to_json(self, raw_resp: ClientResponse) -> dict[str, Any]:
|
|
696
753
|
"""Convert response to JSON, if possible."""
|
|
697
754
|
try:
|
|
@@ -868,7 +925,59 @@ class AmazonEchoApi:
|
|
|
868
925
|
self,
|
|
869
926
|
) -> dict[str, AmazonDevice]:
|
|
870
927
|
"""Get Amazon devices data."""
|
|
871
|
-
|
|
928
|
+
delta_devices = datetime.now(UTC) - self._last_devices_refresh
|
|
929
|
+
if delta_devices >= timedelta(days=1):
|
|
930
|
+
_LOGGER.debug(
|
|
931
|
+
"Refreshing devices data after %s",
|
|
932
|
+
str(timedelta(minutes=round(delta_devices.total_seconds() / 60))),
|
|
933
|
+
)
|
|
934
|
+
# Request base device data
|
|
935
|
+
await self._get_base_devices()
|
|
936
|
+
self._last_devices_refresh = datetime.now(UTC)
|
|
937
|
+
|
|
938
|
+
delta_endpoints = datetime.now(UTC) - self._last_endpoint_refresh
|
|
939
|
+
if delta_endpoints >= timedelta(minutes=30):
|
|
940
|
+
_LOGGER.debug(
|
|
941
|
+
"Refreshing endpoint data after %s",
|
|
942
|
+
str(timedelta(minutes=round(delta_endpoints.total_seconds() / 60))),
|
|
943
|
+
)
|
|
944
|
+
# Set device endpoint data
|
|
945
|
+
await self._set_device_endpoints_data()
|
|
946
|
+
self._last_endpoint_refresh = datetime.now(UTC)
|
|
947
|
+
|
|
948
|
+
await self._get_sensor_data()
|
|
949
|
+
|
|
950
|
+
return self._final_devices
|
|
951
|
+
|
|
952
|
+
async def _get_sensor_data(self) -> None:
|
|
953
|
+
devices_sensors = await self._get_sensors_states()
|
|
954
|
+
dnd_sensors = await self._get_dnd_status()
|
|
955
|
+
for device in self._final_devices.values():
|
|
956
|
+
# Update sensors
|
|
957
|
+
sensors = devices_sensors.get(device.serial_number, {})
|
|
958
|
+
if sensors:
|
|
959
|
+
device.sensors = sensors
|
|
960
|
+
else:
|
|
961
|
+
for device_sensor in device.sensors.values():
|
|
962
|
+
device_sensor.error = True
|
|
963
|
+
if device_dnd := dnd_sensors.get(device.serial_number):
|
|
964
|
+
device.sensors["dnd"] = device_dnd
|
|
965
|
+
|
|
966
|
+
async def _set_device_endpoints_data(self) -> None:
|
|
967
|
+
devices_endpoints = await self._get_devices_endpoint_data()
|
|
968
|
+
for serial_number in self._final_devices:
|
|
969
|
+
device_endpoint = devices_endpoints.get(serial_number, {})
|
|
970
|
+
endpoint_device = self._final_devices[serial_number]
|
|
971
|
+
endpoint_device.entity_id = (
|
|
972
|
+
device_endpoint["legacyIdentifiers"]["chrsIdentifier"]["entityId"]
|
|
973
|
+
if device_endpoint
|
|
974
|
+
else None
|
|
975
|
+
)
|
|
976
|
+
endpoint_device.endpoint_id = (
|
|
977
|
+
device_endpoint["endpointId"] if device_endpoint else None
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
async def _get_base_devices(self) -> None:
|
|
872
981
|
_, raw_resp = await self._session_request(
|
|
873
982
|
method=HTTPMethod.GET,
|
|
874
983
|
url=f"https://alexa.amazon.{self._domain}{URI_DEVICES}",
|
|
@@ -885,7 +994,6 @@ class AmazonEchoApi:
|
|
|
885
994
|
"Skipping device without serial number: %s", data["accountName"]
|
|
886
995
|
)
|
|
887
996
|
continue
|
|
888
|
-
devices[dev_serial] = data
|
|
889
997
|
if not self._account_owner_customer_id:
|
|
890
998
|
self._account_owner_customer_id = (
|
|
891
999
|
await self._get_account_owner_customer_id(data)
|
|
@@ -894,18 +1002,13 @@ class AmazonEchoApi:
|
|
|
894
1002
|
if not self._account_owner_customer_id:
|
|
895
1003
|
raise CannotRetrieveData("Cannot find account owner customer ID")
|
|
896
1004
|
|
|
897
|
-
devices_endpoints, devices_sensors = await self._get_sensors_states(devices)
|
|
898
|
-
|
|
899
1005
|
final_devices_list: dict[str, AmazonDevice] = {}
|
|
900
|
-
for device in devices
|
|
1006
|
+
for device in json_data["devices"]:
|
|
901
1007
|
# Remove stale, orphaned and virtual devices
|
|
902
1008
|
if not device or (device.get("deviceType") in DEVICE_TO_IGNORE):
|
|
903
1009
|
continue
|
|
904
1010
|
|
|
905
1011
|
serial_number: str = device["serialNumber"]
|
|
906
|
-
# Add sensors
|
|
907
|
-
sensors = devices_sensors.get(serial_number, {})
|
|
908
|
-
device_endpoint = devices_endpoints.get(serial_number, {})
|
|
909
1012
|
|
|
910
1013
|
final_devices_list[serial_number] = AmazonDevice(
|
|
911
1014
|
account_name=device["accountName"],
|
|
@@ -919,13 +1022,9 @@ class AmazonEchoApi:
|
|
|
919
1022
|
online=device["online"],
|
|
920
1023
|
serial_number=serial_number,
|
|
921
1024
|
software_version=device["softwareVersion"],
|
|
922
|
-
entity_id=
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
if device_endpoint
|
|
926
|
-
else None,
|
|
927
|
-
endpoint_id=device_endpoint["endpointId"] if device_endpoint else None,
|
|
928
|
-
sensors=sensors,
|
|
1025
|
+
entity_id=None,
|
|
1026
|
+
endpoint_id=None,
|
|
1027
|
+
sensors={},
|
|
929
1028
|
)
|
|
930
1029
|
|
|
931
1030
|
self._list_for_clusters.update(
|
|
@@ -935,7 +1034,7 @@ class AmazonEchoApi:
|
|
|
935
1034
|
}
|
|
936
1035
|
)
|
|
937
1036
|
|
|
938
|
-
|
|
1037
|
+
self._final_devices = final_devices_list
|
|
939
1038
|
|
|
940
1039
|
async def auth_check_status(self) -> bool:
|
|
941
1040
|
"""Check AUTH status."""
|
|
@@ -1240,3 +1339,24 @@ class AmazonEchoApi:
|
|
|
1240
1339
|
|
|
1241
1340
|
_LOGGER.debug("Unexpected refresh data response")
|
|
1242
1341
|
return False, {}
|
|
1342
|
+
|
|
1343
|
+
async def _get_dnd_status(self) -> dict[str, AmazonDeviceSensor]:
|
|
1344
|
+
dnd_status: dict[str, AmazonDeviceSensor] = {}
|
|
1345
|
+
_, raw_resp = await self._session_request(
|
|
1346
|
+
method=HTTPMethod.GET,
|
|
1347
|
+
url=f"https://alexa.amazon.{self._domain}{URI_DND}",
|
|
1348
|
+
)
|
|
1349
|
+
|
|
1350
|
+
dnd_data = await self._response_to_json(raw_resp)
|
|
1351
|
+
_LOGGER.debug("DND data: %s", dnd_data)
|
|
1352
|
+
|
|
1353
|
+
for dnd in dnd_data.get("doNotDisturbDeviceStatusList", {}):
|
|
1354
|
+
dnd_status[dnd.get("deviceSerialNumber")] = AmazonDeviceSensor(
|
|
1355
|
+
name="dnd",
|
|
1356
|
+
value=dnd.get("enabled"),
|
|
1357
|
+
error=False,
|
|
1358
|
+
error_type=None,
|
|
1359
|
+
error_msg=None,
|
|
1360
|
+
scale=None,
|
|
1361
|
+
)
|
|
1362
|
+
return dnd_status
|
aioamazondevices/const.py
CHANGED
|
@@ -52,6 +52,7 @@ REFRESH_ACCESS_TOKEN = "access_token" # noqa: S105
|
|
|
52
52
|
REFRESH_AUTH_COOKIES = "auth_cookies"
|
|
53
53
|
|
|
54
54
|
URI_DEVICES = "/api/devices-v2/device"
|
|
55
|
+
URI_DND = "/api/dnd/device-status-list"
|
|
55
56
|
URI_SIGNIN = "/ap/signin"
|
|
56
57
|
URI_NEXUS_GRAPHQL = "/nexus/v1/graphql"
|
|
57
58
|
|
|
@@ -85,12 +86,6 @@ SENSORS: dict[str, dict[str, str | None]] = {
|
|
|
85
86
|
"subkey": "value",
|
|
86
87
|
"scale": None,
|
|
87
88
|
},
|
|
88
|
-
"speaker": {
|
|
89
|
-
"name": "volume",
|
|
90
|
-
"key": "value",
|
|
91
|
-
"subkey": "volValue",
|
|
92
|
-
"scale": None,
|
|
93
|
-
},
|
|
94
89
|
}
|
|
95
90
|
DEVICE_TO_IGNORE: list[str] = [
|
|
96
91
|
AMAZON_DEVICE_TYPE, # Alexa App for iOS
|
aioamazondevices/query.py
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"""GraphQL Queries."""
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
query
|
|
5
|
-
listEndpoints(
|
|
3
|
+
QUERY_DEVICE_DATA = """
|
|
4
|
+
query getDevicesBaseData {
|
|
5
|
+
listEndpoints(
|
|
6
|
+
listEndpointsInput: {
|
|
7
|
+
displayCategory: "ALEXA_VOICE_ENABLED"
|
|
8
|
+
includeHouseholdDevices: true
|
|
9
|
+
}
|
|
10
|
+
)
|
|
11
|
+
{
|
|
6
12
|
endpoints {
|
|
7
13
|
endpointId: id
|
|
8
14
|
friendlyNameObject { value { text } }
|
|
@@ -12,18 +18,6 @@ query getDevicesState ($latencyTolerance: LatencyToleranceValue) {
|
|
|
12
18
|
softwareVersion { value { text } }
|
|
13
19
|
creationTime
|
|
14
20
|
enablement
|
|
15
|
-
settings {
|
|
16
|
-
doNotDisturb {
|
|
17
|
-
id
|
|
18
|
-
endpointId
|
|
19
|
-
name
|
|
20
|
-
toggleValue
|
|
21
|
-
error {
|
|
22
|
-
type
|
|
23
|
-
message
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
21
|
displayCategories {
|
|
28
22
|
all { value }
|
|
29
23
|
primary { value }
|
|
@@ -41,48 +35,47 @@ query getDevicesState ($latencyTolerance: LatencyToleranceValue) {
|
|
|
41
35
|
chrsIdentifier { entityId }
|
|
42
36
|
}
|
|
43
37
|
legacyAppliance { applianceId }
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
QUERY_SENSOR_STATE = """
|
|
44
|
+
query getEndpointState($endpointId: String!, $latencyTolerance: LatencyToleranceValue) {
|
|
45
|
+
endpoint(id: $endpointId) {
|
|
46
|
+
endpointId: id
|
|
47
|
+
features(latencyToleranceValue: $latencyTolerance) {
|
|
48
|
+
name
|
|
49
|
+
instance
|
|
50
|
+
properties {
|
|
51
51
|
name
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
type
|
|
53
|
+
accuracy
|
|
54
|
+
error { type message }
|
|
55
|
+
__typename
|
|
56
|
+
... on Illuminance {
|
|
57
|
+
illuminanceValue { value }
|
|
58
|
+
timeOfSample
|
|
59
|
+
timeOfLastChange
|
|
60
|
+
}
|
|
61
|
+
... on Reachability {
|
|
62
|
+
reachabilityStatusValue
|
|
63
|
+
timeOfSample
|
|
64
|
+
timeOfLastChange
|
|
65
|
+
}
|
|
66
|
+
... on DetectionState {
|
|
67
|
+
detectionStateValue
|
|
68
|
+
timeOfSample
|
|
69
|
+
timeOfLastChange
|
|
70
|
+
}
|
|
71
|
+
... on TemperatureSensor {
|
|
54
72
|
name
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
__typename
|
|
59
|
-
... on Illuminance {
|
|
60
|
-
illuminanceValue { value }
|
|
61
|
-
timeOfSample
|
|
62
|
-
timeOfLastChange
|
|
63
|
-
}
|
|
64
|
-
... on Reachability {
|
|
65
|
-
reachabilityStatusValue
|
|
66
|
-
timeOfSample
|
|
67
|
-
timeOfLastChange
|
|
68
|
-
}
|
|
69
|
-
... on DetectionState {
|
|
70
|
-
detectionStateValue
|
|
71
|
-
timeOfSample
|
|
72
|
-
timeOfLastChange
|
|
73
|
-
}
|
|
74
|
-
... on Volume {
|
|
75
|
-
value { volValue: value }
|
|
76
|
-
}
|
|
77
|
-
... on TemperatureSensor {
|
|
78
|
-
name
|
|
79
|
-
value {
|
|
80
|
-
value
|
|
81
|
-
scale
|
|
82
|
-
}
|
|
83
|
-
timeOfSample
|
|
84
|
-
timeOfLastChange
|
|
73
|
+
value {
|
|
74
|
+
value
|
|
75
|
+
scale
|
|
85
76
|
}
|
|
77
|
+
timeOfSample
|
|
78
|
+
timeOfLastChange
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
81
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aioamazondevices
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.4.1
|
|
4
4
|
Summary: Python library to control Amazon devices
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -16,8 +16,7 @@ Requires-Dist: aiohttp (>=3.12.7)
|
|
|
16
16
|
Requires-Dist: beautifulsoup4
|
|
17
17
|
Requires-Dist: colorlog
|
|
18
18
|
Requires-Dist: langcodes
|
|
19
|
-
Requires-Dist: orjson
|
|
20
|
-
Requires-Dist: yarl
|
|
19
|
+
Requires-Dist: orjson (>=3.10,<4)
|
|
21
20
|
Project-URL: Bug Tracker, https://github.com/chemelli74/aioamazondevices/issues
|
|
22
21
|
Project-URL: Changelog, https://github.com/chemelli74/aioamazondevices/blob/main/CHANGELOG.md
|
|
23
22
|
Project-URL: Homepage, https://github.com/chemelli74/aioamazondevices
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
aioamazondevices/__init__.py,sha256=W1DlpFQ7YzCz9wmCqo41TbshbOrFmGh0FlSjOpVXN70,276
|
|
2
|
+
aioamazondevices/api.py,sha256=fwy2bPbcdYqy4_1ZXxU6IYnlZkH_NAVe52ij9yFB6R4,50006
|
|
3
|
+
aioamazondevices/const.py,sha256=A0aMbjPgIOAsSL20vjhAVkLBsi9QfkvL-1YAOEEa85I,11474
|
|
4
|
+
aioamazondevices/exceptions.py,sha256=gRYrxNAJnrV6uRuMx5e76VMvtNKyceXd09q84pDBBrI,638
|
|
5
|
+
aioamazondevices/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
aioamazondevices/query.py,sha256=SKn-fXFUnXnCvmKd6IvAGdkFL7sBzhYBEAZ0aZ2ez9E,1800
|
|
7
|
+
aioamazondevices/sounds.py,sha256=CXMDk-KoKVFxBdVAw3MeOClqgpzcVDxvQhFOJp7qX-Y,1896
|
|
8
|
+
aioamazondevices/utils.py,sha256=RzuKRhnq_8ymCoJMoQJ2vBYyuew06RSWpqQWmqdNczE,2019
|
|
9
|
+
aioamazondevices-6.4.1.dist-info/METADATA,sha256=EwLXYMIHymMWkqRnCytEvokAr0E6FyFWb-R_1CbzZdA,7648
|
|
10
|
+
aioamazondevices-6.4.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
11
|
+
aioamazondevices-6.4.1.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
|
|
12
|
+
aioamazondevices-6.4.1.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
aioamazondevices/__init__.py,sha256=uARWO02mQ70rgxwWyOTxs9HC8FjeynIm_FBuhCenQBk,276
|
|
2
|
-
aioamazondevices/api.py,sha256=B7KYropGmSwQl7sYzS7rTDDkiviIASsAszl1tsKDL70,45090
|
|
3
|
-
aioamazondevices/const.py,sha256=pPjMhNABj3rN8uvHzqj41tDiGPx-C50QRcSckvzX9z8,11561
|
|
4
|
-
aioamazondevices/exceptions.py,sha256=gRYrxNAJnrV6uRuMx5e76VMvtNKyceXd09q84pDBBrI,638
|
|
5
|
-
aioamazondevices/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
aioamazondevices/query.py,sha256=qLCuNyVlSbvVQmckZUsmftsz8s04GIukdidsOo4BrD0,2084
|
|
7
|
-
aioamazondevices/sounds.py,sha256=CXMDk-KoKVFxBdVAw3MeOClqgpzcVDxvQhFOJp7qX-Y,1896
|
|
8
|
-
aioamazondevices/utils.py,sha256=RzuKRhnq_8ymCoJMoQJ2vBYyuew06RSWpqQWmqdNczE,2019
|
|
9
|
-
aioamazondevices-6.2.9.dist-info/METADATA,sha256=0ULxMwg8faUXH8FU6_-2qvBd9Oc3LRm2HRVif5JJh7A,7656
|
|
10
|
-
aioamazondevices-6.2.9.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
11
|
-
aioamazondevices-6.2.9.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
|
|
12
|
-
aioamazondevices-6.2.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|