aioamazondevices 6.5.4__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.4 → aioamazondevices-8.0.0}/PKG-INFO +10 -4
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/README.md +9 -3
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/pyproject.toml +1 -1
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/src/aioamazondevices/__init__.py +1 -1
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/src/aioamazondevices/api.py +42 -139
- 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.4/src/aioamazondevices/const.py → aioamazondevices-8.0.0/src/aioamazondevices/const/devices.py +2 -169
- 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.4/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.4/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.4 → aioamazondevices-8.0.0}/src/aioamazondevices/utils.py +1 -1
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/LICENSE +0 -0
- {aioamazondevices-6.5.4 → aioamazondevices-8.0.0}/src/aioamazondevices/exceptions.py +0 -0
- {aioamazondevices-6.5.4 → 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,34 +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
|
-
NOTIFICATIONS_SUPPORTED,
|
|
60
|
-
RECURRING_PATTERNS,
|
|
61
50
|
REFRESH_ACCESS_TOKEN,
|
|
62
51
|
REFRESH_AUTH_COOKIES,
|
|
63
52
|
REQUEST_AGENT,
|
|
64
|
-
SAVE_PATH,
|
|
65
|
-
SENSORS,
|
|
66
|
-
SPEAKER_GROUP_FAMILY,
|
|
67
53
|
URI_DEVICES,
|
|
68
54
|
URI_DND,
|
|
69
55
|
URI_NEXUS_GRAPHQL,
|
|
70
56
|
URI_NOTIFICATIONS,
|
|
71
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,
|
|
72
69
|
WEEKEND_EXCEPTIONS,
|
|
73
70
|
)
|
|
74
71
|
from .exceptions import (
|
|
@@ -78,70 +75,16 @@ from .exceptions import (
|
|
|
78
75
|
CannotRetrieveData,
|
|
79
76
|
WrongMethod,
|
|
80
77
|
)
|
|
81
|
-
from .
|
|
78
|
+
from .structures import (
|
|
79
|
+
AmazonDevice,
|
|
80
|
+
AmazonDeviceSensor,
|
|
81
|
+
AmazonMusicSource,
|
|
82
|
+
AmazonSchedule,
|
|
83
|
+
AmazonSequenceType,
|
|
84
|
+
)
|
|
82
85
|
from .utils import obfuscate_email, scrub_fields
|
|
83
86
|
|
|
84
87
|
|
|
85
|
-
@dataclass
|
|
86
|
-
class AmazonDeviceSensor:
|
|
87
|
-
"""Amazon device sensor class."""
|
|
88
|
-
|
|
89
|
-
name: str
|
|
90
|
-
value: str | int | float
|
|
91
|
-
error: bool
|
|
92
|
-
error_type: str | None
|
|
93
|
-
error_msg: str | None
|
|
94
|
-
scale: str | None
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@dataclass
|
|
98
|
-
class AmazonSchedule:
|
|
99
|
-
"""Amazon schedule class."""
|
|
100
|
-
|
|
101
|
-
type: str # alarm, reminder, timer
|
|
102
|
-
status: str
|
|
103
|
-
label: str
|
|
104
|
-
next_occurrence: datetime | None
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@dataclass
|
|
108
|
-
class AmazonDevice:
|
|
109
|
-
"""Amazon device class."""
|
|
110
|
-
|
|
111
|
-
account_name: str
|
|
112
|
-
capabilities: list[str]
|
|
113
|
-
device_family: str
|
|
114
|
-
device_type: str
|
|
115
|
-
device_owner_customer_id: str
|
|
116
|
-
household_device: bool
|
|
117
|
-
device_cluster_members: list[str]
|
|
118
|
-
online: bool
|
|
119
|
-
serial_number: str
|
|
120
|
-
software_version: str
|
|
121
|
-
entity_id: str | None
|
|
122
|
-
endpoint_id: str | None
|
|
123
|
-
sensors: dict[str, AmazonDeviceSensor]
|
|
124
|
-
notifications: dict[str, AmazonSchedule]
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
class AmazonSequenceType(StrEnum):
|
|
128
|
-
"""Amazon sequence types."""
|
|
129
|
-
|
|
130
|
-
Announcement = "AlexaAnnouncement"
|
|
131
|
-
Speak = "Alexa.Speak"
|
|
132
|
-
Sound = "Alexa.Sound"
|
|
133
|
-
Music = "Alexa.Music.PlaySearchPhrase"
|
|
134
|
-
TextCommand = "Alexa.TextCommand"
|
|
135
|
-
LaunchSkill = "Alexa.Operation.SkillConnections.Launch"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class AmazonMusicSource(StrEnum):
|
|
139
|
-
"""Amazon music sources."""
|
|
140
|
-
|
|
141
|
-
Radio = "TUNEIN"
|
|
142
|
-
AmazonMusic = "AMAZON_MUSIC"
|
|
143
|
-
|
|
144
|
-
|
|
145
88
|
class AmazonEchoApi:
|
|
146
89
|
"""Queries Amazon for Echo devices."""
|
|
147
90
|
|
|
@@ -151,6 +94,8 @@ class AmazonEchoApi:
|
|
|
151
94
|
login_email: str,
|
|
152
95
|
login_password: str,
|
|
153
96
|
login_data: dict[str, Any] | None = None,
|
|
97
|
+
save_to_file: Callable[[str | dict, str, str], Coroutine[Any, Any, None]]
|
|
98
|
+
| None = None,
|
|
154
99
|
) -> None:
|
|
155
100
|
"""Initialize the scanner."""
|
|
156
101
|
# Check if there is a previous login, otherwise use default (US)
|
|
@@ -162,7 +107,7 @@ class AmazonEchoApi:
|
|
|
162
107
|
self._login_password = login_password
|
|
163
108
|
|
|
164
109
|
self._cookies = self._build_init_cookies()
|
|
165
|
-
self.
|
|
110
|
+
self._save_to_file = save_to_file
|
|
166
111
|
self._login_stored_data = login_data or {}
|
|
167
112
|
self._serial = self._serial_number()
|
|
168
113
|
self._account_owner_customer_id: str | None = None
|
|
@@ -183,11 +128,6 @@ class AmazonEchoApi:
|
|
|
183
128
|
"""Return current Amazon domain."""
|
|
184
129
|
return self._domain
|
|
185
130
|
|
|
186
|
-
def save_raw_data(self) -> None:
|
|
187
|
-
"""Save raw data to disk."""
|
|
188
|
-
self._save_raw_data = True
|
|
189
|
-
_LOGGER.debug("Saving raw data to disk")
|
|
190
|
-
|
|
191
131
|
def _country_specific_data(self, domain: str) -> None:
|
|
192
132
|
"""Set country specific data."""
|
|
193
133
|
# Force lower case
|
|
@@ -387,6 +327,8 @@ class AmazonEchoApi:
|
|
|
387
327
|
headers = DEFAULT_HEADERS.copy()
|
|
388
328
|
headers.update({"User-Agent": REQUEST_AGENT[agent]})
|
|
389
329
|
headers.update({"Accept-Language": self._language})
|
|
330
|
+
headers.update({"x-amzn-client": "aioamazondevices"})
|
|
331
|
+
headers.update({"x-amzn-build-version": __version__})
|
|
390
332
|
|
|
391
333
|
if self._csrf_cookie:
|
|
392
334
|
csrf = {CSRF_COOKIE: self._csrf_cookie}
|
|
@@ -463,57 +405,16 @@ class AmazonEchoApi:
|
|
|
463
405
|
f"Request failed: {await self._http_phrase_error(resp.status)}"
|
|
464
406
|
)
|
|
465
407
|
|
|
466
|
-
await
|
|
467
|
-
await resp.text(),
|
|
468
|
-
url,
|
|
469
|
-
mimetypes.guess_extension(content_type.split(";")[0]) or ".raw",
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
return BeautifulSoup(await resp.read() or "", "html.parser"), resp
|
|
408
|
+
raw_content = await resp.read()
|
|
473
409
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
) -> None:
|
|
481
|
-
"""Save response data to disk."""
|
|
482
|
-
if not self._save_raw_data or not raw_data:
|
|
483
|
-
return
|
|
484
|
-
|
|
485
|
-
output_dir = Path(output_path)
|
|
486
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
487
|
-
|
|
488
|
-
if url.startswith("http"):
|
|
489
|
-
url_split = url.split("/")
|
|
490
|
-
base_filename = f"{url_split[3]}-{url_split[4].split('?')[0]}"
|
|
491
|
-
else:
|
|
492
|
-
base_filename = url
|
|
493
|
-
fullpath = Path(output_dir, base_filename + extension)
|
|
494
|
-
|
|
495
|
-
data: str
|
|
496
|
-
if isinstance(raw_data, dict):
|
|
497
|
-
data = orjson.dumps(raw_data, option=orjson.OPT_INDENT_2).decode("utf-8")
|
|
498
|
-
elif extension in [HTML_EXTENSION, BIN_EXTENSION]:
|
|
499
|
-
data = raw_data
|
|
500
|
-
else:
|
|
501
|
-
data = orjson.dumps(
|
|
502
|
-
orjson.loads(raw_data),
|
|
503
|
-
option=orjson.OPT_INDENT_2,
|
|
504
|
-
).decode("utf-8")
|
|
505
|
-
|
|
506
|
-
i = 2
|
|
507
|
-
while fullpath.exists():
|
|
508
|
-
filename = f"{base_filename}_{i!s}{extension}"
|
|
509
|
-
fullpath = Path(output_dir, filename)
|
|
510
|
-
i += 1
|
|
511
|
-
|
|
512
|
-
_LOGGER.warning("Saving data to %s", fullpath)
|
|
410
|
+
if self._save_to_file:
|
|
411
|
+
await self._save_to_file(
|
|
412
|
+
raw_content.decode("utf-8"),
|
|
413
|
+
url,
|
|
414
|
+
content_type,
|
|
415
|
+
)
|
|
513
416
|
|
|
514
|
-
|
|
515
|
-
file.write(data)
|
|
516
|
-
file.write("\n")
|
|
417
|
+
return BeautifulSoup(raw_content or "", "html.parser"), resp
|
|
517
418
|
|
|
518
419
|
async def _register_device(
|
|
519
420
|
self,
|
|
@@ -613,6 +514,9 @@ class AmazonEchoApi:
|
|
|
613
514
|
"""Retrieve devices sensors states."""
|
|
614
515
|
devices_sensors: dict[str, dict[str, AmazonDeviceSensor]] = {}
|
|
615
516
|
|
|
517
|
+
if not self._endpoints:
|
|
518
|
+
return {}
|
|
519
|
+
|
|
616
520
|
endpoint_ids = list(self._endpoints.keys())
|
|
617
521
|
payload = [
|
|
618
522
|
{
|
|
@@ -972,7 +876,6 @@ class AmazonEchoApi:
|
|
|
972
876
|
await self._domain_refresh_auth_cookies()
|
|
973
877
|
|
|
974
878
|
self._login_stored_data.update({"site": f"https://www.amazon.{self._domain}"})
|
|
975
|
-
await self._save_to_file(self._login_stored_data, "login_data", JSON_EXTENSION)
|
|
976
879
|
|
|
977
880
|
# Can take a little while to register device but we need it
|
|
978
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,63 +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"
|
|
537
|
-
NOTIFICATIONS_SUPPORTED = [
|
|
538
|
-
NOTIFICATION_ALARM,
|
|
539
|
-
NOTIFICATION_MUSIC_ALARM,
|
|
540
|
-
NOTIFICATION_REMINDER,
|
|
541
|
-
NOTIFICATION_TIMER,
|
|
542
|
-
]
|
|
@@ -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
|