Restructure public config and deployment

This commit is contained in:
ajp_anton
2026-05-30 19:17:27 +00:00
parent cc4e0c2c0f
commit cdf1f4e3a1
24 changed files with 710 additions and 302 deletions
+1
View File
@@ -6,6 +6,7 @@ import sys
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "config.example"))
from ha_deconz_bridge.color import Color
from ha_deconz_bridge.lights import ChannelSpec, ControllerModeSpec, ControllerSpec, VirtualLightSpec
+3 -3
View File
@@ -95,7 +95,7 @@ def test_double_long_state_is_per_physical_remote() -> None:
def test_hold_count_gesture_patterns() -> None:
action = ActionSpec("turn_off", target="Example Living")
action = ActionSpec("turn_off", target="Living Room")
engine = AutomationEngine(
remotes={"4": RemoteSpec("4", "room", "Room remote")},
rules=(
@@ -124,7 +124,7 @@ def test_hold_count_gesture_patterns() -> None:
def test_automation_rules_bind_to_internal_remote_id() -> None:
action = ActionSpec("turn_off", target="Example Living")
action = ActionSpec("turn_off", target="Living Room")
engine = AutomationEngine(
remotes={
"4": RemoteSpec("4", "room", "First"),
@@ -167,7 +167,7 @@ def test_time_condition_handles_midnight_wrap() -> None:
def test_automation_rules_can_be_built_from_nested_config() -> None:
action = ActionSpec("turn_off", target="Example Living")
action = ActionSpec("turn_off", target="Living Room")
rules = automation_rules(
{
+2 -2
View File
@@ -72,8 +72,8 @@ def test_fixed_brightness_normalizes_relative_and_ha_values() -> None:
def test_example_groups_reference_existing_lights() -> None:
from configs.example_groups import GROUPS
from configs.example_lights import LIGHTS
from groups import GROUPS
from lights import LIGHTS
missing = {
group_name: [
+19 -19
View File
@@ -253,10 +253,10 @@ def test_runtime_ha_command_updates_all_overlapping_virtual_lights(
def test_load_config_module_by_path_supports_repo_config_imports() -> None:
module = load_config_module("configs/example.py")
module = load_config_module("config.example/lights_config.py")
assert "Example Mixed North" in module.LIGHTS
assert "Example Living" in module.GROUPS
assert "Living Room Ceiling" in module.LIGHTS
assert "Living Room" in module.GROUPS
def test_warmup_requests_cover_supported_modes(rgb_light_spec, ct_light_spec) -> None:
@@ -682,9 +682,9 @@ def test_runtime_relative_group_readback_uses_aggregate_output(settings, monkeyp
def test_example_room_scene_reports_requested_brightness_and_ct(settings, monkeypatch) -> None:
from configs.example_actions import scene
from configs.example_groups import GROUPS
from configs.example_lights import LIGHTS
from actions import scene
from groups import GROUPS
from lights import LIGHTS
resources = {
controller_id: _resource_for_controller(controller)
@@ -705,9 +705,9 @@ def test_example_room_scene_reports_requested_brightness_and_ct(settings, monkey
(4000, 255, 250),
(5500, 255, 182),
):
app._run_action(scene("Example Kitchen", brightness=brightness, kelvin=kelvin))
app._run_action(scene("Kitchen", brightness=brightness, kelvin=kelvin))
state = app.group_lights["Example Kitchen"].state
state = app.group_lights["Kitchen"].state
assert state.brightness == brightness
assert state.color.color_temp == mireds
@@ -716,9 +716,9 @@ def test_example_group_readback_uses_aggregate_member_output(
settings,
monkeypatch,
) -> None:
from configs.example_actions import scene
from configs.example_groups import GROUPS
from configs.example_lights import LIGHTS
from actions import scene
from groups import GROUPS
from lights import LIGHTS
resources = {
controller_id: _resource_for_controller(controller)
@@ -730,21 +730,21 @@ def test_example_group_readback_uses_aggregate_member_output(
monkeypatch.setattr("ha_deconz_bridge.app.HomeAssistantBridge", lambda _settings: RecordingBridge())
app = HaDeconzBridgeApp(settings, LIGHTS, groups=GROUPS)
app._run_action(scene("Example Living", brightness=51, kelvin=2200))
app.group_lights["Example Living"].clear_accepted()
state = app.group_lights["Example Living"].handle_member_update()
app._run_action(scene("Living Room", brightness=51, kelvin=2200))
app.group_lights["Living Room"].clear_accepted()
state = app.group_lights["Living Room"].handle_member_update()
assert 45 <= state.brightness <= 60
assert app.lights["Example Plug A"].state.brightness == 255
assert app.lights["Example Plug B"].state.brightness == 255
assert app.lights["Floor Lamp Plug"].state.brightness == 255
assert app.lights["Desk Lamp Plug"].state.brightness == 255
def test_example_native_ct_member_reports_requested_ct(settings) -> None:
from configs.example_lights import LIGHTS
from lights import LIGHTS
light, _bridge, _backend = _build_light(LIGHTS["Example Bedroom West"], settings)
light, _bridge, _backend = _build_light(LIGHTS["Bedroom Left Lamp"], settings)
state = light.handle_ha_command(HaCommandEvent("Example Bedroom West", on=True, brightness=153, color_temp=333))
state = light.handle_ha_command(HaCommandEvent("Bedroom Left Lamp", on=True, brightness=153, color_temp=333))
assert state.brightness == 153
assert state.color.color_temp == 333
+34 -34
View File
@@ -1,6 +1,6 @@
from __future__ import annotations
from configs.example import GROUPS, LIGHTS
from lights_config import GROUPS, LIGHTS
from ha_deconz_bridge.color import Color
from ha_deconz_bridge.debugger.web_debugger import _combine_specs, _group_debug_spec
from ha_deconz_bridge.lights import ChannelSpec, ControllerModeSpec, ControllerSpec, VirtualLightSpec
@@ -202,7 +202,7 @@ def test_onoff_booster_is_held_back_until_dimmables_are_exhausted() -> None:
def test_brightness_mode_compensates_when_onoff_booster_turns_on() -> None:
spec = _combine_specs(LIGHTS, ["Example Plug A", "Example Fixed White A"])
spec = _combine_specs(LIGHTS, ["Floor Lamp Plug", "Plant Light Left"])
model = compile_light_model(spec)
target = Color.from_rgb((255, 255, 255), brightness=1.0)
@@ -407,7 +407,7 @@ def test_ct_line_balancing_uses_comparable_same_label_channels_stably() -> None:
def test_rgb_request_does_not_use_white_boost_when_rgb_labeled_channels_exist() -> None:
spec = _combine_specs(LIGHTS, ["Example Fixed White A", "Example Mixed North"])
spec = _combine_specs(LIGHTS, ["Plant Light Left", "Living Room Ceiling"])
model = compile_light_model(spec)
target = Color.from_rgb((255, 255, 255), brightness=1.0)
@@ -418,19 +418,19 @@ def test_rgb_request_does_not_use_white_boost_when_rgb_labeled_channels_exist()
def test_example_fixed_white_controller_uses_full_ct_command_range() -> None:
controller = LIGHTS["Example Fixed White A"].controllers["fixed_a"]
controller = LIGHTS["Plant Light Left"].controllers["fixed_a"]
assert controller.native_ct_mireds == (153, 500)
def test_example_standard_ct_controllers_use_configured_ct_command_range() -> None:
for light_name in ["Example Mixed North", "Example Hall Floor", "Example Hall Corner", "Example Hall Cabinets"]:
for light_name in ["Living Room Ceiling", "Hallway Floor Light", "Hallway Corner Light", "Hallway Cabinet Lights"]:
for controller in LIGHTS[light_name].controllers.values():
if "color_temp" in controller.modes:
assert controller.native_ct_mireds == (153, 500)
def test_ct_request_uses_native_ct_mode_on_rgb_cct_controller() -> None:
spec = LIGHTS["Example Kitchen Counter"]
spec = LIGHTS["Kitchen Counter Lights"]
result = solve_light(
compile_light_model(spec),
Color.from_color_temp(455, brightness=1.0),
@@ -542,7 +542,7 @@ def test_ct_slack_does_not_use_near_ct_when_outside_band() -> None:
def test_wc_ct_sweep_stays_near_requested_ct_line_through_middle_range() -> None:
spec = _group_debug_spec(GROUPS["Example Bathroom"], LIGHTS)
spec = _group_debug_spec(GROUPS["Bathroom"], LIGHTS)
model = compile_light_model(spec)
for mireds in [220, 250, 286, 320, 360]:
@@ -559,7 +559,7 @@ def test_wc_ct_sweep_stays_near_requested_ct_line_through_middle_range() -> None
def test_wc_low_brightness_ct_can_use_rgb_correction_without_redefining_reference() -> None:
spec = _group_debug_spec(GROUPS["Example Bathroom"], LIGHTS)
spec = _group_debug_spec(GROUPS["Bathroom"], LIGHTS)
model = compile_light_model(spec)
target = Color.from_color_temp(286, brightness=1.0, temp_range=spec.exposed_mireds)
@@ -573,7 +573,7 @@ def test_wc_low_brightness_ct_can_use_rgb_correction_without_redefining_referenc
def test_wc_katto_low_brightness_ct_can_sacrifice_one_bulb_for_rgb_correction() -> None:
spec = LIGHTS["Example Bathroom Ceiling"]
spec = LIGHTS["Bathroom Ceiling Light"]
model = compile_light_model(spec)
target = Color.from_color_temp(286, brightness=1.0, temp_range=spec.exposed_mireds)
@@ -593,7 +593,7 @@ def test_wc_katto_low_brightness_ct_can_sacrifice_one_bulb_for_rgb_correction()
def test_wc_katto_balances_equivalent_channels() -> None:
spec = LIGHTS["Example Bathroom Ceiling"]
spec = LIGHTS["Bathroom Ceiling Light"]
model = compile_light_model(spec)
target = Color.from_color_temp(300, brightness=1.0, temp_range=spec.exposed_mireds)
@@ -614,14 +614,14 @@ def test_example_all_lights_does_not_branch_on_dimmable_off_states() -> None:
spec = _combine_specs(
LIGHTS,
[
"Example Fixed White A",
"Example Fixed White B",
"Example Mixed North",
"Example Plug A",
"Example Plug B",
"Example Hall Floor",
"Example Hall Corner",
"Example Hall Cabinets",
"Plant Light Left",
"Plant Light Right",
"Living Room Ceiling",
"Floor Lamp Plug",
"Desk Lamp Plug",
"Hallway Floor Light",
"Hallway Corner Light",
"Hallway Cabinet Lights",
],
)
model = compile_light_model(spec)
@@ -632,14 +632,14 @@ def test_example_all_lights_deduplicates_reference_combinations() -> None:
spec = _combine_specs(
LIGHTS,
[
"Example Fixed White A",
"Example Fixed White B",
"Example Mixed North",
"Example Plug A",
"Example Plug B",
"Example Hall Floor",
"Example Hall Corner",
"Example Hall Cabinets",
"Plant Light Left",
"Plant Light Right",
"Living Room Ceiling",
"Floor Lamp Plug",
"Desk Lamp Plug",
"Hallway Floor Light",
"Hallway Corner Light",
"Hallway Cabinet Lights",
],
)
model = compile_light_model(spec)
@@ -650,14 +650,14 @@ def test_example_all_lights_ct_sweep_does_not_use_unused_onoff_reference() -> No
spec = _combine_specs(
LIGHTS,
[
"Example Fixed White A",
"Example Fixed White B",
"Example Mixed North",
"Example Plug A",
"Example Plug B",
"Example Hall Floor",
"Example Hall Corner",
"Example Hall Cabinets",
"Plant Light Left",
"Plant Light Right",
"Living Room Ceiling",
"Floor Lamp Plug",
"Desk Lamp Plug",
"Hallway Floor Light",
"Hallway Corner Light",
"Hallway Cabinet Lights",
],
)
model = compile_light_model(spec)