aioamazondevices 6.2.9__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 +181 -67
- aioamazondevices/const.py +1 -6
- aioamazondevices/query.py +47 -54
- {aioamazondevices-6.2.9.dist-info → aioamazondevices-6.4.0.dist-info}/METADATA +1 -1
- aioamazondevices-6.4.0.dist-info/RECORD +12 -0
- aioamazondevices-6.2.9.dist-info/RECORD +0 -12
- {aioamazondevices-6.2.9.dist-info → aioamazondevices-6.4.0.dist-info}/WHEEL +0 -0
- {aioamazondevices-6.2.9.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,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,56 @@ 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
|
+
self._last_endpoint_refresh = datetime.now(UTC)
|
|
751
|
+
return devices_endpoints
|
|
752
|
+
|
|
695
753
|
async def _response_to_json(self, raw_resp: ClientResponse) -> dict[str, Any]:
|
|
696
754
|
"""Convert response to JSON, if possible."""
|
|
697
755
|
try:
|
|
@@ -868,7 +926,51 @@ class AmazonEchoApi:
|
|
|
868
926
|
self,
|
|
869
927
|
) -> dict[str, AmazonDevice]:
|
|
870
928
|
"""Get Amazon devices data."""
|
|
871
|
-
|
|
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:
|
|
872
974
|
_, raw_resp = await self._session_request(
|
|
873
975
|
method=HTTPMethod.GET,
|
|
874
976
|
url=f"https://alexa.amazon.{self._domain}{URI_DEVICES}",
|
|
@@ -885,7 +987,6 @@ class AmazonEchoApi:
|
|
|
885
987
|
"Skipping device without serial number: %s", data["accountName"]
|
|
886
988
|
)
|
|
887
989
|
continue
|
|
888
|
-
devices[dev_serial] = data
|
|
889
990
|
if not self._account_owner_customer_id:
|
|
890
991
|
self._account_owner_customer_id = (
|
|
891
992
|
await self._get_account_owner_customer_id(data)
|
|
@@ -894,18 +995,13 @@ class AmazonEchoApi:
|
|
|
894
995
|
if not self._account_owner_customer_id:
|
|
895
996
|
raise CannotRetrieveData("Cannot find account owner customer ID")
|
|
896
997
|
|
|
897
|
-
devices_endpoints, devices_sensors = await self._get_sensors_states(devices)
|
|
898
|
-
|
|
899
998
|
final_devices_list: dict[str, AmazonDevice] = {}
|
|
900
|
-
for device in devices
|
|
999
|
+
for device in json_data["devices"]:
|
|
901
1000
|
# Remove stale, orphaned and virtual devices
|
|
902
1001
|
if not device or (device.get("deviceType") in DEVICE_TO_IGNORE):
|
|
903
1002
|
continue
|
|
904
1003
|
|
|
905
1004
|
serial_number: str = device["serialNumber"]
|
|
906
|
-
# Add sensors
|
|
907
|
-
sensors = devices_sensors.get(serial_number, {})
|
|
908
|
-
device_endpoint = devices_endpoints.get(serial_number, {})
|
|
909
1005
|
|
|
910
1006
|
final_devices_list[serial_number] = AmazonDevice(
|
|
911
1007
|
account_name=device["accountName"],
|
|
@@ -919,13 +1015,9 @@ class AmazonEchoApi:
|
|
|
919
1015
|
online=device["online"],
|
|
920
1016
|
serial_number=serial_number,
|
|
921
1017
|
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,
|
|
1018
|
+
entity_id=None,
|
|
1019
|
+
endpoint_id=None,
|
|
1020
|
+
sensors={},
|
|
929
1021
|
)
|
|
930
1022
|
|
|
931
1023
|
self._list_for_clusters.update(
|
|
@@ -935,7 +1027,8 @@ class AmazonEchoApi:
|
|
|
935
1027
|
}
|
|
936
1028
|
)
|
|
937
1029
|
|
|
938
|
-
|
|
1030
|
+
self._final_devices = final_devices_list
|
|
1031
|
+
self._last_devices_refresh = datetime.now(UTC)
|
|
939
1032
|
|
|
940
1033
|
async def auth_check_status(self) -> bool:
|
|
941
1034
|
"""Check AUTH status."""
|
|
@@ -1240,3 +1333,24 @@ class AmazonEchoApi:
|
|
|
1240
1333
|
|
|
1241
1334
|
_LOGGER.debug("Unexpected refresh data response")
|
|
1242
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=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
|