Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Some products appear as several devices that share the same `relation_id`. The V
| `color_temperature` | Color temperature in Kelvin |
| `color_temperature_min`, `color_temperature_max` | Supported color temperature range, as reported by the bulb |
| `color_hue`, `color_saturation` | Color, hue 0–360 and saturation 0–1 |
| `color_mode` | Whether the light is showing a color temperature (`"temperature"`) or a hue/saturation color (`"color"`). `None` if the bulb does not report it |
| `startup_on_off` | Behaviour after a power outage (`StartupEnum`) |

```python
Expand Down Expand Up @@ -306,7 +307,7 @@ All sensors support `reload()` and `set_name(name=...)`. Battery powered sensors
| Sensor | Fetch with | Attributes |
| --- | --- | --- |
| Environment sensor | `get_environment_sensors()` | `current_temperature` (°C), `current_r_h` (relative humidity in %), `current_p_m25`, `max_measured_p_m25`, `min_measured_p_m25`, `voc_index` (VINDSTYRKA), `current_c_o2` (ppm, ALPSTUGA) |
| Motion sensor | `get_motion_sensors()` | `is_detected`, `is_on`, `light_level` |
| Motion sensor | `get_motion_sensors()` | `is_detected`, `is_on` (`None` on sensors that do not report it), `light_level` |
| Light sensor | `get_light_sensors()` | `illuminance`, `min_illuminance`, `max_illuminance` |
| Occupancy sensor | `get_occupancy_sensors()` | `is_detected` |
| Open/close sensor | `get_open_close_sensors()` | `is_open` |
Expand Down
3 changes: 3 additions & 0 deletions src/dirigera/devices/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LightAttributes(Attributes):
color_temperature_max: Optional[int] = None
color_hue: Optional[float] = None
color_saturation: Optional[float] = None
color_mode: Optional[str] = None


class Light(Device):
Expand Down Expand Up @@ -86,6 +87,7 @@ def set_color_temperature(self, color_temp: int) -> None:
data = [{"attributes": {"colorTemperature": color_temp}}]
self.dirigera_client.patch(route=f"/devices/{self.id}", data=data)
self.attributes.color_temperature = color_temp
self.attributes.color_mode = "temperature"

def set_light_color(self, hue: float, saturation: float) -> None:
if (
Expand All @@ -104,6 +106,7 @@ def set_light_color(self, hue: float, saturation: float) -> None:
self.dirigera_client.patch(route=f"/devices/{self.id}", data=data)
self.attributes.color_hue = hue
self.attributes.color_saturation = saturation
self.attributes.color_mode = "color"

def set_startup_behaviour(self, behaviour: StartupEnum) -> None:
"""
Expand Down
2 changes: 1 addition & 1 deletion src/dirigera/devices/motion_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class MotionSensorAttributes(Attributes):
battery_percentage: Optional[int] = None
is_on: bool
is_on: Optional[bool] = None
light_level: Optional[float] = None
is_detected: Optional[bool] = False

Expand Down
7 changes: 7 additions & 0 deletions tests/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,13 @@ def test_set_light_level(fake_light: Light, fake_client: FakeDirigeraHub) -> Non

def test_set_color_temperature(fake_light: Light, fake_client: FakeDirigeraHub) -> None:
temp = 2203
fake_light.attributes.color_mode = "color"
fake_light.set_color_temperature(temp)
action = fake_client.patch_actions.pop()
assert action["route"] == f"/devices/{fake_light.id}"
assert action["data"] == [{"attributes": {"colorTemperature": temp}}]
assert fake_light.attributes.color_temperature == temp
assert fake_light.attributes.color_mode == "temperature"


def test_set_color_temperature_out_of_range(
Expand Down Expand Up @@ -279,6 +281,11 @@ def test_set_light_color(fake_light: Light, fake_client: FakeDirigeraHub) -> Non
]
assert fake_light.attributes.color_hue == hue
assert fake_light.attributes.color_saturation == saturation
assert fake_light.attributes.color_mode == "color"


def test_color_mode(fake_light: Light) -> None:
assert fake_light.attributes.color_mode == "temperature"


def test_set_startup_behaviour_off(
Expand Down
12 changes: 12 additions & 0 deletions tests/test_motion_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,15 @@ def test_dict_to_motion_sensor_optional_fields(motion_sensor_dict_non_ikea: Dict
motion_sensor = dict_to_motion_sensor(motion_sensor_dict_non_ikea, fake_client)

assert motion_sensor.attributes.battery_percentage is None


def test_dict_to_motion_sensor_without_is_on(
motion_sensor_dict: Dict, fake_client: FakeDirigeraHub
) -> None:
# Some sensors, such as MYGGSPRAY, do not report isOn
del motion_sensor_dict["attributes"]["isOn"]
motion_sensor_dict["attributes"]["isDetected"] = True
motion_sensor = dict_to_motion_sensor(motion_sensor_dict, fake_client)

assert motion_sensor.attributes.is_on is None
assert motion_sensor.attributes.is_detected is True
Loading