boneIO 1.4.0.dev9__py3-none-any.whl → 1.4.0.dev11__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.
@@ -15,7 +15,7 @@ import logging
15
15
  import time
16
16
  from typing import TYPE_CHECKING, Any
17
17
 
18
- from boneio.const import OFF, ON, SWITCH
18
+ from boneio.const import OFF, ON, OUTPUT, STATE, SWITCH
19
19
  from boneio.core.events import EventBus, async_track_point_in_time, utcnow
20
20
  from boneio.core.utils import callback
21
21
  from boneio.core.utils.timeperiod import TimePeriod, parse_time_to_seconds
@@ -23,6 +23,7 @@ from boneio.models import OutputState
23
23
  from boneio.models.events import OutputEvent
24
24
 
25
25
  if TYPE_CHECKING:
26
+ from boneio.core.messaging import MessageBus
26
27
  from boneio.integration.interlock import SoftwareInterlockManager
27
28
 
28
29
  _LOGGER = logging.getLogger(__name__)
@@ -62,6 +63,8 @@ class RemoteOutputBase:
62
63
  output_id: str,
63
64
  remote_source: str,
64
65
  event_bus: EventBus,
66
+ message_bus: MessageBus | None = None,
67
+ topic_prefix: str = "",
65
68
  output_type: str = SWITCH,
66
69
  show_in_ha: bool = False,
67
70
  area: str | None = None,
@@ -83,6 +86,8 @@ class RemoteOutputBase:
83
86
  self._output_id = output_id
84
87
  self._remote_source = remote_source
85
88
  self._event_bus = event_bus
89
+ self._message_bus: MessageBus | None = message_bus
90
+ self._send_topic = f"{topic_prefix}/{OUTPUT}/{id}" if topic_prefix else ""
86
91
  self._output_type = output_type
87
92
  self.show_in_ha = show_in_ha
88
93
  self.area: str | None = area
@@ -376,10 +381,21 @@ class RemoteOutputBase:
376
381
  async def async_set_brightness(self, brightness: int, timestamp: float | None = None) -> None:
377
382
  """Set brightness on the remote light output.
378
383
 
384
+ Checks interlock before sending the brightness command. Setting
385
+ brightness implicitly turns the light ON, so interlock rules apply.
386
+
379
387
  Args:
380
388
  brightness: Brightness value (0-255).
381
389
  timestamp: Optional timestamp for state tracking.
382
390
  """
391
+ # Brightness > 0 effectively turns ON — must check interlock
392
+ if brightness > 0 and not self.check_interlock():
393
+ _LOGGER.warning(
394
+ "Interlock active: cannot set brightness on remote output '%s'",
395
+ self._id,
396
+ )
397
+ return
398
+
383
399
  if not self._resolve_device_manager():
384
400
  _LOGGER.error("Remote output '%s' has no device manager, cannot set brightness", self._id)
385
401
  return
@@ -466,7 +482,22 @@ class RemoteOutputBase:
466
482
  # ------------------------------------------------------------------
467
483
 
468
484
  def _emit_state_event(self) -> None:
