python-linkplay 0.2.12__py3-none-any.whl → 0.2.14__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.12'
1
+ __version__ = '0.2.14'
linkplay/consts.py CHANGED
@@ -4,7 +4,7 @@ from enum import IntFlag, StrEnum
4
4
  LOGGER = logging.getLogger("linkplay")
5
5
 
6
6
  API_ENDPOINT: str = "{}/httpapi.asp?command={}"
7
- API_TIMEOUT: int = 5
7
+ API_TIMEOUT: int = 10
8
8
  UNKNOWN_TRACK_PLAYING: str = "Unknown"
9
9
  UPNP_DEVICE_TYPE = "urn:schemas-upnp-org:device:MediaRenderer:1"
10
10
  TCPPORT = 8899
linkplay/exceptions.py CHANGED
@@ -1,12 +1,21 @@
1
+ """This module defines custom exceptions for the LinkPlay integration."""
2
+
3
+
1
4
  class LinkPlayException(Exception):
2
- pass
5
+ """Base exception for LinkPlay errors."""
3
6
 
4
7
 
5
8
  class LinkPlayRequestException(LinkPlayException):
6
- pass
9
+ """Exception raised for errors in LinkPlay requests."""
10
+
11
+
12
+ class LinkPlayRequestCancelledException(LinkPlayException):
13
+ """Exception raised when a LinkPlay request is cancelled."""
7
14
 
8
15
 
9
16
  class LinkPlayInvalidDataException(LinkPlayException):
17
+ """Exception raised for invalid data received from LinkPlay endpoints."""
18
+
10
19
  def __init__(self, message: str = "Invalid data received", data: str | None = None):
11
20
  super().__init__(message)
12
21
  self.data = data
linkplay/manufacturers.py CHANGED
@@ -10,6 +10,10 @@ MANUFACTURER_IEAST: Final[str] = "iEAST"
10
10
  MANUFACTURER_WIIM: Final[str] = "WiiM"
11
11
  MANUFACTURER_GGMM: Final[str] = "GGMM"
12
12
  MANUFACTURER_MEDION: Final[str] = "Medion"
13
+ MANUFACTURER_AUGUST: Final[str] = "August"
14
+ MANUFACTURER_MUZO: Final[str] = "Muzo"
15
+ MANUFACTURER_AUDIOPRO: Final[str] = "Audio Pro"
16
+ MANUFACTURER_TRIANGLE: Final[str] = "Triangle"
13
17
  MANUFACTURER_GENERIC: Final[str] = "Generic"
14
18
  MODELS_ARTSOUND_SMART_ZONE4: Final[str] = "Smart Zone 4 AMP"
15
19
  MODELS_ARTSOUND_SMART_HYDE: Final[str] = "Smart Hyde"
@@ -33,8 +37,21 @@ MODELS_WIIM_AMP: Final[str] = "WiiM Amp"
33
37
  MODELS_WIIM_MINI: Final[str] = "WiiM Mini"
34
38
  MODELS_WIIM_PRO: Final[str] = "WiiM Pro"
35
39
  MODELS_WIIM_PRO_PLUS: Final[str] = "WiiM Pro Plus"
40
+ MODELS_WIIM_AMP_PRO: Final[str] = "WiiM Amp Pro"
41
+ MODELS_WIIM_ULTRA: Final[str] = "WiiM Ultra"
42
+ MODELS_WIIM_AMP_ULTRA: Final[str] = "WiiM Amp Ultra"
43
+ MODELS_WIIM_CI_MOD_S: Final[str] = "WiiM CI MOD S"
44
+ MODELS_WIIM_CI_MOD_A80: Final[str] = "WiiM CI MOD A80"
36
45
  MODELS_GGMM_GGMM_E2: Final[str] = "GGMM E2"
37
46
  MODELS_MEDION_MD_43970: Final[str] = "Life P66970 (MD 43970)"
47
+ MODELS_WR320: Final[str] = "WR320"
48
+ MODELS_WS350: Final[str] = "WS350"
49
+ MODELS_MUZO_COBBLESTONE: Final[str] = "MUZO Cobblestone Wi-Fi Audio Receiver"
50
+ MODELS_AUDIOPRO_C3: Final[str] = "C3"
51
+ MODELS_AUDIOPRO_C10: Final[str] = "C10"
52
+ MODELS_AUDIOPRO_A10: Final[str] = "A10"
53
+ MODELS_TRIANGLE_AIO_3: Final[str] = "AIO 3"
54
+
38
55
  MODELS_GENERIC: Final[str] = "Generic"
