PyPlumIO 0.5.49__py3-none-any.whl → 0.5.50__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.
pyplumio/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.5.49'
21
- __version_tuple__ = version_tuple = (0, 5, 49)
20
+ __version__ = version = '0.5.50'
21
+ __version_tuple__ = version_tuple = (0, 5, 50)
pyplumio/const.py CHANGED
@@ -184,6 +184,7 @@ class FrameType(IntEnum):
184
184
  REQUEST_SET_MIXER_PARAMETER = 52
185
185
  REQUEST_SCHEDULES = 54
186
186
  REQUEST_SET_SCHEDULE = 55
187
+ REQUEST_ECOMAX_PARAMETER_CHANGES = 56
187
188
  REQUEST_UID = 57
188
189
  REQUEST_PASSWORD = 58
189
190
  REQUEST_ECOMAX_CONTROL = 59
@@ -203,6 +204,7 @@ class FrameType(IntEnum):
203
204
  RESPONSE_ECOMAX_CONTROL = 187
204
205
  RESPONSE_ALERTS = 189
205
206
  RESPONSE_PROGRAM_VERSION = 192
207
+ RESPONSE_ECOMAX_PARAMETER_CHANGES = 212
206
208
  RESPONSE_REGULATOR_DATA_SCHEMA = 213
207
209
  RESPONSE_THERMOSTAT_PARAMETERS = 220
208
210
  RESPONSE_SET_THERMOSTAT_PARAMETER = 221
@@ -145,21 +145,26 @@ class PhysicalDevice(Device, ABC):
145
145
  @event_listener(filter=on_change)
146
146
  async def on_event_frame_versions(self, versions: dict[int, int]) -> None:
147
147
  """Check frame versions and update outdated frames."""
148
- _LOGGER.info("Received frame version table")
148
+ _LOGGER.debug("Received frame version table")
149
149
  for frame_type, version in versions.items():
150
150
  if (
151
151
  is_known_frame_type(frame_type)
152
152
  and self.supports_frame_type(frame_type)
153
153
  and not self.has_frame_version(frame_type, version)
154
154
  ):
155
- await self._request_frame_version(frame_type, version)
155
+ request_frame_type = (
156
+ FrameType.REQUEST_ECOMAX_PARAMETERS
157
+ if frame_type == FrameType.REQUEST_ECOMAX_PARAMETER_CHANGES
158
+ else frame_type
159
+ )
160
+ await self._request_frame_version(request_frame_type, version)
156
161
  self._frame_versions[frame_type] = version
157
162
 
158
163
  async def _request_frame_version(
159
164
  self, frame_type: FrameType | int, version: int
160
165
  ) -> None:
161
166
  """Request frame version from the device."""
162
- _LOGGER.info("Updating frame %s to version %i", repr(frame_type), version)
167
+ _LOGGER.debug("Updating frame %s to version %i", repr(frame_type), version)
163
168
  request = await Request.create(frame_type, recipient=self.address)
164
169
  self.queue.put_nowait(request)
165
170
 
@@ -234,7 +234,7 @@ class EcoMAX(PhysicalDevice):
234
234
  @event_listener
235
235
  async def on_event_setup(self, setup: bool) -> None:
236
236
  """Request frames required to set up an ecoMAX entry."""
237
- _LOGGER.info("Setting up device entry")
237
+ _LOGGER.debug("Setting up device entry")
238
238
  await self.wait_for(ATTR_SENSORS)
