gurumitts / pylutron-caseta

Apache License 2.0
153 stars 98 forks source link

Adding support for setting Ketra bulb color. #153

Closed eclair4151 closed 7 months ago

eclair4151 commented 9 months ago

Hello, I have a QSX Processor with some Ketra bulbs. They work great just changing the level, but I'd love to add support for being able to change the color on them as well. Ideally, which can then be integrated into Home Assistant for full color support.

I already have the leap commands needed in order to set the color of the Ketra bulbs.

I see code here to handle the ketra lamp, https://github.com/gurumitts/pylutron-caseta/blob/0c327110670fa61b5adba0aa9484007403ae77b7/pylutron_caseta/smartbridge.py#L312

Do you have any suggestions how I should implement this? I was thinking of just adding an optional parameter to the set value method which could then take in a color. Thoughts? or I could make a new method all together which supports taking in a color and value.

cbw commented 9 months ago

Hi @eclair4151, I have't looked at this code in a while – I have Ketra bulbs as well and this was on my eventual to-do list. Won't have time to dig in for a couple weeks, but if you need someone to help test, happy to help!

eclair4151 commented 9 months ago

No problem! I have Ketra bulbs as well to test. I was planning on writing the code and raising a PR myself, just curious if you recommend I add an optional parameter to the current set value method for color or just define a new method all together :)

cbw commented 9 months ago

At first glance, I think an optional parameter is probably the most straightforward/logical way to approach it. Since they can either do full color or a specified color temperature, would be great to accommodate either.

Do the LEAP commands you've found also include being able to change it back from a specific color/color temp to warm dim mode?

eclair4151 commented 9 months ago

Yes I have the leap for setting the full color spectrum, setting the color via kelvin (along the warm/Cool spectrum), setting the vibrancy, and enabling/disabling warm dim.

My thought was you would pass a 'ColorValue' which would be a protocol with 1 method (get_spectrum_tuning_level_parameterss) which returns the command dictionary for any of the options.

FullColorValue which constructor takes in 3 ints 0-255 (R,G,B) WarmCoolColorValue which constructor takes in a kelvin value (1400 - 7000) WarmDimColorValue takes in a bool, enabled or not VibrancyColorValue takes in an int 0-100

So the user of this function creates which ever color property value object they want, and pass it into the set value method, which then uses the getCommand method to get the proper leap command.

Here are the leap comands for the following:

FULL COLOR

