Skip to content

Commit dc96005

Browse files
committed
Make turn_on work if only brightness is used as well
1 parent 2b780ad commit dc96005

File tree

5 files changed

+62
-25
lines changed

5 files changed

+62
-25
lines changed

custom_components/dmx/entity/light/light_controller.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,21 @@ async def _apply_updates(self, updates: Dict[ChannelType, int]):
4444
def _collect_updates_from_kwargs(self, kwargs: Dict[str, Any]) -> Dict[ChannelType, int]:
4545
updates = {}
4646

47-
def set_if_applicable(cond, ct, val):
48-
if cond:
49-
updates[ct] = val
50-
51-
if "brightness" in kwargs and self.state.has_channel(ChannelType.DIMMER):
52-
set_if_applicable(True, ChannelType.DIMMER, kwargs["brightness"])
47+
if "brightness" in kwargs:
48+
brightness = kwargs["brightness"]
49+
updates.update(self.state.get_scaled_brightness_updates(brightness))
5350

5451
if "rgb_color" in kwargs and self.state.has_rgb():
5552
r, g, b = kwargs["rgb_color"]
5653
updates.update({ChannelType.RED: r, ChannelType.GREEN: g, ChannelType.BLUE: b})
5754

5855
if "rgbw_color" in kwargs:
5956
r, g, b, w = kwargs["rgbw_color"]
60-
updates.update({ChannelType.RED: r, ChannelType.GREEN: g, ChannelType.BLUE: b})
61-
set_if_applicable(self.state.has_channel(ChannelType.COLD_WHITE), ChannelType.COLD_WHITE, w)
57+
updates.update({ChannelType.RED: r, ChannelType.GREEN: g, ChannelType.BLUE: b, ChannelType.WARM_WHITE: w})
6258

6359
if "rgbww_color" in kwargs:
6460
r, g, b, cw, ww = kwargs["rgbww_color"]
65-
updates.update({ChannelType.RED: r, ChannelType.GREEN: g, ChannelType.BLUE: b})
66-
set_if_applicable(self.state.has_channel(ChannelType.COLD_WHITE), ChannelType.COLD_WHITE, cw)
67-
set_if_applicable(self.state.has_channel(ChannelType.WARM_WHITE), ChannelType.WARM_WHITE, ww)
61+
updates.update({ChannelType.RED: r, ChannelType.GREEN: g, ChannelType.BLUE: b,ChannelType.COLD_WHITE: cw, ChannelType.WARM_WHITE: ww})
6862

6963
if "color_temp_kelvin" in kwargs:
7064
kelvin = kwargs["color_temp_kelvin"]

custom_components/dmx/entity/light/light_state.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,42 @@ def _update_on_state_without_dimmer(self):
112112
else:
113113
self.is_on = self.brightness > 0
114114

115+
def get_scaled_brightness_updates(self, new_brightness: int) -> Dict[ChannelType, int]:
116+
updates: Dict[ChannelType, int] = {}
117+
118+
if self._has_dimmer():
119+
updates[ChannelType.DIMMER] = new_brightness
120+
return updates
121+
122+
if self.color_mode == ColorMode.COLOR_TEMP:
123+
cw, ww = self.converter.temp_to_cw_ww(self.color_temp_kelvin, new_brightness)
124+
updates[ChannelType.COLD_WHITE] = cw
125+
updates[ChannelType.WARM_WHITE] = ww
126+
return updates
127+
128+
channel_values = {}
129+
130+
if self.color_mode in [ColorMode.RGB, ColorMode.RGBW, ColorMode.RGBWW]:
131+
channel_values[ChannelType.RED] = self.rgb[0]
132+
channel_values[ChannelType.GREEN] = self.rgb[1]
133+
channel_values[ChannelType.BLUE] = self.rgb[2]
134+
135+
if self.color_mode == ColorMode.RGBW:
136+
channel_values[ChannelType.WARM_WHITE] = self.warm_white
137+
138+
if self.color_mode == ColorMode.RGBWW:
139+
channel_values[ChannelType.COLD_WHITE] = self.cold_white
140+
channel_values[ChannelType.WARM_WHITE] = self.warm_white
141+
142+
max_current = max(channel_values.values(), default=1)
143+
scale = new_brightness / max_current if max_current > 0 else 0
144+
145+
for channel, value in channel_values.items():
146+
scaled = round(value * scale)
147+
updates[channel] = min(255, scaled)
148+
149+
return updates
150+
115151
def get_dmx_updates(self, values: Dict[ChannelType, int]) -> Dict[int, int]:
116152
updates = {}
117153
for channel_type, val in values.items():

tests/test_color_temperature.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ def test_8bit_dimmer_color_temp_light_updates(self):
9090
self.assertEqual(100, dimmer.native_value)
9191
self.assertAlmostEqual((color_temp.max_value + color_temp.min_value) / 2, color_temp.native_value, None, "", 5)
9292

