aioamazondevices 6.2.8__py3-none-any.whl → 6.4.0__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 +214 -72
- aioamazondevices/const.py +1 -6
- aioamazondevices/query.py +47 -54
- {aioamazondevices-6.2.8.dist-info → aioamazondevices-6.4.0.dist-info}/METADATA +1 -1
- aioamazondevices-6.4.0.dist-info/RECORD +12 -0
- aioamazondevices-6.2.8.dist-info/RECORD +0 -12
- {aioamazondevices-6.2.8.dist-info → aioamazondevices-6.4.0.dist-info}/WHEEL +0 -0
- {aioamazondevices-6.2.8.dist-info → aioamazondevices-6.4.0.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,7 +144,12 @@ class AmazonEchoApi:
|
|
|
141
144
|
self._list_for_clusters: dict[str, str] = {}
|
|
142
145
|
|
|
143
146
|
self._session = client_session
|
|
144
|
-
self.
|
|
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
|
|
145
153
|
|
|
146
154
|
_LOGGER.debug("Initialize library v%s", __version__)
|
|
147
155
|
|
|
@@ -337,7 +345,7 @@ class AmazonEchoApi:
|
|
|
337
345
|
self,
|
|
338
346
|
method: str,
|
|
339
347
|
url: str,
|
|
340
|
-
input_data: dict[str, Any] | None = None,
|
|
348
|
+
input_data: dict[str, Any] | list[dict[str, Any]] | None = None,
|
|
341
349
|
json_data: bool = False,
|
|
342
350
|
) -> tuple[BeautifulSoup, ClientResponse]:
|
|
343
351
|
"""Return request response context data."""
|
|
@@ -573,17 +581,21 @@ class AmazonEchoApi:
|
|
|
573
581
|
_LOGGER.info("Register device: %s", scrub_fields(login_data))
|
|
574
582
|
return login_data
|
|
575
583
|
|
|
576
|
-
async def
|
|
577
|
-
self,
|
|
578
|
-
) -> dict[str, Any]:
|
|
579
|
-
"""Get
|
|
580
|
-
payload =
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
"
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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
|
+
]
|
|
587
599
|
|
|
588
600
|
_, raw_resp = await self._session_request(
|
|
589
601
|
method=HTTPMethod.POST,
|
|
@@ -594,52 +606,52 @@ class AmazonEchoApi:
|
|
|
594
606
|
|
|
595
607
|
return await self._response_to_json(raw_resp)
|
|
596
608
|
|
|
597
|
-
async def _get_sensors_states(
|
|
598
|
-
self,
|
|
599
|
-
) -> tuple[dict[str, dict[str, Any]], dict[str, dict[str, AmazonDeviceSensor]]]:
|
|
609
|
+
async def _get_sensors_states(self) -> dict[str, dict[str, AmazonDeviceSensor]]:
|
|
600
610
|
"""Retrieve devices sensors states."""
|
|
601
|
-
devices_state = await self._get_devices_state()
|
|
602
611
|
devices_sensors: dict[str, dict[str, AmazonDeviceSensor]] = {}
|
|
603
|
-
devices_endpoints: dict[str, dict[str, Any]] = {}
|
|
604
|
-
|
|
605
|
-
if error := devices_state.get("errors"):
|
|
606
|
-
if isinstance(error, list):
|
|
607
|
-
error = error[0]
|
|
608
|
-
msg = error.get("message", "Unknown error")
|
|
609
|
-
path = error.get("path", "Unknown path")
|
|
610
|
-
_LOGGER.error("Error retrieving devices state: %s for path %s", msg, path)
|
|
611
|
-
return {}, {}
|
|
612
|
-
|
|
613
|
-
if not (data := devices_state.get("data")) or not data.get("listEndpoints"):
|
|
614
|
-
_LOGGER.error("Malformed devices state data received: %s", devices_state)
|
|
615
|
-
return {}, {}
|
|
616
612
|
|
|
617
|
-
endpoints
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
if
|
|
625
|
-
|
|
626
|
-
|
|
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
|
|
627
629
|
)
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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
|
|
631
650
|
|
|
632
651
|
def _get_device_sensor_state(
|
|
633
652
|
self, endpoint: dict[str, Any], serial_number: str
|
|
634
653
|
) -> dict[str, AmazonDeviceSensor]:
|
|
635
654
|
device_sensors: dict[str, AmazonDeviceSensor] = {}
|
|
636
|
-
if endpoint_dnd := endpoint.get("settings", {}).get("doNotDisturb"):
|
|
637
|
-
device_sensors["dnd"] = AmazonDeviceSensor(
|
|
638
|
-
name="dnd",
|
|
639
|
-
value=endpoint_dnd.get("toggleValue"),
|
|
640
|
-
error=bool(endpoint_dnd.get("error")),
|
|
641
|
-
scale=None,
|
|
642
|
-
)
|
|
643
655
|
for feature in endpoint.get("features", {}):
|
|
644
656
|
if (sensor_template := SENSORS.get(feature["name"])) is None:
|
|
645
657
|
# Skip sensors that are not in the predefined list
|
|
@@ -654,7 +666,11 @@ class AmazonEchoApi:
|
|
|
654
666
|
|
|
655
667
|
value: str | int | float = "n/a"
|
|
656
668
|
scale: str | None = None
|
|
657
|
-
|
|
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")
|
|
658
674
|
if not error:
|
|
659
675
|
try:
|
|
660
676
|
value_raw = feature_property[sensor_template["key"]]
|
|
@@ -684,15 +700,56 @@ class AmazonEchoApi:
|
|
|
684
700
|
feature_property,
|
|
685
701
|
repr(exc),
|
|
686
702
|
)
|
|
703
|
+
if error:
|
|
704
|
+
_LOGGER.debug(
|
|
705
|
+
"error in sensor %s - %s - %s", name, error_type, error_msg
|
|
706
|
+
)
|
|
687
707
|
device_sensors[name] = AmazonDeviceSensor(
|
|
688
708
|
name,
|
|
689
709
|
value,
|
|
690
710
|
error,
|
|
711
|
+
error_type,
|
|
712
|
+
error_msg,
|
|
691
713
|
scale,
|
|
692
714
|
)
|
|
693
715
|
|
|
694
716
|
return device_sensors
|
|
695
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
|
+
self._last_endpoint_refresh = datetime.now(UTC)
|
|
751
|
+
return devices_endpoints
|
|
752
|
+
|
|
696
753
|
async def _response_to_json(self, raw_resp: ClientResponse) -> dict[str, Any]:
|
|
697
754
|
"""Convert response to JSON, if possible."""
|
|
698
755
|
try:
|
|
@@ -843,11 +900,77 @@ class AmazonEchoApi:
|
|
|
843
900
|
self._country_specific_data(user_domain)
|
|
844
901
|
await self._refresh_auth_cookies()
|
|
845
902
|
|
|
903
|
+
async def _get_account_owner_customer_id(self, data: dict[str, Any]) -> str | None:
|
|
904
|
+
"""Get account owner customer ID."""
|
|
905
|
+
if data["deviceType"] != AMAZON_DEVICE_TYPE:
|
|
906
|
+
return None
|
|
907
|
+
|
|
908
|
+
account_owner_customer_id: str | None = None
|
|
909
|
+
|
|
910
|
+
this_device_serial = self._login_stored_data["device_info"][
|
|
911
|
+
"device_serial_number"
|
|
912
|
+
]
|
|
913
|
+
|
|
914
|
+
for subdevice in data["appDeviceList"]:
|
|
915
|
+
if subdevice["serialNumber"] == this_device_serial:
|
|
916
|
+
account_owner_customer_id = data["deviceOwnerCustomerId"]
|
|
917
|
+
_LOGGER.debug(
|
|
918
|
+
"Setting account owner: %s",
|
|
919
|
+
account_owner_customer_id,
|
|
920
|
+
)
|
|
921
|
+
break
|
|
922
|
+
|
|
923
|
+
return account_owner_customer_id
|
|
924
|
+
|
|
846
925
|
async def get_devices_data(
|
|
847
926
|
self,
|
|
848
927
|
) -> dict[str, AmazonDevice]:
|
|
849
928
|
"""Get Amazon devices data."""
|
|
850
|
-
self.
|
|
929
|
+
if not self._final_devices or (
|
|
930
|
+
datetime.now(UTC) - self._last_devices_refresh >= timedelta(days=1)
|
|
931
|
+
):
|
|
932
|
+
# Request base device data
|
|
933
|
+
await self._get_base_devices()
|
|
934
|
+
|
|
935
|
+
if not self._endpoints or (
|
|
936
|
+
datetime.now(UTC) - self._last_endpoint_refresh >= timedelta(minutes=30)
|
|
937
|
+
):
|
|
938
|
+
# Set device endpoint data
|
|
939
|
+
await self._set_device_endpoints_data()
|
|
940
|
+
|
|
941
|
+
await self._get_sensor_data()
|
|
942
|
+
|
|
943
|
+
return self._final_devices
|
|
944
|
+
|
|
945
|
+
async def _get_sensor_data(self) -> None:
|
|
946
|
+
devices_sensors = await self._get_sensors_states()
|
|
947
|
+
dnd_sensors = await self._get_dnd_status()
|
|
948
|
+
for device in self._final_devices.values():
|
|
949
|
+
# Update sensors
|
|
950
|
+
sensors = devices_sensors.get(device.serial_number, {})
|
|
951
|
+
if sensors:
|
|
952
|
+
device.sensors = sensors
|
|
953
|
+
else:
|
|
954
|
+
for device_sensor in device.sensors.values():
|
|
955
|
+
device_sensor.error = True
|
|
956
|
+
if device_dnd := dnd_sensors.get(device.serial_number):
|
|
957
|
+
device.sensors["dnd"] = device_dnd
|
|
958
|
+
|
|
959
|
+
async def _set_device_endpoints_data(self) -> None:
|
|
960
|
+
devices_endpoints = await self._get_devices_endpoint_data()
|
|
961
|
+
for serial_number in self._final_devices:
|
|
962
|
+
device_endpoint = devices_endpoints.get(serial_number, {})
|
|
963
|
+
endpoint_device = self._final_devices[serial_number]
|
|
964
|
+
endpoint_device.entity_id = (
|
|
965
|
+
device_endpoint["legacyIdentifiers"]["chrsIdentifier"]["entityId"]
|
|
966
|
+
if device_endpoint
|
|
967
|
+
else None
|
|
968
|
+
)
|
|
969
|
+
endpoint_device.endpoint_id = (
|
|
970
|
+
device_endpoint["endpointId"] if device_endpoint else None
|
|
971
|
+
)
|
|
972
|
+
|
|
973
|
+
async def _get_base_devices(self) -> None:
|
|
851
974
|
_, raw_resp = await self._session_request(
|
|
852
975
|
method=HTTPMethod.GET,
|
|
853
976
|
url=f"https://alexa.amazon.{self._domain}{URI_DEVICES}",
|
|
@@ -857,27 +980,28 @@ class AmazonEchoApi:
|
|
|
857
980
|
|
|
858
981
|
_LOGGER.debug("JSON devices data: %s", scrub_fields(json_data))
|
|
859
982
|
|
|
860
|
-
this_device_serial = self._login_stored_data["device_info"][
|
|
861
|
-
"device_serial_number"
|
|
862
|
-
]
|
|
863
983
|
for data in json_data["devices"]:
|
|
864
984
|
dev_serial = data.get("serialNumber")
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
985
|
+
if not dev_serial:
|
|
986
|
+
_LOGGER.warning(
|
|
987
|
+
"Skipping device without serial number: %s", data["accountName"]
|
|
988
|
+
)
|
|
989
|
+
continue
|
|
990
|
+
if not self._account_owner_customer_id:
|
|
991
|
+
self._account_owner_customer_id = (
|
|
992
|
+
await self._get_account_owner_customer_id(data)
|
|
993
|
+
)
|
|
868
994
|
|
|
869
|
-
|
|
995
|
+
if not self._account_owner_customer_id:
|
|
996
|
+
raise CannotRetrieveData("Cannot find account owner customer ID")
|
|
870
997
|
|
|
871
998
|
final_devices_list: dict[str, AmazonDevice] = {}
|
|
872
|
-
for device in
|
|
999
|
+
for device in json_data["devices"]:
|
|
873
1000
|
# Remove stale, orphaned and virtual devices
|
|
874
1001
|
if not device or (device.get("deviceType") in DEVICE_TO_IGNORE):
|
|
875
1002
|
continue
|
|
876
1003
|
|
|
877
1004
|
serial_number: str = device["serialNumber"]
|
|
878
|
-
# Add sensors
|
|
879
|
-
sensors = devices_sensors.get(serial_number, {})
|
|
880
|
-
device_endpoint = devices_endpoints.get(serial_number, {})
|
|
881
1005
|
|
|
882
1006
|
final_devices_list[serial_number] = AmazonDevice(
|
|
883
1007
|
account_name=device["accountName"],
|
|
@@ -891,13 +1015,9 @@ class AmazonEchoApi:
|
|
|
891
1015
|
online=device["online"],
|
|
892
1016
|
serial_number=serial_number,
|
|
893
1017
|
software_version=device["softwareVersion"],
|
|
894
|
-
entity_id=
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
if device_endpoint
|
|
898
|
-
else None,
|
|
899
|
-
endpoint_id=device_endpoint["endpointId"] if device_endpoint else None,
|
|
900
|
-
sensors=sensors,
|
|
1018
|
+
entity_id=None,
|
|
1019
|
+
endpoint_id=None,
|
|
1020
|
+
sensors={},
|
|
901
1021
|
)
|
|
902
1022
|
|
|
903
1023
|
self._list_for_clusters.update(
|
|
@@ -907,7 +1027,8 @@ class AmazonEchoApi:
|
|
|
907
1027
|
}
|
|
908
1028
|
)
|
|
909
1029
|
|
|
910
|
-
|
|
1030
|
+
self._final_devices = final_devices_list
|
|
1031
|
+
self._last_devices_refresh = datetime.now(UTC)
|
|
911
1032
|
|
|
912
1033
|
async def auth_check_status(self) -> bool:
|
|
913
1034
|
"""Check AUTH status."""
|
|
@@ -1212,3 +1333,24 @@ class AmazonEchoApi:
|
|
|
1212
1333
|
|
|
1213
1334
|
_LOGGER.debug("Unexpected refresh data response")
|
|
1214
1335
|
return False, {}
|
|
1336
|
+
|
|
1337
|
+
async def _get_dnd_status(self) -> dict[str, AmazonDeviceSensor]:
|
|
1338
|
+
dnd_status: dict[str, AmazonDeviceSensor] = {}
|
|
1339
|
+
_, raw_resp = await self._session_request(
|
|
1340
|
+
method=HTTPMethod.GET,
|
|
1341
|
+
url=f"https://alexa.amazon.{self._domain}{URI_DND}",
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
dnd_data = await self._response_to_json(raw_resp)
|
|
1345
|
+
_LOGGER.debug("DND data: %s", dnd_data)
|
|
1346
|
+
|
|
1347
|
+
for dnd in dnd_data.get("doNotDisturbDeviceStatusList", {}):
|
|
1348
|
+
dnd_status[dnd.get("deviceSerialNumber")] = AmazonDeviceSensor(
|
|
1349
|
+
name="dnd",
|
|
1350
|
+
value=dnd.get("enabled"),
|
|
1351
|
+
error=False,
|
|
1352
|
+
error_type=None,
|
|
1353
|
+
error_msg=None,
|
|
1354
|
+
scale=None,
|
|
1355
|
+
)
|
|
1356
|
+
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
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
aioamazondevices/__init__.py,sha256=zz9ketTcgCPBPuHWcXvZG6yu5M4IxzEpRNRWvR4ETpc,276
|
|
2
|
+
aioamazondevices/api.py,sha256=YX-3khyvvvWdsq3XE2Q1P3AzRtkw-juWoBC_qdnGA3g,49661
|
|
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.0.dist-info/METADATA,sha256=xuedY3lpMT_rHFMdPFRh6IgxMiSB_requRjwulwbxRE,7656
|
|
10
|
+
aioamazondevices-6.4.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
11
|
+
aioamazondevices-6.4.0.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
|
|
12
|
+
aioamazondevices-6.4.0.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
aioamazondevices/__init__.py,sha256=fC_cVxoQ9UV0g3MPcq9xo24JwXEXPPXuU1x5i1IA00o,276
|
|
2
|
-
aioamazondevices/api.py,sha256=xJyDMmWDizrr4k8cpoUtr3FMb7A0K3y-ls9sbh3x0lw,44084
|
|
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.8.dist-info/METADATA,sha256=HM04uPbCYPajVoqRxnrnywFsqV7YUmHDEupi0qWLd1k,7656
|
|
10
|
-
aioamazondevices-6.2.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
11
|
-
aioamazondevices-6.2.8.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
|
|
12
|
-
aioamazondevices-6.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|