python-linkplay 0.0.12__py3-none-any.whl → 0.0.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- linkplay/__version__.py +1 -1
- linkplay/bridge.py +17 -1
- linkplay/consts.py +4 -1
- linkplay/controller.py +28 -19
- linkplay/utils.py +0 -2
- {python_linkplay-0.0.12.dist-info → python_linkplay-0.0.15.dist-info}/METADATA +1 -1
- python_linkplay-0.0.15.dist-info/RECORD +15 -0
- python_linkplay-0.0.12.dist-info/RECORD +0 -15
- {python_linkplay-0.0.12.dist-info → python_linkplay-0.0.15.dist-info}/LICENSE +0 -0
- {python_linkplay-0.0.12.dist-info → python_linkplay-0.0.15.dist-info}/WHEEL +0 -0
- {python_linkplay-0.0.12.dist-info → python_linkplay-0.0.15.dist-info}/top_level.txt +0 -0
linkplay/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.0.
|
1
|
+
__version__ = '0.0.15'
|
linkplay/bridge.py
CHANGED
@@ -4,6 +4,7 @@ from typing import Any
|
|
4
4
|
|
5
5
|
from linkplay.consts import (
|
6
6
|
INPUT_MODE_MAP,
|
7
|
+
LOGGER,
|
7
8
|
PLAY_MODE_SEND_MAP,
|
8
9
|
ChannelType,
|
9
10
|
DeviceAttribute,
|
@@ -258,11 +259,13 @@ class LinkPlayBridge:
|
|
258
259
|
endpoint: LinkPlayEndpoint
|
259
260
|
device: LinkPlayDevice
|
260
261
|
player: LinkPlayPlayer
|
262
|
+
multiroom: LinkPlayMultiroom | None
|
261
263
|
|
262
264
|
def __init__(self, *, endpoint: LinkPlayEndpoint):
|
263
265
|
self.endpoint = endpoint
|
264
266
|
self.device = LinkPlayDevice(self)
|
265
267
|
self.player = LinkPlayPlayer(self)
|
268
|
+
self.multiroom = None
|
266
269
|
|
267
270
|
def __str__(self) -> str:
|
268
271
|
if self.device.name == "":
|
@@ -276,14 +279,20 @@ class LinkPlayBridge:
|
|
276
279
|
"endpoint": self.endpoint.to_dict(),
|
277
280
|
"device": self.device.to_dict(),
|
278
281
|
"player": self.player.to_dict(),
|
282
|
+
"multiroom": self.multiroom.to_dict() if self.multiroom else None,
|
279
283
|
}
|
280
284
|
|
281
285
|
async def json_request(self, command: str) -> dict[str, str]:
|
282
286
|
"""Performs a GET request on the given command and returns the result as a JSON object."""
|
283
|
-
|
287
|
+
LOGGER.debug(str.format("Request {} at {}", command, self.endpoint))
|
288
|
+
response = await self.endpoint.json_request(command)
|
289
|
+
LOGGER.debug(str.format("Response {}: {}", command, response))
|
290
|
+
return response
|
284
291
|
|
285
292
|
async def request(self, command: str) -> None:
|
286
293
|
"""Performs a GET request on the given command and verifies the result."""
|
294
|
+
|
295
|
+
LOGGER.debug(str.format("Request command at {}: {}", self.endpoint, command))
|
287
296
|
await self.endpoint.request(command)
|
288
297
|
|
289
298
|
|
@@ -298,6 +307,13 @@ class LinkPlayMultiroom:
|
|
298
307
|
self.leader = leader
|
299
308
|
self.followers = []
|
300
309
|
|
310
|
+
def to_dict(self):
|
311
|
+
"""Return the state of the LinkPlayMultiroom."""
|
312
|
+
return {
|
313
|
+
"leader": self.leader.to_dict(),
|
314
|
+
"followers": [follower.to_dict() for follower in self.followers],
|
315
|
+
}
|
316
|
+
|
301
317
|
async def update_status(self, bridges: list[LinkPlayBridge]) -> None:
|
302
318
|
"""Updates the multiroom status."""
|
303
319
|
properties: dict[Any, Any] = await self.leader.json_request(
|
linkplay/consts.py
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
import logging
|
1
2
|
from enum import IntFlag, StrEnum
|
2
3
|
|
4
|
+
LOGGER = logging.getLogger("linkplay")
|
5
|
+
|
3
6
|
API_ENDPOINT: str = "{}/httpapi.asp?command={}"
|
4
|
-
API_TIMEOUT: int =
|
7
|
+
API_TIMEOUT: int = 5
|
5
8
|
UNKNOWN_TRACK_PLAYING: str = "Unknown"
|
6
9
|
UPNP_DEVICE_TYPE = "urn:schemas-upnp-org:device:MediaRenderer:1"
|
7
10
|
TCPPORT = 8899
|
linkplay/controller.py
CHANGED
@@ -40,31 +40,40 @@ class LinkPlayController:
|
|
40
40
|
async def discover_multirooms(self) -> None:
|
41
41
|
"""Attempts to discover multirooms on the local network."""
|
42
42
|
|
43
|
+
# Find and update existing multirooms
|
44
|
+
multirooms = [
|
45
|
+
bridge.multiroom
|
46
|
+
for bridge in self.bridges
|
47
|
+
if bridge.multiroom and bridge.multiroom.leader is bridge
|
48
|
+
]
|
49
|
+
|
50
|
+
removed_multirooms = []
|
51
|
+
for multiroom in multirooms:
|
52
|
+
for follower in multiroom.followers:
|
53
|
+
follower.multiroom = None
|
54
|
+
await multiroom.update_status(self.bridges)
|
55
|
+
if len(multiroom.followers) > 0:
|
56
|
+
for follower in multiroom.followers:
|
57
|
+
follower.multiroom = multiroom
|
58
|
+
else:
|
59
|
+
multiroom.leader.multiroom = None
|
60
|
+
removed_multirooms.append(multiroom)
|
61
|
+
|
43
62
|
# Create new multirooms from new bridges
|
44
|
-
new_multirooms = []
|
45
63
|
for bridge in self.bridges:
|
46
|
-
|
47
|
-
multiroom for multiroom in self.multirooms if multiroom.leader == bridge
|
48
|
-
)
|
49
|
-
|
50
|
-
if has_multiroom:
|
64
|
+
if bridge.multiroom:
|
51
65
|
continue
|
52
66
|
|
53
67
|
multiroom = LinkPlayMultiroom(bridge)
|
54
68
|
await multiroom.update_status(self.bridges)
|
55
69
|
if len(multiroom.followers) > 0:
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
await multiroom.update_status(self.bridges)
|
70
|
+
multirooms.append(multiroom)
|
71
|
+
bridge.multiroom = multiroom
|
72
|
+
for follower in multiroom.followers:
|
73
|
+
follower.multiroom = multiroom
|
61
74
|
|
62
|
-
# Remove multirooms
|
63
|
-
|
64
|
-
multiroom for multiroom in self.multirooms if not multiroom.followers
|
65
|
-
]
|
66
|
-
for empty_multiroom in empty_multirooms:
|
67
|
-
self.multirooms.remove(empty_multiroom)
|
75
|
+
# Remove multirooms with no followers
|
76
|
+
multirooms = [item for item in multirooms if item not in removed_multirooms]
|
68
77
|
|
69
|
-
#
|
70
|
-
self.multirooms
|
78
|
+
# Update multirooms in controller
|
79
|
+
self.multirooms = multirooms
|
linkplay/utils.py
CHANGED
@@ -24,8 +24,6 @@ from linkplay.consts import (
|
|
24
24
|
)
|
25
25
|
from linkplay.exceptions import LinkPlayRequestException
|
26
26
|
|
27
|
-
_LOGGER = logging.getLogger(__name__)
|
28
|
-
|
29
27
|
|
30
28
|
async def session_call_api(endpoint: str, session: ClientSession, command: str) -> str:
|
31
29
|
"""Calls the LinkPlay API and returns the result as a string.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
linkplay/__init__.py,sha256=y9ZehEq-KhS3cwn-PUpwVSJGfDUx7e5wf_G6guODcTk,56
|
2
|
+
linkplay/__main__.py,sha256=Wcza80QaWfOaHjyJEfQYhB9kiPLE0NOqIj4zVWv2Nqs,577
|
3
|
+
linkplay/__version__.py,sha256=o8ktXEQwpPz87S9ENy9HQ1pZX4vOWks2rVYTxs5_YVY,23
|
4
|
+
linkplay/bridge.py,sha256=A5W8Qgtn9KVNYdhxEmwP9iKoH5YTAknFrKJxDKd5juY,13120
|
5
|
+
linkplay/consts.py,sha256=IoIEKT8yUULqtc2dui_5qBFTqx3OD15zzbHAkWHF-wY,13457
|
6
|
+
linkplay/controller.py,sha256=i3eLlaZ5pWoGgRT27I564Z9Bmi_aiY9g6lUocXE2qmk,2894
|
7
|
+
linkplay/discovery.py,sha256=aEzN_94pKLmHKYIL7DxSW0FYRsaF2ruZe2bwXz0zf5U,4299
|
8
|
+
linkplay/endpoint.py,sha256=5Ybr54aroFVEZ6fnFYP41QAuSP7-J9qHYAzLod4S3KY,2459
|
9
|
+
linkplay/exceptions.py,sha256=tWJWHsKVkUEq3Yet1Z739IxcaQT8YamDeSp0tqHde9c,107
|
10
|
+
linkplay/utils.py,sha256=aU_9TL39ngQaEMhFWMtlwB3POba2GjGlfNBshLFFS90,7788
|
11
|
+
python_linkplay-0.0.15.dist-info/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
|
12
|
+
python_linkplay-0.0.15.dist-info/METADATA,sha256=1YOxNR-y7rIZbjipaYnkK_Vot5LK2VPuaY93K7LSOgU,2988
|
13
|
+
python_linkplay-0.0.15.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
14
|
+
python_linkplay-0.0.15.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
|
15
|
+
python_linkplay-0.0.15.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
linkplay/__init__.py,sha256=y9ZehEq-KhS3cwn-PUpwVSJGfDUx7e5wf_G6guODcTk,56
|
2
|
-
linkplay/__main__.py,sha256=Wcza80QaWfOaHjyJEfQYhB9kiPLE0NOqIj4zVWv2Nqs,577
|
3
|
-
linkplay/__version__.py,sha256=9pBH_sWelBMNY03FEugYdlVXfX9_b6TK-v2lLt7j0dY,23
|
4
|
-
linkplay/bridge.py,sha256=Ew9zKOL3bFlXSaxskPcF1ZFPYeZsc9O4gLJHz8K5C3o,12465
|
5
|
-
linkplay/consts.py,sha256=fck-MIcJ1MVwkWa5K1dTTWcleRuXs1EO7RY4MwJga8s,13402
|
6
|
-
linkplay/controller.py,sha256=IYoXvHh2zhrsRoRG7gwYFoWSIrL5Hl9hR7c2dhGPNX8,2484
|
7
|
-
linkplay/discovery.py,sha256=aEzN_94pKLmHKYIL7DxSW0FYRsaF2ruZe2bwXz0zf5U,4299
|
8
|
-
linkplay/endpoint.py,sha256=5Ybr54aroFVEZ6fnFYP41QAuSP7-J9qHYAzLod4S3KY,2459
|
9
|
-
linkplay/exceptions.py,sha256=tWJWHsKVkUEq3Yet1Z739IxcaQT8YamDeSp0tqHde9c,107
|
10
|
-
linkplay/utils.py,sha256=WVKdxITDymLCmKGqlD9Ieyb96qZ-QSC9oIe-KGW4IFU,7827
|
11
|
-
python_linkplay-0.0.12.dist-info/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
|
12
|
-
python_linkplay-0.0.12.dist-info/METADATA,sha256=I_YhOhrdEBBE5Ye5h9t6pSpoOaED_CL6yENZRvIv7DE,2988
|
13
|
-
python_linkplay-0.0.12.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
14
|
-
python_linkplay-0.0.12.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
|
15
|
-
python_linkplay-0.0.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|