93+
asyncio.run(light.async_turn_on(brightness=128))
94+
assert_dmx_range(self.universe, 1, [128, 128])
95+
self.assertAlmostEqual(50.0, dimmer.native_value, 0)
96+
self.assertAlmostEqual((color_temp.max_value + color_temp.min_value) / 2, color_temp.native_value, None, "", 5)
97+
9398
asyncio.run(light.async_turn_on(brightness=255, color_temp_kelvin=light.max_color_temp_kelvin))
9499
assert_dmx_range(self.universe, 1, [255, 255])
95100
self.assertEqual(100, dimmer.native_value)

tests/test_cw_ww.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ def test_8bit_wc_light_updates(self):
8585
self.assertAlmostEqual(50.0, warm_white.native_value, 0)
8686
self.assertAlmostEqual(50.0, cold_white.native_value, 0)
8787

88+
asyncio.run(light.async_turn_on(brightness=64))
89+
assert_dmx_range(self.universe, 2, [64, 64])
90+
self.assertAlmostEqual(25.0, warm_white.native_value, 0)
91+
self.assertAlmostEqual(25.0, cold_white.native_value, 0)
92+
8893
asyncio.run(light.async_turn_on(brightness=255, color_temp_kelvin=light.max_color_temp_kelvin))
8994
assert_dmx_range(self.universe, 2, [0, 255])
9095
self.assertEqual(0, warm_white.native_value)

tests/test_rgbw.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,27 @@ def test_8bit_rgbw_light_updates(self):
8787
white: DmxNumberEntity = get_entity_by_name(entities, 'RGBW fader White')
8888
light: DmxLightEntity = get_entity_by_name(entities, 'RGBW fader Light')
8989

90-
# Test setting pure red
91-
asyncio.run(light.async_turn_on(rgbw_color=(255, 0, 0, 0)))
92-
assert_dmx_range(self.universe, 2, [255, 0, 0, 0])
90+
asyncio.run(light.async_turn_on(rgbw_color=(255, 128, 64, 0)))
91+
assert_dmx_range(self.universe, 2, [255, 128, 64, 0])
9392
self.assertEqual(100, red.native_value)
94-
self.assertEqual(0, green.native_value)
95-
self.assertEqual(0, blue.native_value)
93+
self.assertAlmostEqual(50.0, green.native_value, 0)
94+
self.assertAlmostEqual(25.0, blue.native_value, 0)
95+
self.assertEqual(0, white.native_value)
96+
97+
asyncio.run(light.async_turn_on(brightness=128))
98+
assert_dmx_range(self.universe, 2, [128, 64, 32, 0])
99+
self.assertAlmostEqual(50.0, red.native_value, 0)
100+
self.assertAlmostEqual(25.0, green.native_value, 0)
101+
self.assertAlmostEqual(12.5, blue.native_value, 0)
96102
self.assertEqual(0, white.native_value)
97103

98-
# Test setting mixed color
99104
asyncio.run(light.async_turn_on(rgbw_color=(127, 191, 63, 0)))
100105
assert_dmx_range(self.universe, 2, [127, 191, 63, 0])
101106
self.assertAlmostEqual(50.0, red.native_value, 0)
102107
self.assertAlmostEqual(75.0, green.native_value, 0)
103108
self.assertAlmostEqual(25.0, blue.native_value, 0)
104109
self.assertEqual(0, white.native_value)
105110

106-
# Test setting white
107-
asyncio.run(light.async_turn_on(rgbw_color=(255, 255, 255, 0)))
108-
# White light might be handled differently - adjust expectations based on implementation
109-
self.assertTrue(light.is_on)
110-
111111
def test_16bit_rgbw_number_updates(self):
112112
channels = self.fixture.select_mode('16bit')
113113
entities = delegator.create_entities('RGBW fader', 3, channels, None, self.universe)
@@ -118,7 +118,6 @@ def test_16bit_rgbw_number_updates(self):
118118
white: DmxNumberEntity = get_entity_by_name(entities, 'RGBW fader White')
119119
light: DmxLightEntity = get_entity_by_name(entities, 'RGBW fader Light')
120120

121-
# Test pure red (16-bit: high byte, low byte for each channel)
122121
asyncio.run(red.async_set_native_value(100))
123122
asyncio.run(green.async_set_native_value(0))
124123
asyncio.run(blue.async_set_native_value(0))
@@ -127,7 +126,6 @@ def test_16bit_rgbw_number_updates(self):
127126
self.assertEqual(255, light.brightness)
128127
self.assertEqual((255, 0, 0), light.rgb_color)
129128

130-
# Test mixed color
131129
asyncio.run(red.async_set_native_value(50))
132130
asyncio.run(green.async_set_native_value(75))
133131
asyncio.run(blue.async_set_native_value(25))
@@ -136,7 +134,6 @@ def test_16bit_rgbw_number_updates(self):
136134
self.assertEqual(191, light.brightness)
137135
self.assertEqual((127, 191, 64), light.rgb_color)
138136

139-
# Test RGBW combination
140137
asyncio.run(red.async_set_native_value(50))
141138
asyncio.run(green.async_set_native_value(50))
142139
asyncio.run(blue.async_set_native_value(50))

0 commit comments

Comments
 (0)