469
- """Emit OutputEvent on EventBus for WebSocket/state tracking."""
485
+ """Emit OutputEvent on EventBus for WebSocket/state tracking.
486
+
487
+ Also publishes the current state to the MQTT state topic so that
488
+ Home Assistant (and any other MQTT consumer) sees the updated state.
489
+ """
490
+ # Publish state to MQTT so HA sees the update
491
+ if self._message_bus and self._send_topic:
492
+ payload: dict[str, Any] = {STATE: self._state}
493
+ if self._brightness is not None:
494
+ payload["brightness"] = self._brightness
495
+ self._message_bus.send_message(
496
+ topic=self._send_topic,
497
+ payload=payload,
498
+ retain=True,
499
+ )
500
+
470
501
  output_state = OutputState(
471
502
  id=self._id,
472
503
  name=self._name,
@@ -1118,6 +1118,9 @@ def strip_default_values(data: Any, schema: dict | None = None, section: str | N
1118
1118
  """Remove keys with default values from dict."""
1119
1119
  cleaned = {}
1120
1120
  for key, value in obj.items():
1121
+ # Skip empty strings and None values — they are never valid config
1122
+ if value is None or value == "":
1123
+ continue
1121
1124
  # Special handling for nested structures
1122
1125
  if key == "actions" and isinstance(value, dict):
1123
1126
  # Clean actions recursively
@@ -276,17 +276,21 @@ class IrrigationManager:
276
276
  # Build list of discovery IDs to remove
277
277
  discovery_ids: list[tuple[str, str]] = [
278
278
  (f"{ctrl.id}", "switch"),
279
- (f"{ctrl.id}_auto_advance", "switch"),
280
- (f"{ctrl.id}_reverse", "switch"),
281
279
  (f"{ctrl.id}_skip_next_run", "switch"),
282
280
  (f"{ctrl.id}_standby", "switch"),
283
281
  (f"{ctrl.id}_multiplier", "number"),
284
282
  (f"{ctrl.id}_repeat", "number"),
285
- (f"{ctrl.id}_next_valve", "button"),
286
283
  (f"{ctrl.id}_pause", "button"),
287
284
  (f"{ctrl.id}_resume", "button"),
288
285
  (f"{ctrl.id}_event", "event"),
289
286
  ]
287
+ # Multi-zone-only entities
288
+ if len(ctrl.zones) > 1:
289
+ discovery_ids.extend([
290
+ (f"{ctrl.id}_auto_advance", "switch"),
291
+ (f"{ctrl.id}_reverse", "switch"),
292
+ (f"{ctrl.id}_next_valve", "button"),
293
+ ])
290
294
  for zone in ctrl.zones:
291
295
  discovery_ids.append((f"{ctrl.id}_zone_{zone.id}", "valve"))
292
296
  discovery_ids.append((f"{ctrl.id}_zone_{zone.id}_enabled", "switch"))
@@ -338,8 +342,10 @@ class IrrigationManager:
338
342
  async def handle_standby(_topic: str, payload: str, _ctrl: IrrigationController = ctrl) -> None:
339
343
  await _ctrl.set_standby(payload.strip().upper() == ON)
340
344
 
341
- await self._subscribe_topic(ctrl._setting_cmd_topic("auto_advance"), handle_auto_advance)
342
- await self._subscribe_topic(ctrl._setting_cmd_topic("reverse"), handle_reverse)
345
+ # Subscribe multi-zone-only MQTT handlers
346
+ if len(ctrl.zones) > 1:
347
+ await self._subscribe_topic(ctrl._setting_cmd_topic("auto_advance"), handle_auto_advance)
348
+ await self._subscribe_topic(ctrl._setting_cmd_topic("reverse"), handle_reverse)
343
349
  await self._subscribe_topic(ctrl._setting_cmd_topic("multiplier"), handle_multiplier)
344
350
  await self._subscribe_topic(ctrl._setting_cmd_topic("repeat"), handle_repeat)
345
351
  await self._subscribe_topic(ctrl._setting_cmd_topic("skip_next_run"), handle_skip_next)
@@ -401,29 +407,31 @@ class IrrigationManager:
401
407
  payload=ha_irrigation_main_switch_message(ctrl.id, ctrl.name, cfg),
402
408
  )
403
409
 
404
- _pub(
405
- id=f"{ctrl.id}_auto_advance",
406
- ha_type="switch",
407
- payload=ha_irrigation_switch_message(
408
- ctrl.id,
409
- ctrl.name,
410
- suffix="auto_advance",
411
- name=f"{ctrl.name} Auto Advance",
412
- config_helper=cfg,
413
- ),
414
- )
410
+ # Multi-zone-only switches: auto_advance, reverse
411
+ if len(ctrl.zones) > 1:
412
+ _pub(
413
+ id=f"{ctrl.id}_auto_advance",
414
+ ha_type="switch",
415
+ payload=ha_irrigation_switch_message(
416
+ ctrl.id,
417
+ ctrl.name,
418
+ suffix="auto_advance",
419
+ name=f"{ctrl.name} Auto Advance",
420
+ config_helper=cfg,
421
+ ),
422
+ )
415
423
 
416
- _pub(
417
- id=f"{ctrl.id}_reverse",
418
- ha_type="switch",
419
- payload=ha_irrigation_switch_message(
420
- ctrl.id,
421
- ctrl.name,
422
- suffix="reverse",
423
- name=f"{ctrl.name} Reverse",
424
- config_helper=cfg,
425
- ),
426
- )
424
+ _pub(
425
+ id=f"{ctrl.id}_reverse",
426
+ ha_type="switch",
427
+ payload=ha_irrigation_switch_message(
428
+ ctrl.id,
429
+ ctrl.name,
430
+ suffix="reverse",
431
+ name=f"{ctrl.name} Reverse",
432
+ config_helper=cfg,
433
+ ),
434
+ )
427
435
 
428
436
  _pub(
429
437
  id=f"{ctrl.id}_skip_next_run",
@@ -481,18 +489,20 @@ class IrrigationManager:
481
489
  ),
482
490
  )
