python-rako-2025 0.0.1__tar.gz → 0.2.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 (24) hide show
  1. {python_rako_2025-0.0.1/python_rako_2025.egg-info → python_rako_2025-0.2.0}/PKG-INFO +1 -1
  2. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/pyproject.toml +3 -2
  3. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/__init__.py +3 -0
  4. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/__version__.py +2 -1
  5. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/bridge.py +73 -18
  6. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/helpers.py +1 -1
  7. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/model.py +24 -1
  8. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0/python_rako_2025.egg-info}/PKG-INFO +1 -1
  9. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/setup.py +6 -3
  10. python_rako_2025-0.2.0/tests/test_bridge.py +225 -0
  11. python_rako_2025-0.0.1/tests/test_bridge.py +0 -99
  12. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/LICENSE +0 -0
  13. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/README.md +0 -0
  14. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/const.py +0 -0
  15. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/exceptions.py +0 -0
  16. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako/py.typed +0 -0
  17. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako_2025.egg-info/SOURCES.txt +0 -0
  18. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako_2025.egg-info/dependency_links.txt +0 -0
  19. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako_2025.egg-info/not-zip-safe +0 -0
  20. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako_2025.egg-info/requires.txt +0 -0
  21. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/python_rako_2025.egg-info/top_level.txt +0 -0
  22. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/setup.cfg +0 -0
  23. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/tests/test_helpers.py +0 -0
  24. {python_rako_2025-0.0.1 → python_rako_2025-0.2.0}/tests/test_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-rako-2025
3
- Version: 0.0.1
3
+ Version: 0.2.0
4
4
  Summary: Asynchronous Python client for Rako Controls Lighting
5
5
  Home-page: https://github.com/simonleigh/python-rako
6
6
  Author: Simon Leigh
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-rako-2025"
7
- version = "0.0.1"
7
+ version = "0.2.0"
8
8
  description = "Asynchronous Python client for Rako Controls Lighting"
9
9
  readme = "README.md"
10
10
  keywords = ["rako", "controls", "api", "async", "client"]
@@ -81,6 +81,7 @@ warn_unused_ignores = true
81
81
  warn_return_any = true
82
82
  warn_unreachable = true
83
83
  strict_equality = true
84
+ enable_error_code = ["ignore-without-code"]
84
85
 
85
86
  [tool.pytest.ini_options]
86
- asyncio_mode = "auto"
87
+ asyncio_mode = "auto"
@@ -15,14 +15,17 @@ from python_rako.model import ( # noqa
15
15
  BridgeInfo,
16
16
  ChannelLight,
17
17
  ChannelStatusMessage,
18
+ ChannelVentilation,
18
19
  LevelCache,
19
20
  LevelCacheItem,
20
21
  Light,
21
22
  RoomChannel,
22
23
  RoomLight,
24
+ RoomVentilation,
23
25
  SceneCache,
24
26
  SceneStatusMessage,
25
27
  UnsupportedMessage,
28
+ Ventilation,
26
29
  )
27
30
 
28
31
  _LOGGER = logging.getLogger(__name__)
@@ -1,2 +1,3 @@
1
1
  """AUTOGENERATED ON RELEASE."""
2
- __version__ = "0.0.1"
2
+
3
+ __version__ = "0.2.0"
@@ -2,7 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from typing import Any, AsyncGenerator, Generator, Tuple
5
+ from collections.abc import AsyncGenerator, Generator
6
+ from typing import Any
6
7
 
7
8
  import aiohttp
8
9
  import xmltodict