239
239
  results = await asyncio.gather(
240
240
  *(
@@ -251,14 +251,14 @@ class EcoMAX(PhysicalDevice):
251
251
  if errors:
252
252
  self.dispatch_nowait(ATTR_FRAME_ERRORS, errors)
253
253
 
254
- _LOGGER.info("Device entry setup done")
254
+ _LOGGER.debug("Device entry setup done")
255
255
 
256
256
  @event_listener
257
257
  async def on_event_ecomax_parameters(
258
258
  self, parameters: list[tuple[int, ParameterValues]]
259
259
  ) -> bool:
260
260
  """Update ecoMAX parameters and dispatch the events."""
261
- _LOGGER.info("Received device parameters")
261
+ _LOGGER.debug("Received device parameters")
262
262
  product_info: ProductInfo = await self.get(ATTR_PRODUCT)
263
263
  parameter_types = await get_ecomax_parameter_types(product_info)
264
264
 
@@ -307,7 +307,7 @@ class EcoMAX(PhysicalDevice):
307
307
  parameters: dict[int, list[tuple[int, ParameterValues]]] | None,
308
308
  ) -> bool:
309
309
  """Handle mixer parameters and dispatch the events."""
310
- _LOGGER.info("Received mixer parameters")
310
+ _LOGGER.debug("Received mixer parameters")
311
311
  if parameters:
312
312
  await asyncio.gather(
313
313
  *(
@@ -324,7 +324,7 @@ class EcoMAX(PhysicalDevice):
324
324
  self, sensors: dict[int, dict[str, Any]] | None
325
325
  ) -> bool:
326
326
  """Update mixer sensors and dispatch the events."""
327
- _LOGGER.info("Received mixer sensors")
327
+ _LOGGER.debug("Received mixer sensors")
328
328
  if sensors:
329
329
  await asyncio.gather(
330
330
  *(
@@ -364,7 +364,7 @@ class EcoMAX(PhysicalDevice):
364
364
  @event_listener
365
365
  async def on_event_sensors(self, sensors: dict[str, Any]) -> bool:
366
366
  """Update ecoMAX sensors and dispatch the events."""
367
- _LOGGER.info("Received device sensors")
367
+ _LOGGER.debug("Received device sensors")
368
368
  await asyncio.gather(
369
369
  *(self.dispatch(name, value) for name, value in sensors.items())
370
370
  )
@@ -376,7 +376,7 @@ class EcoMAX(PhysicalDevice):
376
376
  parameters: dict[int, list[tuple[int, ParameterValues]]] | None,
377
377
  ) -> bool:
378
378
  """Handle thermostat parameters and dispatch the events."""
379
- _LOGGER.info("Received thermostat parameters")
379
+ _LOGGER.debug("Received thermostat parameters")
380
380
  if parameters:
381
381
  await asyncio.gather(
382
382
  *(
@@ -407,7 +407,7 @@ class EcoMAX(PhysicalDevice):
407
407
  self, sensors: dict[int, dict[str, Any]] | None
408
408
  ) -> bool:
409
409
  """Update thermostat sensors and dispatch the events."""
410
- _LOGGER.info("Received thermostat sensors")
410
+ _LOGGER.debug("Received thermostat sensors")
411
411
  if sensors:
412
412
  await asyncio.gather(
413
413
  *(
@@ -427,7 +427,7 @@ class EcoMAX(PhysicalDevice):
427
427
  self, schedules: list[tuple[int, list[list[bool]]]]
428
428
  ) -> dict[str, Schedule]:
429
429
  """Update schedules."""
430
- _LOGGER.info("Received device schedules")
430
+ _LOGGER.debug("Received device schedules")
431
431
  return {
432
432
  SCHEDULES[index]: Schedule(
433
433
  name=SCHEDULES[index],
pyplumio/devices/mixer.py CHANGED
@@ -29,7 +29,7 @@ class Mixer(VirtualDevice):
29
29
  @event_listener
30
30
  async def on_event_mixer_sensors(self, sensors: dict[str, Any]) -> bool:
31
31
  """Update mixer sensors and dispatch the events."""
32
- _LOGGER.info("Received mixer %i sensors", self.index)
32
+ _LOGGER.debug("Received mixer %i sensors", self.index)
33
33
  await asyncio.gather(
34
34
  *(self.dispatch(name, value) for name, value in sensors.items())
35
35
  )
@@ -40,7 +40,7 @@ class Mixer(VirtualDevice):
40
40
  self, parameters: list[tuple[int, ParameterValues]]
41
41
  ) -> bool:
42
42
  """Update mixer parameters and dispatch the events."""
43
- _LOGGER.info("Received mixer %i parameters", self.index)
43
+ _LOGGER.debug("Received mixer %i parameters", self.index)
44
44
  product_info: ProductInfo = await self.parent.get(ATTR_PRODUCT)
45
45
  parameter_types = get_mixer_parameter_types(product_info)
46
46
 
@@ -28,7 +28,7 @@ class Thermostat(VirtualDevice):
28
28
  @event_listener
29
29
  async def on_event_thermostat_sensors(self, sensors: dict[str, Any]) -> bool:
30
30
  """Update thermostat sensors and dispatch the events."""
31
- _LOGGER.info("Received thermostat %i sensors", self.index)
31
+ _LOGGER.debug("Received thermostat %i sensors", self.index)
32
32
  await asyncio.gather(
33
33
  *(self.dispatch(name, value) for name, value in sensors.items())
34
34
  )
@@ -39,7 +39,7 @@ class Thermostat(VirtualDevice):
39
39
  self, parameters: list[tuple[int, ParameterValues]]
40
40
  ) -> bool:
41
41
  """Update thermostat parameters and dispatch the events."""
42
- _LOGGER.info("Received thermostat %i parameters", self.index)
42
+ _LOGGER.debug("Received thermostat %i parameters", self.index)
43
43
  parameter_types = get_thermostat_parameter_types()
44
44
 
45
45
  def _thermostat_parameter_events() -> Generator[Coroutine]:
pyplumio/protocol.py CHANGED
@@ -230,20 +230,17 @@ class AsyncProtocol(Protocol, EventManager[PhysicalDevice]):
230
230
  @acache
231
231
  async def get_device_entry(self, device_type: DeviceType) -> PhysicalDevice:
232
232
  """Return the device entry."""
233
-
234
- @acache
235
- async def _setup_device_entry(device_type: DeviceType) -> PhysicalDevice:
236
- """Set up the device entry."""
237
- device = await PhysicalDevice.create(
238
- device_type, queue=self._queues.write, network=self._network
239
- )
240
- device.dispatch_nowait(ATTR_CONNECTED, True)
241
- device.dispatch_nowait(ATTR_SETUP, True)
242
- self.dispatch_nowait(device_type.name.lower(), device)
243
- return device
244
-
245
233
  async with self._entry_lock:
246
- return await _setup_device_entry(device_type)
234
+ name = device_type.name.lower()
235
+ if name not in self.data:
236
+ device = await PhysicalDevice.create(
237
+ device_type, queue=self._queues.write, network=self._network
238
+ )
239
+ device.dispatch_nowait(ATTR_CONNECTED, True)
240
+ device.dispatch_nowait(ATTR_SETUP, True)
241
+ await self.dispatch(device_type.name.lower(), device)
242
+
243
+ return self.data[name]
247
244
 
248
245
 
249
246
  __all__ = ["Protocol", "DummyProtocol", "AsyncProtocol"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPlumIO
3
- Version: 0.5.49
3
+ Version: 0.5.50
4
4
  Summary: PyPlumIO is a native ecoNET library for Plum ecoMAX controllers.
5
5
  Author-email: Denis Paavilainen <denpa@denpa.pro>
6
6
  License: MIT License
@@ -1,20 +1,20 @@
1
1
  pyplumio/__init__.py,sha256=3H5SO4WFw5mBTFeEyD4w0H8-MsNo93NyOH3RyMN7IS0,3337
2
2
  pyplumio/__main__.py,sha256=3IwHHSq-iay5FaeMc95klobe-xv82yydSKcBE7BFZ6M,500
3
- pyplumio/_version.py,sha256=u94vlma_2aQlFbifB92wUyxJiUQkXGcFrFlXXxDUYBA,513
3
+ pyplumio/_version.py,sha256=W2qdBOtSMf_VJh64HmusP_jxYyzDL0VrJZ_ZkeEZpKE,513
4
4
  pyplumio/connection.py,sha256=9MCPb8W62uqCrzd1YCROcn9cCjRY8E65934FnJDF5Js,5902
5
- pyplumio/const.py,sha256=FxF97bl_GunYuB8Wo72zCzHtznRCM64ygC2qfaR3UyA,5684
5
+ pyplumio/const.py,sha256=QIM5ueC8dx40Ccg1QHLI_mZ5wpBTptOofJWPdOOR7hk,5770
6
6
  pyplumio/data_types.py,sha256=r-QOIZiIpBFo4kRongyu8n0BHTaEU6wWMTmNkWBNjq8,9223
7
7
  pyplumio/exceptions.py,sha256=_B_0EgxDxd2XyYv3WpZM733q0cML5m6J-f55QOvYRpI,996
8
8
  pyplumio/filters.py,sha256=s35hmm8HxqktMOtNZMdXbqMeywBNKoIsAc5hWd0AEpk,15391
9
- pyplumio/protocol.py,sha256=UnrXDouo4dDi7hqwJYHoEAvCoYJs3PgP1DFBBwRqBrw,8427
9
+ pyplumio/protocol.py,sha256=9F_nkzsEuv6YWjuDyaoFH29dLaPBxeBxndogbWUG2jw,8337
10
10
  pyplumio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  pyplumio/stream.py,sha256=iCB-XlNXRRE0p7nstb1AkXwVDwcCsgym_ggB_IDiJc8,4926
12
12
  pyplumio/utils.py,sha256=D6_SJzYkFjXoUrlNPt_mIQAP8hjMU05RsTqlAFphj3Y,1205
13
- pyplumio/devices/__init__.py,sha256=frEoioDkJJuSGoBDlW42qxsRN_8lpzOvNJH56YQpd9E,7999
14
- pyplumio/devices/ecomax.py,sha256=-4rVUEg5MbzzoNXOFjp4cShsf4cqFh0mlIqlloZyWz4,16191
13
+ pyplumio/devices/__init__.py,sha256=n0h2RwLxjm9YPjRoxURpMzVjfk2SP-GZQKJTcoMkxcc,8238
14
+ pyplumio/devices/ecomax.py,sha256=5jc1dgWG8LCSeC4ZrQ9-hEYRsZB_N1i0V-L-aj0r0Is,16200
15
15
  pyplumio/devices/ecoster.py,sha256=X46ky5XT8jHMFq9sBW0ve8ZI_tjItQDMt4moXsW-ogY,307
16
- pyplumio/devices/mixer.py,sha256=q2UXMCQl6gueigHt-1Y1_P1sTEbBisZeQC75u2zAKmc,2729
17
- pyplumio/devices/thermostat.py,sha256=LBHJHfbkJgrwAifILk_IW_rRuDzSX1CDnA2xcLh4-NI,2251
16
+ pyplumio/devices/mixer.py,sha256=7WdUVgwO4VXmaPNzh3ZWpKr2ooRXWemz2KFHAw35_Rk,2731
17
+ pyplumio/devices/thermostat.py,sha256=MHMKe45fQ7jKlhBVObJ7McbYQKuF6-LOKSHy-9VNsCU,2253
18
18
  pyplumio/frames/__init__.py,sha256=5lw19oFlN89ZvO8KGwnkwERULQNYiP-hhZKk65LsjYY,7862
19
19
  pyplumio/frames/messages.py,sha256=ImQGWFFTa2eaXfytQmFZKC-IxyPRkxD8qp0bEm16-ws,3628
20
20
  pyplumio/frames/requests.py,sha256=jr-_XSSCCDDTbAmrw95CKyWa5nb7JNeGzZ2jDXIxlAo,7348
@@ -59,8 +59,8 @@ pyplumio/structures/statuses.py,sha256=1h-EUw1UtuS44E19cNOSavUgZeAxsLgX3iS0eVC8p
59
59
  pyplumio/structures/temperatures.py,sha256=2VD3P_vwp9PEBkOn2-WhifOR8w-UYNq35aAxle0z2Vg,2831
60
60
  pyplumio/structures/thermostat_parameters.py,sha256=st3x3HkjQm3hqBrn_fpvPDQu8fuc-Sx33ONB19ViQak,3007
61
61
  pyplumio/structures/thermostat_sensors.py,sha256=rO9jTZWGQpThtJqVdbbv8sYMYHxJi4MfwZQza69L2zw,3399
62
- pyplumio-0.5.49.dist-info/licenses/LICENSE,sha256=m-UuZFjXJ22uPTGm9kSHS8bqjsf5T8k2wL9bJn1Y04o,1088
63
- pyplumio-0.5.49.dist-info/METADATA,sha256=dmnFwYN07jJBW5VBjNpme32Y7DbbAp1M9FPDn4AuRJA,5611
64
- pyplumio-0.5.49.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
65
- pyplumio-0.5.49.dist-info/top_level.txt,sha256=kNBz9UPPkPD9teDn3U_sEy5LjzwLm9KfADCXtBlbw8A,9
66
- pyplumio-0.5.49.dist-info/RECORD,,
62
+ pyplumio-0.5.50.dist-info/licenses/LICENSE,sha256=m-UuZFjXJ22uPTGm9kSHS8bqjsf5T8k2wL9bJn1Y04o,1088
63
+ pyplumio-0.5.50.dist-info/METADATA,sha256=3cCn3n--0U3EccfpB_R7fKOwj2oX2w7bc4fyii4OzTg,5611
64
+ pyplumio-0.5.50.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
65
+ pyplumio-0.5.50.dist-info/top_level.txt,sha256=kNBz9UPPkPD9teDn3U_sEy5LjzwLm9KfADCXtBlbw8A,9
66
+ pyplumio-0.5.50.dist-info/RECORD,,