python-linkplay 0.2.1__py3-none-any.whl → 0.2.3__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 CHANGED
@@ -1 +1 @@
1
- __version__ = '0.2.1'
1
+ __version__ = '0.2.3'
linkplay/bridge.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import time
4
- from typing import Any
4
+ from typing import Any, Callable
5
5
 
6
6
  from linkplay.consts import (
7
7
  INPUT_MODE_MAP,
@@ -36,6 +36,8 @@ class LinkPlayDevice:
36
36
  bridge: LinkPlayBridge
37
37
  properties: dict[DeviceAttribute, str]
38
38
 
39
+ controller: Callable[[], None] | None = None
40
+
39
41
  def __init__(self, bridge: LinkPlayBridge):
40
42
  self.bridge = bridge
41
43
  self.properties = dict.fromkeys(DeviceAttribute.__members__.values(), "")
@@ -44,6 +46,10 @@ class LinkPlayDevice:
44
46
  """Return the state of the LinkPlayDevice."""
45
47
  return {"properties": self.properties}
46
48
 
49
+ def set_callback(self, controller: Callable[[], None]) -> None:
50
+ """Sets a callback function to notify events."""
51
+ self.controller = controller
52
+
47
53
  async def update_status(self) -> None:
48
54
  """Update the device status."""
49
55
  self.properties = await self.bridge.json_request(LinkPlayCommand.DEVICE_STATUS) # type: ignore[assignment]
@@ -123,6 +129,8 @@ class LinkPlayPlayer:
123
129
  properties: dict[PlayerAttribute, str]
124
130
  custom_properties: dict[PlayerAttribute, str]
125
131
 
132
+ previous_playing_mode: PlayingMode | None = None
133
+
126
134
  def __init__(self, bridge: LinkPlayBridge):
127
135
  self.bridge = bridge
128
136
  self.properties = dict.fromkeys(PlayerAttribute.__members__.values(), "")
@@ -140,6 +148,20 @@ class LinkPlayPlayer:
140
148
 
141
149
  self.properties = fixup_player_properties(properties)
142
150
 
151
+ # handle multiroom changes
152
+ if self.bridge.device.controller is not None and (
153
+ (
154
+ self.previous_playing_mode != PlayingMode.FOLLOWER
155
+ and self.play_mode == PlayingMode.FOLLOWER
156
+ )
157
+ or (
158
+ self.previous_playing_mode == PlayingMode.FOLLOWER
159
+ and self.play_mode != PlayingMode.FOLLOWER
160
+ )
161
+ ):
162
+ self.bridge.device.controller()
163
+ self.previous_playing_mode = self.play_mode
164
+
143
165
  async def next(self) -> None:
144
166
  """Play the next song in the playlist."""
145
167
  await self.bridge.request(LinkPlayCommand.NEXT)
linkplay/controller.py CHANGED
@@ -18,6 +18,16 @@ class LinkPlayController:
18
18
  self.bridges = []
19
19
  self.multirooms = []
20
20
 
21
+ def get_bridge_callback(self):
22
+ """Returns an async callback function for LinkPlayBridge."""
23
+
24
+ async def callback() -> None:
25
+ """Async callback function to handle events from a LinkPlayBridge."""
26
+ LOGGER.debug("Controller event received")
27
+ await self.discover_multirooms()
28
+
29
+ return callback
30
+
21
31
  async def discover_bridges(self) -> None:
22
32
  """Attempts to discover LinkPlay devices on the local network."""
23
33
 
@@ -46,6 +56,7 @@ class LinkPlayController:
46
56
  # Add bridge
47
57
  current_bridges = [bridge.device.uuid for bridge in self.bridges]
48
58
  if bridge_to_add.device.uuid not in current_bridges:
59
+ bridge_to_add.device.set_callback(self.get_bridge_callback())
49
60
  self.bridges.append(bridge_to_add)
50
61
 
51
62
  async def remove_bridge(self, bridge_to_remove: LinkPlayBridge) -> None:
@@ -80,6 +91,8 @@ class LinkPlayController:
80
91
  multiroom.leader.multiroom = None
81
92
  removed_multirooms.append(multiroom)
82
93
  except LinkPlayInvalidDataException as exc:
94
+ multiroom.leader.multiroom = None
95
+ removed_multirooms.append(multiroom)
83
96
  LOGGER.exception(exc)
84
97
 
85
98
  # Create new multirooms from new bridges
linkplay/utils.py CHANGED
@@ -185,7 +185,7 @@ async def async_create_ssl_context(
185
185
  with contextlib.suppress(AttributeError):
186
186
  # This only works for OpenSSL >= 1.0.0
187
187
  sslcontext.options |= ssl.OP_NO_COMPRESSION
188
- sslcontext.set_default_verify_paths()
188
+ await loop.run_in_executor(executor, sslcontext.set_default_verify_paths)
189
189
  return sslcontext
190
190
 
191
191
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python_linkplay
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: A Python Library for Seamless LinkPlay Device Control
5
5
  Author: Velleman Group nv
6
6
  License: MIT
@@ -0,0 +1,16 @@
1
+ linkplay/__init__.py,sha256=y9ZehEq-KhS3cwn-PUpwVSJGfDUx7e5wf_G6guODcTk,56
2
+ linkplay/__main__.py,sha256=Wcza80QaWfOaHjyJEfQYhB9kiPLE0NOqIj4zVWv2Nqs,577
3
+ linkplay/__version__.py,sha256=XtWUl6HPylv5jZLd2KkgtPptuzuda93kC2REmOrF-Cs,22
4
+ linkplay/bridge.py,sha256=m_1E71dP5sftvA4ahmRvDsNrYDHXGV9CpOynuv2v29I,20262
5
+ linkplay/consts.py,sha256=3yUX_a_wOjpVLUPK5ogSCEOwgVJs-TIPb8LPo4Ds1Ic,14242
6
+ linkplay/controller.py,sha256=U370dMVl-E7iIhDC1wWmsrnFcdrWso84K0vkImsgCTo,4430
7
+ linkplay/discovery.py,sha256=NnkO9gknp3Cyff7830zBu1LwyhkkWCdhDbEDbAwF8D8,4610
8
+ linkplay/endpoint.py,sha256=_gelW0cDWt0SC8EApwaKIVh_YJIMNiOkfrLR_RYW7aM,2677
9
+ linkplay/exceptions.py,sha256=Kow13uJPSL4y6rXMnkcl_Yp9wH1weOyKw_knd0p-Exc,173
10
+ linkplay/manufacturers.py,sha256=oddlZTbtrCBVCcy5adbXk0bhBOXEcmC6U5-a7QShLHY,3906
11
+ linkplay/utils.py,sha256=U6hy5KKUzeEc3RMZigTJBynT-ddNfW8KIIMHaydZGQc,9459
12
+ python_linkplay-0.2.3.dist-info/licenses/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
13
+ python_linkplay-0.2.3.dist-info/METADATA,sha256=Y6N8RNsgHABjHRGztEuT_Gsbv4DP2u8K-Bsce10FO7E,3179
14
+ python_linkplay-0.2.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
15
+ python_linkplay-0.2.3.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
16
+ python_linkplay-0.2.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
1
- linkplay/__init__.py,sha256=y9ZehEq-KhS3cwn-PUpwVSJGfDUx7e5wf_G6guODcTk,56
2
- linkplay/__main__.py,sha256=Wcza80QaWfOaHjyJEfQYhB9kiPLE0NOqIj4zVWv2Nqs,577
3
- linkplay/__version__.py,sha256=PmcQ2PI2oP8irnLtJLJby2YfW6sBvLAmL-VpABzTqwc,22
4
- linkplay/bridge.py,sha256=OPYXoLCCWqFTeZvxpweLdNegleZXfkbO6NpoWTlNzCs,19472
5
- linkplay/consts.py,sha256=3yUX_a_wOjpVLUPK5ogSCEOwgVJs-TIPb8LPo4Ds1Ic,14242
6
- linkplay/controller.py,sha256=ZW3WbOhm1fzFwkkNTEAfZjBhJkhkd61LtfiFgWXqjE0,3903
7
- linkplay/discovery.py,sha256=NnkO9gknp3Cyff7830zBu1LwyhkkWCdhDbEDbAwF8D8,4610
8
- linkplay/endpoint.py,sha256=_gelW0cDWt0SC8EApwaKIVh_YJIMNiOkfrLR_RYW7aM,2677
9
- linkplay/exceptions.py,sha256=Kow13uJPSL4y6rXMnkcl_Yp9wH1weOyKw_knd0p-Exc,173
10
- linkplay/manufacturers.py,sha256=oddlZTbtrCBVCcy5adbXk0bhBOXEcmC6U5-a7QShLHY,3906
11
- linkplay/utils.py,sha256=duJAbPWkjKlK2bZUNSoM_Ny1lDK5v7S9_HHT7UysjrI,9423
12
- python_linkplay-0.2.1.dist-info/licenses/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
13
- python_linkplay-0.2.1.dist-info/METADATA,sha256=49HJlQPdHQkHmXQEVh7e7bzSeG39He3OnRzl5R8MB78,3179
14
- python_linkplay-0.2.1.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
15
- python_linkplay-0.2.1.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
16
- python_linkplay-0.2.1.dist-info/RECORD,,