pywiim 2.2.7__tar.gz → 2.2.8__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 (85) hide show
  1. {pywiim-2.2.7/pywiim.egg-info → pywiim-2.2.8}/PKG-INFO +1 -1
  2. {pywiim-2.2.7 → pywiim-2.2.8}/pyproject.toml +1 -1
  3. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/__init__.py +3 -1
  4. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/discovery.py +28 -0
  5. {pywiim-2.2.7 → pywiim-2.2.8/pywiim.egg-info}/PKG-INFO +1 -1
  6. {pywiim-2.2.7 → pywiim-2.2.8}/LICENSE +0 -0
  7. {pywiim-2.2.7 → pywiim-2.2.8}/README.md +0 -0
  8. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/__init__.py +0 -0
  9. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/audio_pro.py +0 -0
  10. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/audio_settings.py +0 -0
  11. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/base.py +0 -0
  12. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/bluetooth.py +0 -0
  13. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/constants.py +0 -0
  14. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/device.py +0 -0
  15. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/diagnostics.py +0 -0
  16. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/endpoints.py +0 -0
  17. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/eq.py +0 -0
  18. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/firmware.py +0 -0
  19. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/group.py +0 -0
  20. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/lms.py +0 -0
  21. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/loop_mode.py +0 -0
  22. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/misc.py +0 -0
  23. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/parser.py +0 -0
  24. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/peq.py +0 -0
  25. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/playback.py +0 -0
  26. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/preset.py +0 -0
  27. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/ssl.py +0 -0
  28. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/subwoofer.py +0 -0
  29. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/api/timer.py +0 -0
  30. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/backoff.py +0 -0
  31. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/capabilities.py +0 -0
  32. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/__init__.py +0 -0
  33. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/diagnostics.py +0 -0
  34. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/discovery_cli.py +0 -0
  35. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/group_test_cli.py +0 -0
  36. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/join_test_cli.py +0 -0
  37. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/monitor_cli.py +0 -0
  38. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/cli/verify_cli.py +0 -0
  39. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/client.py +0 -0
  40. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/device_capabilities.py +0 -0
  41. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/exceptions.py +0 -0
  42. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/group.py +0 -0
  43. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/group_helpers.py +0 -0
  44. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/__init__.py +0 -0
  45. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/__main__.py +0 -0
  46. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/config.example.json +0 -0
  47. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/config.py +0 -0
  48. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/context.py +0 -0
  49. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/mcp/server.py +0 -0
  50. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/metadata.py +0 -0
  51. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/model_names.py +0 -0
  52. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/models.py +0 -0
  53. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/normalize.py +0 -0
  54. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/__init__.py +0 -0
  55. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/audio.py +0 -0
  56. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/base.py +0 -0
  57. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/bluetooth.py +0 -0
  58. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/coverart.py +0 -0
  59. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/debounce.py +0 -0
  60. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/diagnostics.py +0 -0
  61. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/groupops.py +0 -0
  62. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/media.py +0 -0
  63. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/playback.py +0 -0
  64. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/properties.py +0 -0
  65. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/source_capabilities.py +0 -0
  66. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/statemgr.py +0 -0
  67. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/stream.py +0 -0
  68. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/stream_enricher.py +0 -0
  69. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/player/volume.py +0 -0
  70. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/polling.py +0 -0
  71. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/profiles.py +0 -0
  72. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/py.typed +0 -0
  73. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/role.py +0 -0
  74. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/state.py +0 -0
  75. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/upnp/__init__.py +0 -0
  76. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/upnp/client.py +0 -0
  77. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/upnp/eventer.py +0 -0
  78. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/upnp/health.py +0 -0
  79. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim/upnp/metadata.py +0 -0
  80. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim.egg-info/SOURCES.txt +0 -0
  81. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim.egg-info/dependency_links.txt +0 -0
  82. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim.egg-info/entry_points.txt +0 -0
  83. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim.egg-info/requires.txt +0 -0
  84. {pywiim-2.2.7 → pywiim-2.2.8}/pywiim.egg-info/top_level.txt +0 -0
  85. {pywiim-2.2.7 → pywiim-2.2.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywiim
3
- Version: 2.2.7
3
+ Version: 2.2.8
4
4
  Summary: Python library for WiiM/LinkPlay device communication
5
5
  Author-email: Michael Cumming <mjcumming@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pywiim"
7
- version = "2.2.7"
7
+ version = "2.2.8"
8
8
  description = "Python library for WiiM/LinkPlay device communication"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -62,6 +62,7 @@ from .discovery import (
62
62
  discover_devices,
63
63
  discover_via_ssdp,
64
64
  validate_device,
65
+ validate_device_strict,
65
66
  )
66
67
  from .exceptions import (
67
68
  WiiMConnectionError,
@@ -87,7 +88,7 @@ from .profiles import (
87
88
  from .role import RoleDetectionResult, detect_role
88
89
  from .state import GroupStateSynchronizer, StateSynchronizer
89
90
 
90
- __version__ = "2.2.7"
91
+ __version__ = "2.2.8"
91
92
  __all__ = [
92
93
  # Main client
93
94
  "WiiMClient",
@@ -111,6 +112,7 @@ __all__ = [
111
112
  "discover_devices",
112
113
  "discover_via_ssdp",
113
114
  "validate_device",
115
+ "validate_device_strict",
114
116
  # Backoff
115
117
  "BackoffController",
116
118
  # Normalization
@@ -22,6 +22,7 @@ except ImportError:
22
22
  async_search = None # type: ignore[assignment]
23
23
 
24
24
  from .client import WiiMClient
25
+ from .exceptions import WiiMConnectionError
25
26
 
26
27
  _LOGGER = logging.getLogger(__name__)
27
28
 
@@ -32,6 +33,7 @@ __all__ = [
32
33
  "is_known_linkplay",
33
34
  "is_linkplay_device",
34
35
  "validate_device",
36
+ "validate_device_strict",
35
37
  ]
36
38
 
37
39
  # Known LinkPlay/WiiM server patterns (devices we're CERTAIN are LinkPlay)
@@ -485,6 +487,32 @@ async def validate_device(device: DiscoveredDevice) -> DiscoveredDevice:
485
487
  return device
486
488
 
487
489
 
490
+ async def validate_device_strict(device: DiscoveredDevice) -> DiscoveredDevice:
491
+ """Validate a discovered device and raise if it is not usable.
492
+
493
+ ``validate_device()`` is intentionally soft-fail for bulk discovery: it
494
+ returns the input device with ``validated=False`` when the host does not
495
+ pass the LinkPlay/WiiM probe. Use this helper for manual setup flows or
496
+ other code paths where an unvalidated device is an error.
497
+
498
+ Args:
499
+ device: Device to validate.
500
+
501
+ Returns:
502
+ Updated device with full information.
503
+
504
+ Raises:
505
+ WiiMConnectionError: If the host cannot be validated as LinkPlay/WiiM.
506
+ """
507
+ validated_device = await validate_device(device)
508
+ if not validated_device.validated:
509
+ raise WiiMConnectionError(
510
+ f"Device at {device.ip} did not validate as a LinkPlay/WiiM device",
511
+ operation_context="device_validation",
512
+ )
513
+ return validated_device
514
+
515
+
488
516
  async def discover_devices(
489
517
  methods: list[str] | None = None,
490
518
  validate: bool = True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywiim
3
- Version: 2.2.7
3
+ Version: 2.2.8
4
4
  Summary: Python library for WiiM/LinkPlay device communication
5
5
  Author-email: Michael Cumming <mjcumming@gmail.com>
6
6
  License: MIT
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes