aioamazondevices 11.0.1__tar.gz → 11.1.2__tar.gz

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.
Files changed (24) hide show
  1. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/PKG-INFO +1 -1
  2. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/pyproject.toml +2 -2
  3. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/__init__.py +1 -1
  4. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/api.py +117 -20
  5. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/devices.py +26 -1
  6. aioamazondevices-11.1.2/src/aioamazondevices/const/metadata.py +86 -0
  7. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/queries.py +47 -31
  8. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/http_wrapper.py +1 -0
  9. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/implementation/sequence.py +1 -1
  10. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/structures.py +1 -0
  11. aioamazondevices-11.0.1/src/aioamazondevices/const/metadata.py +0 -46
  12. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/LICENSE +0 -0
  13. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/README.md +0 -0
  14. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/__init__.py +0 -0
  15. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/http.py +0 -0
  16. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/schedules.py +0 -0
  17. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/const/sounds.py +0 -0
  18. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/exceptions.py +0 -0
  19. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/implementation/__init__.py +0 -0
  20. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/implementation/dnd.py +0 -0
  21. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/implementation/notification.py +0 -0
  22. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/login.py +0 -0
  23. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/py.typed +0 -0
  24. {aioamazondevices-11.0.1 → aioamazondevices-11.1.2}/src/aioamazondevices/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioamazondevices
3
- Version: 11.0.1
3
+ Version: 11.1.2
4
4
  Summary: Python library to control Amazon devices
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aioamazondevices"
3
- version = "11.0.1"
3
+ version = "11.1.2"
4
4
  requires-python = ">=3.12"
5
5
  description = "Python library to control Amazon devices"