@@ -24,6 +25,7 @@ from python_rako.helpers import (
24
25
  from python_rako.model import (
25
26
  BridgeInfo,
26
27
  ChannelLight,
28
+ ChannelVentilation,
27
29
  CommandHTTP,
28
30
  CommandLevelHTTP,
29
31
  CommandSceneHTTP,
@@ -32,7 +34,9 @@ from python_rako.model import (
32
34
  LevelCache,
33
35
  Light,
34
36
  RoomLight,
37
+ RoomVentilation,
35
38
  SceneCache,
39
+ Ventilation,
36
40
  )
37
41
 
38
42
  _LOGGER = logging.getLogger(__name__)
@@ -158,11 +162,26 @@ class Bridge:
158
162
 
159
163
  async def discover_lights(
160
164
  self, session: aiohttp.ClientSession
161
- ) -> AsyncGenerator[Light, None]:
165
+ ) -> AsyncGenerator[Light]:
162
166
  rako_xml = await self.get_rako_xml(session)
163
167
  for light in self.get_lights_from_discovery_xml(rako_xml):
164
168
  yield light
165
169
 
170
+ async def discover_ventilation(
171
+ self, session: aiohttp.ClientSession
172
+ ) -> AsyncGenerator[Ventilation]:
173
+ rako_xml = await self.get_rako_xml(session)
174
+ for device in self.get_devices_from_discovery_xml(rako_xml, "Ventilation"):
175
+ if isinstance(device, (RoomVentilation, ChannelVentilation)):
176
+ yield device
177
+
178
+ async def discover_all_devices(
179
+ self, session: aiohttp.ClientSession
180
+ ) -> AsyncGenerator[Light | Ventilation]:
181
+ rako_xml = await self.get_rako_xml(session)
182
+ for device in self.get_devices_from_discovery_xml(rako_xml):
183
+ yield device
184
+
166
185
  async def get_info(self, session: aiohttp.ClientSession) -> BridgeInfo:
167
186
  try:
168
187
  rako_xml = await self.get_rako_xml(session)
@@ -192,18 +211,43 @@ class Bridge:
192
211
  )
193
212
 
194
213
  @staticmethod
195
- def get_lights_from_discovery_xml(xml: str) -> Generator[Light, None, None]:
196
- xml_dict = xmltodict.parse(xml, force_list={'Room'})
214
+ def get_lights_from_discovery_xml(xml: str) -> Generator[Light]:
215
+ for device in Bridge.get_devices_from_discovery_xml(xml, "Lights"):
216
+ if isinstance(device, (RoomLight, ChannelLight)):
217
+ yield device
218
+
219
+ @staticmethod
220
+ def get_all_devices_from_discovery_xml(xml: str) -> Generator[Light | Ventilation]:
221
+ """Get all devices (lights and ventilation) from discovery XML."""
222
+ return Bridge.get_devices_from_discovery_xml(xml)
223
+
224
+ @staticmethod
225
+ def get_devices_from_discovery_xml(
226
+ xml: str, device_types: str | list[str] | None = None
227
+ ) -> Generator[Light | Ventilation]:
228
+ # Handle different input types for backward compatibility
229
+ if device_types is None or device_types == "All":
230
+ target_types = {"Lights", "Ventilation"}
231
+ elif isinstance(device_types, str):
232
+ target_types = {device_types}
233
+ else:
234
+ target_types = set(device_types)
235
+
236
+ xml_dict = xmltodict.parse(xml, force_list={"Room"})
197
237
  for room in xml_dict["rako"]["rooms"]["Room"]:
198
238
  room_id = int(room["@id"])
199
239
  room_type = room.get("Type", "Lights")
200
- if room_type != "Lights":
201
- _LOGGER.info(
202
- "Unsupported room type. room_id=%s room_type=%s", room_id, room_type
203
- )
240
+ if room_type not in target_types:
204
241
  continue
205
242
  room_title = room["Title"]
206
- yield RoomLight(room_id, room_title)
243
+
244
+ # Yield room-level device
245
+ if room_type == "Lights":
246
+ yield RoomLight(room_id, room_title)
247
+ elif room_type == "Ventilation":
248
+ yield RoomVentilation(room_id, room_title)
249
+
250
+ # Yield channel-level devices
207
251
  channels_section = room.get("Channel", [])
