Skip to content

Commit

Permalink
feat: perform deep merging of updates
Browse files Browse the repository at this point in the history
  • Loading branch information
muhlba91 committed Dec 14, 2023
1 parent c0c9b81 commit e560027
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 45 deletions.
17 changes: 17 additions & 0 deletions onyx_client/data/animation_value.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Animation Values of Onyx devices."""
from typing import Optional

from onyx_client.data.animation_keyframe import AnimationKeyframe


Expand Down Expand Up @@ -35,6 +37,21 @@ def create(properties: dict):
],
)

def update_with(self, other: Optional):
"""Updates this value with the target.
other: the other value"""
if other is not None:
self.start = self.start if other.start is None else other.start
self.current_value = (
self.current_value
if other.current_value is None
else other.current_value
)
self.keyframes = (
self.keyframes if other.keyframes is None else other.keyframes
)

def __eq__(self, other):
if isinstance(self, other.__class__):
return (
Expand Down
8 changes: 8 additions & 0 deletions onyx_client/data/boolean_value.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Boolean Values of Onyx devices."""
from typing import Optional


class BooleanValue:
Expand All @@ -25,6 +26,13 @@ def create(properties: dict):
properties.get("read_only", "false") == "true",
)

def update_with(self, other: Optional):
"""Updates this value with the target.
other: the other value"""
if other is not None:
self.value = self.value if other.value is None else other.value

def __str__(self) -> str:
return f"BooleanValue(value={self.value})"

Expand Down
7 changes: 4 additions & 3 deletions onyx_client/data/numeric_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ def update_with(self, other: Optional):
self.read_only = (
self.read_only if other.read_only is None else other.read_only
)
self.animation = (
self.animation if other.animation is None else other.animation
)
if self.animation is not None:
self.animation.update_with(other.animation)
else:
self.animation = other.animation

def __eq__(self, other):
if isinstance(self, other.__class__):
Expand Down
16 changes: 3 additions & 13 deletions onyx_client/device/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,9 @@ def update_with(self, update):
update: the update patch"""
super().update_with(update)

self.target_brightness = (
self.target_brightness
if update.target_brightness is None
else update.target_brightness
)
self.actual_brightness = (
self.actual_brightness
if update.actual_brightness is None
else update.actual_brightness
)
self.dim_duration = (
self.dim_duration if update.dim_duration is None else update.dim_duration
)
self.target_brightness.update_with(update.target_brightness)
self.actual_brightness.update_with(update.actual_brightness)
self.dim_duration.update_with(update.dim_duration)

@staticmethod
def keys() -> list:
Expand Down
12 changes: 3 additions & 9 deletions onyx_client/device/shutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,10 @@ def update_with(self, update):
update: the update patch"""
super().update_with(update)

self.target_position = (
self.target_position
if update.target_position is None
else update.target_position
)
self.target_angle = (
self.target_angle if update.target_angle is None else update.target_angle
)
self.actual_angle.update_with(update.actual_angle)
self.target_position.update_with(update.target_position)
self.target_angle.update_with(update.target_angle)
self.actual_position.update_with(update.actual_position)
self.actual_angle.update_with(update.actual_angle)