6
6
  authors = [
@@ -36,7 +36,7 @@ dependencies = [
36
36
  [tool.poetry.group.dev.dependencies]
37
37
  pytest = "^9.0"
38
38
  pytest-cov = ">=5,<8"
39
- types-python-dateutil = "^2.9.0.20251115"
39
+ types-python-dateutil = "^2.9.0.20260124"
40
40
 
41
41
  [tool.semantic_release]
42
42
  version_toml = ["pyproject.toml:project.version"]
@@ -1,6 +1,6 @@
1
1
  """aioamazondevices library."""
2
2
 
3
- __version__ = "11.0.1"
3
+ __version__ = "11.1.2"
4
4
 
5
5
 
6
6
  from .api import AmazonDevice, AmazonEchoApi
@@ -9,6 +9,7 @@ from aiohttp import ClientSession
9
9
 
10
10
  from . import __version__
11
11
  from .const.devices import (
12
+ AQM_DEVICE_TYPE,
12
13
  DEVICE_TO_IGNORE,
13
14
  DEVICE_TYPE_TO_MODEL,
14
15
  SPEAKER_GROUP_FAMILY,
@@ -20,7 +21,7 @@ from .const.http import (
20
21
  URI_DEVICES,
21
22
  URI_NEXUS_GRAPHQL,
22
23
  )
23
- from .const.metadata import SENSORS
24
+ from .const.metadata import ALEXA_INFO_SKILLS, AQM_RANGE_SENSORS, SENSORS
24
25
  from .const.queries import QUERY_DEVICE_DATA, QUERY_SENSOR_STATE
25
26
  from .const.schedules import (
26
27
  NOTIFICATION_ALARM,
@@ -164,12 +165,13 @@ class AmazonEchoApi:
164
165
  self, endpoint: dict[str, Any], serial_number: str
165
166
  ) -> dict[str, AmazonDeviceSensor]:
166
167
  device_sensors: dict[str, AmazonDeviceSensor] = {}
168
+ device = self._final_devices[serial_number]
167
169
  for feature in endpoint.get("features", {}):
168
170
  if (sensor_template := SENSORS.get(feature["name"])) is None:
169
171
  # Skip sensors that are not in the predefined list
170
172
  continue
171
173
 
172
- if not (name := sensor_template["name"]):
174
+ if not (sensor_template_name_value := sensor_template["name"]):
173
175
  raise CannotRetrieveData("Unable to read sensor template")
174
176
 
175
177
  for feature_property in feature.get("properties"):
@@ -190,7 +192,7 @@ class AmazonEchoApi:
190
192
  if not value_raw:
191
193
  _LOGGER.warning(
192
194
  "Sensor %s [device %s] ignored due to empty value",
193
- name,
195
+ sensor_template_name_value,
194
196
  serial_number,
195
197
  )
196
198
  continue
@@ -208,26 +210,50 @@ class AmazonEchoApi:
208
210
  except (KeyError, ValueError) as exc:
209
211
  _LOGGER.warning(
210
212
  "Sensor %s [device %s] ignored due to errors in feature %s: %s", # noqa: E501
211
- name,
213
+ sensor_template_name_value,
212
214
  serial_number,
213
215
  feature_property,
214
216
  repr(exc),
215
217
  )
216
218
  if error:
217
219
  _LOGGER.debug(
218
- "error in sensor %s - %s - %s", name, error_type, error_msg
219
- )
220
-
221
- if error_type != "NOT_FOUND":
222
- device_sensors[name] = AmazonDeviceSensor(
223
- name,
224
- value,
225
- error,
220
+ "error in sensor %s - %s - %s",
221
+ sensor_template_name_value,
226
222
  error_type,
227
223
  error_msg,
228
- scale,
229
224
  )
230
225
 
226
+ if error_type == "NOT_FOUND":
227
+ continue
228
+
229
+ sensor_name = sensor_template_name_value
230
+
231
+ if (
232
+ device.device_type == AQM_DEVICE_TYPE
233
+ and sensor_template_name_value == "rangeValue"
234
+ ):
235
+ if not (
236
+ (instance := feature.get("instance"))
237
+ and (aqm_sensor := AQM_RANGE_SENSORS.get(instance))
238
+ and (aqm_sensor_name := aqm_sensor.get("name"))
239
+ ):
240
+ _LOGGER.debug(
241
+ "No template for rangeValue (%s) - Skipping sensor",
242
+ instance,
243
+ )
244
+ continue
245
+ sensor_name = aqm_sensor_name
246
+ scale = aqm_sensor.get("scale")
247
+
248
+ device_sensors[sensor_name] = AmazonDeviceSensor(
249
+ sensor_name,
250
+ value,
251
+ error,
252
+ error_type,
253
+ error_msg,
254
+ scale,
255
+ )
256
+
231
257
  return device_sensors
232
258
 
233
259
  async def _get_devices_endpoint_data(self) -> dict[str, dict[str, Any]]:
@@ -247,13 +273,15 @@ class AmazonEchoApi:
247
273
 
248
274
  endpoint_data = await self._http_wrapper.response_to_json(raw_resp, "endpoint")
249
275
 
250
- if not (data := endpoint_data.get("data")) or not data.get("listEndpoints"):
276
+ if not (data := endpoint_data.get("data")) or not data.get("alexaVoiceDevices"):
251
277
  await self._format_human_error(endpoint_data)
252
278
  return {}
253
279
 
254
- endpoints = data["listEndpoints"]
255
280
  devices_endpoints: dict[str, dict[str, Any]] = {}
256
- for endpoint in endpoints.get("endpoints"):
281
+
282
+ # Process Alexa Voice Enabled devices
283
+ # Just map endpoint ID to serial number to facilitate sensor lookup
284
+ for endpoint in data.get("alexaVoiceDevices", {}).get("endpoints", {}):
257
285
  # save looking up sensor data on apps
258
286
  if endpoint.get("alexaEnabledMetadata", {}).get("category") == "APP":
259
287
  continue
@@ -263,6 +291,39 @@ class AmazonEchoApi:
263
291
  devices_endpoints[serial_number] = endpoint
264
292
  self._endpoints[endpoint["endpointId"]] = serial_number
265
293
 
294
+ # Process Air Quality Monitors if present
295
+ # map endpoint ID to serial number to facilitate sensor lookup but also
296
+ # create AmazonDevice as these are not present in api/devices-v2/device endpoint
297
+ for aqm_endpoint in data.get("airQualityMonitors", {}).get("endpoints", {}):
298
+ aqm_serial_number: str = aqm_endpoint["serialNumber"]["value"]["text"]
299
+ devices_endpoints[aqm_serial_number] = aqm_endpoint
300
+ self._endpoints[aqm_endpoint["endpointId"]] = aqm_serial_number
301
+
302
+ device_name = aqm_endpoint["friendlyNameObject"]["value"]["text"]
303
+ device_type = aqm_endpoint["legacyIdentifiers"]["dmsIdentifier"][
304
+ "deviceType"
305
+ ]["value"]["text"]
306
+ software_version = aqm_endpoint["softwareVersion"]["value"]["text"]
307
+
308
+ self._final_devices[aqm_serial_number] = AmazonDevice(
309
+ account_name=device_name,
310
+ capabilities=[],
311
+ device_family="AIR_QUALITY_MONITOR",
312
+ device_type=device_type,
313
+ device_owner_customer_id=self._session_state_data.account_customer_id
314
+ or "n/a",
315
+ household_device=False,
316
+ device_cluster_members={aqm_serial_number: AQM_DEVICE_TYPE},
317
+ online=True,
318
+ serial_number=aqm_serial_number,
319
+ software_version=software_version,
320
+ entity_id=None,
321
+ endpoint_id=aqm_endpoint.get("endpointId"),
322
+ sensors={},
323
+ notifications_supported=False,
324
+ notifications={},
325
+ )
326
+
266
327
  return devices_endpoints
267
328
 
268
329
  async def get_devices_data(
@@ -307,9 +368,15 @@ class AmazonEchoApi:
307
368
  sensors = devices_sensors.get(device.serial_number, {})
308
369
  if sensors:
309
370
  device.sensors = sensors
371
+ if reachability_sensor := sensors.get("reachability"):
372
+ device.online = reachability_sensor.value == "OK"
373
+ else:
374
+ device.online = False
310
375
  else:
376
+ device.online = False
311
377
  for device_sensor in device.sensors.values():
312
378
  device_sensor.error = True
379
+
313
380
  if (
314
381
  device_dnd := dnd_sensors.get(device.serial_number)
315
382
  ) and device.device_family != SPEAKER_GROUP_FAMILY:
@@ -341,6 +408,15 @@ class AmazonEchoApi:
341
408
  ):
342
409
  device.notifications[notification_type] = notification_object
343
410
 
411
+ # base online status of speaker groups on their members
412
+ for device in self._final_devices.values():
413
+ if device.device_family == SPEAKER_GROUP_FAMILY:
414
+ device.online = all(
415
+ d.online
416
+ for d in self._final_devices.values()
417
+ if d.serial_number in device.device_cluster_members
418
+ )
419
+
344
420
  async def _set_device_endpoints_data(self) -> None:
345
421
  """Set device endpoint data."""
346
422
  devices_endpoints = await self._get_devices_endpoint_data()
@@ -382,6 +458,11 @@ class AmazonEchoApi:
382
458
 
383
459
  serial_number: str = device["serialNumber"]
384
460
 
461
+ _has_notification_capability = any(
462
+ capability in capabilities
463
+ for capability in ["REMINDERS", "TIMERS_AND_ALARMS"]
464
+ )
465
+
385
466
  final_devices_list[serial_number] = AmazonDevice(
386
467
  account_name=account_name,
387
468
  capabilities=capabilities,
@@ -399,6 +480,7 @@ class AmazonEchoApi:
399
480
  entity_id=None,
400
481
  endpoint_id=None,
401
482
  sensors={},
483
+ notifications_supported=_has_notification_capability,
402
484
  notifications={},
403
485
  )
404
486
 
@@ -453,7 +535,7 @@ class AmazonEchoApi:
453
535
  sound_name: str,
454
536
  ) -> None:
455
537
  """Call Alexa.Sound to play sound."""
456
- await self._sequence_handler.send_message(
538
+ await self._call_alexa_command_per_cluster_member(
457
539
  device, AmazonSequenceType.Sound, sound_name
458
540
  )
459
541
 
@@ -474,7 +556,7 @@ class AmazonEchoApi:
474
556
  text_command: str,
475
557
  ) -> None:
476
558
  """Call Alexa.TextCommand to issue command."""
477
- await self._sequence_handler.send_message(
559
+ await self._call_alexa_command_per_cluster_member(
478
560
  device, AmazonSequenceType.TextCommand, text_command
479
561
  )
480
562
 
@@ -484,7 +566,7 @@ class AmazonEchoApi:
484
566
  skill_name: str,
485
567
  ) -> None:
486
568
  """Call Alexa.LaunchSkill to launch a skill."""
487
- await self._sequence_handler.send_message(
569
+ await self._call_alexa_command_per_cluster_member(
488
570
  device, AmazonSequenceType.LaunchSkill, skill_name
489
571
  )
490
572
 
@@ -494,7 +576,22 @@ class AmazonEchoApi:
494
576
  info_skill_name: str,
495
577
  ) -> None:
496
578
  """Call Info skill. See ALEXA_INFO_SKILLS . const."""
497
- await self._sequence_handler.send_message(device, info_skill_name, "")
579
+ info_skill = ALEXA_INFO_SKILLS.get(info_skill_name, info_skill_name)
580
+ await self._call_alexa_command_per_cluster_member(device, info_skill, "")
581
+
582
+ async def _call_alexa_command_per_cluster_member(
583
+ self,
584
+ device: AmazonDevice,
585
+ message_type: str,
586
+ message_body: str,
587
+ ) -> None:
588
+ """Call Alexa command per cluster member."""
589
+ for cluster_member in device.device_cluster_members:
590
+ await self._sequence_handler.send_message(
591
+ self._final_devices[cluster_member],
592
+ message_type,
593
+ message_body,
594
+ )
498
595
 
499
596
  async def _format_human_error(self, sensors_state: dict) -> bool:
500
597
  """Format human readable error from malformed data."""
@@ -4,6 +4,7 @@ from .http import AMAZON_DEVICE_TYPE
4
4
 
5
5
  SPEAKER_GROUP_FAMILY = "WHA"
6
6
  SPEAKER_GROUP_MODEL = "Speaker Group"
7
+ AQM_DEVICE_TYPE = "AEZME1X38KDRA"
7
8
 
8
9
  DEVICE_TO_IGNORE: list[str] = [
9
10
  AMAZON_DEVICE_TYPE, # Alexa App for iOS
@@ -28,10 +29,15 @@ DEVICE_TO_IGNORE: list[str] = [
28
29
  "A3BW5ZVFHRCQPO", # BMW Mini Car System - issue #479
29
30
  "A133UZ2CB0IB8", # Sony Soundbar Sony HT-A5000 - issue #486
30
31
  "A2M9HB23M9MSSM", # Smartwatch Amazfit Bip U Pro - issue #507
32
+ "A2QDHDQIWC2LTG", # Echo Buds (Left) - issue #515
33
+ "A31PMVIWCRNTX2", # Echo Buds (Right) - issue #515
34
+ "A3HVREY4JWAZ6K", # Echo Buds (Charger) - issue #515
31
35
  "A1P7E7V3FCZKU6", # Toshiba Corporation TV 32LF221U19 - issue #531
36
+ "APHEAY6LX7T13", # Samsung Refrigerator RS22T5561SR/AA - issue #577
32
37
  "A1NPP2J03FTS0I", # Eero Pro 6 - issue #602
33
38
  "A14AIWB3T3AS1Z", # Samsung Soundbar HW-Q950A - issue #603
34
- "APHEAY6LX7T13", # Samsung Refrigerator RS22T5561SR/AA - issue #577
39
+ "A1X5IB2CRN3E8G", # Fitbit Versa 3 - issue #651
40
+ "A1NQ0LXWBGVQS9", # Samsung 2012 QLED TV - Issue #660
35
41
  ]
36
42
 
37
43
  DEVICE_TYPE_TO_MODEL: dict[str, dict[str, str | None]] = {
@@ -426,4 +432,23 @@ DEVICE_TYPE_TO_MODEL: dict[str, dict[str, str | None]] = {
426
432
  "model": "Orbi Voice (RBS40V)",
427
433
  "hw_version": None,
428
434
  },
435
+ AQM_DEVICE_TYPE: {
436
+ "model": "Air Quality Monitor",
437
+ "hw_version": "Gen1",
438
+ },
439
+ "A1MR3F8QRZNAXI": {
440
+ "model": "Echo Dot Max",
441
+ "hw_version": "Gen1",
442
+ },
443
+ "A1XULUOD31VLF4": {
444
+ "manufacturer": "Broan-NuTone LLC",
445
+ "model": "Bathroom Fan with Alexa (VC110CCT)",
446
+ "hw_version": None,
447
+ },
448
+ "A15QWUTQ6FSMYX": {
449
+ # This appears to be a group for both speakers
450
+ # but four devices show this device type (see issue #515)
451
+ "model": "Echo Buds",
452
+ "hw_version": "Gen2",
453
+ },
429
454
  }
@@ -0,0 +1,86 @@
1
+ """aioamazondevices Additional entities const."""
2
+
3
+ SENSOR_STATE_OFF = "NOT_DETECTED"
4
+
5
+ SENSORS: dict[str, dict[str, str | None]] = {
6
+ "temperatureSensor": {
7
+ "name": "temperature",
8
+ "key": "value",
9
+ "subkey": "value",
10
+ "scale": "scale",
11
+ },
12
+ "motionSensor": {
13
+ "name": "detectionState",
14
+ "key": "detectionStateValue",
15
+ "subkey": None,
16
+ "scale": None,
17
+ },
18
+ "lightSensor": {
19
+ "name": "illuminance",
20
+ "key": "illuminanceValue",
21
+ "subkey": "value",
22
+ "scale": None,
23
+ },
24
+ "connectivity": {
25
+ "name": "reachability",
26
+ "key": "reachabilityStatusValue",
27
+ "subkey": None,
28
+ "scale": None,
29
+ },
30
+ "range": {
31
+ "name": "rangeValue",
32
+ "key": "rangeValue",
33
+ "subkey": "value",
34
+ "scale": None,
35
+ },
36
+ }
37
+
38
+ AQM_RANGE_SENSORS: dict[str, dict[str, str | None]] = {
39
+ "4": {
40
+ "name": "Humidity",
41
+ "scale": "%",
42
+ },
43
+ "5": {
44
+ "name": "VOC",
45
+ "scale": None,
46
+ },
47
+ "6": {
48
+ "name": "PM25",
49
+ "scale": "MicroGramsPerCubicMeter",
50
+ },
51
+ "7": {
52
+ "name": "PM10",
53
+ "scale": "MicroGramsPerCubicMeter",
54
+ },
55
+ "8": {
56
+ "name": "CO",
57
+ "scale": "ppm",
58
+ },
59
+ "9": {
60
+ "name": "Air Quality",
61
+ "scale": None,
62
+ },
63
+ }
64
+
65
+
66
+ ALEXA_INFO_SKILLS = {
67
+ "alexa_calendar_today": "Alexa.Calendar.PlayToday",
68
+ "alexa_calendar_tomorrow": "Alexa.Calendar.PlayTomorrow",
69
+ "alexa_calendar_next": "Alexa.Calendar.PlayNext",
70
+ "alexa_date": "Alexa.Date.Play",
71
+ "alexa_time": "Alexa.Time.Play",
72
+ "alexa_nationalnews": "Alexa.News.NationalNews",
73
+ "alexa_flashbriefing": "Alexa.FlashBriefing.Play",
74
+ "alexa_traffic": "Alexa.Traffic.Play",
75
+ "alexa_weather": "Alexa.Weather.Play",
76
+ "alexa_cleanup": "Alexa.CleanUp.Play",
77
+ "alexa_goodmorning": "Alexa.GoodMorning.Play",
78
+ "alexa_singasong": "Alexa.SingASong.Play",
79
+ "alexa_funfact": "Alexa.FunFact.Play",
80
+ "alexa_joke": "Alexa.Joke.Play",
81
+ "alexa_tellstory": "Alexa.TellStory.Play",
82
+ "alexa_imhome": "Alexa.ImHome.Play",
83
+ "alexa_goodnight": "Alexa.GoodNight.Play",
84
+ }
85
+
86
+ MAX_CUSTOMER_ACCOUNT_RETRIES = 3
@@ -2,40 +2,50 @@
2
2
 
3
3
  QUERY_DEVICE_DATA = """
4
4
  query getDevicesBaseData {
5
- listEndpoints(
5
+ alexaVoiceDevices: listEndpoints(
6
6
  listEndpointsInput: {
7
- displayCategory: "ALEXA_VOICE_ENABLED"
8
- includeHouseholdDevices: true
7
+ displayCategory: "ALEXA_VOICE_ENABLED"
8
+ includeHouseholdDevices: true
9
9
  }
10
- )
11
- {
12
- endpoints {
13
- endpointId: id
14
- friendlyNameObject { value { text } }
15
- manufacturer { value { text } }
16
- model { value { text} }
17
- serialNumber { value { text } }
18
- softwareVersion { value { text } }
19
- creationTime
20
- enablement
21
- displayCategories {
22
- all { value }
23
- primary { value }
24
- }
25
- alexaEnabledMetadata {
26
- iconId
27
- isVisible
28
- category
29
- capabilities
30
- }
31
- legacyIdentifiers {
32
- dmsIdentifier {
33
- deviceType { value { text } }
34
- }
35
- chrsIdentifier { entityId }
36
- }
37
- legacyAppliance { applianceId }
10
+ ) {
11
+ ...DeviceEndpoints
12
+ }
13
+
14
+ airQualityMonitors: listEndpoints(
15
+ listEndpointsInput: {
16
+ displayCategory: "AIR_QUALITY_MONITOR"
17
+ includeHouseholdDevices: true
38
18
  }
19
+ ) {
20
+ ...DeviceEndpoints
21
+ }
22
+ }
23
+
24
+ fragment DeviceEndpoints on ListEndpointsResponse {
25
+ endpoints {
26
+ endpointId: id
27
+ friendlyNameObject { value { text } }
28
+ manufacturer { value { text } }
29
+ model { value { text } }
30
+ serialNumber { value { text } }
31
+ softwareVersion { value { text } }
32
+ creationTime
33
+ enablement
34
+ displayCategories {
35
+ all { value }
36
+ primary { value }
37
+ }
38
+ alexaEnabledMetadata {
39
+ iconId
40
+ isVisible
41
+ category
42
+ capabilities
43
+ }
44
+ legacyIdentifiers {
45
+ dmsIdentifier { deviceType { value { text } } }
46
+ chrsIdentifier { entityId }
47
+ }
48
+ legacyAppliance { applianceId }
39
49
  }
40
50
  }
41
51
  """
@@ -46,6 +56,7 @@ fragment EndpointState on Endpoint {
46
56
  friendlyNameObject { value { text } }
47
57
  features {
48
58
  name
59
+ instance
49
60
  properties {
50
61
  name
51
62
  type
@@ -76,6 +87,11 @@ fragment EndpointState on Endpoint {
76
87
  timeOfSample
77
88
  timeOfLastChange
78
89
  }
90
+ ... on RangeValue {
91
+ rangeValue { value }
92
+ timeOfSample
93
+ timeOfLastChange
94
+ }
79
95
  }
80
96
  }
81
97
  }
@@ -371,6 +371,7 @@ class AmazonHttpWrapper:
371
371
  ]:
372
372
  raise CannotAuthenticate(await self.http_phrase_error(resp.status))
373
373
  if not await self._ignore_ap_signin_error(resp):
374
+ _LOGGER.debug("Error response content: %s", await resp.text())
374
375
  raise CannotRetrieveData(
375
376
  f"Request failed: {await self.http_phrase_error(resp.status)}"
376
377
  )
@@ -123,7 +123,7 @@ class AmazonSequenceHandler:
123
123
  "uri": "connection://AMAZON.Launch/" + message_body,
124
124
  },
125
125
  }
