quilt-hp-python 0.2.1__tar.gz → 0.2.2__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.
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/CHANGELOG.md +6 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/PKG-INFO +1 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/client.md +1 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/pyproject.toml +1 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/__init__.py +1 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/cli/tui.py +13 -4
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/system.py +6 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_cli_surfaces_extra.py +1 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_models_from_proto.py +103 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_tui_bindings.py +16 -1
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/.github/copilot-instructions.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/.github/workflows/ci.yml +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/.github/workflows/docs-deploy.yml +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/.github/workflows/release.yml +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/.gitignore +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/LICENSE +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/README.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/explanation/architecture.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/explanation/authentication.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/explanation/grpc-and-protobuf.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/explanation/snapshot-and-stream.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/explanation/streaming-protocol.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/authenticate.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/automation-daemon.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/cli-scripting.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/configure-comfort-settings.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/configure-schedules.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/contribute.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/control-spaces.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/home-assistant.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/regenerate-protos.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/stream-updates.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/how-to/tui-app.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/index.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/api-reference.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/documentation-standards.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/grpc-services-matrix.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/hds-entities.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/models.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/reference/token-management.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/docs/tutorial/get-started.md +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/mkdocs.yml +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/proto/cleaned/quilt_device_pairing.proto +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/proto/cleaned/quilt_hds.proto +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/proto/cleaned/quilt_notifier.proto +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/proto/cleaned/quilt_services.proto +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/proto/cleaned/quilt_system.proto +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/scripts/bump_version.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/scripts/check_docs_nav.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/scripts/generate_public_api_reference.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/scripts/regen_protos.sh +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_paths.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/__init__.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2.pyi +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2_grpc.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_hds_pb2.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_hds_pb2.pyi +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_hds_pb2_grpc.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_notifier_pb2.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_notifier_pb2.pyi +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_notifier_pb2_grpc.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_services_pb2.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_services_pb2.pyi +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_services_pb2_grpc.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_system_pb2.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_system_pb2.pyi +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_system_pb2_grpc.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/auth.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/cli/__init__.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/cli/main.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/cli/settings.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/cli/store.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/client.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/const.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/exceptions.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/__init__.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/comfort.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/controller.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/energy.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/enums.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/indoor_unit.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/outdoor_unit.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/qsm.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/schedule.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/sensor.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/software_update.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/models/space.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/py.typed +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/services/__init__.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/services/hds.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/services/streaming.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/services/system.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/services/user.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/tokens.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/transport.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/__init__.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/conftest.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_auth.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_auth_store_settings_edges.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_cli_feature_completion.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_cli_login.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_client_cache.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_client_service_error_paths.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_hds_schedule_mapping.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_hds_service_branches.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_models.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_settings_store.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_streaming.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_streaming_reconnect_dispatch_extra.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_tokens.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_transport.py +0 -0
- {quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_transport_interceptor_extra.py +0 -0
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2026-05-11
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Corrected mapping of outdoor units to indoor units in SystemSnapshot
|
|
14
|
+
- Fixed TUI interaction issues with button handling and bindings
|
|
15
|
+
|
|
10
16
|
## [0.2.1] - 2026-05-10
|
|
11
17
|
|
|
12
18
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quilt-hp-python
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Async Python client for Quilt mini-split HVAC systems
|
|
5
5
|
Project-URL: Repository, https://github.com/eman/quilt-hp-python
|
|
6
6
|
Project-URL: Issues, https://github.com/eman/quilt-hp-python/issues
|
|
@@ -606,7 +606,7 @@ class DashboardScreen(Screen):
|
|
|
606
606
|
self.app._persist()
|
|
607
607
|
|
|
608
608
|
def action_system(self) -> None:
|
|
609
|
-
self.app.push_screen(SystemScreen(self._snapshot, self._client))
|
|
609
|
+
self.app.push_screen(SystemScreen(self._snapshot, self._client, use_f=self.use_f))
|
|
610
610
|
|
|
611
611
|
def action_select_room(self) -> None:
|
|
612
612
|
lv = self.query_one(ListView)
|
|
@@ -633,7 +633,7 @@ class DashboardScreen(Screen):
|
|
|
633
633
|
(c for c in self._snapshot.controllers if c.space_id == space_id),
|
|
634
634
|
None,
|
|
635
635
|
)
|
|
636
|
-
odu = self._snapshot.
|
|
636
|
+
odu = self._snapshot.odu_for_idu(idu) if idu else None
|
|
637
637
|
qsm = self._snapshot.qsm_for_idu(idu) if idu else None
|
|
638
638
|
self.app.push_screen(
|
|
639
639
|
RoomScreen(
|
|
@@ -2239,10 +2239,13 @@ class SystemScreen(Screen):
|
|
|
2239
2239
|
self,
|
|
2240
2240
|
snapshot: SystemSnapshot,
|
|
2241
2241
|
client: QuiltClient,
|
|
2242
|
+
*,
|
|
2243
|
+
use_f: bool = False,
|
|
2242
2244
|
) -> None:
|
|
2243
2245
|
super().__init__()
|
|
2244
2246
|
self._snapshot = snapshot
|
|
2245
2247
|
self._client = client
|
|
2248
|
+
self.use_f = use_f
|
|
2246
2249
|
|
|
2247
2250
|
def compose(self) -> ComposeResult:
|
|
2248
2251
|
yield Header(show_clock=True)
|
|
@@ -2283,7 +2286,6 @@ class SystemScreen(Screen):
|
|
|
2283
2286
|
yield Footer()
|
|
2284
2287
|
|
|
2285
2288
|
def on_mount(self) -> None:
|
|
2286
|
-
self.use_f = False
|
|
2287
2289
|
self._populate()
|
|
2288
2290
|
|
|
2289
2291
|
def _populate(self) -> None:
|
|
@@ -2486,6 +2488,11 @@ class SystemScreen(Screen):
|
|
|
2486
2488
|
self._populate()
|
|
2487
2489
|
|
|
2488
2490
|
def action_toggle_units(self) -> None:
|
|
2491
|
+
self.use_f = not self.use_f
|
|
2492
|
+
self._populate()
|
|
2493
|
+
self.app._persist()
|
|
2494
|
+
|
|
2495
|
+
def action_toggle_schedule(self) -> None:
|
|
2489
2496
|
loc = self._snapshot.primary_location
|
|
2490
2497
|
if loc is None:
|
|
2491
2498
|
self.notify("No location found", severity="error")
|
|
@@ -2645,7 +2652,9 @@ class QuiltApp(App[None]):
|
|
|
2645
2652
|
if self._snapshot:
|
|
2646
2653
|
odu = self._snapshot.apply_outdoor_unit(odu)
|
|
2647
2654
|
screen = self.screen
|
|
2648
|
-
if isinstance(screen, (DashboardScreen,
|
|
2655
|
+
if isinstance(screen, (DashboardScreen, SystemScreen)) or (
|
|
2656
|
+
isinstance(screen, RoomScreen) and screen._odu and screen._odu.id == odu.id
|
|
2657
|
+
):
|
|
2649
2658
|
screen.update_odu(odu)
|
|
2650
2659
|
|
|
2651
2660
|
def _dispatch_ctrl(self, ctrl: Controller) -> None:
|
|
@@ -416,6 +416,12 @@ class SystemSnapshot:
|
|
|
416
416
|
self.controller_remote_sensors.append(crs)
|
|
417
417
|
return crs
|
|
418
418
|
|
|
419
|
+
def odu_for_idu(self, idu: IndoorUnit) -> OutdoorUnit | None:
|
|
420
|
+
"""Return the OutdoorUnit connected to the given IDU, or None."""
|
|
421
|
+
if not idu.outdoor_unit_id:
|
|
422
|
+
return None
|
|
423
|
+
return next((u for u in self.outdoor_units if u.id == idu.outdoor_unit_id), None)
|
|
424
|
+
|
|
419
425
|
def qsm_for_idu(self, idu: IndoorUnit) -> QuiltSmartModule | None:
|
|
420
426
|
"""Return the QSM embedded in the given IDU, or None."""
|
|
421
427
|
if not idu.qsm_id:
|
|
@@ -15,7 +15,7 @@ runner = CliRunner()
|
|
|
15
15
|
def test_version_option_outputs_package_version() -> None:
|
|
16
16
|
result = runner.invoke(cli_main.app, ["--version"])
|
|
17
17
|
assert result.exit_code == 0
|
|
18
|
-
assert result.stdout.strip() == "0.2.
|
|
18
|
+
assert result.stdout.strip() == "0.2.2"
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class _FakeClient:
|
|
@@ -1216,3 +1216,106 @@ def test_away_setpoints_reflected_in_controls_when_away() -> None:
|
|
|
1216
1216
|
assert s1_away.is_away is True
|
|
1217
1217
|
assert s1_away.controls.heating_setpoint_c == pytest.approx(away.heating_setpoint_c)
|
|
1218
1218
|
assert s1_away.controls.cooling_setpoint_c == pytest.approx(away.cooling_setpoint_c)
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
# ─── SystemSnapshot.odu_for_idu ───────────────────────────────────────────────
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
def _make_odu_proto(odu_id: str, space_id: str = "space-1") -> SimpleNamespace:
|
|
1225
|
+
return _ns(
|
|
1226
|
+
header=_make_header(odu_id),
|
|
1227
|
+
relationships=_ns(space_id=space_id, hardware_id="", firmware_update_info_id=""),
|
|
1228
|
+
state=_ns(hvac_state=0),
|
|
1229
|
+
performance_data=_ns(
|
|
1230
|
+
ambient_temperature_c=0.0,
|
|
1231
|
+
compressor_frequency_hz=0.0,
|
|
1232
|
+
energy_measurement_j=0.0,
|
|
1233
|
+
),
|
|
1234
|
+
)
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
def _make_snap_with_multiple_odus() -> SystemSnapshot:
|
|
1238
|
+
from quilt_hp._proto import quilt_hds_pb2 as hds
|
|
1239
|
+
|
|
1240
|
+
loc = _ns(
|
|
1241
|
+
header=_make_header("loc-1"),
|
|
1242
|
+
attributes=_ns(name="", tz_identifier="UTC"),
|
|
1243
|
+
controls=_ns(schedule_execution=hds.SCHEDULE_EXECUTION_RUNNING),
|
|
1244
|
+
)
|
|
1245
|
+
|
|
1246
|
+
def _idu(idu_id: str, space_id: str, odu_id: str) -> SimpleNamespace:
|
|
1247
|
+
proto = _make_idu_proto(idu_id, space_id)
|
|
1248
|
+
proto.relationships = _ns(
|
|
1249
|
+
space_id=space_id,
|
|
1250
|
+
outdoor_unit_id=odu_id,
|
|
1251
|
+
hardware_id="hw-1",
|
|
1252
|
+
quilt_smart_module_id="",
|
|
1253
|
+
firmware_update_info_id="",
|
|
1254
|
+
)
|
|
1255
|
+
return proto
|
|
1256
|
+
|
|
1257
|
+
return SystemSnapshot.from_proto(
|
|
1258
|
+
_ns(
|
|
1259
|
+
spaces=[
|
|
1260
|
+
_make_space_proto("s1", "Room 1", parent_space_id="root"),
|
|
1261
|
+
_make_space_proto("s2", "Room 2", parent_space_id="root"),
|
|
1262
|
+
_make_space_proto("s3", "Room 3", parent_space_id="root"),
|
|
1263
|
+
],
|
|
1264
|
+
indoor_units=[
|
|
1265
|
+
_idu("idu-1", "s1", "odu-1"),
|
|
1266
|
+
_idu("idu-2", "s2", "odu-2"),
|
|
1267
|
+
_idu("idu-3", "s3", "odu-1"), # shares odu-1 with room 1
|
|
1268
|
+
],
|
|
1269
|
+
outdoor_units=[
|
|
1270
|
+
_make_odu_proto("odu-1"),
|
|
1271
|
+
_make_odu_proto("odu-2"),
|
|
1272
|
+
_make_odu_proto("odu-3"), # present but not linked to any IDU
|
|
1273
|
+
],
|
|
1274
|
+
outdoor_unit_hardware=[],
|
|
1275
|
+
controller_hardware=[],
|
|
1276
|
+
controllers=[],
|
|
1277
|
+
quilt_smart_modules=[],
|
|
1278
|
+
comfort_settings=[],
|
|
1279
|
+
schedule_weeks=[],
|
|
1280
|
+
schedule_days=[],
|
|
1281
|
+
remote_sensors=[],
|
|
1282
|
+
controller_remote_sensors=[],
|
|
1283
|
+
software_update_infos=[],
|
|
1284
|
+
locations=[loc],
|
|
1285
|
+
)
|
|
1286
|
+
)
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
def test_odu_for_idu_returns_correct_odu() -> None:
|
|
1290
|
+
snap = _make_snap_with_multiple_odus()
|
|
1291
|
+
idu1 = next(u for u in snap.indoor_units if u.id == "idu-1")
|
|
1292
|
+
idu2 = next(u for u in snap.indoor_units if u.id == "idu-2")
|
|
1293
|
+
idu3 = next(u for u in snap.indoor_units if u.id == "idu-3")
|
|
1294
|
+
|
|
1295
|
+
assert snap.odu_for_idu(idu1) is not None
|
|
1296
|
+
assert snap.odu_for_idu(idu1).id == "odu-1" # type: ignore[union-attr]
|
|
1297
|
+
|
|
1298
|
+
assert snap.odu_for_idu(idu2) is not None
|
|
1299
|
+
assert snap.odu_for_idu(idu2).id == "odu-2" # type: ignore[union-attr]
|
|
1300
|
+
|
|
1301
|
+
assert snap.odu_for_idu(idu3) is not None
|
|
1302
|
+
assert snap.odu_for_idu(idu3).id == "odu-1" # type: ignore[union-attr]
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
def test_odu_for_idu_no_outdoor_unit_id_returns_none() -> None:
|
|
1306
|
+
snap = _make_snap_with_multiple_odus()
|
|
1307
|
+
idu1 = next(u for u in snap.indoor_units if u.id == "idu-1")
|
|
1308
|
+
from dataclasses import replace
|
|
1309
|
+
|
|
1310
|
+
idu_no_odu = replace(idu1, outdoor_unit_id=None)
|
|
1311
|
+
assert snap.odu_for_idu(idu_no_odu) is None
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
def test_odu_for_idu_unlinked_odu_not_returned() -> None:
|
|
1315
|
+
"""ODU-3 exists in the snapshot but is not linked to any IDU."""
|
|
1316
|
+
snap = _make_snap_with_multiple_odus()
|
|
1317
|
+
assert len(snap.outdoor_units) == 3
|
|
1318
|
+
assert all(
|
|
1319
|
+
u.id != "odu-3"
|
|
1320
|
+
for u in (snap.odu_for_idu(idu) for idu in snap.indoor_units if idu is not None)
|
|
1321
|
+
)
|
|
@@ -4,7 +4,7 @@ import pytest
|
|
|
4
4
|
|
|
5
5
|
pytest.importorskip("textual")
|
|
6
6
|
|
|
7
|
-
from quilt_hp.cli.tui import RoomScreen
|
|
7
|
+
from quilt_hp.cli.tui import RoomScreen, SystemScreen
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def _key_action_map() -> dict[str, set[str]]:
|
|
@@ -21,3 +21,18 @@ def test_fan_key_does_not_overlap_with_fence_adjustment() -> None:
|
|
|
21
21
|
assert "fence_fwd_inc" not in keymap["f"]
|
|
22
22
|
assert "ctrl+up" in keymap
|
|
23
23
|
assert keymap["ctrl+up"] == {"fence_fwd_inc"}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_system_bindings_map_units_and_schedule_actions() -> None:
|
|
27
|
+
keymap: dict[str, set[str]] = {}
|
|
28
|
+
for binding in SystemScreen.BINDINGS:
|
|
29
|
+
for key in binding.key.split(","):
|
|
30
|
+
keymap.setdefault(key, set()).add(binding.action)
|
|
31
|
+
|
|
32
|
+
assert keymap["u"] == {"toggle_units"}
|
|
33
|
+
assert keymap["p"] == {"toggle_schedule"}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_system_screen_accepts_initial_unit_preference() -> None:
|
|
37
|
+
screen = SystemScreen(snapshot=object(), client=object(), use_f=True)
|
|
38
|
+
assert screen.use_f is True
|
|
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
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2.py
RENAMED
|
File without changes
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2.pyi
RENAMED
|
File without changes
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_device_pairing_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_notifier_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_services_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/src/quilt_hp/_proto/quilt_system_pb2_grpc.py
RENAMED
|
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
|
{quilt_hp_python-0.2.1 → quilt_hp_python-0.2.2}/tests/test_streaming_reconnect_dispatch_extra.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|