python-aidot-cameras 0.1.0__tar.gz → 0.5.1__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.
- {python_aidot_cameras-0.1.0/python_aidot_cameras.egg-info → python_aidot_cameras-0.5.1}/PKG-INFO +18 -10
- python_aidot_cameras-0.5.1/pyproject.toml +40 -0
- python_aidot_cameras-0.5.1/setup.cfg +4 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/__init__.py +2 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/client.py +20 -28
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/device_client.py +15 -15
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/discover.py +3 -3
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src/python_aidot_cameras.egg-info}/PKG-INFO +18 -10
- python_aidot_cameras-0.5.1/src/python_aidot_cameras.egg-info/SOURCES.txt +27 -0
- python_aidot_cameras-0.5.1/src/python_aidot_cameras.egg-info/requires.txt +12 -0
- python_aidot_cameras-0.1.0/aidot/login_const.py +0 -13
- python_aidot_cameras-0.1.0/pyproject.toml +0 -22
- python_aidot_cameras-0.1.0/python_aidot_cameras.egg-info/SOURCES.txt +0 -29
- python_aidot_cameras-0.1.0/setup.cfg +0 -7
- python_aidot_cameras-0.1.0/setup.py +0 -40
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/LICENSE +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/README.md +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/aes_utils.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/const.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/credentials.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/exceptions.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/aidot/g711.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src}/python_aidot_cameras.egg-info/top_level.txt +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_alarm_event.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_highport_nomination.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_motion_poll.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_sdes_talk.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_sdes_watchdog.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_speak.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_stream_cap.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_talk.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_terminal_ack.py +0 -0
- {python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1}/tests/test_token_refresh.py +0 -0
{python_aidot_cameras-0.1.0/python_aidot_cameras.egg-info → python_aidot_cameras-0.5.1}/PKG-INFO
RENAMED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.1
|
|
4
|
-
Summary:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Project-URL:
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
|
|
5
|
+
Author-email: cbrightly <chris.brightly@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cbrightly/python-AiDot
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/cbrightly/python-AiDot/issues
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
10
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.11
|
|
13
12
|
Description-Content-Type: text/markdown
|
|
14
13
|
License-File: LICENSE
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
Requires-Dist: aiohttp
|
|
15
|
+
Requires-Dist: paho-mqtt>=2.0
|
|
16
|
+
Requires-Dist: cryptography
|
|
17
|
+
Requires-Dist: pycryptodome
|
|
18
|
+
Provides-Extra: webrtc
|
|
19
|
+
Requires-Dist: aiortc>=1.9.0; extra == "webrtc"
|
|
20
|
+
Requires-Dist: av; extra == "webrtc"
|
|
21
|
+
Requires-Dist: pylibsrtp; extra == "webrtc"
|
|
22
|
+
Requires-Dist: pyopenssl; extra == "webrtc"
|
|
23
|
+
Requires-Dist: numpy; extra == "webrtc"
|
|
24
|
+
Requires-Dist: Pillow; extra == "webrtc"
|
|
17
25
|
Dynamic: license-file
|
|
18
26
|
|
|
19
27
|
# python-aidot
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "python-aidot-cameras"
|
|
7
|
+
version = "0.5.1"
|
|
8
|
+
description = "Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "cbrightly", email = "chris.brightly@gmail.com" }]
|
|
13
|
+
requires-python = ">=3.11"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"aiohttp",
|
|
20
|
+
"paho-mqtt>=2.0",
|
|
21
|
+
"cryptography",
|
|
22
|
+
"pycryptodome",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
webrtc = [
|
|
27
|
+
"aiortc>=1.9.0",
|
|
28
|
+
"av",
|
|
29
|
+
"pylibsrtp",
|
|
30
|
+
"pyopenssl",
|
|
31
|
+
"numpy",
|
|
32
|
+
"Pillow",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/cbrightly/python-AiDot"
|
|
37
|
+
"Issue Tracker" = "https://github.com/cbrightly/python-AiDot/issues"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
where = ["src"]
|
|
@@ -6,6 +6,7 @@ from .discover import Discover
|
|
|
6
6
|
from .exceptions import (
|
|
7
7
|
AidotAuthFailed,
|
|
8
8
|
AidotAuthTokenExpired,
|
|
9
|
+
AidotCameraBusy,
|
|
9
10
|
AidotError,
|
|
10
11
|
AidotNotLogin,
|
|
11
12
|
AidotOSError,
|
|
@@ -19,6 +20,7 @@ __all__ = [
|
|
|
19
20
|
"AidotClient",
|
|
20
21
|
"DeviceClient",
|
|
21
22
|
"Discover",
|
|
23
|
+
"AidotCameraBusy",
|
|
22
24
|
"AidotError",
|
|
23
25
|
"AidotAuthFailed",
|
|
24
26
|
"AidotAuthTokenExpired",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""The aidot integration."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
import hashlib
|
|
5
4
|
import json
|
|
6
5
|
import logging
|
|
7
6
|
import base64
|
|
@@ -54,10 +53,6 @@ def rsa_password_encrypt(message: str) -> str:
|
|
|
54
53
|
return base64.b64encode(encrypted).decode("utf-8")
|
|
55
54
|
|
|
56
55
|
|
|
57
|
-
def md5_password(message: str) -> str:
|
|
58
|
-
"""MD5 hex digest of the password (for /users/login web-app flow)."""
|
|
59
|
-
return hashlib.md5(message.encode("utf-8")).hexdigest()
|
|
60
|
-
|
|
61
56
|
|
|
62
57
|
class AidotClient:
|
|
63
58
|
_base_url: str = BASE_URL
|
|
@@ -128,7 +123,7 @@ class AidotClient:
|
|
|
128
123
|
try:
|
|
129
124
|
response = await self.session.post(url, headers=headers, json=data)
|
|
130
125
|
response_data = await response.json(content_type=None)
|
|
131
|
-
_LOGGER.debug("async_post_login HTTP=%d
|
|
126
|
+
_LOGGER.debug("async_post_login HTTP=%d code=%s", response.status, response_data.get(CONF_CODE))
|
|
132
127
|
app_code = response_data.get(CONF_CODE)
|
|
133
128
|
if app_code == ServerErrorCode.USER_PWD_INCORRECT:
|
|
134
129
|
raise AidotUserOrPassIncorrect
|
|
@@ -183,7 +178,7 @@ class AidotClient:
|
|
|
183
178
|
async with self.session.get(url, headers=headers,
|
|
184
179
|
timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
|
185
180
|
body = await resp.json(content_type=None)
|
|
186
|
-
_LOGGER.debug("userConfig response
|
|
181
|
+
_LOGGER.debug("userConfig response keys=%s", list(body.keys()) if isinstance(body, dict) else type(body).__name__)
|
|
187
182
|
# The MQTT password field may be named mqttPassword or similar.
|
|
188
183
|
# Store the full response data alongside login_info for DeviceClient.
|
|
189
184
|
data = body if isinstance(body, dict) else {}
|
|
@@ -253,7 +248,7 @@ class AidotClient:
|
|
|
253
248
|
inflight = self._ensure_token_inflight
|
|
254
249
|
if inflight is not None and not inflight.done():
|
|
255
250
|
return await inflight
|
|
256
|
-
fut = asyncio.
|
|
251
|
+
fut = asyncio.get_running_loop().create_future()
|
|
257
252
|
self._ensure_token_inflight = fut
|
|
258
253
|
try:
|
|
259
254
|
result = await self._do_ensure_token()
|
|
@@ -342,26 +337,23 @@ class AidotClient:
|
|
|
342
337
|
|
|
343
338
|
async def async_get_all_device(self) -> dict[str, Any]:
|
|
344
339
|
final_device_list: list[dict[str, Any]] = []
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
for
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
device[CONF_PRODUCT] = product
|
|
363
|
-
except Exception:
|
|
364
|
-
raise
|
|
340
|
+
houses = await self.async_get_houses()
|
|
341
|
+
for house in houses:
|
|
342
|
+
if house.get(CONF_IS_OWNER) is False:
|
|
343
|
+
continue
|
|
344
|
+
# get device_list
|
|
345
|
+
device_list = await self.async_get_devices(house[CONF_ID])
|
|
346
|
+
if device_list:
|
|
347
|
+
final_device_list.extend(device_list)
|
|
348
|
+
|
|
349
|
+
# get product_list
|
|
350
|
+
productIds = ",".join([item[CONF_PRODUCT_ID] for item in final_device_list])
|
|
351
|
+
product_list = await self.async_get_products(productIds)
|
|
352
|
+
|
|
353
|
+
for product in product_list:
|
|
354
|
+
for device in final_device_list:
|
|
355
|
+
if device[CONF_PRODUCT_ID] == product[CONF_ID]:
|
|
356
|
+
device[CONF_PRODUCT] = product
|
|
365
357
|
|
|
366
358
|
# Share the full device ID list with every DeviceClient so that
|
|
367
359
|
# batchGetDeviceUserInfo is called with all IDs (the server may return
|
|
@@ -992,7 +992,7 @@ class TutkStreamSession:
|
|
|
992
992
|
|
|
993
993
|
async def start(self) -> bool:
|
|
994
994
|
"""Load native libs, connect P2P, and start the frame-receive thread."""
|
|
995
|
-
return await asyncio.
|
|
995
|
+
return await asyncio.get_running_loop().run_in_executor(
|
|
996
996
|
None, self._start_sync)
|
|
997
997
|
|
|
998
998
|
def _start_sync(self) -> bool:
|
|
@@ -1211,7 +1211,7 @@ class TutkStreamSession:
|
|
|
1211
1211
|
"""Signal the receive thread to stop and wait for it."""
|
|
1212
1212
|
self._stop_event.set()
|
|
1213
1213
|
if self._thread is not None:
|
|
1214
|
-
await asyncio.
|
|
1214
|
+
await asyncio.get_running_loop().run_in_executor(
|
|
1215
1215
|
None, lambda: self._thread.join(timeout=5.0)
|
|
1216
1216
|
)
|
|
1217
1217
|
|
|
@@ -1328,7 +1328,7 @@ class LiveStreamSession:
|
|
|
1328
1328
|
return False
|
|
1329
1329
|
|
|
1330
1330
|
# Start background receive/heartbeat task.
|
|
1331
|
-
self._task = asyncio.
|
|
1331
|
+
self._task = asyncio.get_running_loop().create_task(self._receive_loop())
|
|
1332
1332
|
return True
|
|
1333
1333
|
|
|
1334
1334
|
async def stop(self) -> None:
|
|
@@ -4248,7 +4248,7 @@ class DeviceClient(object):
|
|
|
4248
4248
|
buf = _io.BytesIO()
|
|
4249
4249
|
pil_img.save(buf, "JPEG")
|
|
4250
4250
|
self.latest_jpeg = buf.getvalue()
|
|
4251
|
-
self._last_frame_time = asyncio.
|
|
4251
|
+
self._last_frame_time = asyncio.get_running_loop().time()
|
|
4252
4252
|
except Exception as enc_exc:
|
|
4253
4253
|
_LOGGER.debug("Streaming encode failed for %s: %s", self.device_id, enc_exc)
|
|
4254
4254
|
|
|
@@ -4287,7 +4287,7 @@ class DeviceClient(object):
|
|
|
4287
4287
|
try:
|
|
4288
4288
|
while self._streaming_active:
|
|
4289
4289
|
await asyncio.sleep(5.0)
|
|
4290
|
-
elapsed = asyncio.
|
|
4290
|
+
elapsed = asyncio.get_running_loop().time() - self._last_frame_time
|
|
4291
4291
|
if self._last_frame_time > 0 and elapsed > _WATCHDOG:
|
|
4292
4292
|
_LOGGER.warning(
|
|
4293
4293
|
"No frames from %s in %.0fs - restarting stream",
|
|
@@ -4417,7 +4417,7 @@ class DeviceClient(object):
|
|
|
4417
4417
|
serve_url = self._keepalive_rtsp_url
|
|
4418
4418
|
_MIN_DELAY, _MAX_DELAY = 5.0, 300.0
|
|
4419
4419
|
retry_delay = _MIN_DELAY
|
|
4420
|
-
loop = asyncio.
|
|
4420
|
+
loop = asyncio.get_running_loop()
|
|
4421
4421
|
while self._streaming_active:
|
|
4422
4422
|
# Thread-safe queues: taps run on the loop, the A/V mux in a thread.
|
|
4423
4423
|
vq: "_queue.Queue" = _queue.Queue(maxsize=600)
|
|
@@ -7162,10 +7162,10 @@ class DeviceClient(object):
|
|
|
7162
7162
|
# the camera silently ignores the original request and we time out.
|
|
7163
7163
|
_init_done: set = set()
|
|
7164
7164
|
_init_pending: set = {answer_fut, camera_offer_fut, webrtc_req_echo_fut}
|
|
7165
|
-
_init_deadline = asyncio.
|
|
7165
|
+
_init_deadline = asyncio.get_running_loop().time() + timeout
|
|
7166
7166
|
_init_reconnect_resends = 0
|
|
7167
|
-
while asyncio.
|
|
7168
|
-
_init_remaining = _init_deadline - asyncio.
|
|
7167
|
+
while asyncio.get_running_loop().time() < _init_deadline:
|
|
7168
|
+
_init_remaining = _init_deadline - asyncio.get_running_loop().time()
|
|
7169
7169
|
_init_done, _init_pending = await asyncio.wait(
|
|
7170
7170
|
_init_pending,
|
|
7171
7171
|
timeout=min(1.0, max(0.01, _init_remaining)),
|
|
@@ -7201,12 +7201,12 @@ class DeviceClient(object):
|
|
|
7201
7201
|
and camera_offer_fut not in _rr_done):
|
|
7202
7202
|
_status("webrtcReq echo received - waiting for camera webrtcResp...")
|
|
7203
7203
|
_rr_secondary_limit = 20.0
|
|
7204
|
-
_rr_secondary_deadline = asyncio.
|
|
7204
|
+
_rr_secondary_deadline = asyncio.get_running_loop().time() + _rr_secondary_limit
|
|
7205
7205
|
_rr_done2: set = set()
|
|
7206
7206
|
_rr_pending2 = _rr_pending # {answer_fut, camera_offer_fut}
|
|
7207
7207
|
_rr_reconnect_resends = 0
|
|
7208
|
-
while asyncio.
|
|
7209
|
-
_remaining = _rr_secondary_deadline - asyncio.
|
|
7208
|
+
while asyncio.get_running_loop().time() < _rr_secondary_deadline:
|
|
7209
|
+
_remaining = _rr_secondary_deadline - asyncio.get_running_loop().time()
|
|
7210
7210
|
_rr_done2, _rr_pending2 = await asyncio.wait(
|
|
7211
7211
|
_rr_pending2,
|
|
7212
7212
|
timeout=min(1.0, max(0.01, _remaining)),
|
|
@@ -7246,11 +7246,11 @@ class DeviceClient(object):
|
|
|
7246
7246
|
outgoing_q.put_nowait(_di_p)
|
|
7247
7247
|
|
|
7248
7248
|
_rr_ext_limit = 20.0
|
|
7249
|
-
_rr_ext_deadline = asyncio.
|
|
7249
|
+
_rr_ext_deadline = asyncio.get_running_loop().time() + _rr_ext_limit
|
|
7250
7250
|
_rr_done3: set = set()
|
|
7251
7251
|
_rr_reconnect_ext = 0
|
|
7252
|
-
while asyncio.
|
|
7253
|
-
_ext_rem = _rr_ext_deadline - asyncio.
|
|
7252
|
+
while asyncio.get_running_loop().time() < _rr_ext_deadline:
|
|
7253
|
+
_ext_rem = _rr_ext_deadline - asyncio.get_running_loop().time()
|
|
7254
7254
|
_rr_done3, _rr_pending2 = await asyncio.wait(
|
|
7255
7255
|
_rr_pending2,
|
|
7256
7256
|
timeout=min(1.0, max(0.01, _ext_rem)),
|
|
@@ -93,7 +93,7 @@ class BroadcastProtocol:
|
|
|
93
93
|
"service": "device",
|
|
94
94
|
"method": "devDiscoveryReq",
|
|
95
95
|
"seq": seq,
|
|
96
|
-
"srcAddr": f"0.{self.user_id}
|
|
96
|
+
"srcAddr": f"0.{self.user_id}",
|
|
97
97
|
"tst": current_timestamp_milliseconds,
|
|
98
98
|
"payload": {
|
|
99
99
|
"extends": {},
|
|
@@ -166,7 +166,7 @@ class Discover:
|
|
|
166
166
|
self._discover_callback, user_id, broadcast_addr=broadcast_ip
|
|
167
167
|
)
|
|
168
168
|
try:
|
|
169
|
-
await asyncio.
|
|
169
|
+
await asyncio.get_running_loop().create_datagram_endpoint(
|
|
170
170
|
lambda p=protocol: p,
|
|
171
171
|
local_addr=(bind_ip, 0),
|
|
172
172
|
)
|
|
@@ -183,7 +183,7 @@ class Discover:
|
|
|
183
183
|
# Last-resort fallback
|
|
184
184
|
protocol = BroadcastProtocol(self._discover_callback, user_id)
|
|
185
185
|
try:
|
|
186
|
-
await asyncio.
|
|
186
|
+
await asyncio.get_running_loop().create_datagram_endpoint(
|
|
187
187
|
lambda: protocol,
|
|
188
188
|
local_addr=("0.0.0.0", 0),
|
|
189
189
|
)
|
{python_aidot_cameras-0.1.0 → python_aidot_cameras-0.5.1/src/python_aidot_cameras.egg-info}/PKG-INFO
RENAMED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.1
|
|
4
|
-
Summary:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Project-URL:
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
|
|
5
|
+
Author-email: cbrightly <chris.brightly@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cbrightly/python-AiDot
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/cbrightly/python-AiDot/issues
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
10
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.11
|
|
13
12
|
Description-Content-Type: text/markdown
|
|
14
13
|
License-File: LICENSE
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
Requires-Dist: aiohttp
|
|
15
|
+
Requires-Dist: paho-mqtt>=2.0
|
|
16
|
+
Requires-Dist: cryptography
|
|
17
|
+
Requires-Dist: pycryptodome
|
|
18
|
+
Provides-Extra: webrtc
|
|
19
|
+
Requires-Dist: aiortc>=1.9.0; extra == "webrtc"
|
|
20
|
+
Requires-Dist: av; extra == "webrtc"
|
|
21
|
+
Requires-Dist: pylibsrtp; extra == "webrtc"
|
|
22
|
+
Requires-Dist: pyopenssl; extra == "webrtc"
|
|
23
|
+
Requires-Dist: numpy; extra == "webrtc"
|
|
24
|
+
Requires-Dist: Pillow; extra == "webrtc"
|
|
17
25
|
Dynamic: license-file
|
|
18
26
|
|
|
19
27
|
# python-aidot
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/aidot/__init__.py
|
|
5
|
+
src/aidot/aes_utils.py
|
|
6
|
+
src/aidot/client.py
|
|
7
|
+
src/aidot/const.py
|
|
8
|
+
src/aidot/credentials.py
|
|
9
|
+
src/aidot/device_client.py
|
|
10
|
+
src/aidot/discover.py
|
|
11
|
+
src/aidot/exceptions.py
|
|
12
|
+
src/aidot/g711.py
|
|
13
|
+
src/python_aidot_cameras.egg-info/PKG-INFO
|
|
14
|
+
src/python_aidot_cameras.egg-info/SOURCES.txt
|
|
15
|
+
src/python_aidot_cameras.egg-info/dependency_links.txt
|
|
16
|
+
src/python_aidot_cameras.egg-info/requires.txt
|
|
17
|
+
src/python_aidot_cameras.egg-info/top_level.txt
|
|
18
|
+
tests/test_alarm_event.py
|
|
19
|
+
tests/test_highport_nomination.py
|
|
20
|
+
tests/test_motion_poll.py
|
|
21
|
+
tests/test_sdes_talk.py
|
|
22
|
+
tests/test_sdes_watchdog.py
|
|
23
|
+
tests/test_speak.py
|
|
24
|
+
tests/test_stream_cap.py
|
|
25
|
+
tests/test_talk.py
|
|
26
|
+
tests/test_terminal_ack.py
|
|
27
|
+
tests/test_token_refresh.py
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""Constants for the aidot integration."""
|
|
2
|
-
|
|
3
|
-
APP_ID = "1383974540041977857"
|
|
4
|
-
BASE_URL = "https://prod-us-api.arnoo.com/v17"
|
|
5
|
-
|
|
6
|
-
PUBLIC_KEY_PEM = b"""
|
|
7
|
-
-----BEGIN PUBLIC KEY-----
|
|
8
|
-
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtQAnPCi8ksPnS1Du6z96PsKfN
|
|
9
|
-
p2Gp/f/bHwlrAdplbX3p7/TnGpnbJGkLq8uRxf6cw+vOthTsZjkPCF7CatRvRnTj
|
|
10
|
-
c9fcy7yE0oXa5TloYyXD6GkxgftBbN/movkJJGQCc7gFavuYoAdTRBOyQoXBtm0m
|
|
11
|
-
kXMSjXOldI/290b9BQIDAQAB
|
|
12
|
-
-----END PUBLIC KEY-----
|
|
13
|
-
"""
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "python-aidot-cameras"
|
|
7
|
-
version = "0.1.0"
|
|
8
|
-
authors = [
|
|
9
|
-
{ name="Chris Brightly", email="chris.brightly@gmail.com" }
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
description = "Adds camera support to AiDot-Development-Team's python-AiDot library"
|
|
13
|
-
readme = "README.md"
|
|
14
|
-
requires-python = ">=3.8"
|
|
15
|
-
classifiers = [
|
|
16
|
-
"Programming Language :: Python :: 3",
|
|
17
|
-
"License :: OSI Approved :: MIT License",
|
|
18
|
-
"Operating System :: OS Independent",
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
[project.urls]
|
|
22
|
-
Homepage = "https://github.com"
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
setup.cfg
|
|
5
|
-
setup.py
|
|
6
|
-
aidot/__init__.py
|
|
7
|
-
aidot/aes_utils.py
|
|
8
|
-
aidot/client.py
|
|
9
|
-
aidot/const.py
|
|
10
|
-
aidot/credentials.py
|
|
11
|
-
aidot/device_client.py
|
|
12
|
-
aidot/discover.py
|
|
13
|
-
aidot/exceptions.py
|
|
14
|
-
aidot/g711.py
|
|
15
|
-
aidot/login_const.py
|
|
16
|
-
python_aidot_cameras.egg-info/PKG-INFO
|
|
17
|
-
python_aidot_cameras.egg-info/SOURCES.txt
|
|
18
|
-
python_aidot_cameras.egg-info/dependency_links.txt
|
|
19
|
-
python_aidot_cameras.egg-info/top_level.txt
|
|
20
|
-
tests/test_alarm_event.py
|
|
21
|
-
tests/test_highport_nomination.py
|
|
22
|
-
tests/test_motion_poll.py
|
|
23
|
-
tests/test_sdes_talk.py
|
|
24
|
-
tests/test_sdes_watchdog.py
|
|
25
|
-
tests/test_speak.py
|
|
26
|
-
tests/test_stream_cap.py
|
|
27
|
-
tests/test_talk.py
|
|
28
|
-
tests/test_terminal_ack.py
|
|
29
|
-
tests/test_token_refresh.py
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import setuptools
|
|
2
|
-
|
|
3
|
-
with open("README.md", "r") as fh:
|
|
4
|
-
long_description = fh.read()
|
|
5
|
-
|
|
6
|
-
setuptools.setup(
|
|
7
|
-
name="python-aidot",
|
|
8
|
-
version="0.4.19",
|
|
9
|
-
author="aidotdev2024",
|
|
10
|
-
url='https://github.com/cbrightly/python-AiDot',
|
|
11
|
-
description="Control AIDOT WiFi lights and cameras",
|
|
12
|
-
long_description=long_description,
|
|
13
|
-
long_description_content_type="text/markdown",
|
|
14
|
-
packages=setuptools.find_packages(),
|
|
15
|
-
install_requires=[
|
|
16
|
-
"requests",
|
|
17
|
-
"aiohttp",
|
|
18
|
-
# Camera cloud APIs + MQTT signaling are part of the core camera support.
|
|
19
|
-
"paho-mqtt>=2.0",
|
|
20
|
-
"cryptography",
|
|
21
|
-
"pycryptodome",
|
|
22
|
-
],
|
|
23
|
-
extras_require={
|
|
24
|
-
# Required for liveType=2 cameras (WebRTC-over-MQTT streaming, snapshots,
|
|
25
|
-
# two-way audio). Install with: pip install "python-aidot[webrtc] @ git+..."
|
|
26
|
-
"webrtc": [
|
|
27
|
-
"aiortc>=1.9.0",
|
|
28
|
-
"av",
|
|
29
|
-
"pylibsrtp",
|
|
30
|
-
"pyopenssl",
|
|
31
|
-
"numpy",
|
|
32
|
-
"Pillow",
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
classifiers=(
|
|
36
|
-
"Programming Language :: Python :: 3.12",
|
|
37
|
-
"License :: OSI Approved :: MIT License",
|
|
38
|
-
"Operating System :: OS Independent",
|
|
39
|
-
),
|
|
40
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|