208
252
  channels = (
209
253
  channels_section
@@ -215,14 +259,25 @@ class Bridge:
215
259
  channel_type = channel.get("type", "Default")
216
260
  channel_name = channel["Name"]
217
261
  channel_levels = channel["Levels"]
218
- yield ChannelLight(
219
- room_id,
220
- room_title,
221
- channel_id,
222
- channel_type,
223
- channel_name,
224
- channel_levels,
225
- )
262
+
263
+ if room_type == "Lights":
264
+ yield ChannelLight(
265
+ room_id,
266
+ room_title,
267
+ channel_id,
268
+ channel_type,
269
+ channel_name,
270
+ channel_levels,
271
+ )
272
+ elif room_type == "Ventilation":
273
+ yield ChannelVentilation(
274
+ room_id,
275
+ room_title,
276
+ channel_id,
277
+ channel_type,
278
+ channel_name,
279
+ channel_levels,
280
+ )
226
281
 
227
282
  async def next_pushed_message(self, dg_listener: DatagramServer) -> Any | None:
228
283
  resp = await dg_listener.recv()
@@ -241,7 +296,7 @@ class Bridge:
241
296
 
242
297
  async def get_cache_state(
243
298
  self, cache_type: RequestType = RequestType.SCENE_LEVEL_CACHE
244
- ) -> Tuple[LevelCache, SceneCache]:
299
+ ) -> tuple[LevelCache, SceneCache]:
245
300
  scene_cache = SceneCache()
246
301
  level_cache = LevelCache()
247
302
  async with get_dg_commander(self.host, self.port) as dg_client:
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ from collections.abc import AsyncIterator
4
5
  from contextlib import asynccontextmanager
5
- from typing import AsyncIterator
6
6
 
7
7
  import asyncio_dgram
8
8
  from asyncio_dgram.aio import DatagramClient, DatagramServer
@@ -1,5 +1,5 @@
1
+ from collections.abc import Iterable
1
2
  from dataclasses import dataclass
2
- from typing import Iterable
3
3
 
4
4
  from python_rako.const import CommandType, MessageType
5
5
 
@@ -33,6 +33,29 @@ class ChannelLight(Light):
33
33
  channel_levels: str
34
34
 
35
35
 
36
+ @dataclass
37
+ class Ventilation:
38
+ room_id: int
39
+ room_title: str
40
+ channel_id: int
41
+
42
+ @property
43
+ def room_channel(self) -> RoomChannel:
44
+ return RoomChannel(self.room_id, self.channel_id)
45
+
46
+
47
+ @dataclass
48
+ class RoomVentilation(Ventilation):
49
+ channel_id: int = 0
50
+
51
+
52
+ @dataclass
53
+ class ChannelVentilation(Ventilation):
54
+ channel_type: str
55
+ channel_name: str
56
+ channel_levels: str
57
+
58
+
36
59
  @dataclass(frozen=True)
37
60
  class BridgeInfo:
38
61
  version: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-rako-2025
3
- Version: 0.0.1
3
+ Version: 0.2.0
4
4
  Summary: Asynchronous Python client for Rako Controls Lighting
5
5
  Home-page: https://github.com/simonleigh/python-rako
6
6
  Author: Simon Leigh
@@ -1,18 +1,21 @@
1
1
  import os
2
+
2
3
  from setuptools import find_packages, setup
3
4
 
5
+
4
6
  def read(*parts):
5
7
  """Read file."""
6
8
  filename = os.path.join(os.path.abspath(os.path.dirname(__file__)), *parts)
7
- with open(filename, encoding="utf-8", mode="rt") as fp:
9
+ with open(filename, encoding="utf-8") as fp:
8
10
  return fp.read()
9
11
 
12
+
10
13
  with open("README.md") as readme_file:
11
14
  readme = readme_file.read()
12
15
 
