Skip to content

Commit

Permalink
New feature lumaris rgb tunable white (#177)
Browse files Browse the repository at this point in the history
* add support for new light type to enable control of Lumaris RGB + White Tune

* Update version to 0.23.0

* combine spectrum and colortune

* Updates baed on review comments

* Update __init__.py

Update whitespace

* Add tests for new device type.
  • Loading branch information
RBaragona authored Jan 6, 2025
1 parent 2f46086 commit efde230
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/pylutron_caseta/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
"Dimmed",
"SpectrumTune", # Ketra lamps
"DivaSmartDimmer",
"WhiteTune", # Lumaris Tape Light
"WhiteTune", # Lumaris Tunable White Tape Light
"PowPak0-10V",
"ColorTune", # Lumaris RGB + Tunable White Tape Light
],
"switch": [
"WallSwitch",
Expand Down
6 changes: 4 additions & 2 deletions src/pylutron_caseta/smartbridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ async def set_warm_dim(
command = {}
if device.get("type") == "SpectrumTune":
command = color_value.get_spectrum_tuning_level_parameters()
elif device.get("type") == "ColorTune":
command = color_value.get_spectrum_tuning_level_parameters()
elif device.get("type") == "WhiteTune":
command = color_value.get_white_tuning_level_parameters()

Expand Down Expand Up @@ -404,8 +406,8 @@ async def set_value(
if not zone_id:
return

# Handle Ketra lamps
if device.get("type") == "SpectrumTune":
# Handle Ketra lamps and Lumaris RGB + Tunable White Tape Light
if device.get("type") in ["SpectrumTune", "ColorTune"]:
spectrum_params: Dict[str, Union[str, int]] = {}
if value is not None:
spectrum_params["Level"] = value
Expand Down
19 changes: 19 additions & 0 deletions tests/responses/hwqsx/area/804/associatedzone.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@
"Max": 5000
}
}
},
{
"href": "/zone/991",
"Name": "Lumaris Tape Strip RGB+TW",
"ControlType": "ColorTune",
"Category": {
"Type": "",
"IsLight": true
},
"AssociatedArea": {
"href": "/area/804"
},
"SortOrder": 2,
"ColorTuningProperties": {
"WhiteTuningLevelRange": {
"Min": 1800,
"Max": 5000
}
}
}
]
}
Expand Down
26 changes: 26 additions & 0 deletions tests/responses/hwqsx/device-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,32 @@
},
"AddressedState": "Unaddressed"
},
{
"Name": "Lumaris Tape Strip RGB+TW",
"DeviceType": "Lumaris",
"AssociatedArea": {
"href": "/area/804"
},
"href": "/device/991",
"Parent": {
"href": "/project"
},
"ModelNumber": "HWL-MTK-RT-IN",
"LocalZones": [
{
"href": "/zone/991"
}
],
"LinkNodes": [
{
"href": "/device/989/linknode/992"
}
],
"DeviceClass": {
"HexadecimalEncoding": "61a0101"
},
"AddressedState": "Unaddressed"
},
{
"Name": "Keypad 1",
"DeviceType": "PalladiomKeypad",
Expand Down
74 changes: 74 additions & 0 deletions tests/test_smartbridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2370,6 +2370,80 @@ async def test_qsx_set_ketra_level_with_fade(qsx_processor: Bridge):
await qsx_processor.target.close()


@pytest.mark.asyncio
async def test_qsx_set_LumarisRGB_color(qsx_processor: Bridge):
"""
Test that setting the color of a Lumaris RGB produces the
right command.
"""
hue = 150
saturation = 30
full_color = color_value.FullColorValue(hue, saturation)
task = asyncio.get_running_loop().create_task(
qsx_processor.target.set_value("991", color_value=full_color)
)
command, _ = await qsx_processor.leap.requests.get()
assert command == Request(
communique_type="CreateRequest",
url="/zone/991/commandprocessor",
body={
"Command": {
"CommandType": "GoToSpectrumTuningLevel",
"SpectrumTuningLevelParameters": {
"ColorTuningStatus": {
"HSVTuningLevel": {"Hue": hue, "Saturation": saturation}
}
},
}
},
)
qsx_processor.leap.requests.task_done()
task.cancel()

kelvin = 2700
warm_color = color_value.WarmCoolColorValue(kelvin)
task = asyncio.get_running_loop().create_task(
qsx_processor.target.set_value("991", color_value=warm_color)
)
command, _ = await qsx_processor.leap.requests.get()
assert command == Request(
communique_type="CreateRequest",
url="/zone/991/commandprocessor",
body={
"Command": {
"CommandType": "GoToSpectrumTuningLevel",
"SpectrumTuningLevelParameters": {
"ColorTuningStatus": {"WhiteTuningLevel": {"Kelvin": kelvin}}
},
}
},
)
qsx_processor.leap.requests.task_done()
task.cancel()

task = asyncio.get_running_loop().create_task(
qsx_processor.target.set_warm_dim("991", True)
)
command, _ = await qsx_processor.leap.requests.get()
assert command == Request(
communique_type="CreateRequest",
url="/zone/991/commandprocessor",
body={
"Command": {
"CommandType": "GoToSpectrumTuningLevel",
"SpectrumTuningLevelParameters": {
"ColorTuningStatus": {
"CurveDimming": {"Curve": {"href": "/curve/1"}}
}
},
}
},
)
qsx_processor.leap.requests.task_done()
task.cancel()
await qsx_processor.target.close()


@pytest.mark.asyncio
async def test_qsx_tap_button(qsx_processor: Bridge):
"""Test that tapping a keypad button produces the right command."""
Expand Down

0 comments on commit efde230

Please sign in to comment.