126
- elif message_type in ALEXA_INFO_SKILLS:
126
+ elif message_type in ALEXA_INFO_SKILLS.values():
127
127
  payload = {
128
128
  **base_payload,
129
129
  }
@@ -44,6 +44,7 @@ class AmazonDevice:
44
44
  entity_id: str | None
45
45
  endpoint_id: str | None
46
46
  sensors: dict[str, AmazonDeviceSensor]
47
+ notifications_supported: bool
47
48
  notifications: dict[str, AmazonSchedule]
48
49
 
49
50
 
@@ -1,46 +0,0 @@
1
- """aioamazondevices Additional entities const."""
2
-
3
- SENSOR_STATE_OFF = "NOT_DETECTED"
4
-
5
- SENSORS: dict[str, dict[str, str | None]] = {
6
- "temperatureSensor": {
7
- "name": "temperature",
8
- "key": "value",
9
- "subkey": "value",
10
- "scale": "scale",
11
- },
12
- "motionSensor": {
13
- "name": "detectionState",
14
- "key": "detectionStateValue",
15
- "subkey": None,
16
- "scale": None,
17
- },
18
- "lightSensor": {
19
- "name": "illuminance",
20
- "key": "illuminanceValue",
21
- "subkey": "value",
22
- "scale": None,
23
- },
24
- }
25
-
26
- ALEXA_INFO_SKILLS = [
27
- "Alexa.Calendar.PlayToday",
28
- "Alexa.Calendar.PlayTomorrow",
29
- "Alexa.Calendar.PlayNext",
30
- "Alexa.Date.Play",
31
- "Alexa.Time.Play",
32
- "Alexa.News.NationalNews",
33
- "Alexa.FlashBriefing.Play",
34
- "Alexa.Traffic.Play",
35
- "Alexa.Weather.Play",
36
- "Alexa.CleanUp.Play",
37
- "Alexa.GoodMorning.Play",
38
- "Alexa.SingASong.Play",
39
- "Alexa.FunFact.Play",
40
- "Alexa.Joke.Play",
41
- "Alexa.TellStory.Play",
42
- "Alexa.ImHome.Play",
43
- "Alexa.GoodNight.Play",
44
- ]
45
-
46
- MAX_CUSTOMER_ACCOUNT_RETRIES = 3