@staticmethod
def keys() -> list:
Expand Down
26 changes: 6 additions & 20 deletions onyx_client/device/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,12 @@ def update_with(self, update):
update: the update patch"""
super().update_with(update)

self.wind_peak = (
self.wind_peak if update.wind_peak is None else update.wind_peak
)
self.sun_brightness_peak = (
self.sun_brightness_peak
if update.sun_brightness_peak is None
else update.sun_brightness_peak
)
self.sun_brightness_sink = (
self.sun_brightness_sink
if update.sun_brightness_sink is None
else update.sun_brightness_sink
)
self.air_pressure = (
self.air_pressure if update.air_pressure is None else update.air_pressure
)
self.humidity = self.humidity if update.humidity is None else update.humidity
self.temperature = (
self.temperature if update.temperature is None else update.temperature
)
self.wind_peak.update_with(update.wind_peak)
self.sun_brightness_peak.update_with(update.sun_brightness_peak)
self.sun_brightness_sink.update_with(update.sun_brightness_sink)
self.air_pressure.update_with(update.air_pressure)
self.humidity.update_with(update.humidity)
self.temperature.update_with(update.temperature)

@staticmethod
def keys() -> list:
Expand Down
74 changes: 74 additions & 0 deletions tests/data/test_animation_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,77 @@ def test_str(self):

def test_not_eq(self):
assert AnimationValue(10, 10, list()) != 10

def test_update_with(self):
value1 = AnimationValue(1.0, 1, [AnimationKeyframe("linear", 0, 1.0, 1)])
value2 = AnimationValue(
2.0,
2,
[
AnimationKeyframe("linear", 1, 2.0, 2),
AnimationKeyframe("linear", 2, 3.0, 3),
],
)
value1.update_with(value2)
assert value1.start == 2.0
assert value1.current_value == 2
assert len(value1.keyframes) == 2
assert value1.keyframes[0].delay == 1
assert value1.keyframes[0].duration == 2.0
assert value1.keyframes[0].value == 2

def test_update_with_none(self):
value1 = AnimationValue(1.0, 1, [AnimationKeyframe("linear", 0, 1.0, 1)])
value2 = None
value1.update_with(value2)
assert value1.start == 1.0
assert value1.current_value == 1
assert len(value1.keyframes) == 1
assert value1.keyframes[0].delay == 0
assert value1.keyframes[0].duration == 1.0
assert value1.keyframes[0].value == 1

def test_update_with_partials(self):
value1 = AnimationValue(1.0, 1, [AnimationKeyframe("linear", 0, 1.0, 1)])
value2 = AnimationValue(
None,
2,
[
AnimationKeyframe("linear", 1, 2.0, 2),
AnimationKeyframe("linear", 2, 3.0, 3),
],
)
value1.update_with(value2)
assert value1.start == 1.0
assert value1.current_value == 2
assert len(value1.keyframes) == 2
assert value1.keyframes[0].delay == 1
assert value1.keyframes[0].duration == 2.0
assert value1.keyframes[0].value == 2

value1 = AnimationValue(1.0, 1, [AnimationKeyframe("linear", 0, 1.0, 1)])
value2 = AnimationValue(
2.0,
None,
[
AnimationKeyframe("linear", 1, 2.0, 2),
AnimationKeyframe("linear", 2, 3.0, 3),
],
)
value1.update_with(value2)
assert value1.start == 2.0
assert value1.current_value == 1
assert len(value1.keyframes) == 2
assert value1.keyframes[0].delay == 1
assert value1.keyframes[0].duration == 2.0
assert value1.keyframes[0].value == 2

value1 = AnimationValue(1.0, 1, [AnimationKeyframe("linear", 0, 1.0, 1)])
value2 = AnimationValue(2.0, 2, None)
value1.update_with(value2)
assert value1.start == 2.0
assert value1.current_value == 2
assert len(value1.keyframes) == 1
assert value1.keyframes[0].delay == 0
assert value1.keyframes[0].duration == 1.0
assert value1.keyframes[0].value == 1
18 changes: 18 additions & 0 deletions tests/data/test_boolean_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,21 @@ def test_str(self):

def test_not_eq(self):
assert BooleanValue(True, True) != 10

def test_update_with_true(self):
value1 = BooleanValue(False, False)
value2 = BooleanValue(True, False)
value1.update_with(value2)
assert value1.value

def test_update_with_false(self):
value1 = BooleanValue(True, False)
value2 = BooleanValue(False, False)
value1.update_with(value2)
assert not value1.value

def test_update_with_none(self):
value1 = BooleanValue(True, False)
value2 = BooleanValue(None, False)
value1.update_with(value2)
assert value1.value
33 changes: 33 additions & 0 deletions tests/device/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,36 @@ def test_update_with_exception(self, device_mode):
)
with pytest.raises(UpdateException):
light.update_with(update)

def test_update_with_partials(self, device_mode):
value1 = NumericValue(1, 0, 10, False)
value2 = NumericValue(2, 0, 10, False)
value3 = NumericValue(3, 0, 10, False)
value4 = NumericValue(None, 10, None, False)
value5 = NumericValue(20, None, None, False)
value6 = NumericValue(None, None, 100, False)
light = Light(
"id",
"name",
DeviceType.BASIC_LIGHT,
device_mode,
list(Action),
value1,
value2,
value3,
)
update = Light(
"id",
"name1",
DeviceType.BASIC_LIGHT,
device_mode,
list(Action),
value4,
value5,
value6,
)
light.update_with(update)
assert light.name == "name1"
assert light.target_brightness == NumericValue(1, 10, 10, False)
assert light.actual_brightness == NumericValue(20, 0, 10, False)
assert light.dim_duration == NumericValue(3, 0, 100, False)
38 changes: 38 additions & 0 deletions tests/device/test_shutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,41 @@ def test_update_with_exception(self, device_mode):
)
with pytest.raises(UpdateException):
shutter.update_with(update)

def test_update_with_partials(self, device_mode):
value1 = NumericValue(1, 0, 10, False)
value2 = NumericValue(2, 0, 10, False)
value3 = NumericValue(3, 0, 10, False)
value4 = NumericValue(4, 0, 10, False)
value5 = NumericValue(10, None, None, False)
value6 = NumericValue(None, 10, None, False)
value7 = NumericValue(None, None, 100, False)
value8 = NumericValue(None, None, None, False)
shutter = Shutter(
"id",
"name",
DeviceType.AWNING,
device_mode,
list(Action),
value1,
value2,
value3,
value4,
)
update = Shutter(
"id",
"name1",
DeviceType.AWNING,
device_mode,
list(Action),
value5,
value6,
value7,
value8,
)
shutter.update_with(update)
assert shutter.name == "name1"
assert shutter.target_position == NumericValue(10, 0, 10, False)
assert shutter.target_angle == NumericValue(2, 10, 10, False)
assert shutter.actual_angle == NumericValue(3, 0, 100, False)
assert shutter.actual_position == NumericValue(4, 0, 10, False)
48 changes: 48 additions & 0 deletions tests/device/test_weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,51 @@ def test_update_with_exception(self, device_mode):
)
with pytest.raises(UpdateException):
weather.update_with(update)

def test_update_with_partials(self, device_mode):
value1 = NumericValue(1, 0, 10, False)
value2 = NumericValue(2, 0, 10, False)
value3 = NumericValue(3, 0, 10, False)
value4 = NumericValue(4, 0, 10, False)
value5 = NumericValue(5, 0, 10, False)
value6 = NumericValue(6, 0, 10, False)
value7 = NumericValue(10, None, None, False)
value8 = NumericValue(None, 10, None, False)
value9 = NumericValue(None, None, 100, False)
value10 = NumericValue(40, None, None, False)
value11 = NumericValue(None, 10, None, False)
value12 = NumericValue(None, None, 100, False)
weather = Weather(
"id",
"name",
DeviceType.WEATHER,
device_mode,
list(Action),
value1,
value2,
value3,
value4,
value5,
value6,
)
update = Weather(
"id",
"name1",
DeviceType.WEATHER,
device_mode,
list(Action),
value7,
value8,
value9,
value10,
value11,
value12,
)
weather.update_with(update)
assert weather.name == "name1"
assert weather.wind_peak == NumericValue(10, 0, 10, False)
assert weather.sun_brightness_peak == NumericValue(2, 10, 10, False)
assert weather.sun_brightness_sink == NumericValue(3, 0, 100, False)
assert weather.air_pressure == NumericValue(40, 0, 10, False)
assert weather.humidity == NumericValue(5, 10, 10, False)
assert weather.temperature == NumericValue(6, 0, 100, False)

0 comments on commit e560027

Please sign in to comment.