39
56
 
40
57
  PROJECTID_LOOKUP: Final[dict[str, tuple[str, str]]] = {
@@ -71,9 +88,21 @@ PROJECTID_LOOKUP: Final[dict[str, tuple[str, str]]] = {
71
88
  "WiiM_Pro_with_gc4a": (MANUFACTURER_WIIM, MODELS_WIIM_PRO),
72
89
  "WiiM_Pro_Plus": (MANUFACTURER_WIIM, MODELS_WIIM_PRO_PLUS),
73
90
  "WiiM_AMP": (MANUFACTURER_WIIM, MODELS_WIIM_AMP),
91
+ "WiiM_Amp_Pro": (MANUFACTURER_WIIM, MODELS_WIIM_AMP_PRO),
74
92
  "Muzo_Mini": (MANUFACTURER_WIIM, MODELS_WIIM_MINI),
75
93
  "GGMM_E2A": (MANUFACTURER_GGMM, MODELS_GGMM_GGMM_E2),
76
94
  "A16": (MANUFACTURER_MEDION, MODELS_MEDION_MD_43970),
95
+ "Lanzi_4566": (MANUFACTURER_AUGUST, MODELS_WR320),
96
+ "WS350": (MANUFACTURER_AUGUST, MODELS_WS350),
97
+ "a31imuzobox": (MANUFACTURER_MUZO, MODELS_MUZO_COBBLESTONE),
98
+ "AudioPro_C3": (MANUFACTURER_AUDIOPRO, MODELS_AUDIOPRO_C3),
99
+ "AudioPro_C10": (MANUFACTURER_AUDIOPRO, MODELS_AUDIOPRO_C10),
100
+ "AudioPro_A10": (MANUFACTURER_AUDIOPRO, MODELS_AUDIOPRO_A10),
101
+ "U-AIO3v2": (MANUFACTURER_TRIANGLE, MODELS_TRIANGLE_AIO_3),
102
+ "WiiM_Ultra": (MANUFACTURER_WIIM, MODELS_WIIM_ULTRA),
103
+ "WiiM_Amp_Ultra": (MANUFACTURER_WIIM, MODELS_WIIM_AMP_ULTRA),
104
+ "WiiM_CI_MOD_S": (MANUFACTURER_WIIM, MODELS_WIIM_CI_MOD_S),
105
+ "WiiM_CI_MOD_A80": (MANUFACTURER_WIIM, MODELS_WIIM_CI_MOD_A80),
77
106
  }
78
107
 
79
108
 
linkplay/utils.py CHANGED
@@ -10,20 +10,25 @@ from http import HTTPStatus
10
10
 
11
11
  import aiofiles
12
12
  import async_timeout
13
- from aiohttp import ClientError, ClientSession, TCPConnector
13
+ from aiohttp import ClientError, ClientSession, ClientTimeout, TCPConnector
14
14
  from appdirs import AppDirs
15
15
  from deprecated import deprecated
16
16
 
17
17
  from linkplay.consts import (
18
18
  API_ENDPOINT,
19
19
  API_TIMEOUT,
20
+ LOGGER,
20
21
  MTLS_CERTIFICATE_CONTENTS,
21
22
  TCP_MESSAGE_LENGTH,
22
23
  EqualizerMode,
23
24
  PlayerAttribute,
24
25
  PlayingStatus,
25
26
  )
26
- from linkplay.exceptions import LinkPlayInvalidDataException, LinkPlayRequestException
27
+ from linkplay.exceptions import (
28
+ LinkPlayInvalidDataException,
29
+ LinkPlayRequestCancelledException,
30
+ LinkPlayRequestException,
31
+ )
27
32
 
28
33
 
29
34
  async def session_call_api(endpoint: str, session: ClientSession, command: str) -> str:
@@ -45,18 +50,29 @@ async def session_call_api(endpoint: str, session: ClientSession, command: str)
45
50
  try:
46
51
  async with async_timeout.timeout(API_TIMEOUT):
47
52
  response = await session.get(url)
48
-
49
- except (asyncio.TimeoutError, ClientError, asyncio.CancelledError) as error:
53
+ if response.status != HTTPStatus.OK:
54
+ raise LinkPlayRequestException(
55
+ f"Unexpected HTTPStatus {response.status} received from '{url}'"
56
+ )
57
+ return await response.text()
58
+
59
+ except ClientError as error:
60
+ LOGGER.warning("ClientError for %s: %s", url, error)
50
61
  raise LinkPlayRequestException(
51
62
  f"{error} error requesting data from '{url}'"
52
63
  ) from error
53
64
 
54
- if response.status != HTTPStatus.OK:
65
+ except asyncio.TimeoutError as error:
66
+ LOGGER.warning("Timeout for %s: %s", url, error)
55
67
  raise LinkPlayRequestException(
56
- f"Unexpected HTTPStatus {response.status} received from '{url}'"
57
- )
68
+ f"{error} error requesting data from '{url}'"
69
+ ) from error
58
70
 
