python-linkplay 0.0.19__tar.gz → 0.1.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.
Files changed (23) hide show
  1. {python_linkplay-0.0.19/src/python_linkplay.egg-info → python_linkplay-0.1.0}/PKG-INFO +1 -1
  2. python_linkplay-0.1.0/src/linkplay/__version__.py +1 -0
  3. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/bridge.py +19 -3
  4. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/consts.py +2 -0
  5. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/discovery.py +16 -10
  6. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/endpoint.py +4 -2
  7. {python_linkplay-0.0.19 → python_linkplay-0.1.0/src/python_linkplay.egg-info}/PKG-INFO +1 -1
  8. python_linkplay-0.0.19/src/linkplay/__version__.py +0 -1
  9. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/LICENSE +0 -0
  10. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/README.md +0 -0
  11. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/pyproject.toml +0 -0
  12. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/setup.cfg +0 -0
  13. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/setup.py +0 -0
  14. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/__init__.py +0 -0
  15. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/__main__.py +0 -0
  16. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/controller.py +0 -0
  17. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/exceptions.py +0 -0
  18. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/linkplay/utils.py +0 -0
  19. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/python_linkplay.egg-info/SOURCES.txt +0 -0
  20. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/python_linkplay.egg-info/dependency_links.txt +0 -0
  21. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/python_linkplay.egg-info/not-zip-safe +0 -0
  22. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/python_linkplay.egg-info/requires.txt +0 -0
  23. {python_linkplay-0.0.19 → python_linkplay-0.1.0}/src/python_linkplay.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python_linkplay
3
- Version: 0.0.19
3
+ Version: 0.1.0
4
4
  Summary: A Python Library for Seamless LinkPlay Device Control
5
5
  Author: Velleman Group nv
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ __version__ = '0.1.0'
@@ -73,7 +73,17 @@ class LinkPlayDevice:
73
73
  def eth(self) -> str | None:
74
74
  """Returns the ethernet address."""
75
75
  eth2 = self.properties.get(DeviceAttribute.ETH2)
76
- return eth2 if eth2 else self.properties.get(DeviceAttribute.APCLI0)
76
+ eth0 = self.properties.get(DeviceAttribute.ETH0)
77
+ for eth in [eth2, eth0]:
78
+ if eth == "0.0.0.0":
79
+ eth = None
80
+ return (
81
+ eth2
82
+ if eth2
83
+ else eth0
84
+ if eth0
85
+ else self.properties.get(DeviceAttribute.APCLI0)
86
+ )
77
87
 
78
88
  async def timesync(self) -> None:
79
89
  """Sync the time."""
@@ -370,6 +380,8 @@ class LinkPlayMultiroom:
370
380
  async def ungroup(self) -> None:
371
381
  """Ungroups the multiroom group."""
372
382
  await self.leader.request(LinkPlayCommand.MULTIROOM_UNGROUP)
383
+ for follewer in self.followers:
384
+ follewer.multiroom = None
373
385
  self.followers = []
374
386
 
375
387
  async def add_follower(self, follower: LinkPlayBridge) -> None:
@@ -377,14 +389,18 @@ class LinkPlayMultiroom:
377
389
  await follower.request(
378
390
  LinkPlayCommand.MULTIROOM_JOIN.format(self.leader.device.eth)
379
391
  ) # type: ignore[str-format]
380
- self.followers.append(follower)
392
+ if follower not in self.followers:
393
+ follower.multiroom = self
394
+ self.followers.append(follower)
381
395
 
382
396
  async def remove_follower(self, follower: LinkPlayBridge) -> None:
383
397
  """Removes a follower from the multiroom group."""
384
398
  await self.leader.request(
385
399
  LinkPlayCommand.MULTIROOM_KICK.format(follower.device.eth)
386
400
  ) # type: ignore[str-format]
387
- self.followers.remove(follower)
401
+ if follower in self.followers:
402
+ follower.multiroom = None
403
+ self.followers.remove(follower)
388
404
 
389
405
  async def set_volume(self, value: int) -> None:
390
406
  """Sets the volume for the multiroom group."""
@@ -145,6 +145,7 @@ class PlayingMode(StrEnum):
145
145
  HTTP_MAX = "29"