13
16
  setup(
14
17
  name="python-rako-2025",
15
- version="0.0.1",
18
+ version="0.2.0",
16
19
  license="MIT",
17
20
  url="https://github.com/simonleigh/python-rako",
18
21
  author="Simon Leigh",
@@ -49,4 +52,4 @@ setup(
49
52
  "Development Status :: 4 - Beta",
50
53
  ],
51
54
  python_requires=">=3.10",
52
- )
55
+ )
@@ -0,0 +1,225 @@
1
+ from python_rako.bridge import Bridge
2
+ from python_rako.model import (
3
+ BridgeInfo,
4
+ ChannelLight,
5
+ ChannelVentilation,
6
+ RoomLight,
7
+ RoomVentilation,
8
+ )
9
+
10
+
11
+ def test_get_lights_from_discovery_xml(rako_xml):
12
+ lights = Bridge.get_lights_from_discovery_xml(rako_xml)
13
+
14
+ expected_lights = [
15
+ RoomLight(room_id=5, room_title="Living Room", channel_id=0),
16
+ ChannelLight(
17
+ room_id=5,
18
+ room_title="Living Room",
19
+ channel_id=1,
20
+ channel_type="Default",
21
+ channel_name="Downlights",
22
+ channel_levels="FF347F3F000000000000000000000000",
23
+ ),
24
+ ChannelLight(
25
+ room_id=5,
26
+ room_title="Living Room",
27
+ channel_id=2,
28
+ channel_type="Default",
29
+ channel_name="Kitchen Downlights",
30
+ channel_levels="FF337F3F000000000000000000000000",
31
+ ),
32
+ RoomLight(room_id=9, room_title="Bedroom 1", channel_id=0),
33
+ ChannelLight(
34
+ room_id=9,
35
+ room_title="Bedroom 1",
36
+ channel_id=1,
37
+ channel_type="Default",
38
+ channel_name="Downlights",
39
+ channel_levels="FFBF7F25000000000000000000000000",
40
+ ),
41
+ ChannelLight(
42
+ room_id=9,
43
+ room_title="Bedroom 1",
44
+ channel_id=2,
45
+ channel_type="Default",
46
+ channel_name="LED",
47
+ channel_levels="FFBF7F00000000000000000000000000",
48
+ ),
49
+ ]
50
+ assert list(lights) == expected_lights
51
+
52
+
53
+ def test_get_bridge_info_from_discovery_xml(rako_xml):
54
+ info = Bridge.get_bridge_info_from_discovery_xml(rako_xml)
55
+
56
+ expected_info = BridgeInfo(
57
+ version="2.4.0 RA",
58
+ buildDate="Nov 17 2017 10:01:01",
59
+ hostName="RAKOBRIDGE",
60
+ hostIP="someip",
61
+ hostMAC="somemac",
62
+ hwStatus="05",
63
+ dbVersion="-31",
64
+ requirepassword=None,
65
+ passhash="NAN",
66
+ charset="UTF-8",
67
+ )
68
+ assert info == expected_info
69
+
70
+
71
+ def test_get_bridge_info_from_discovery_xml2(rako_xml2):
72
+ info = Bridge.get_bridge_info_from_discovery_xml(rako_xml2)
73
+
74
+ expected_info = BridgeInfo(
75
+ version=None,
76
+ buildDate=None,
77
+ hostName=None,
78
+ hostIP=None,
79
+ hostMAC=None,
80
+ hwStatus=None,
81
+ dbVersion=None,
82
+ requirepassword=None,
83
+ passhash="NAN",
84
+ charset=None,
85
+ )
86
+ assert info == expected_info
87
+
88
+
89
+ def test_get_lights_from_discovery_xml2(rako_xml2):
90
+ lights = Bridge.get_lights_from_discovery_xml(rako_xml2)
91
+
92
+ expected_lights = [
93
+ RoomLight(room_id=112, room_title="Bedroom 1", channel_id=0),
94
+ ChannelLight(
95
+ room_id=112,
96
+ room_title="Bedroom 1",
97
+ channel_id=1,
98
+ channel_type="Default",
99
+ channel_name="Ceiling Light",
100
+ channel_levels="FFBF7F3F000000000000000000000000",
101
+ ),
102
+ RoomLight(room_id=108, room_title="Master Ensuite", channel_id=0),
103
+ ]
104
+
105
+ assert list(lights) == expected_lights
106
+
107
+
108
+ def test_get_ventilation_from_discovery_xml(rako_xml3):
109
+ ventilation_devices = Bridge.get_devices_from_discovery_xml(
110
+ rako_xml3, "Ventilation"
111
+ )
112
+
113
+ expected_ventilation = [
114
+ RoomVentilation(room_id=161, room_title="Fans", channel_id=0),
115
+ ChannelVentilation(
116
+ room_id=161,
117
+ room_title="Fans",
118
+ channel_id=1,
119
+ channel_type="switch",
120
+ channel_name="Fans",
121
+ channel_levels="FFBF7F3F000000000000000000000000",
122
+ ),
123
+ ]
124
+
125
+ ventilation_list = [
126
+ dev
127
+ for dev in ventilation_devices
128
+ if isinstance(dev, (RoomVentilation, ChannelVentilation))
129
+ ]
130
+ assert ventilation_list == expected_ventilation
131
+
132
+
133
+ def test_ventilation_command_compatibility():
134
+ """Test that ventilation can use the same commands as lighting"""
135
+ from python_rako.model import CommandLevelHTTP, CommandSceneHTTP
136
+
137
+ # Test that ventilation room can use lighting commands
138
+ room_scene_command = CommandSceneHTTP(room=161, channel=0, scene=1)
139
+ assert room_scene_command.as_params() == {"room": 161, "ch": 0, "sc": 1}
140
+
141
+ # Test that ventilation channel can use lighting level commands
142
+ channel_level_command = CommandLevelHTTP(room=161, channel=1, level=128)
143
+ assert channel_level_command.as_params() == {"room": 161, "ch": 1, "lev": 128}
144
+
145
+
146
+ def test_get_all_devices_from_discovery_xml(rako_xml3):
147
+ """Test discovering all device types from XML"""
148
+ all_devices = list(Bridge.get_all_devices_from_discovery_xml(rako_xml3))
149
+
150
+ # Should contain both lights and ventilation
151
+ lights = [dev for dev in all_devices if isinstance(dev, (RoomLight, ChannelLight))]
152
+ ventilation = [
153
+ dev
154
+ for dev in all_devices
155
+ if isinstance(dev, (RoomVentilation, ChannelVentilation))
156
+ ]
157
+
158
+ # Should have many lights and 2 ventilation devices
159
+ assert len(lights) > 10 # rako3.xml has many light rooms
160
+ assert len(ventilation) == 2 # 1 RoomVentilation + 1 ChannelVentilation
161
+
162
+ # Check specific ventilation devices are included
163
+ ventilation_room = next(
164
+ (dev for dev in ventilation if isinstance(dev, RoomVentilation)), None
165
+ )
166
+ assert ventilation_room is not None
167
+ assert ventilation_room.room_id == 161
168
+ assert ventilation_room.room_title == "Fans"
169
+
170
+
171
+ def test_get_devices_with_specific_types(rako_xml3):
172
+ """Test discovering specific device types using list parameter"""
173
+ # Test with list of device types
174
+ lights_only = list(Bridge.get_devices_from_discovery_xml(rako_xml3, ["Lights"]))
175
+ ventilation_only = list(
176
+ Bridge.get_devices_from_discovery_xml(rako_xml3, ["Ventilation"])
177
+ )
178
+ both_types = list(
179
+ Bridge.get_devices_from_discovery_xml(rako_xml3, ["Lights", "Ventilation"])
180
+ )
181
+
182
+ # Verify filtering works correctly
183
+ assert all(isinstance(dev, (RoomLight, ChannelLight)) for dev in lights_only)
184
+ assert all(
185
+ isinstance(dev, (RoomVentilation, ChannelVentilation))
186
+ for dev in ventilation_only
187
+ )
188
+ assert len(both_types) == len(lights_only) + len(ventilation_only)
189
+
190
+
191
+ def test_get_devices_backward_compatibility(rako_xml3):
192
+ """Test that existing string parameter still works"""
193
+ # Test backward compatibility with string parameter
194
+ lights_str = list(Bridge.get_devices_from_discovery_xml(rako_xml3, "Lights"))
195
+ lights_list = list(Bridge.get_devices_from_discovery_xml(rako_xml3, ["Lights"]))
196
+
197
+ # Should return the same devices
198
+ assert lights_str == lights_list
199
+
200
+ # Test ventilation backward compatibility
201
+ ventilation_str = list(
202
+ Bridge.get_devices_from_discovery_xml(rako_xml3, "Ventilation")
203
+ )
204
+ ventilation_list = list(
205
+ Bridge.get_devices_from_discovery_xml(rako_xml3, ["Ventilation"])
206
+ )
207
+
208
+ assert ventilation_str == ventilation_list
209
+
210
+
211
+ def test_get_devices_all_parameter_variants(rako_xml3):
212
+ """Test different ways to get all devices"""
213
+ all_devices_none = list(Bridge.get_devices_from_discovery_xml(rako_xml3, None))
214
+ all_devices_all = list(Bridge.get_devices_from_discovery_xml(rako_xml3, "All"))
215
+ all_devices_method = list(Bridge.get_all_devices_from_discovery_xml(rako_xml3))
216
+
217
+ # All should return the same devices
218
+ assert all_devices_none == all_devices_all == all_devices_method
219
+
220
+ # Should contain both lights and ventilation
221
+ assert any(isinstance(dev, (RoomLight, ChannelLight)) for dev in all_devices_none)
222
+ assert any(
223
+ isinstance(dev, (RoomVentilation, ChannelVentilation))
224
+ for dev in all_devices_none
225
+ )
@@ -1,99 +0,0 @@
1
- from python_rako.bridge import Bridge
2
- from python_rako.model import BridgeInfo, ChannelLight, RoomLight
3
-
4
-
5
- def test_get_lights_from_discovery_xml(rako_xml):
6
- lights = Bridge.get_lights_from_discovery_xml(rako_xml)
7
-
8
- expected_lights = [
9
- RoomLight(room_id=5, room_title="Living Room", channel_id=0),
10
- ChannelLight(
11
- room_id=5,
12
- room_title="Living Room",
13
- channel_id=1,
14
- channel_type="Default",
15
- channel_name="Downlights",
16
- channel_levels="FF347F3F000000000000000000000000",
17
- ),
18
- ChannelLight(
19
- room_id=5,
20
- room_title="Living Room",
21
- channel_id=2,
22
- channel_type="Default",
23
- channel_name="Kitchen Downlights",
24
- channel_levels="FF337F3F000000000000000000000000",
25
- ),
26
- RoomLight(room_id=9, room_title="Bedroom 1", channel_id=0),
27
- ChannelLight(
28
- room_id=9,
29
- room_title="Bedroom 1",
30
- channel_id=1,
31
- channel_type="Default",
32
- channel_name="Downlights",
33
- channel_levels="FFBF7F25000000000000000000000000",
34
- ),
35
- ChannelLight(
36
- room_id=9,
37
- room_title="Bedroom 1",
38
- channel_id=2,
39
- channel_type="Default",
40
- channel_name="LED",
41
- channel_levels="FFBF7F00000000000000000000000000",
42
- ),
43
- ]
44
- assert list(lights) == expected_lights
45
-
46
-
47
- def test_get_bridge_info_from_discovery_xml(rako_xml):
48
- info = Bridge.get_bridge_info_from_discovery_xml(rako_xml)
49
-
50
- expected_info = BridgeInfo(
51
- version="2.4.0 RA",
52
- buildDate="Nov 17 2017 10:01:01",
53
- hostName="RAKOBRIDGE",
54
- hostIP="someip",
55
- hostMAC="somemac",
56
- hwStatus="05",
57
- dbVersion="-31",
58
- requirepassword=None,
59
- passhash="NAN",
60
- charset="UTF-8",
61
- )
62
- assert info == expected_info
63
-
64
-
65
- def test_get_bridge_info_from_discovery_xml2(rako_xml2):
66
- info = Bridge.get_bridge_info_from_discovery_xml(rako_xml2)
67
-
68
- expected_info = BridgeInfo(
69
- version=None,
70
- buildDate=None,
71
- hostName=None,
72
- hostIP=None,
73
- hostMAC=None,
74
- hwStatus=None,
75
- dbVersion=None,
76
- requirepassword=None,
77
- passhash="NAN",
78
- charset=None,
79
- )
80
- assert info == expected_info
81
-
82
-
83
- def test_get_lights_from_discovery_xml2(rako_xml2):
84
- lights = Bridge.get_lights_from_discovery_xml(rako_xml2)
85
-
86
- expected_lights = [
87
- RoomLight(room_id=112, room_title="Bedroom 1", channel_id=0),
88
- ChannelLight(
89
- room_id=112,
90
- room_title="Bedroom 1",
91
- channel_id=1,
92
- channel_type="Default",
93
- channel_name="Ceiling Light",
94
- channel_levels="FFBF7F3F000000000000000000000000",
95
- ),
96
- RoomLight(room_id=108, room_title="Master Ensuite", channel_id=0),
97
- ]
98
-
99
- assert list(lights) == expected_lights