483
491
 
484
- _pub(
485
- id=f"{ctrl.id}_next_valve",
486
- ha_type="button",
487
- payload=ha_irrigation_button_message(
488
- ctrl.id,
489
- ctrl.name,
490
- suffix="next_valve",
491
- name=f"{ctrl.name} Next Valve",
492
- payload_press=NEXT_VALVE,
493
- config_helper=cfg,
494
- ),
495
- )
492
+ # Multi-zone-only button: next_valve
493
+ if len(ctrl.zones) > 1:
494
+ _pub(
495
+ id=f"{ctrl.id}_next_valve",
496
+ ha_type="button",
497
+ payload=ha_irrigation_button_message(
498
+ ctrl.id,
499
+ ctrl.name,
500
+ suffix="next_valve",
501
+ name=f"{ctrl.name} Next Valve",
502
+ payload_press=NEXT_VALVE,
503
+ config_helper=cfg,
504
+ ),
505
+ )
496
506
 
497
507
  _pub(
498
508
  id=f"{ctrl.id}_pause",
@@ -1426,6 +1426,8 @@ class Manager:
1426
1426
  output_id=output_id,
1427
1427
  remote_source=remote_source,
1428
1428
  event_bus=self._event_bus,
1429
+ message_bus=self._message_bus,
1430
+ topic_prefix=self._topic_prefix,
1429
1431
  output_type=output_type,
1430
1432
  show_in_ha=show_in_ha,
1431
1433
  area=area,
@@ -1765,7 +1767,15 @@ class Manager:
1765
1767
  if msg_type == OUTPUT and command == SET_BRIGHTNESS:
1766
1768
  target_device = self.outputs.get_output(device_id)
1767
1769
  if target_device and target_device.output_type != "none" and message != "":
1768
- target_device.set_brightness(int(message))
1770
+ brightness_val = int(message)
1771
+ # Brightness > 0 effectively turns ON — must respect interlock
1772
+ if brightness_val > 0 and hasattr(target_device, "check_interlock") and not target_device.check_interlock():
1773
+ _LOGGER.warning(
1774
+ "Interlock active: cannot set brightness on '%s'",
1775
+ device_id,
1776
+ )
1777
+ return
1778
+ target_device.set_brightness(brightness_val)
1769
1779
  else:
1770
1780
  _LOGGER.debug("Target device not found %s.", device_id)
1771
1781
  return
boneio/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  # flake8: noqa
2
- __version__ = "1.4.0dev9"
2
+ __version__ = "1.4.0dev11"
@@ -184,7 +184,9 @@ def slider_tile(
184
184
  "entity": entity,
185
185
  "name": name,
186
186
  "icon": icon,
187
- "features": [{"type": "numeric-input", "style": "buttons"}],
187
+ "vertical": False,
188
+ "features": [{"type": "numeric-input", "style": "slider"}],
189
+ "features_position": "inline",
188
190
  }
189
191
 
190
192
 
@@ -137,6 +137,13 @@ def invalidate_config_cache():
137
137
  """
138
138
  _config_cache["data"] = None
139
139
  _config_cache["mtime"] = 0
140
+ # Also invalidate ConfigHelper's internal cache so GET /api/config
141
+ # re-reads from disk instead of returning stale data.
142
+ try:
143
+ app_state = _get_app_state()
144
+ app_state.manager.config_helper._config_cache = None
145
+ except Exception:
146
+ pass
140
147
  try:
141
148
  config_file = _get_app_state().yaml_config_file
142
149
  clear_config_cache(config_file)
@@ -609,22 +609,14 @@ def _generate_irrigation_dashboard_cards(ctrl: Any, serial: str) -> list[dict]:
609
609
  badges=[entity_badge(main_switch), entity_badge(next_run)],
610
610
  ))
611
611
 
612
- # ── 2. Podlewanie ręczne — valve tiles in rows of 2 ──────────────
612
+ # ── 2. Podlewanie ręczne — valve tiles ──────────────────────────
613
613
  cards.append(heading_card("Podlewanie ręczne", style="subtitle"))
614
- zone_tiles: list[dict] = []
615
614
  for zone in ctrl.zones:
616
615
  zone_valve = eid("valve", f"zone_{zone.id}")
617
- zone_tiles.append(tile_card(
616
+ cards.append(tile_card(
618
617
  zone_valve, zone.name, "mdi:sprinkler-variant",
619
618
  state_content=["last_changed", "state"],
620
619
  ))
621
- # Pack tiles into horizontal-stacks of 2
622
- for i in range(0, len(zone_tiles), 2):
623
- pair = zone_tiles[i : i + 2]
624
- if len(pair) == 1:
625
- cards.append(pair[0])
626
- else:
627
- cards.append(horizontal_stack(pair))
628
620
 
629
621
  # ── 3. Czasy podlewania — tile cards with +/- buttons ──────────
630
622
  cards.append(heading_card("Czasy podlewania", style="subtitle"))
@@ -634,8 +626,13 @@ def _generate_irrigation_dashboard_cards(ctrl: Any, serial: str) -> list[dict]:
634
626
 
635
627
  # ── 4. Ustawienia ─────────────────────────────────────────────────
636
628
  cards.append(heading_card("Ustawienia", style="subtitle"))
637
- for s in ("auto_advance", "standby", "skip_next_run", "reverse"):
638
- cards.append(inline_tile(eid("switch", s)))
629
+ # Multi-zone-only switches
630
+ if len(ctrl.zones) > 1:
631
+ for s in ("auto_advance", "standby", "skip_next_run", "reverse"):
632
+ cards.append(inline_tile(eid("switch", s)))
633
+ else:
634
+ for s in ("standby", "skip_next_run"):
635
+ cards.append(inline_tile(eid("switch", s)))
639
636
  cards.append(inline_tile(
640
637
  eid("number", "multiplier"),
641
638
  features=[{"type": "numeric-input", "style": "buttons"}],
@@ -650,11 +647,12 @@ def _generate_irrigation_dashboard_cards(ctrl: Any, serial: str) -> list[dict]:
650
647
 
651
648
  # ── 5. Sterowanie ─────────────────────────────────────────────────
652
649
  cards.append(heading_card("Sterowanie", style="subtitle"))
653
- cards.append(horizontal_stack([
654
- tile_card(eid("button", "next_valve"), "Next valve", "mdi:skip-next"),
655
- tile_card(eid("button", "pause"), "Pause", "mdi:pause"),
656
- tile_card(eid("button", "resume"), "Resume", "mdi:play"),
657
- ]))
650
+ control_tiles = []
651
+ if len(ctrl.zones) > 1:
652
+ control_tiles.append(tile_card(eid("button", "next_valve"), "Next valve", "mdi:skip-next"))
653
+ control_tiles.append(tile_card(eid("button", "pause"), "Pause", "mdi:pause"))
654
+ control_tiles.append(tile_card(eid("button", "resume"), "Resume", "mdi:play"))
655
+ cards.append(horizontal_stack(control_tiles))
658
656
 
659
657
  # Water source select (if multiple)
660
658
  if len(ctrl.water_sources) > 1:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.4.0.dev9
3
+ Version: 1.4.0.dev11
4
4
  Summary: Python App for BoneIO
5
5
  Author-email: Paweł Szafer <pszafer@gmail.com>
6
6
  License: GNU General Public License v3.0
@@ -3,7 +3,7 @@ boneio/bonecli.py,sha256=MfkiiMkoIZ98davH3L7IrBvugQbiIpAidWEabn5GZmQ,13160
3
3
  boneio/const.py,sha256=M981R2gwfjDX3lcoufWOyGlNxvGMESWgXOjVkmJfX60,7208
4
4
  boneio/exceptions.py,sha256=cBph-TsLF7FSz6p4wYeMs3pjVmVRaNQRJP82JgYYV-c,810
5
5
  boneio/runner.py,sha256=q_3050BKgnDcsT1ChFr9IZrAn2p6EyGp4DFKQy9BVno,17886
6
- boneio/version.py,sha256=vKazO0zF1I5OzjFuSDHgk3Lqa2HWK_JR8DIUaKd9Z-I,41
6
+ boneio/version.py,sha256=f7o6S1aJtoR2CLRjzQvugW2n5dQ1sV4LnLk4_eXG0gI,42
7
7
  boneio/boards/0.2/input.yaml,sha256=K5EcB44BZ8PxbPnH1izYwJ-ePo8gs4qZttMXhnMnfQ8,1259
8
8
  boneio/boards/0.2/output_24_16.yaml,sha256=GQGM3gUK7UobdGL-Ejt9UKdCs1HLPgZ7kziVZ1tjQlA,1462
9
9
  boneio/boards/0.2/output_32_10.yaml,sha256=169ubuzRqFLGiOr7zgB1xL1tKdQyOx2FJZvTCkxCA4U,1920
@@ -66,7 +66,7 @@ boneio/components/output/basic.py,sha256=uLiXW0zVa-trXzEl-j4chQdAMoDRuNrQN6aPBaP
66
66
  boneio/components/output/mcp.py,sha256=T5dfga2Nk2HZRxdWDiAgVMWFIpPfgQdraSsb4LBUygM,2322
67
67
  boneio/components/output/pca.py,sha256=JX3ddnh8eBeWcafn4moG1wva8EoXmRxsQ7S4ngO-NtY,3202
68
68
  boneio/components/output/pcf.py,sha256=wuQKGlDBbr6mIZpn-KEHtm21pp1CWZCBfd4qsIgTlwg,1826
69
- boneio/components/output/remote.py,sha256=sEBE4aDc4ST7Rzt5FtcxPMKCd8KRNLZ9QX1mMfrHkNE,27036
69
+ boneio/components/output/remote.py,sha256=lk-4eLcpJ2C5lSDdAZo8BK90xuzg0VIYsCDDzlZTdtc,28356
70
70
  boneio/components/sensor/__init__.py,sha256=6HAcMYUS89qtepYuLU2EQ4Zk_7RfQlsW_ODK8d_R4Bw,254
71
71
  boneio/components/sensor/virtual_energy.py,sha256=Np4VVTB_MG83PDNraUM4nZEs8aGpVYPx373wg5w923s,11440
72
72
  boneio/components/template/__init__.py,sha256=-MYMHjdGeAGkl9XH34-3vwEkzgEBOnVpfk9bGkUFKqU,498
@@ -87,7 +87,7 @@ boneio/core/config/config_helper.py,sha256=7QOqBDMPCMQ9TuSPrAcY5rNM7tQbqgh9k5uUM
87
87
  boneio/core/config/package-lock.json,sha256=AeqhAJcsqGoKGJHoF_Qduy0gatmXV6nNesZwZYYrnWM,85
88
88
  boneio/core/config/package.json,sha256=yj0WO6sFU4GCciYUBWjzvvfqrBh869doeOC2Pp5EI1Y,3
89
89
  boneio/core/config/schema_converter.py,sha256=c1tSuGWMIrKX6eNiZJJLx5QYBTugy6xLIKd5Dc11WYc,13397
90
- boneio/core/config/yaml_util.py,sha256=0OOe8t6zbWcgcgZPoaYmGSUYviMNYjwBTTWJy7mjFKY,58113
90
+ boneio/core/config/yaml_util.py,sha256=PmsWUlUrTezCTFjlinIt1doTdl-1pU9Fo7tH0pOuchg,58264
91
91
  boneio/core/config/migrations/__init__.py,sha256=ZkGWxJ5ebyWPJvl96v72xiJNT-805rdSyMMzCXqtDb4,7212
92
92
  boneio/core/config/migrations/v1_proxy_port.py,sha256=MVWhNH9M9_LG92CR9UU7rnGy-LhjHr5_2FxoZihMrHc,2169
93
93
  boneio/core/config/migrations/v2_transition.py,sha256=pCpCrmjSHDDz3lXk4ANC9shdTVgvk2Mi9eq7je_EcWo,3742
@@ -99,8 +99,8 @@ boneio/core/manager/canopen.py,sha256=t5CNPFB5CZtAgfm0Maac72fBKHNTEYqu6rwdVKoIjd
99
99
  boneio/core/manager/covers.py,sha256=es4bxUpUv10XI4S3VmNFXtdXkOn3rcLJnSrjxUYxKr0,20744
100
100
  boneio/core/manager/display.py,sha256=MeuCvagebfXsJfr2I3PButkQPhPJQeEAIuTPnn9jMFg,12819
101
101
  boneio/core/manager/inputs.py,sha256=0QfLmFu2u-ENtpUglfDYrGTCtR7Neu7iOHlRtbHqPic,41370
102
- boneio/core/manager/irrigation.py,sha256=UjDPtJq-naNRZGS47qgHMQ0ixkfz6O-Rj8dZPk7UPXk,24513
103
- boneio/core/manager/manager.py,sha256=wLKIANaissYd7Q0ihU9Fh2vfStmAsHM88yuMOjAOFC0,81704
102
+ boneio/core/manager/irrigation.py,sha256=kFTmBa6mKOylV6o2gflPFCZoztuejxlku4C77ggvYwM,25035
103
+ boneio/core/manager/manager.py,sha256=gGTKLWzBTxGso635EqkIUXHKs9QrTw7Dd4oI14BmSno,82250
104
104
  boneio/core/manager/modbus.py,sha256=xkKdn3gQviHubW8VwYq_cW0tCyI31Jna2TcOyxRsNfc,15854
105
105
  boneio/core/manager/outputs.py,sha256=XKu4RFcPirdpul89-airVEEBrfQH4ZJlUmCXx6VNNzw,37983
106
106
  boneio/core/manager/remote.py,sha256=zHwhIsB20CbzM23OiNSxkmh3nkWY3kEc_qO1zFiR0no,40861
@@ -325,7 +325,7 @@ boneio/schema/temp_unit.yaml,sha256=m32VGz9RTW92Lz08l9n6RftkcVNZquOGPPr5mc3eZVc,
325
325
  boneio/schema/update_interval.yaml,sha256=RBuAFj1gGn89ydZkaUUP-f88utvth1Qtt5u6lau2iOc,186
326
326
  boneio/webui/action_validation.py,sha256=2tdshl9MpgjHIYXYDV4XHW6lGTZn-05XgicFMWRcny4,7318
327
327
  boneio/webui/app.py,sha256=yN53jS8p91hIiwKKJFLprv3nQ6gVhknchF_c9nSbCL4,33123
328
- boneio/webui/dashboard_cards.py,sha256=FTqPD6Dfwn9NZsBBmvEiTNbq_R6Ha-G5MOBtMbrxpWM,7735
328
+ boneio/webui/dashboard_cards.py,sha256=ssurw3oD5VH3-52AbizTQsRPP-A3Bfyafx_Fd810dw4,7800
329
329
  boneio/webui/web_server.py,sha256=EZRUqwLqwLA5kdUZeYuriBY0nCq0Ffmo5f-Dz_eSxxg,9471
330
330
  boneio/webui/websocket_manager.py,sha256=MGo_yaXEC-30EB0mvA1dnZ14YZglFZlXBq-vTgl1rlc,6430
331
331
  boneio/webui/frontend-dist/boneio-192.png,sha256=2Q-HiAx3kB1yppMriZ46fDZ94Ft_1VpDbZ9EShGUBSo,23489
@@ -388,9 +388,9 @@ boneio/webui/routes/__init__.py,sha256=qddXxa09T2Vrzp_wfyh6wkB503rm3A1hp-UxDTRa_
388
388
  boneio/webui/routes/auth.py,sha256=5jPKYL7NnXni_r9ssBHppmqtgai6JObd3vqhycPeLdU,1589
389
389
  boneio/webui/routes/caddy.py,sha256=zS21OctOueuza_zigWoEz9V9-1S6IN4D77AKI5U7Pd4,24020
390
390
  boneio/webui/routes/can.py,sha256=18RVS2pPe_bNeZDcHSmwoLqsdmizjvTf18IdphfmeuU,14660
391
- boneio/webui/routes/config.py,sha256=Lg70p4CA-k7DcKkSGizTi4IaNWz83O8vT4hr6i9ln9U,52450
391
+ boneio/webui/routes/config.py,sha256=CNd9YaYb_MpUl89wD_ar8kiN3peSbT28mY9raOd5CxA,52721
392
392
  boneio/webui/routes/covers.py,sha256=DtT4hSomRjR2MzBrfBiT0e4T0xbwet49hlpjXGv8vuw,3719
393
- boneio/webui/routes/irrigation.py,sha256=5mG3rOdQApm33eUmuV7I1uo9D7lwtY7b8gi2wk91sfM,26157
393
+ boneio/webui/routes/irrigation.py,sha256=BCJMNtXNqQ0oNGjZJcjlzXS-l17c0x-h_qCYxxe9PQg,26186
394
394
  boneio/webui/routes/migrations.py,sha256=Xa2CUg8wvhIRgHkDqd7C9AVVXLfZSLeSA74U62SFkLU,5895
395
395
  boneio/webui/routes/modbus.py,sha256=4ZLB0Wrpdf1xLUMGbJXNE7txoHrpi4UPJ-ejrnjcxoA,28401
396
396
  boneio/webui/routes/outputs.py,sha256=5ze6qYHYGcM0L0Hsx-4TPX-SG_WkfAWWAvKjaGKxJlQ,6241
@@ -435,9 +435,9 @@ boneio/webui/schema/virtual_energy_sensor.schema.json,sha256=BN6Egh-CAnXSa80bQ6Y
435
435
  boneio/webui/schema/web.schema.json,sha256=cactLq1MVwDL5hu8bLeuq5yiz49BWVS4OtjWLmhbw2M,2592
436
436
  boneio/webui/services/__init__.py,sha256=l_L3YUPhc0ZbrWqKH1RurC7UQ4q0k-5ABGTwOSS-YFQ,282
437
437
  boneio/webui/services/logs.py,sha256=7n596oxeWNIPDyKYdMJXFpH-GCvdKb_YrqTLy6kPBWA,11423
438
- boneio-1.4.0.dev9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
439
- boneio-1.4.0.dev9.dist-info/METADATA,sha256=YE_ZFJ1zHObOVSzymBkV36OOzmhBoNI-KBIXC-lArkw,1961
440
- boneio-1.4.0.dev9.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
441
- boneio-1.4.0.dev9.dist-info/entry_points.txt,sha256=JX7gluDIkQ6MBlzzxGHMItnBjciiJ73tsXwYcazMW_U,47
442
- boneio-1.4.0.dev9.dist-info/top_level.txt,sha256=ag9S5n1_KXZfyk9tN8R0YUDYbdA--e5a2w2FOD_yMdg,7
443
- boneio-1.4.0.dev9.dist-info/RECORD,,
438
+ boneio-1.4.0.dev11.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
439
+ boneio-1.4.0.dev11.dist-info/METADATA,sha256=8hiEjUqRbhpsTlxtGJ2rwWWoOUMsqqGa7AejrHjJYS0,1962
440
+ boneio-1.4.0.dev11.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
441
+ boneio-1.4.0.dev11.dist-info/entry_points.txt,sha256=JX7gluDIkQ6MBlzzxGHMItnBjciiJ73tsXwYcazMW_U,47
442
+ boneio-1.4.0.dev11.dist-info/top_level.txt,sha256=ag9S5n1_KXZfyk9tN8R0YUDYbdA--e5a2w2FOD_yMdg,7
443
+ boneio-1.4.0.dev11.dist-info/RECORD,,