Initial public release
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from ha_deconz_bridge.ha import HomeAssistantBridge
|
||||
from ha_deconz_bridge.lights import ChannelSpec, ControllerModeSpec, ControllerSpec, VirtualLightSpec
|
||||
from ha_deconz_bridge.light import VirtualLightState
|
||||
from ha_deconz_bridge.color import Color
|
||||
|
||||
|
||||
class FakeMQTTClient:
|
||||
def __init__(self) -> None:
|
||||
self.connected = False
|
||||
self.on_connect = None
|
||||
self.on_message = None
|
||||
self.published: list[tuple[str, str, bool]] = []
|
||||
self.subscriptions: list[str] = []
|
||||
|
||||
def username_pw_set(self, username, password) -> None:
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def connect(self, host: str, port: int, keepalive: int) -> None:
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.keepalive = keepalive
|
||||
|
||||
def loop_start(self) -> None:
|
||||
self.connected = True
|
||||
if self.on_connect is not None:
|
||||
self.on_connect(self, None, None, 0)
|
||||
|
||||
def loop_stop(self) -> None:
|
||||
self.connected = False
|
||||
|
||||
def disconnect(self) -> None:
|
||||
self.connected = False
|
||||
|
||||
def publish(self, topic: str, payload: str, retain: bool = False):
|
||||
if not self.connected:
|
||||
raise RuntimeError("publish before MQTT connect")
|
||||
self.published.append((topic, payload, retain))
|
||||
|
||||
def subscribe(self, topic: str) -> None:
|
||||
if not self.connected:
|
||||
raise RuntimeError("subscribe before MQTT connect")
|
||||
self.subscriptions.append(topic)
|
||||
|
||||
|
||||
def test_bridge_waits_for_connect_before_discovery(settings, rgb_light_spec) -> None:
|
||||
mqtt = FakeMQTTClient()
|
||||
bridge = HomeAssistantBridge(settings, mqtt_client=mqtt)
|
||||
|
||||
bridge.start(on_command=lambda event: None)
|
||||
bridge.publish_discovery(rgb_light_spec)
|
||||
bridge.publish_state(
|
||||
rgb_light_spec,
|
||||
VirtualLightState(
|
||||
on=True,
|
||||
color=rgb_light_spec.controllers["1"].modes["rgb"].channels["r"].color,
|
||||
ha_mode="rgb",
|
||||
brightness=128,
|
||||
exact_chroma_match=True,
|
||||
),
|
||||
)
|
||||
|
||||
assert mqtt.published[0][0] == "homeassistant/light/rgb_light/config"
|
||||
assert json.loads(mqtt.published[0][1])["schema"] == "json"
|
||||
assert json.loads(mqtt.published[0][1])["name"] == "rgb_light"
|
||||
assert mqtt.subscriptions == ["ha-deconz-bridge/light/rgb_light/set"]
|
||||
|
||||
|
||||
def test_bridge_sanitizes_mqtt_object_id_for_discovery_topics(settings) -> None:
|
||||
mqtt = FakeMQTTClient()
|
||||
bridge = HomeAssistantBridge(settings, mqtt_client=mqtt)
|
||||
bridge.start(on_command=lambda event: None)
|
||||
|
||||
spec = VirtualLightSpec(
|
||||
name="Example Light North",
|
||||
supported_color_modes=("brightness",),
|
||||
controllers={
|
||||
"example_controller": ControllerSpec(
|
||||
zigbee_id="example_controller",
|
||||
name="Example controller",
|
||||
modes={
|
||||
"brightness": ControllerModeSpec(
|
||||
name="brightness",
|
||||
channels={
|
||||
"w": ChannelSpec(
|
||||
"w",
|
||||
Color.from_color_temp(182, brightness=1.0),
|
||||
semantic_label="color_temp",
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
bridge.publish_discovery(spec)
|
||||
|
||||
assert mqtt.published[0][0] == "homeassistant/light/Example_Light_North/config"
|
||||
payload = json.loads(mqtt.published[0][1])
|
||||
assert payload["name"] == "Example Light North"
|
||||
assert payload["unique_id"] == "Example_Light_North"
|
||||
assert payload["device"]["identifiers"] == ["ha-deconz-bridge:Example_Light_North"]
|
||||
assert payload["device"]["name"] == "HA deCONZ Bridge: Example Light North"
|
||||
assert payload["command_topic"] == "ha-deconz-bridge/light/Example_Light_North/set"
|
||||
assert payload["state_topic"] == "ha-deconz-bridge/light/Example_Light_North/state"
|
||||
assert mqtt.subscriptions == ["ha-deconz-bridge/light/Example_Light_North/set"]
|
||||
|
||||
|
||||
def test_bridge_resubscribes_to_command_topics_on_reconnect(settings, rgb_light_spec) -> None:
|
||||
mqtt = FakeMQTTClient()
|
||||
bridge = HomeAssistantBridge(settings, mqtt_client=mqtt)
|
||||
bridge.start(on_command=lambda event: None)
|
||||
bridge.publish_discovery(rgb_light_spec)
|
||||
|
||||
mqtt.loop_stop()
|
||||
mqtt.loop_start()
|
||||
|
||||
assert mqtt.subscriptions == [
|
||||
"ha-deconz-bridge/light/rgb_light/set",
|
||||
"ha-deconz-bridge/light/rgb_light/set",
|
||||
]
|
||||
Reference in New Issue
Block a user