(Takes in an HS(V) (no value actually passed in). so can easily be converted https://www.rapidtables.com/convert/color/rgb-to-hsv.html

Request: {"Body":{"Command":{"CommandType":"GoToSpectrumTuningLevel","SpectrumTuningLevelParameters":{"ColorTuningStatus":{"HSVTuningLevel":{"Hue":120.356125,"Saturation":60.867912}}}}},"CommuniqueType":"CreateRequest","Header":{"ClientTag":"XXXXXXX","Url":"/zone/2138/commandprocessor"}}

Response: {"CommuniqueType":"CreateResponse","Header":{"MessageBodyType":"OneZoneStatus","StatusCode":"201 Created","Url":"\/zone\/2138\/commandprocessor","ClientTag":"XXXXXX"},"Body":{"ZoneStatus":{"href":"\/zone\/2138\/status","ColorTuningStatus":{"XYTuningLevel":{"X":0.2387,"Y":0.6331},"HSVTuningLevel":{"Hue":120,"Saturation":61}},"Zone":{"href":"\/zone\/2138"},"StatusAccuracy":"Good","Availability":"Available"}}}

Warm/Cool Kelvin

Request: {"Body":{"Command":{"CommandType":"GoToSpectrumTuningLevel","SpectrumTuningLevelParameters":{"ColorTuningStatus":{"WhiteTuningLevel":{"Kelvin":3600}}}}},"CommuniqueType":"CreateRequest","Header":{"ClientTag":"XXXXXX","Url":"/zone/2138/commandprocessor"}}

Response: {"CommuniqueType":"CreateResponse","Header":{"MessageBodyType":"OneZoneStatus","StatusCode":"201 Created","Url":"\/zone\/2138\/commandprocessor","ClientTag":"XXXX"},"Body":{"ZoneStatus":{"href":"\/zone\/2138\/status","ColorTuningStatus":{"WhiteTuningLevel":{"Kelvin":3600}},"Zone":{"href":"\/zone\/2138"},"StatusAccuracy":"Good","Availability":"Available"}}}

Enabled Warm Dim

Request: {"Body":{"Command":{"CommandType":"GoToSpectrumTuningLevel","SpectrumTuningLevelParameters":{"ColorTuningStatus":{"CurveDimming":{"Curve":{"href":"/curve/1"}}}}}},"CommuniqueType":"CreateRequest","Header":{"ClientTag":"XXXX","Url":"/zone/2138/commandprocessor"}}

Response: {"CommuniqueType":"CreateResponse","Header":{"MessageBodyType":"OneZoneStatus","StatusCode":"201 Created","Url":"\/zone\/2138\/commandprocessor","ClientTag":"XXXXX"},"Body":{"ZoneStatus":{"href":"\/zone\/2138\/status","ColorTuningStatus":{"CurveDimming":{"Curve":{"href":"\/curve\/1"}}},"Zone":{"href":"\/zone\/2138"},"StatusAccuracy":"Good","Availability":"Available"}}}

Disable Warm/Dim

Request: {"Body":{"Command":{"CommandType":"GoToSpectrumTuningLevel","SpectrumTuningLevelParameters":{"ColorTuningStatus":{"CurveDimming":null}}}},"CommuniqueType":"CreateRequest","Header":{"ClientTag":"XXXXXX","Url":"/zone/2138/commandprocessor"}}

Response: {"CommuniqueType":"CreateResponse","Header":{"MessageBodyType":"OneZoneStatus","StatusCode":"201 Created","Url":"\/zone\/2138\/commandprocessor","ClientTag":"XXXX"},"Body":{"ZoneStatus":{"href":"\/zone\/2138\/status","ColorTuningStatus":{"XYTuningLevel":{"X":0.4743,"Y":0.4134},"HSVTuningLevel":{"Hue":39,"Saturation":53}},"Zone":{"href":"\/zone\/2138"},"StatusAccuracy":"Good","Availability":"Available"}}}

Adjust Vibrancy

Request: {"Body":{"Command":{"CommandType":"GoToSpectrumTuningLevel","SpectrumTuningLevelParameters":{"Vibrancy":51}}},"CommuniqueType":"CreateRequest","Header":{"ClientTag":"d1699795-a5fe-4ff7-a0ef-3a7a88740790$","Url":"/zone/2138/commandprocessor"}}

Response: {"CommuniqueType":"CreateResponse","Header":{"MessageBodyType":"OneZoneStatus","StatusCode":"201 Created","Url":"\/zone\/2138\/commandprocessor","ClientTag":"XXXXXX"},"Body":{"ZoneStatus":{"href":"\/zone\/2138\/status","Vibrancy":51,"Zone":{"href":"\/zone\/2138"},"StatusAccuracy":"Good","Availability":"Available"}}}

eclair4151 commented 9 months ago

Heres my initial take at what it would look like. Tested and works great for my bulbs. Still need to finish the tests and handle the responses, but let me know if you think is a good direction. One thing you'll notice is, I marked the value as optional as well because you can set the color of the Ketra bulb without adjusting the value.

https://github.com/gurumitts/pylutron-caseta/compare/dev...eclair4151:pylutron-caseta:dev

ketra_device_id = "XYZ"

color_value = WarmCoolColorValue(2700)
# color_value = FullColorValue(RGBColorParameter(r=0, g=250, b=10))
# color_value = FullColorValue(HueSaturationColorParameter(hue=50, saturation=20))
# color_value = WarmDimmingColorValue(True)
# color_value = VibrancyColorValue(50)

await bridge.set_value(ketra_device_id,  color_value=color_value)
# or with value in the same command
await bridge.set_value(ketra_device_id,  value=50, color_value=color_value)
eclair4151 commented 9 months ago

Just raised a PR for this. take a look whenever you get a chance and let me know if you have any feedback

154

eclair4151 commented 9 months ago

Still got a bunch of work to do to make it production ready but already have a POC of this working with Home Assistant as well.

https://photos.app.goo.gl/VAziwYKXhbo8fo4z7

eclair4151 commented 8 months ago

Corresponding Home Assistant feature branch that pairs to this PR #154

https://github.com/eclair4151/home-assistant-core/tree/ketra_lumaris_color_support

Once you checkout that branch, youll need to manually install the new version of pylutron-caseta as well. Open a terminal in your Home Assistant Core, or the terminal tab in vscode docker, and run

pip uninstall pylutron-caseta
pip install git+https://github.com/eclair4151/pylutron-caseta.git@dev

eclair4151 commented 8 months ago

@cbw Any initial thoughts :) would love some feedback just to make sure it looks like I'm going in the right direction. The PR is pretty much done besides some tests I need to update, but haven't been able to get in contact with the repo maintainers to get some feedback. I know you guys are all super busy, so I don't want to be pushy at all! Just excited to get this new functionality into home assistant so I can start using it with my automations 😁.

mdonoughe commented 7 months ago

Fixed in #154

mdonoughe commented 7 months ago

https://pypi.org/project/pylutron-caseta/0.19.0/

eclair4151 commented 7 months ago

Awesome, thanks again for the help! I'll get the Home Assistant PR raised, and hopefully we can all start using the new feature soon 😁