aioamazondevices 6.5.3__tar.gz → 8.0.0__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.
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/PKG-INFO +10 -4
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/README.md +9 -3
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/pyproject.toml +1 -1
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/src/aioamazondevices/__init__.py +1 -1
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/src/aioamazondevices/api.py +54 -138
- aioamazondevices-8.0.0/src/aioamazondevices/const/__init__.py +1 -0
- aioamazondevices-8.0.0/src/aioamazondevices/const/common.py +26 -0
- aioamazondevices-6.5.3/src/aioamazondevices/const.py → aioamazondevices-8.0.0/src/aioamazondevices/const/devices.py +2 -163
- aioamazondevices-8.0.0/src/aioamazondevices/const/http.py +36 -0
- aioamazondevices-8.0.0/src/aioamazondevices/const/metadata.py +44 -0
- aioamazondevices-6.5.3/src/aioamazondevices/query.py → aioamazondevices-8.0.0/src/aioamazondevices/const/queries.py +1 -1
- aioamazondevices-8.0.0/src/aioamazondevices/const/schedules.py +61 -0
- {aioamazondevices-6.5.3/src/aioamazondevices → aioamazondevices-8.0.0/src/aioamazondevices/const}/sounds.py +2 -1
- aioamazondevices-8.0.0/src/aioamazondevices/structures.py +65 -0
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/src/aioamazondevices/utils.py +1 -1
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/LICENSE +0 -0
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/src/aioamazondevices/exceptions.py +0 -0
- {aioamazondevices-6.5.3 → aioamazondevices-8.0.0}/src/aioamazondevices/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aioamazondevices
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
Summary: Python library to control Amazon devices
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -81,7 +81,6 @@ The script accept command line arguments or a library_test.json config file:
|
|
|
81
81
|
"single_device_name": "Echo Dot Livingroom",
|
|
82
82
|
"cluster_device_name": "Everywhere",
|
|
83
83
|
"login_data_file": "out/login_data.json",
|
|
84
|
-
"save_raw_data": true,
|
|
85
84
|
"test": true
|
|
86
85
|
}
|
|
87
86
|
```
|
|
@@ -142,6 +141,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
142
141
|
<sub><b>Flo</b></sub>
|
|
143
142
|
</a>
|
|
144
143
|
</td>
|
|
144
|
+
<td align="center">
|
|
145
|
+
<a href="https://github.com/francescolf">
|
|
146
|
+
<img src="https://avatars.githubusercontent.com/u/14892143?v=4" width="100;" alt="francescolf"/>
|
|
147
|
+
<br />
|
|
148
|
+
<sub><b>Francesco Lo Faro</b></sub>
|
|
149
|
+
</a>
|
|
150
|
+
</td>
|
|
151
|
+
</tr>
|
|
152
|
+
<tr>
|
|
145
153
|
<td align="center">
|
|
146
154
|
<a href="https://github.com/lchavezcuu">
|
|
147
155
|
<img src="https://avatars.githubusercontent.com/u/22165856?v=4" width="100;" alt="lchavezcuu"/>
|
|
@@ -149,8 +157,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
149
157
|
<sub><b>Luis Chavez</b></sub>
|
|
150
158
|
</a>
|
|
151
159
|
</td>
|
|
152
|
-
</tr>
|
|
153
|
-
<tr>
|
|
154
160
|
<td align="center">
|
|
155
161
|
<a href="https://github.com/maxmati">
|
|
156
162
|
<img src="https://avatars.githubusercontent.com/u/509560?v=4" width="100;" alt="maxmati"/>
|
|
@@ -56,7 +56,6 @@ The script accept command line arguments or a library_test.json config file:
|
|
|
56
56
|
"single_device_name": "Echo Dot Livingroom",
|
|
57
57
|
"cluster_device_name": "Everywhere",
|
|
58
58
|
"login_data_file": "out/login_data.json",
|
|
59
|
-
"save_raw_data": true,
|
|
60
59
|
"test": true
|
|
61
60
|
}
|
|
62
61
|
```
|
|
@@ -117,6 +116,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
117
116
|
<sub><b>Flo</b></sub>
|
|
118
117
|
</a>
|
|
119
118
|
</td>
|
|
119
|
+
<td align="center">
|
|
120
|
+
<a href="https://github.com/francescolf">
|
|
121
|
+
<img src="https://avatars.githubusercontent.com/u/14892143?v=4" width="100;" alt="francescolf"/>
|
|
122
|
+
<br />
|
|
123
|
+
<sub><b>Francesco Lo Faro</b></sub>
|
|
124
|
+
</a>
|
|
125
|
+
</td>
|
|
126
|
+
</tr>
|
|
127
|
+
<tr>
|
|
120
128
|
<td align="center">
|
|
121
129
|
<a href="https://github.com/lchavezcuu">
|
|
122
130
|
<img src="https://avatars.githubusercontent.com/u/22165856?v=4" width="100;" alt="lchavezcuu"/>
|
|
@@ -124,8 +132,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
124
132
|
<sub><b>Luis Chavez</b></sub>
|
|
125
133
|
</a>
|
|
126
134
|
</td>
|
|
127
|
-
</tr>
|
|
128
|
-
<tr>
|
|
129
135
|
<td align="center">
|
|
130
136
|
<a href="https://github.com/maxmati">
|
|
131
137
|
<img src="https://avatars.githubusercontent.com/u/509560?v=4" width="100;" alt="maxmati"/>
|
|
@@ -3,15 +3,12 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import base64
|
|
5
5
|
import hashlib
|
|
6
|
-
import mimetypes
|
|
7
6
|
import secrets
|
|
8
7
|
import uuid
|
|
9
|
-
from
|
|
8
|
+
from collections.abc import Callable, Coroutine
|
|
10
9
|
from datetime import UTC, datetime, timedelta
|
|
11
|
-
from enum import StrEnum
|
|
12
10
|
from http import HTTPMethod, HTTPStatus
|
|
13
11
|
from http.cookies import Morsel
|
|
14
|
-
from pathlib import Path
|
|
15
12
|
from typing import Any, cast
|
|
16
13
|
from urllib.parse import parse_qs, urlencode
|
|
17
14
|
|
|
@@ -30,9 +27,13 @@ from multidict import MultiDictProxy
|
|
|
30
27
|
from yarl import URL
|
|
31
28
|
|
|
32
29
|
from . import __version__
|
|
33
|
-
from .const import
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
from .const.common import _LOGGER
|
|
31
|
+
from .const.devices import (
|
|
32
|
+
DEVICE_TO_IGNORE,
|
|
33
|
+
DEVICE_TYPE_TO_MODEL,
|
|
34
|
+
SPEAKER_GROUP_FAMILY,
|
|
35
|
+
)
|
|
36
|
+
from .const.http import (
|
|
36
37
|
AMAZON_APP_BUNDLE_ID,
|
|
37
38
|
AMAZON_APP_ID,
|
|
38
39
|
AMAZON_APP_NAME,
|
|
@@ -41,33 +42,30 @@ from .const import (
|
|
|
41
42
|
AMAZON_DEVICE_SOFTWARE_VERSION,
|
|
42
43
|
AMAZON_DEVICE_TYPE,
|
|
43
44
|
ARRAY_WRAPPER,
|
|
44
|
-
BIN_EXTENSION,
|
|
45
|
-
COUNTRY_GROUPS,
|
|
46
45
|
CSRF_COOKIE,
|
|
47
46
|
DEFAULT_HEADERS,
|
|
48
47
|
DEFAULT_SITE,
|
|
49
|
-
DEVICE_TO_IGNORE,
|
|
50
|
-
DEVICE_TYPE_TO_MODEL,
|
|
51
|
-
HTML_EXTENSION,
|
|
52
48
|
HTTP_ERROR_199,
|
|
53
49
|
HTTP_ERROR_299,
|
|
54
|
-
JSON_EXTENSION,
|
|
55
|
-
NOTIFICATION_ALARM,
|
|
56
|
-
NOTIFICATION_MUSIC_ALARM,
|
|
57
|
-
NOTIFICATION_REMINDER,
|
|
58
|
-
NOTIFICATION_TIMER,
|
|
59
|
-
RECURRING_PATTERNS,
|
|
60
50
|
REFRESH_ACCESS_TOKEN,
|
|
61
51
|
REFRESH_AUTH_COOKIES,
|
|
62
52
|
REQUEST_AGENT,
|
|
63
|
-
SAVE_PATH,
|
|
64
|
-
SENSORS,
|
|
65
|
-
SPEAKER_GROUP_FAMILY,
|
|
66
53
|
URI_DEVICES,
|
|
67
54
|
URI_DND,
|
|
68
55
|
URI_NEXUS_GRAPHQL,
|
|
69
56
|
URI_NOTIFICATIONS,
|
|
70
57
|
URI_SIGNIN,
|
|
58
|
+
)
|
|
59
|
+
from .const.metadata import ALEXA_INFO_SKILLS, SENSORS
|
|
60
|
+
from .const.queries import QUERY_DEVICE_DATA, QUERY_SENSOR_STATE
|
|
61
|
+
from .const.schedules import (
|
|
62
|
+
COUNTRY_GROUPS,
|
|
63
|
+
NOTIFICATION_ALARM,
|
|
64
|
+
NOTIFICATION_MUSIC_ALARM,
|
|
65
|
+
NOTIFICATION_REMINDER,
|
|
66
|
+
NOTIFICATION_TIMER,
|
|
67
|
+
NOTIFICATIONS_SUPPORTED,
|
|
68
|
+
RECURRING_PATTERNS,
|
|
71
69
|
WEEKEND_EXCEPTIONS,
|
|
72
70
|
)
|
|
73
71
|
from .exceptions import (
|
|
@@ -77,70 +75,16 @@ from .exceptions import (
|
|
|
77
75
|
CannotRetrieveData,
|
|
78
76
|
WrongMethod,
|
|
79
77
|
)
|
|
80
|
-
from .
|
|
78
|
+
from .structures import (
|
|
79
|
+
AmazonDevice,
|
|
80
|
+
AmazonDeviceSensor,
|
|
81
|
+
AmazonMusicSource,
|
|
82
|
+
AmazonSchedule,
|
|
83
|
+
AmazonSequenceType,
|
|
84
|
+
)
|
|
81
85
|
from .utils import obfuscate_email, scrub_fields
|
|
82
86
|
|
|
83
87
|
|
|
84
|
-
@dataclass
|
|
85
|
-
class AmazonDeviceSensor:
|
|
86
|
-
"""Amazon device sensor class."""
|
|
87
|
-
|
|
88
|
-
name: str
|
|
89
|
-
value: str | int | float
|
|
90
|
-
error: bool
|
|
91
|
-
error_type: str | None
|
|
92
|
-
error_msg: str | None
|
|
93
|
-
scale: str | None
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@dataclass
|
|
97
|
-
class AmazonSchedule:
|
|
98
|
-
"""Amazon schedule class."""
|
|
99
|
-
|
|
100
|
-
type: str # alarm, reminder, timer
|
|
101
|
-
status: str
|
|
102
|
-
label: str
|
|
103
|
-
next_occurrence: datetime | None
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@dataclass
|
|
107
|
-
class AmazonDevice:
|
|
108
|
-
"""Amazon device class."""
|
|
109
|
-
|
|
110
|
-
account_name: str
|
|
111
|
-
capabilities: list[str]
|
|
112
|
-
device_family: str
|
|
113
|
-
device_type: str
|
|
114
|
-
device_owner_customer_id: str
|
|
115
|
-
household_device: bool
|
|
116
|
-
device_cluster_members: list[str]
|
|
117
|
-
online: bool
|
|
118
|
-
serial_number: str
|
|
119
|
-
software_version: str
|
|
120
|
-
entity_id: str | None
|
|
121
|
-
endpoint_id: str | None
|
|
122
|
-
sensors: dict[str, AmazonDeviceSensor]
|
|
123
|
-
notifications: dict[str, AmazonSchedule]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
class AmazonSequenceType(StrEnum):
|
|
127
|
-
"""Amazon sequence types."""
|
|
128
|
-
|
|
129
|
-
Announcement = "AlexaAnnouncement"
|
|
130
|
-
Speak = "Alexa.Speak"
|
|
131
|
-
Sound = "Alexa.Sound"
|
|
132
|
-
Music = "Alexa.Music.PlaySearchPhrase"
|
|
133
|
-
TextCommand = "Alexa.TextCommand"
|
|
134
|
-
LaunchSkill = "Alexa.Operation.SkillConnections.Launch"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class AmazonMusicSource(StrEnum):
|
|
138
|
-
"""Amazon music sources."""
|
|
139
|
-
|
|
140
|
-
Radio = "TUNEIN"
|
|
141
|
-
AmazonMusic = "AMAZON_MUSIC"
|
|
142
|
-
|
|
143
|
-
|
|
144
88
|
class AmazonEchoApi:
|
|
145
89
|
"""Queries Amazon for Echo devices."""
|
|
146
90
|
|
|
@@ -150,6 +94,8 @@ class AmazonEchoApi:
|
|
|
150
94
|
login_email: str,
|
|
151
95
|
login_password: str,
|
|
152
96
|
login_data: dict[str, Any] | None = None,
|
|
97
|
+
save_to_file: Callable[[str | dict, str, str], Coroutine[Any, Any, None]]
|
|
98
|
+
| None = None,
|
|
153
99
|
) -> None:
|
|
154
100
|
"""Initialize the scanner."""
|
|
155
101
|
# Check if there is a previous login, otherwise use default (US)
|
|
@@ -161,7 +107,7 @@ class AmazonEchoApi:
|
|
|
161
107
|
self._login_password = login_password
|
|
162
108
|
|
|
163
109
|
self._cookies = self._build_init_cookies()
|
|
164
|
-
self.
|
|
110
|
+
self._save_to_file = save_to_file
|
|
165
111
|
self._login_stored_data = login_data or {}
|
|
166
112
|
self._serial = self._serial_number()
|
|
167
113
|
self._account_owner_customer_id: str | None = None
|
|
@@ -182,11 +128,6 @@ class AmazonEchoApi:
|
|
|
182
128
|
"""Return current Amazon domain."""
|
|
183
129
|
return self._domain
|
|
184
130
|
|
|
185
|
-
def save_raw_data(self) -> None:
|
|
186
|
-
"""Save raw data to disk."""
|
|
187
|
-
self._save_raw_data = True
|
|
188
|
-
_LOGGER.debug("Saving raw data to disk")
|
|
189
|
-
|
|
190
131
|
def _country_specific_data(self, domain: str) -> None:
|
|
191
132
|
"""Set country specific data."""
|
|
192
133
|
# Force lower case
|
|
@@ -386,6 +327,8 @@ class AmazonEchoApi:
|
|
|
386
327
|
headers = DEFAULT_HEADERS.copy()
|
|
387
328
|
headers.update({"User-Agent": REQUEST_AGENT[agent]})
|
|
388
329
|
headers.update({"Accept-Language": self._language})
|
|
330
|
+
headers.update({"x-amzn-client": "aioamazondevices"})
|
|
331
|
+
headers.update({"x-amzn-build-version": __version__})
|
|
389
332
|
|
|
390
333
|
if self._csrf_cookie:
|
|
391
334
|
csrf = {CSRF_COOKIE: self._csrf_cookie}
|
|
@@ -462,57 +405,16 @@ class AmazonEchoApi:
|
|
|
462
405
|
f"Request failed: {await self._http_phrase_error(resp.status)}"
|
|
463
406
|
)
|
|
464
407
|
|
|
465
|
-
await
|
|
466
|
-
await resp.text(),
|
|
467
|
-
url,
|
|
468
|
-
mimetypes.guess_extension(content_type.split(";")[0]) or ".raw",
|
|
469
|
-
)
|
|
470
|
-
|
|
471
|
-
return BeautifulSoup(await resp.read() or "", "html.parser"), resp
|
|
472
|
-
|
|
473
|
-
async def _save_to_file(
|
|
474
|
-
self,
|
|
475
|
-
raw_data: str | dict,
|
|
476
|
-
url: str,
|
|
477
|
-
extension: str = HTML_EXTENSION,
|
|
478
|
-
output_path: str = SAVE_PATH,
|
|
479
|
-
) -> None:
|
|
480
|
-
"""Save response data to disk."""
|
|
481
|
-
if not self._save_raw_data or not raw_data:
|
|
482
|
-
return
|
|
483
|
-
|
|
484
|
-
output_dir = Path(output_path)
|
|
485
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
486
|
-
|
|
487
|
-
if url.startswith("http"):
|
|
488
|
-
url_split = url.split("/")
|
|
489
|
-
base_filename = f"{url_split[3]}-{url_split[4].split('?')[0]}"
|
|
490
|
-
else:
|
|
491
|
-
base_filename = url
|
|
492
|
-
fullpath = Path(output_dir, base_filename + extension)
|
|
493
|
-
|
|
494
|
-
data: str
|
|
495
|
-
if isinstance(raw_data, dict):
|
|
496
|
-
data = orjson.dumps(raw_data, option=orjson.OPT_INDENT_2).decode("utf-8")
|
|
497
|
-
elif extension in [HTML_EXTENSION, BIN_EXTENSION]:
|
|
498
|
-
data = raw_data
|
|
499
|
-
else:
|
|
500
|
-
data = orjson.dumps(
|
|
501
|
-
orjson.loads(raw_data),
|
|
502
|
-
option=orjson.OPT_INDENT_2,
|
|
503
|
-
).decode("utf-8")
|
|
504
|
-
|
|
505
|
-
i = 2
|
|
506
|
-
while fullpath.exists():
|
|
507
|
-
filename = f"{base_filename}_{i!s}{extension}"
|
|
508
|
-
fullpath = Path(output_dir, filename)
|
|
509
|
-
i += 1
|
|
408
|
+
raw_content = await resp.read()
|
|
510
409
|
|
|
511
|
-
|
|
410
|
+
if self._save_to_file:
|
|
411
|
+
await self._save_to_file(
|
|
412
|
+
raw_content.decode("utf-8"),
|
|
413
|
+
url,
|
|
414
|
+
content_type,
|
|
415
|
+
)
|
|
512
416
|
|
|
513
|
-
|
|
514
|
-
file.write(data)
|
|
515
|
-
file.write("\n")
|
|
417
|
+
return BeautifulSoup(raw_content or "", "html.parser"), resp
|
|
516
418
|
|
|
517
419
|
async def _register_device(
|
|
518
420
|
self,
|
|
@@ -612,6 +514,9 @@ class AmazonEchoApi:
|
|
|
612
514
|
"""Retrieve devices sensors states."""
|
|
613
515
|
devices_sensors: dict[str, dict[str, AmazonDeviceSensor]] = {}
|
|
614
516
|
|
|
517
|
+
if not self._endpoints:
|
|
518
|
+
return {}
|
|
519
|
+
|
|
615
520
|
endpoint_ids = list(self._endpoints.keys())
|
|
616
521
|
payload = [
|
|
617
522
|
{
|
|
@@ -793,6 +698,18 @@ class AmazonEchoApi:
|
|
|
793
698
|
for schedule in notifications["notifications"]:
|
|
794
699
|
schedule_type: str = schedule["type"]
|
|
795
700
|
schedule_device_serial = schedule["deviceSerialNumber"]
|
|
701
|
+
|
|
702
|
+
if schedule_device_serial in DEVICE_TO_IGNORE:
|
|
703
|
+
continue
|
|
704
|
+
|
|
705
|
+
if schedule_type not in NOTIFICATIONS_SUPPORTED:
|
|
706
|
+
_LOGGER.debug(
|
|
707
|
+
"Unsupported schedule type %s for device %s",
|
|
708
|
+
schedule_type,
|
|
709
|
+
schedule_device_serial,
|
|
710
|
+
)
|
|
711
|
+
continue
|
|
712
|
+
|
|
796
713
|
if schedule_type == NOTIFICATION_MUSIC_ALARM:
|
|
797
714
|
# Structure is the same as standard Alarm
|
|
798
715
|
schedule_type = NOTIFICATION_ALARM
|
|
@@ -959,7 +876,6 @@ class AmazonEchoApi:
|
|
|
959
876
|
await self._domain_refresh_auth_cookies()
|
|
960
877
|
|
|
961
878
|
self._login_stored_data.update({"site": f"https://www.amazon.{self._domain}"})
|
|
962
|
-
await self._save_to_file(self._login_stored_data, "login_data", JSON_EXTENSION)
|
|
963
879
|
|
|
964
880
|
# Can take a little while to register device but we need it
|
|
965
881
|
# to be able to pickout account customer ID
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""aioamazondevices const package."""
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""aioamazondevices Common const."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
_LOGGER = logging.getLogger(__package__)
|
|
6
|
+
|
|
7
|
+
TO_REDACT = {
|
|
8
|
+
"address",
|
|
9
|
+
"address1",
|
|
10
|
+
"address2",
|
|
11
|
+
"address3",
|
|
12
|
+
"city",
|
|
13
|
+
"county",
|
|
14
|
+
"customerId",
|
|
15
|
+
"deviceAccountId",
|
|
16
|
+
"deviceAddress",
|
|
17
|
+
"deviceOwnerCustomerId",
|
|
18
|
+
"given_name",
|
|
19
|
+
"name",
|
|
20
|
+
"password",
|
|
21
|
+
"postalCode",
|
|
22
|
+
"searchCustomerId",
|
|
23
|
+
"state",
|
|
24
|
+
"street",
|
|
25
|
+
"user_id",
|
|
26
|
+
}
|
|
@@ -1,117 +1,10 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""aioamazondevices devices."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
_LOGGER = logging.getLogger(__package__)
|
|
6
|
-
|
|
7
|
-
ARRAY_WRAPPER = "generatedArrayWrapper"
|
|
8
|
-
|
|
9
|
-
HTTP_ERROR_199 = 199
|
|
10
|
-
HTTP_ERROR_299 = 299
|
|
11
|
-
|
|
12
|
-
TO_REDACT = {
|
|
13
|
-
"address",
|
|
14
|
-
"address1",
|
|
15
|
-
"address2",
|
|
16
|
-
"address3",
|
|
17
|
-
"city",
|
|
18
|
-
"county",
|
|
19
|
-
"customerId",
|
|
20
|
-
"deviceAccountId",
|
|
21
|
-
"deviceAddress",
|
|
22
|
-
"deviceOwnerCustomerId",
|
|
23
|
-
"given_name",
|
|
24
|
-
"name",
|
|
25
|
-
"password",
|
|
26
|
-
"postalCode",
|
|
27
|
-
"searchCustomerId",
|
|
28
|
-
"state",
|
|
29
|
-
"street",
|
|
30
|
-
"user_id",
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
# Amazon APP info
|
|
34
|
-
AMAZON_APP_BUNDLE_ID = "com.amazon.echo"
|
|
35
|
-
AMAZON_APP_ID = "MAPiOSLib/6.0/ToHideRetailLink"
|
|
36
|
-
AMAZON_APP_NAME = "AioAmazonDevices"
|
|
37
|
-
AMAZON_APP_VERSION = "2.2.663733.0"
|
|
38
|
-
AMAZON_DEVICE_SOFTWARE_VERSION = "35602678"
|
|
39
|
-
AMAZON_DEVICE_TYPE = "A2IVLV5VM2W81"
|
|
40
|
-
AMAZON_CLIENT_OS = "18.5"
|
|
41
|
-
|
|
42
|
-
DEFAULT_SITE = "https://www.amazon.com"
|
|
43
|
-
DEFAULT_HEADERS = {
|
|
44
|
-
"Accept-Charset": "utf-8",
|
|
45
|
-
"Accept-Encoding": "gzip",
|
|
46
|
-
"Connection": "keep-alive",
|
|
47
|
-
}
|
|
48
|
-
CSRF_COOKIE = "csrf"
|
|
49
|
-
REQUEST_AGENT = {
|
|
50
|
-
"Amazon": f"AmazonWebView/AmazonAlexa/{AMAZON_APP_VERSION}/iOS/{AMAZON_CLIENT_OS}/iPhone", # noqa: E501
|
|
51
|
-
"Browser": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0", # noqa: E501
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
REFRESH_ACCESS_TOKEN = "access_token" # noqa: S105
|
|
55
|
-
REFRESH_AUTH_COOKIES = "auth_cookies"
|
|
56
|
-
|
|
57
|
-
URI_DEVICES = "/api/devices-v2/device"
|
|
58
|
-
URI_DND = "/api/dnd/device-status-list"
|
|
59
|
-
URI_NOTIFICATIONS = "/api/notifications"
|
|
60
|
-
URI_SIGNIN = "/ap/signin"
|
|
61
|
-
URI_NEXUS_GRAPHQL = "/nexus/v1/graphql"
|
|
62
|
-
|
|
63
|
-
SENSOR_STATE_OFF = "NOT_DETECTED"
|
|
64
|
-
|
|
65
|
-
# File extensions
|
|
66
|
-
SAVE_PATH = "out"
|
|
67
|
-
HTML_EXTENSION = ".html"
|
|
68
|
-
JSON_EXTENSION = ".json"
|
|
69
|
-
BIN_EXTENSION = ".bin"
|
|
3
|
+
from .http import AMAZON_DEVICE_TYPE
|
|
70
4
|
|
|
71
5
|
SPEAKER_GROUP_FAMILY = "WHA"
|
|
72
6
|
SPEAKER_GROUP_MODEL = "Speaker Group"
|
|
73
7
|
|
|
74
|
-
SENSORS: dict[str, dict[str, str | None]] = {
|
|
75
|
-
"temperatureSensor": {
|
|
76
|
-
"name": "temperature",
|
|
77
|
-
"key": "value",
|
|
78
|
-
"subkey": "value",
|
|
79
|
-
"scale": "scale",
|
|
80
|
-
},
|
|
81
|
-
"motionSensor": {
|
|
82
|
-
"name": "detectionState",
|
|
83
|
-
"key": "detectionStateValue",
|
|
84
|
-
"subkey": None,
|
|
85
|
-
"scale": None,
|
|
86
|
-
},
|
|
87
|
-
"lightSensor": {
|
|
88
|
-
"name": "illuminance",
|
|
89
|
-
"key": "illuminanceValue",
|
|
90
|
-
"subkey": "value",
|
|
91
|
-
"scale": None,
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
ALEXA_INFO_SKILLS = [
|
|
96
|
-
"Alexa.Calendar.PlayToday",
|
|
97
|
-
"Alexa.Calendar.PlayTomorrow",
|
|
98
|
-
"Alexa.Calendar.PlayNext",
|
|
99
|
-
"Alexa.Date.Play",
|
|
100
|
-
"Alexa.Time.Play",
|
|
101
|
-
"Alexa.News.NationalNews",
|
|
102
|
-
"Alexa.FlashBriefing.Play",
|
|
103
|
-
"Alexa.Traffic.Play",
|
|
104
|
-
"Alexa.Weather.Play",
|
|
105
|
-
"Alexa.CleanUp.Play",
|
|
106
|
-
"Alexa.GoodMorning.Play",
|
|
107
|
-
"Alexa.SingASong.Play",
|
|
108
|
-
"Alexa.FunFact.Play",
|
|
109
|
-
"Alexa.Joke.Play",
|
|
110
|
-
"Alexa.TellStory.Play",
|
|
111
|
-
"Alexa.ImHome.Play",
|
|
112
|
-
"Alexa.GoodNight.Play",
|
|
113
|
-
]
|
|
114
|
-
|
|
115
8
|
DEVICE_TO_IGNORE: list[str] = [
|
|
116
9
|
AMAZON_DEVICE_TYPE, # Alexa App for iOS
|
|
117
10
|
"A2TF17PFR55MTB", # Alexa App for Android
|
|
@@ -480,57 +373,3 @@ DEVICE_TYPE_TO_MODEL: dict[str, dict[str, str | None]] = {
|
|
|
480
373
|
"hw_version": "Gen2",
|
|
481
374
|
},
|
|
482
375
|
}
|
|
483
|
-
|
|
484
|
-
RECURRING_PATTERNS: dict[str, str] = {
|
|
485
|
-
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
|
|
486
|
-
"XXXX-WE": "FREQ=WEEKLY;BYDAY=SA,SU",
|
|
487
|
-
"XXXX-WXX-1": "FREQ=WEEKLY;BYDAY=MO",
|
|
488
|
-
"XXXX-WXX-2": "FREQ=WEEKLY;BYDAY=TU",
|
|
489
|
-
"XXXX-WXX-3": "FREQ=WEEKLY;BYDAY=WE",
|
|
490
|
-
"XXXX-WXX-4": "FREQ=WEEKLY;BYDAY=TH",
|
|
491
|
-
"XXXX-WXX-5": "FREQ=WEEKLY;BYDAY=FR",
|
|
492
|
-
"XXXX-WXX-6": "FREQ=WEEKLY;BYDAY=SA",
|
|
493
|
-
"XXXX-WXX-7": "FREQ=WEEKLY;BYDAY=SU",
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
WEEKEND_EXCEPTIONS = {
|
|
497
|
-
"TH-FR": {
|
|
498
|
-
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,SA,SU",
|
|
499
|
-
"XXXX-WE": "FREQ=WEEKLY;BYDAY=TH,FR",
|
|
500
|
-
},
|
|
501
|
-
"FR-SA": {
|
|
502
|
-
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,SU",
|
|
503
|
-
"XXXX-WE": "FREQ=WEEKLY;BYDAY=FR,SA",
|
|
504
|
-
},
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
# Countries grouped by their weekend type
|
|
508
|
-
COUNTRY_GROUPS = {
|
|
509
|
-
"TH-FR": ["IR"],
|
|
510
|
-
"FR-SA": [
|
|
511
|
-
"AF",
|
|
512
|
-
"BD",
|
|
513
|
-
"BH",
|
|
514
|
-
"DZ",
|
|
515
|
-
"EG",
|
|
516
|
-
"IL",
|
|
517
|
-
"IQ",
|
|
518
|
-
"JO",
|
|
519
|
-
"KW",
|
|
520
|
-
"LY",
|
|
521
|
-
"MV",
|
|
522
|
-
"MY",
|
|
523
|
-
"OM",
|
|
524
|
-
"PS",
|
|
525
|
-
"QA",
|
|
526
|
-
"SA",
|
|
527
|
-
"SD",
|
|
528
|
-
"SY",
|
|
529
|
-
"YE",
|
|
530
|
-
],
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
NOTIFICATION_ALARM = "Alarm"
|
|
534
|
-
NOTIFICATION_MUSIC_ALARM = "MusicAlarm"
|
|
535
|
-
NOTIFICATION_REMINDER = "Reminder"
|
|
536
|
-
NOTIFICATION_TIMER = "Timer"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""aioamazondevices HTTP const."""
|
|
2
|
+
|
|
3
|
+
HTTP_ERROR_199 = 199
|
|
4
|
+
HTTP_ERROR_299 = 299
|
|
5
|
+
|
|
6
|
+
ARRAY_WRAPPER = "generatedArrayWrapper"
|
|
7
|
+
|
|
8
|
+
# Amazon APP info
|
|
9
|
+
AMAZON_APP_BUNDLE_ID = "com.amazon.echo"
|
|
10
|
+
AMAZON_APP_ID = "MAPiOSLib/6.0/ToHideRetailLink"
|
|
11
|
+
AMAZON_APP_NAME = "AioAmazonDevices"
|
|
12
|
+
AMAZON_APP_VERSION = "2.2.663733.0"
|
|
13
|
+
AMAZON_DEVICE_SOFTWARE_VERSION = "35602678"
|
|
14
|
+
AMAZON_DEVICE_TYPE = "A2IVLV5VM2W81"
|
|
15
|
+
AMAZON_CLIENT_OS = "18.5"
|
|
16
|
+
|
|
17
|
+
DEFAULT_SITE = "https://www.amazon.com"
|
|
18
|
+
DEFAULT_HEADERS = {
|
|
19
|
+
"Accept-Charset": "utf-8",
|
|
20
|
+
"Accept-Encoding": "gzip",
|
|
21
|
+
"Connection": "keep-alive",
|
|
22
|
+
}
|
|
23
|
+
CSRF_COOKIE = "csrf"
|
|
24
|
+
REQUEST_AGENT = {
|
|
25
|
+
"Amazon": f"AmazonWebView/AmazonAlexa/{AMAZON_APP_VERSION}/iOS/{AMAZON_CLIENT_OS}/iPhone", # noqa: E501
|
|
26
|
+
"Browser": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0", # noqa: E501
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
REFRESH_ACCESS_TOKEN = "access_token" # noqa: S105
|
|
30
|
+
REFRESH_AUTH_COOKIES = "auth_cookies"
|
|
31
|
+
|
|
32
|
+
URI_DEVICES = "/api/devices-v2/device"
|
|
33
|
+
URI_DND = "/api/dnd/device-status-list"
|
|
34
|
+
URI_NOTIFICATIONS = "/api/notifications"
|
|
35
|
+
URI_SIGNIN = "/ap/signin"
|
|
36
|
+
URI_NEXUS_GRAPHQL = "/nexus/v1/graphql"
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""aioamazondevices: schedules."""
|
|
2
|
+
|
|
3
|
+
NOTIFICATION_ALARM = "Alarm"
|
|
4
|
+
NOTIFICATION_MUSIC_ALARM = "MusicAlarm"
|
|
5
|
+
NOTIFICATION_REMINDER = "Reminder"
|
|
6
|
+
NOTIFICATION_TIMER = "Timer"
|
|
7
|
+
NOTIFICATIONS_SUPPORTED = [
|
|
8
|
+
NOTIFICATION_ALARM,
|
|
9
|
+
NOTIFICATION_MUSIC_ALARM,
|
|
10
|
+
NOTIFICATION_REMINDER,
|
|
11
|
+
NOTIFICATION_TIMER,
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
RECURRING_PATTERNS: dict[str, str] = {
|
|
15
|
+
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
|
|
16
|
+
"XXXX-WE": "FREQ=WEEKLY;BYDAY=SA,SU",
|
|
17
|
+
"XXXX-WXX-1": "FREQ=WEEKLY;BYDAY=MO",
|
|
18
|
+
"XXXX-WXX-2": "FREQ=WEEKLY;BYDAY=TU",
|
|
19
|
+
"XXXX-WXX-3": "FREQ=WEEKLY;BYDAY=WE",
|
|
20
|
+
"XXXX-WXX-4": "FREQ=WEEKLY;BYDAY=TH",
|
|
21
|
+
"XXXX-WXX-5": "FREQ=WEEKLY;BYDAY=FR",
|
|
22
|
+
"XXXX-WXX-6": "FREQ=WEEKLY;BYDAY=SA",
|
|
23
|
+
"XXXX-WXX-7": "FREQ=WEEKLY;BYDAY=SU",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
WEEKEND_EXCEPTIONS = {
|
|
27
|
+
"TH-FR": {
|
|
28
|
+
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,SA,SU",
|
|
29
|
+
"XXXX-WE": "FREQ=WEEKLY;BYDAY=TH,FR",
|
|
30
|
+
},
|
|
31
|
+
"FR-SA": {
|
|
32
|
+
"XXXX-WD": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,SU",
|
|
33
|
+
"XXXX-WE": "FREQ=WEEKLY;BYDAY=FR,SA",
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Countries grouped by their weekend type
|
|
38
|
+
COUNTRY_GROUPS = {
|
|
39
|
+
"TH-FR": ["IR"],
|
|
40
|
+
"FR-SA": [
|
|
41
|
+
"AF",
|
|
42
|
+
"BD",
|
|
43
|
+
"BH",
|
|
44
|
+
"DZ",
|
|
45
|
+
"EG",
|
|
46
|
+
"IL",
|
|
47
|
+
"IQ",
|
|
48
|
+
"JO",
|
|
49
|
+
"KW",
|
|
50
|
+
"LY",
|
|
51
|
+
"MV",
|
|
52
|
+
"MY",
|
|
53
|
+
"OM",
|
|
54
|
+
"PS",
|
|
55
|
+
"QA",
|
|
56
|
+
"SA",
|
|
57
|
+
"SD",
|
|
58
|
+
"SY",
|
|
59
|
+
"YE",
|
|
60
|
+
],
|
|
61
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""aioamazondevices structures module."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from enum import StrEnum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class AmazonDeviceSensor:
|
|
10
|
+
"""Amazon device sensor class."""
|
|
11
|
+
|
|
12
|
+
name: str
|
|
13
|
+
value: str | int | float
|
|
14
|
+
error: bool
|
|
15
|
+
error_type: str | None
|
|
16
|
+
error_msg: str | None
|
|
17
|
+
scale: str | None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class AmazonSchedule:
|
|
22
|
+
"""Amazon schedule class."""
|
|
23
|
+
|
|
24
|
+
type: str # alarm, reminder, timer
|
|
25
|
+
status: str
|
|
26
|
+
label: str
|
|
27
|
+
next_occurrence: datetime | None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class AmazonDevice:
|
|
32
|
+
"""Amazon device class."""
|
|
33
|
+
|
|
34
|
+
account_name: str
|
|
35
|
+
capabilities: list[str]
|
|
36
|
+
device_family: str
|
|
37
|
+
device_type: str
|
|
38
|
+
device_owner_customer_id: str
|
|
39
|
+
household_device: bool
|
|
40
|
+
device_cluster_members: list[str]
|
|
41
|
+
online: bool
|
|
42
|
+
serial_number: str
|
|
43
|
+
software_version: str
|
|
44
|
+
entity_id: str | None
|
|
45
|
+
endpoint_id: str | None
|
|
46
|
+
sensors: dict[str, AmazonDeviceSensor]
|
|
47
|
+
notifications: dict[str, AmazonSchedule]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AmazonSequenceType(StrEnum):
|
|
51
|
+
"""Amazon sequence types."""
|
|
52
|
+
|
|
53
|
+
Announcement = "AlexaAnnouncement"
|
|
54
|
+
Speak = "Alexa.Speak"
|
|
55
|
+
Sound = "Alexa.Sound"
|
|
56
|
+
Music = "Alexa.Music.PlaySearchPhrase"
|
|
57
|
+
TextCommand = "Alexa.TextCommand"
|
|
58
|
+
LaunchSkill = "Alexa.Operation.SkillConnections.Launch"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class AmazonMusicSource(StrEnum):
|
|
62
|
+
"""Amazon music sources."""
|
|
63
|
+
|
|
64
|
+
Radio = "TUNEIN"
|
|
65
|
+
AmazonMusic = "AMAZON_MUSIC"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|