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.

@@ -1,6 +1,6 @@
1
1
  """aioamazondevices library."""
2
2
 
3
- __version__ = "6.2.8"
3
+ __version__ = "6.4.0"
4
4
 
5
5
 
6
6
  from .api import AmazonDevice, AmazonEchoApi
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 QUERY_DEVICE_STATE
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._devices: dict[str, Any] = {}
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 _get_devices_state(
577
- self,
578
- ) -> dict[str, Any]:
579
- """Get Device State."""
580
- payload = {
581
- "operationName": "getDevicesState",
582
- "variables": {
583
- "latencyTolerance": "LOW",
584
- },
585
- "query": QUERY_DEVICE_STATE,
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 = data["listEndpoints"]
618
- for endpoint in endpoints.get("endpoints"):
619
- serial_number = (
620
- endpoint["serialNumber"]["value"]["text"]
621
- if endpoint["serialNumber"]
622
- else None
623
- )
624
- if serial_number in self._devices:
625
- devices_sensors[serial_number] = self._get_device_sensor_state(
626
- endpoint, serial_number
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
- devices_endpoints[serial_number] = endpoint
629
-
630
- return devices_endpoints, devices_sensors
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
- error = bool(feature_property.get("error"))
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._devices = {}
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
- self._devices[dev_serial] = data
866
- if dev_serial == this_device_serial:
867
- self._account_owner_customer_id = data["deviceOwnerCustomerId"]
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
- devices_endpoints, devices_sensors = await self._get_sensors_states()
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 self._devices.values():
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=device_endpoint["legacyIdentifiers"]["chrsIdentifier"][
895
- "entityId"
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
- return final_devices_list
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
- QUERY_DEVICE_STATE = """
4
- query getDevicesState ($latencyTolerance: LatencyToleranceValue) {
5
- listEndpoints(listEndpointsInput: { includeHouseholdDevices: true }) {
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
- associatedUnits { id }
45
- connections {
46
- type
47
- macAddress
48
- bleMeshDeviceUuid
49
- }
50
- features(latencyToleranceValue: $latencyTolerance) {
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
- instance
53
- properties {
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
- type
56
- accuracy
57
- error { message }
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.2.8
3
+ Version: 6.4.0
4
4
  Summary: Python library to control Amazon devices
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -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,,