Skip to content

Commit fc26e86

Browse files
zerzhangbdraco
andauthored
Return the snake_case style for led effects (#362)
Co-authored-by: J. Nick Koston <[email protected]>
1 parent 1b14eb3 commit fc26e86

File tree

5 files changed

+95
-29
lines changed

5 files changed

+95
-29
lines changed

switchbot/devices/base_light.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def max_temp(self) -> int:
6565
@property
6666
def get_effect_list(self) -> list[str] | None:
6767
"""Return the list of supported effects."""
68-
return list(self._effect_dict.keys()) if self._effect_dict else None
68+
return list(self._effect_dict) if self._effect_dict else None
6969

7070
def is_on(self) -> bool | None:
7171
"""Return bulb state from cache."""
@@ -111,7 +111,7 @@ async def set_rgb(self, brightness: int, r: int, g: int, b: int) -> bool:
111111
@update_after_operation
112112
async def set_effect(self, effect: str) -> bool:
113113
"""Set effect."""
114-
effect_template = self._effect_dict.get(effect)
114+
effect_template = self._effect_dict.get(effect.lower())
115115
if not effect_template:
116116
raise SwitchbotOperationError(f"Effect {effect} not supported")
117117
result = await self._send_multiple_commands(effect_template)

switchbot/devices/bulb.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ class SwitchbotBulb(SwitchbotSequenceBaseLight):
2525
_set_brightness_command = f"{COLOR_BULB_CONTROL_HEADER}14{{}}"
2626
_get_basic_info_command = ["570003", "570f4801"]
2727
_effect_dict = {
28-
"Colorful": ["570F4701010300"],
29-
"Flickering": ["570F4701010301"],
30-
"Breathing": ["570F4701010302"],
28+
"colorful": ["570F4701010300"],
29+
"flickering": ["570F4701010301"],
30+
"breathing": ["570F4701010302"],
3131
}
3232

3333
@property

switchbot/devices/light_strip.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,78 +20,78 @@
2020
}
2121
LIGHT_STRIP_CONTROL_HEADER = "570F4901"
2222
COMMON_EFFECTS = {
23-
"Christmas": [
23+
"christmas": [
2424
"570F49070200033C01",
2525
"570F490701000600009902006D0EFF0021",
2626
"570F490701000603009902006D0EFF0021",
2727
],
28-
"Halloween": ["570F49070200053C04", "570F490701000300FF6A009E00ED00EA0F"],
29-
"Sunset": [
28+
"halloween": ["570F49070200053C04", "570F490701000300FF6A009E00ED00EA0F"],
29+
"sunset": [
3030
"570F49070200033C3C",
3131
"570F490701000900FF9000ED8C04DD5800",
3232
"570F490701000903FF2E008E0B004F0500",
3333
"570F4907010009063F0010270056140033",
3434
],
35-
"Vitality": [
35+
"vitality": [
3636
"570F49070200053C02",
3737
"570F490701000600C5003FD9530AEC9800",
3838
"570F490701000603FFDF0000895500468B",
3939
],
40-
"Flashing": [
40+
"flashing": [
4141
"570F49070200053C02",
4242
"570F4907010006000000FF00FF00FF0000",
4343
"570F490701000603FFFF0000FFFFA020F0",
4444
],
45-
"Strobe": ["570F49070200043C02", "570F490701000300FF00E19D70FFFF0515"],
46-
"Fade": [
45+
"strobe": ["570F49070200043C02", "570F490701000300FF00E19D70FFFF0515"],
46+
"fade": [
4747
"570F49070200043C04",
4848
"570F490701000500FF5481FF00E19D70FF",
4949
"570F490701000503FF0515FF7FEB",
5050
],
51-
"Smooth": [
51+
"smooth": [
5252
"570F49070200033C02",
5353
"570F4907010007000036FC00F6FF00ED13",
5454
"570F490701000703F6FF00FF8300FF0800",
5555
"570F490701000706FF00E1",
5656
],
57-
"Forest": [
57+
"forest": [
5858
"570F49070200033C06",
5959
"570F490701000400006400228B223CB371",
6060
"570F49070100040390EE90",
6161
],
62-
"Ocean": [
62+
"ocean": [
6363
"570F49070200033C06",
6464
"570F4907010007004400FF0061FF007BFF",
6565
"570F490701000703009DFF00B2FF00CBFF",
6666
"570F49070100070600E9FF",
6767
],
68-
"Autumn": [
68+
"autumn": [
6969
"570F49070200043C05",
7070
"570F490701000700D10035922D13A16501",
7171
"570F490701000703AB9100DD8C00F4AA29",
7272
"570F490701000706E8D000",
7373
],
74-
"Cool": [
74+
"cool": [
7575
"570F49070200043C04",
7676
"570F490701000600001A63006C9A00468B",
7777
"570F490701000603009DA50089BE4378B6",
7878
],
79-
"Flow": [
79+
"flow": [
8080
"570F49070200033C02",
8181
"570F490701000600FF00D8E100FFAA00FF",
8282
"570F4907010006037F00FF5000FF1900FF",
8383
],
84-
"Relax": [
84+
"relax": [
8585
"570F49070200033C03",
8686
"570F490701000400FF8C00FF7200FF1D00",
8787
"570F490701000403FF5500",
8888
],
89-
"Modern": [
89+
"modern": [
9090
"570F49070200043C03",
9191
"570F49070100060089231A5F8969829E5A",
9292
"570F490701000603BCB05EEDBE5AFF9D60",
9393
],
94-
"Rose": [
94+
"rose": [
9595
"570F49070200043C04",
9696
"570F490701000500FF1969BC215F7C0225",
9797
"570F490701000503600C2B35040C",

tests/test_bulb.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ async def test_default_info():
7272
assert device.brightness == 1
7373
assert device.min_temp == 2700
7474
assert device.max_temp == 6500
75-
assert device.get_effect_list == list(device._effect_dict.keys())
75+
assert device.get_effect_list == ["colorful", "flickering", "breathing"]
7676

7777

7878
@pytest.mark.asyncio
@@ -217,8 +217,35 @@ async def test_set_effect_with_valid_effect():
217217
"""Test setting a valid effect."""
218218
device = create_device_for_command_testing()
219219

220-
await device.set_effect("Colorful")
220+
await device.set_effect("colorful")
221221

222-
device._send_command.assert_called_with(device._effect_dict["Colorful"][0])
222+
device._send_command.assert_called_with(device._effect_dict["colorful"][0])
223223

224-
assert device.get_effect() == "Colorful"
224+
assert device.get_effect() == "colorful"
225+
226+
227+
def test_effect_list_contains_lowercase_names():
228+
"""Test that all effect names in get_effect_list are lowercase."""
229+
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
230+
device = bulb.SwitchbotBulb(ble_device)
231+
effect_list = device.get_effect_list
232+
233+
assert effect_list is not None, "Effect list should not be None"
234+
assert effect_list == ["colorful", "flickering", "breathing"]
235+
for effect_name in effect_list:
236+
assert effect_name.islower(), f"Effect name '{effect_name}' is not lowercase"
237+
238+
239+
@pytest.mark.asyncio
240+
async def test_set_effect_normalizes_case():
241+
"""Test that set_effect normalizes effect names to lowercase."""
242+
device = create_device_for_command_testing()
243+
244+
# Test various case combinations
245+
test_cases = ["COLORFUL", "Colorful", "CoLoRfUl", "colorful"]
246+
247+
for test_effect in test_cases:
248+
await device.set_effect(test_effect)
249+
# Should always work regardless of case
250+
device._send_command.assert_called()
251+
assert device.get_effect() == test_effect # Stored as provided

tests/test_strip_light.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,14 @@ async def test_default_info():
7777
assert device.brightness == 30
7878
assert device.min_temp == 2700
7979
assert device.max_temp == 6500
80-
assert device.get_effect_list == list(device._effect_dict.keys())
80+
# Check that effect list contains expected lowercase effect names
81+
effect_list = device.get_effect_list
82+
assert effect_list is not None
83+
assert all(effect.islower() for effect in effect_list)
84+
# Verify some known effects are present
85+
assert "christmas" in effect_list
86+
assert "halloween" in effect_list
87+
assert "sunset" in effect_list
8188

8289

8390
@pytest.mark.asyncio
@@ -223,11 +230,43 @@ async def test_set_effect_with_valid_effect():
223230
device = create_device_for_command_testing()
224231
device._send_multiple_commands = AsyncMock()
225232

226-
await device.set_effect("Christmas")
233+
await device.set_effect("christmas")
227234

228-
device._send_multiple_commands.assert_called_with(device._effect_dict["Christmas"])
235+
device._send_multiple_commands.assert_called_with(device._effect_dict["christmas"])
229236

230-
assert device.get_effect() == "Christmas"
237+
assert device.get_effect() == "christmas"
238+
239+
240+
def test_effect_list_contains_lowercase_names():
241+
"""Test that all effect names in get_effect_list are lowercase."""
242+
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
243+
device = light_strip.SwitchbotLightStrip(ble_device)
244+
effect_list = device.get_effect_list
245+
246+
assert effect_list is not None, "Effect list should not be None"
247+
# All effect names should be lowercase
248+
for effect_name in effect_list:
249+
assert effect_name.islower(), f"Effect name '{effect_name}' is not lowercase"
250+
# Verify some known effects are present
251+
assert "christmas" in effect_list
252+
assert "halloween" in effect_list
253+
assert "sunset" in effect_list
254+
255+
256+
@pytest.mark.asyncio
257+
async def test_set_effect_normalizes_case():
258+
"""Test that set_effect normalizes effect names to lowercase."""
259+
device = create_device_for_command_testing()
260+
device._send_multiple_commands = AsyncMock()
261+
262+
# Test various case combinations
263+
test_cases = ["CHRISTMAS", "Christmas", "ChRiStMaS", "christmas"]
264+
265+
for test_effect in test_cases:
266+
await device.set_effect(test_effect)
267+
# Should always work regardless of case
268+
device._send_multiple_commands.assert_called()
269+
assert device.get_effect() == test_effect # Stored as provided
231270

232271

233272
@pytest.mark.asyncio

0 commit comments

Comments
 (0)