59
- return await response.text()
71
+ except asyncio.CancelledError as error:
72
+ LOGGER.warning("Cancelled for %s: %s", url, error)
73
+ raise LinkPlayRequestCancelledException(
74
+ f"{error} error requesting data from '{url}'"
75
+ ) from error
60
76
 
61
77
 
62
78
  async def session_call_api_json(
@@ -81,6 +97,7 @@ async def session_call_api_json(
81
97
  return json.loads(result) # type: ignore
82
98
  except json.JSONDecodeError as jsonexc:
83
99
  url = API_ENDPOINT.format(endpoint, command)
100
+ LOGGER.warning("Unexpected json for %s: %s", url, jsonexc)
84
101
  raise LinkPlayInvalidDataException(
85
102
  message=f"Unexpected JSON ({result}) received from '{url}'", data=result
86
103
  ) from jsonexc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python_linkplay
3
- Version: 0.2.12
3
+ Version: 0.2.14
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=rfy0OFG8rEvQ6bRSAURO04IijvDzG0it93O1BM4V4E0,23
4
+ linkplay/bridge.py,sha256=Id0yDa807qo0Jv_0IUIwnok0EuUa-0z01rABul4AcXs,21834
5
+ linkplay/consts.py,sha256=PYjegdpzXov7UpUaRxgbIe-IFdbt_Gy0qGfZuMzT_8I,15781
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=9zBBhNdPj6qQj1SD1nkhruhN8mhlkuTaiUj87FEqzJM,682
10
+ linkplay/manufacturers.py,sha256=UZk8wWZGPOi9pN9wnqOKbcWZBkZZHljkODWPvcNpZPA,6206
11
+ linkplay/utils.py,sha256=otPFrx5c0MFmvXiiZSVUFaIBFG-YVMRi4SeInq0T4rY,10128
12
+ python_linkplay-0.2.14.dist-info/licenses/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
13
+ python_linkplay-0.2.14.dist-info/METADATA,sha256=kfVa_GqjRt0sil1S2vFcpaaaz7Zaww12kcw0ejI3rl8,3261
14
+ python_linkplay-0.2.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ python_linkplay-0.2.14.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
16
+ python_linkplay-0.2.14.dist-info/RECORD,,
@@ -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=GOlqYpAbeXBU8pYgXsAgMtKusKeeO1iC_GrwyupHF50,23
4
- linkplay/bridge.py,sha256=Id0yDa807qo0Jv_0IUIwnok0EuUa-0z01rABul4AcXs,21834
5
- linkplay/consts.py,sha256=J2tocNaSyb5xs-qY0PqvOLl8_DzwarWZjTi-F9tXY4U,15780
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=UHcV0Yok0hdM0MYgHRwTWnMJ612Ts0iJvMFHX-IxmNo,312
10
- linkplay/manufacturers.py,sha256=vyxkQKXB6uAwa2t754rSDU-FWK7rfol-ScKJ-Ceo21I,4717
11
- linkplay/utils.py,sha256=fZHGnUM4XFrQ7MM6guHhaEmxJbVlwilbwoZXvXwSfMs,9480
12
- python_linkplay-0.2.12.dist-info/licenses/LICENSE,sha256=bgEtxMyjEHX_4uwaAY3GCFTm234D4AOZ5dM15sk26ms,1073
13
- python_linkplay-0.2.12.dist-info/METADATA,sha256=let7Td1GXZbmo3nDdmSQorjLgEnuwTgzeYsc5Q0AEYE,3261
14
- python_linkplay-0.2.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- python_linkplay-0.2.12.dist-info/top_level.txt,sha256=CpSaOVPTzJf5TVIL7MrotSCR34gcIOQy-11l4zGmxxM,9
16
- python_linkplay-0.2.12.dist-info/RECORD,,