146
146
  ALARM = "30"
147
147
  SPOTIFY = "31"
148
+ TIDAL = "32"
148
149
  LINE_IN = "40"
149
150
  BLUETOOTH = "41"
150
151
  OPTICAL = "43"
@@ -179,6 +180,7 @@ PLAY_MODE_SEND_MAP: dict[PlayingMode, str] = { # case sensitive!
179
180
  PlayingMode.UDISK: "udisk",
180
181
  PlayingMode.ALARM: "Alarm",
181
182
  PlayingMode.SPOTIFY: "Spotify",
183
+ PlayingMode.TIDAL: "Tidal",
182
184
  PlayingMode.LINE_IN: "line-in",
183
185
  PlayingMode.BLUETOOTH: "bluetooth",
184
186
  PlayingMode.OPTICAL: "optical",
@@ -21,7 +21,7 @@ async def linkplay_factory_bridge(
21
21
  """Attempts to create a LinkPlayBridge from the given IP address.
22
22
  Returns None if the device is not an expected LinkPlay device."""
23
23
  endpoint: LinkPlayApiEndpoint = LinkPlayApiEndpoint(
24
- protocol="http", endpoint=ip_address, session=session
24
+ protocol="http", port=80, endpoint=ip_address, session=session
25
25
  )
26
26
  try:
27
27
  return await linkplay_factory_bridge_endpoint(endpoint)
@@ -48,16 +48,22 @@ async def linkplay_factory_httpapi_bridge(
48
48
  Attempts to use HTTPS first, then falls back to HTTP.
49
49
  Raises LinkPlayRequestException if the device is not an expected LinkPlay device."""
50
50
 
51
- https_endpoint: LinkPlayApiEndpoint = LinkPlayApiEndpoint(
52
- protocol="https", endpoint=ip_address, session=session
53
- )
54
- try:
55
- return await linkplay_factory_bridge_endpoint(https_endpoint)
56
- except LinkPlayRequestException:
57
- http_endpoint: LinkPlayApiEndpoint = LinkPlayApiEndpoint(
58
- protocol="http", endpoint=ip_address, session=session
51
+ protocol_port_pairs = [("https", 443), ("https", 4443)]
52
+
53
+ for protocol, port in protocol_port_pairs:
54
+ endpoint: LinkPlayApiEndpoint = LinkPlayApiEndpoint(
55
+ protocol=protocol, port=port, endpoint=ip_address, session=session
59
56
  )
60
- return await linkplay_factory_bridge_endpoint(http_endpoint)
57
+
58
+ try:
59
+ return await linkplay_factory_bridge_endpoint(endpoint)
60
+ except LinkPlayRequestException:
61
+ pass
62
+
63
+ http_endpoint: LinkPlayApiEndpoint = LinkPlayApiEndpoint(
64
+ protocol="http", port=80, endpoint=ip_address, session=session
65
+ )
66
+ return await linkplay_factory_bridge_endpoint(http_endpoint)
61
67
 
62
68
 
63
69
  async def discover_linkplay_bridges(
@@ -30,12 +30,14 @@ class LinkPlayEndpoint(ABC):
30
30
  class LinkPlayApiEndpoint(LinkPlayEndpoint):
31
31
  """Represents a LinkPlay HTTP API endpoint."""
32
32
 
33
- def __init__(self, *, protocol: str, endpoint: str, session: ClientSession):
33
+ def __init__(
34
+ self, *, protocol: str, port: int, endpoint: str, session: ClientSession
35
+ ):
34
36
  assert protocol in [
35
37
  "http",
36
38
  "https",
37
39
  ], "Protocol must be either 'http' or 'https'"
38
- self._endpoint: str = f"{protocol}://{endpoint}"
40
+ self._endpoint: str = f"{protocol}://{endpoint}:{port}"
39
41
  self._session: ClientSession = session
40
42
 
41
43
  def to_dict(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python_linkplay
3
- Version: 0.0.19
3
+ Version: 0.1.0
4
4
  Summary: A Python Library for Seamless LinkPlay Device Control
5
5
  Author: Velleman Group nv
6
6
  License: MIT
@@ -1 +0,0 @@
1
- __version__ = '0.0.19'