xaviml / controllerx

Create controller-based automations with ease to control your home devices and scenes.
https://xaviml.github.io/controllerx/
MIT License
335 stars 70 forks source link

[NEW DEVICE] #38

Closed mendevi closed 4 years ago

mendevi commented 4 years ago

New Device Support

Device Information

Integrations

If possible, provide the event mappings for the different actions that can be performed on the controller. Specify the integration.

If you can provide mappings for multiple integrations, copy the section below as many times as needed.

Integration: https://github.com/upsert/lutron-caseta-pro

Actions

 Button | Sensor Value
      No buttons pressed = 0 | **ON** (top button) = 1 | **FAVORITE** (middle round) = 2 | **OFF** (bottom) = 4 | **RAISE** (up arrow) = 8 | **LOWER** (down arrow) = 16

Notes

With the above integration the remote becomes a 'sensor' for home assistant. I tried to edit your py file to work with the Pico Remotes but I'm not a skilled python programmer and could not get it to work. If you could do this that would be great, or if you could tell me how I could update my version of the app. Thank you for the time and the app is great.

sreknob commented 4 years ago

Funny, I was thinking of looking into this last night but ran out or time. I use them extensively and my nodeRED flows can get out of control with them!

Xavi - important to note that the sensor remains with the ON value as long as the button is pressed with no release command. In NodeRED I reevaluate the sensor every 250ms in a loop to activate dimming steps. The pain is that when I want to reassign a remote I need to edit the template to evaluate the current brightness if the desired bulb/group as well. Also, there is an ON/OFF only remote (2-button) in addition to the 5 button one. I will check but I think the ON/OFF values are the same so wouldn’t necessarily need a separate controller integration - could just be CasetaProPico

sreknob commented 4 years ago

This is my NodeRED flow

image

Just double checked, indeed, ON and OFF are same between the picos, regardless of the type (light/shade/on-off) so only one needed for the remote.

sreknob commented 4 years ago

These remotes are used for lights, covers and audio - same remote but different labels on the buttons. They can be used natively with SONOS so the media player integration should mimic that: top button = 1 = play_pause up button = 8 = volume_up middle round = 2 = next source/sonos favourite down arrow = 16 = volume_down bottom = 4 = next track

mendevi commented 4 years ago

Agreed, the flows do get out of control with them. That's what made me look into Appdaemon and stumbled across Controllerx. Plus I wanted to learn some python. But they are great little remotes and thanks to HA (especially @upsert ) can control anything in my home.

@sreknob Would you mind sharing the template you made for the Brighten/Dim control?

tube0013 commented 4 years ago

I discussed the pico's on the forums a bit, I haven't gotten back around to testing the last suggested changes:

https://community.home-assistant.io/t/controllerx-bring-full-functionality-to-light-and-media-player-controllers/148855/166

I was toying with an HA automation that if a pico button is pushed so sensor a specific value past 1 second, it would trigger a rest command that would be like a hold action fro the xcontroller

sreknob commented 4 years ago

Yes indeed Xavi, I was going to just use z2m but that wouldn't solve the hold problem for the buttons. Looked at your post and I had forgotten that the state returns to "0" once the button is release and can use that as a release command. Would using the "hold_brightness_up" give a suitable effect if you set a minimum step with hold? Either that or use a loop to check if the sensor state is unchanged and fire another step like I do in NodeRED?

I'm going to give it a go when I'm home tonight.

@mendevi - this is my NodeRED flow. The template to evaluate the current brightness of the group/light is the magic sauce that makes it work.

This is the template

brighten --> {{ [10, state_attr('light.ikea_night_light', 'brightness')|int(0) + 26]|max|int }} dim --> {{ [10, state_attr('light.ikea_night_light', 'brightness')|int(0) - 26]|max|int }}

change the 26 to more or less to change the number of steps

And my whole flow (click to expand) ```json [ { "id": "9ce48951.f648a8", "type": "server-state-changed", "z": "cf4e273e.d72598", "name": "Pico ON", "server": "b3217b27.630be8", "version": 1, "entityidfilter": "sensor.master_bedroom_pico", "entityidfiltertype": "exact", "outputinitially": false, "state_type": "str", "haltifstate": "1", "halt_if_type": "str", "halt_if_compare": "is", "outputs": 2, "output_only_on_state_change": true, "x": 140, "y": 100, "wires": [ [ "f6e76419.ba49b8" ], [] ] }, { "id": "b9f6cd2f.5618", "type": "server-state-changed", "z": "cf4e273e.d72598", "name": "Pico UP", "server": "b3217b27.630be8", "version": 1, "entityidfilter": "sensor.master_bedroom_pico", "entityidfiltertype": "exact", "outputinitially": false, "state_type": "str", "haltifstate": "8", "halt_if_type": "str", "halt_if_compare": "is", "outputs": 2, "output_only_on_state_change": false, "x": 140, "y": 140, "wires": [ [ "43e40cfb.92b664" ], [] ] }, { "id": "e4f2a2d5.abd0d", "type": "server-state-changed", "z": "cf4e273e.d72598", "name": "MIDDLE", "server": "b3217b27.630be8", "version": 1, "entityidfilter": "sensor.master_bedroom_pico", "entityidfiltertype": "exact", "outputinitially": false, "state_type": "str", "haltifstate": "2", "halt_if_type": "str", "halt_if_compare": "is", "outputs": 2, "output_only_on_state_change": true, "x": 140, "y": 180, "wires": [ [ "29083b07.59cda4" ], [] ] }, { "id": "894a63a9.12fb7", "type": "server-state-changed", "z": "cf4e273e.d72598", "name": "Pico DOWN", "server": "b3217b27.630be8", "version": 1, "entityidfilter": "sensor.master_bedroom_pico", "entityidfiltertype": "exact", "outputinitially": false, "state_type": "str", "haltifstate": "16", "halt_if_type": "str", "halt_if_compare": "is", "outputs": 2, "output_only_on_state_change": false, "x": 150, "y": 220, "wires": [ [ "1095e7f0.facfd8" ], [] ] }, { "id": "3fb877df.4d1068", "type": "server-state-changed", "z": "cf4e273e.d72598", "name": "Pico OFF", "server": "b3217b27.630be8", "version": 1, "entityidfilter": "sensor.master_bedroom_pico", "entityidfiltertype": "exact", "outputinitially": false, "state_type": "str", "haltifstate": "4", "halt_if_type": "str", "halt_if_compare": "is", "outputs": 2, "output_only_on_state_change": true, "x": 140, "y": 260, "wires": [ [ "3d849107.074ace" ], [] ] }, { "id": "f6e76419.ba49b8", "type": "api-call-service", "z": "cf4e273e.d72598", "name": "Ikea Night Light ON", "server": "b3217b27.630be8", "version": "1", "debugenabled": false, "service_domain": "light", "service": "turn_on", "entityId": "light.ikea_night_light", "data": "", "dataType": "json", "mergecontext": "", "output_location": "", "output_location_type": "none", "mustacheAltTags": false, "x": 530, "y": 100, "wires": [ [] ] }, { "id": "3d849107.074ace", "type": "api-call-service", "z": "cf4e273e.d72598", "name": "Ikea Night Light OFF", "server": "b3217b27.630be8", "version": "1", "debugenabled": false, "service_domain": "light", "service": "turn_off", "entityId": "light.ikea_night_light", "data": "", "dataType": "json", "mergecontext": "", "output_location": "", "output_location_type": "none", "mustacheAltTags": false, "x": 540, "y": 260, "wires": [ [] ] }, { "id": "753670eb.f2772", "type": "api-call-service", "z": "cf4e273e.d72598", "name": "Ikea Night Light UP", "server": "b3217b27.630be8", "version": "1", "debugenabled": false, "service_domain": "light", "service": "turn_on", "entityId": "light.ikea_night_light", "data": "{\"brightness\":\"{{payload}}\"}", "dataType": "json", "mergecontext": "", "output_location": "", "output_location_type": "none", "mustacheAltTags": false, "x": 530, "y": 140, "wires": [ [] ] }, { "id": "e93c39ae.4f8b78", "type": "api-call-service", "z": "cf4e273e.d72598", "name": "Ikea Night Light DOWN", "server": "b3217b27.630be8", "version": "1", "debugenabled": false, "service_domain": "light", "service": "turn_on", "entityId": "light.ikea_night_light", "data": "{\"brightness\":\"{{payload}}\"}", "dataType": "json", "mergecontext": "", "output_location": "", "output_location_type": "none", "mustacheAltTags": false, "x": 550, "y": 220, "wires": [ [] ] }, { "id": "29083b07.59cda4", "type": "api-call-service", "z": "cf4e273e.d72598", "name": "Ikea Night Light ON", "server": "b3217b27.630be8", "version": "1", "debugenabled": false, "service_domain": "light", "service": "turn_on", "entityId": "light.ikea_night_light", "data": "{\"brightness_pct\":\"20\"}", "dataType": "json", "mergecontext": "", "output_location": "", "output_location_type": "none", "mustacheAltTags": false, "x": 530, "y": 180, "wires": [ [] ] }, { "id": "43e40cfb.92b664", "type": "api-render-template", "z": "cf4e273e.d72598", "name": "Brighten", "server": "b3217b27.630be8", "template": "{{ [255, state_attr('light.ikea_night_light', 'brightness')|int(0) + 26]|min }}", "resultsLocation": "payload", "resultsLocationType": "msg", "templateLocation": "template", "templateLocationType": "msg", "x": 320, "y": 140, "wires": [ [ "753670eb.f2772", "6f7693a8.c8334c" ] ] }, { "id": "1095e7f0.facfd8", "type": "api-render-template", "z": "cf4e273e.d72598", "name": "Dim", "server": "b3217b27.630be8", "template": "{{ [10, state_attr('light.ikea_night_light', 'brightness')|int(0) - 26]|max|int }}", "resultsLocation": "payload", "resultsLocationType": "msg", "templateLocation": "template", "templateLocationType": "msg", "x": 310, "y": 220, "wires": [ [ "e93c39ae.4f8b78", "1c02f221.a2aa5e" ] ] }, { "id": "8144f2b.7be6a1", "type": "comment", "z": "cf4e273e.d72598", "name": "Master Bedroom Pico", "info": "", "x": 180, "y": 60, "wires": [] }, { "id": "159407fd.3ba328", "type": "api-current-state", "z": "cf4e273e.d72598", "name": "detect hold", "server": "b3217b27.630be8", "version": 1, "outputs": 2, "halt_if": "0", "halt_if_type": "str", "halt_if_compare": "is_not", "override_topic": false, "entity_id": "sensor.master_bedroom_pico", "state_type": "str", "state_location": "payload", "override_payload": "msg", "entity_location": "data", "override_data": "msg", "blockInputOverrides": false, "x": 670, "y": 40, "wires": [ [ "43e40cfb.92b664" ], [] ] }, { "id": "6f7693a8.c8334c", "type": "delay", "z": "cf4e273e.d72598", "name": "250ms delay", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "x": 510, "y": 40, "wires": [ [ "159407fd.3ba328" ] ] }, { "id": "669a2493.0e14cc", "type": "api-current-state", "z": "cf4e273e.d72598", "name": "detect hold", "server": "b3217b27.630be8", "version": 1, "outputs": 2, "halt_if": "0", "halt_if_type": "str", "halt_if_compare": "is_not", "override_topic": false, "entity_id": "sensor.master_bedroom_pico", "state_type": "str", "state_location": "payload", "override_payload": "msg", "entity_location": "data", "override_data": "msg", "blockInputOverrides": false, "x": 670, "y": 320, "wires": [ [ "1095e7f0.facfd8" ], [] ] }, { "id": "1c02f221.a2aa5e", "type": "delay", "z": "cf4e273e.d72598", "name": "250ms delay", "pauseType": "delay", "timeout": "250", "timeoutUnits": "milliseconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "x": 510, "y": 320, "wires": [ [ "669a2493.0e14cc" ] ] }, { "id": "b3217b27.630be8", "type": "server", "z": "", "name": "Home Assistant", "legacy": false, "hassio": false, "rejectUnauthorizedCerts": true, "ha_boolean": "y|yes|true|on|home|open", "connectionDelay": true } ] ```
mendevi commented 4 years ago

@sreknob Thank you for sharing the template. And I look forward to seeing if what you stated above works out.

sreknob commented 4 years ago

@xaviml @mendevi @tube0013 - great news! It works near flawlessly with the following configuration using z2m integration. Confirms that it can be integrated easily with z2m type.

PicoTestRemote:
  module: controllerx
  class: CustomLightController
  integration: z2m
  controller: sensor.kids_bedroom_pico
  light: light.ikea_test_bulb
  mapping:
    "1": on_full_brightness
    "8": hold_brightness_up
    "2": set_half_brightness
    "16": hold_brightness_down
    "4": "off"
    "0": release
  smooth_power_on: true

EDIT Added smooth_power_on: true to fix below.

The only, quite small issue is that pressing the up/down buttons with the light off does not turn the bulb on. I think we discussed this before Xavi and that's the intended behaviour of ControllerX -- however its still pretty close to native with Lutron so I'm not complaining. That part does work with my NodeRED flow. I wonder if this would be a reason to make a custom integration for lutron for this or not....

Which brings me to, @xaviml do we want to break it out into a new integration or just document that it needs to use z2m in the docs?

I'll work on a PR to include it, as well as the other (and only) Lutron zigbee remote.

sreknob commented 4 years ago

The only, quite small issue is that pressing the up/down buttons with the light off does not turn the bulb on. I think we discussed this before Xavi and that's the intended behaviour of ControllerX -- however its still pretty close to native with Lutron so I'm not complaining. That part does work with my NodeRED flow. I wonder if this would be a reason to make a custom integration for lutron for this or not....

Never mind... I just realized that this is fixed with smooth_power_on: true

mendevi commented 4 years ago

@sreknob This is great news, I will check it out as soon as you can get in merged in. Thanks for working on it.

xaviml commented 4 years ago

Hi guys,

Sorry for not having replying back before. I am glad that the configuration example that @sreknob showed, worked. I merged his PR and I created a beta released v2.3.0b7. You can check the documentation for the added devices in here. You can use this template for the Lutron Caset Pro Pico:

example_app:
  module: controllerx
  class: LutronCasetaProPicoLightController
  integration: state
  controller: sensor.<your sensor id>
  light: light.example_light

You can also try it with custom controller as @sreknob did. Take into account that the top button (state 1) is used now to turn the light on and not to turn it to full brightness as you submitted @sreknob.

I will close this issue and I will create the v2.3.0 once this works. Thanks to everyone :)

xaviml commented 4 years ago

As of now, the integration "state" and "z2m" do the same, since they both read from the state of an entity, however, I cannot assure that the z2m will remain like this (maybe I will change it to listen to the MQTT messages, who knows), but I can assure that state integration will always read from the state of an entity. Therefore, I recommend you to use state integration.

sreknob commented 4 years ago

This is great! I think that the state integration will custom controller is going to very powerful for doing all sorts of crazy custom things, should one want to venture there. Good idea to break it out from z2m in case things change there. FYI, I made the default top button "on_full_brightness" just because that's when they do when the remotes are paired directly to a castea in-wall switches. I think that "on" is probably a better behaviour though.

xaviml commented 4 years ago

I do not have a Lutron Caseta Pro Pico, so I cannot test it physically. Once I get the feedback from you guys I will be able to close this issue and release v2.3.0

sreknob commented 4 years ago

Hey Xavi - Working well in my setup! In regards to on_full_brightness vs on maybe other Lutron users can pipe in with their thoughts. It's not like it's hard to change the behaviour by using it as a custom controller anyway... Personally, I think this one is ready to ship!

xaviml commented 4 years ago

I will close this issue then and ship the release. Thanks @sreknob and everyone else for helping this project better :)

mendevi commented 4 years ago

@xaviml Sorry stuck in ops the last couple of days, but the beta is working great when I tested it out this morning. Thank you for the working on it.

@sreknob My whole house is covered with lutron switches and these pico remotes. From my experiences with the standard setup being on_full_brightness it works out better and gives the lights a more standard operation. With just 'on' being the action my wife and I always run into the lights being rimmed from the night before and have to then adjust the brightness accordingly (I know first world problems here lol). That's just our 2 cents though, maybe others appreciate the 'resume previous state' being the action.

xaviml commented 4 years ago

If you all prefer, I can change it back to on_full_brightness. Either way, it can be changed now with custom controllers with the template that @sreknob shared:

PicoTestRemote:
  module: controllerx
  class: CustomLightController
  integration: z2m
  controller: sensor.kids_bedroom_pico
  light: light.ikea_test_bulb
  mapping:
    "1": on_full_brightness
    "8": hold_brightness_up
    "2": set_half_brightness
    "16": hold_brightness_down
    "4": "off"
    "0": release
  smooth_power_on: true
sreknob commented 4 years ago

@mendevi Amen. Need to keep the WAF high.

@xaviml -- I know the ethos of the project is to keep the default behaviours of the controllers as close to the native behaviour as possible and currently both ways are slightly off default. ON goes to last state but this is different than the default behaviour. It does however, offer a nice transition. ON_FULL_BRIGHTNESS makes the top button button go on full, but we lose the transition so it doesn't fade on like is does with ON While writing this, I just remembered that if one uses the 2-button or 3-button remotes, the on command is the same. We would be left in a state where the light is dimmed with no way to brighten it from the controller. I had forgotten about this after I mapped things but that was part of the original decision to use ON_FULL_BRIGHTNESS. I think we should change it back for consistency sake so that 3 and 2 button remotes work as expected.

On an semi-related note, is there any way to achieve a transition with ON_FULL_BRIGHTNESS or add that as a configuration option?

xaviml commented 4 years ago

@sreknob Indeed, you are right. The default implementation should follow as close as possible the logic with the original hub/software. So I will change it back to ON_FULL_BRIGHTNESS for all the Lutron Light Controllers you integrated.

Does your integration take into account both 2-button and 3-button remotes? Since you only integrated LutronCasetaProPicoLightController which is for the controller with 5 buttons (the favourite one).

I will also add a new attribute transition that will take by default 300ms, but you will be able to change it from yaml. See #42

sreknob commented 4 years ago

@xaviml - AMAZING!

Yes, the integration works for all the Lutron Picos using the controller, that's why I only created it as one controller type.

2,3,4,5 buttons all produce the same sensor outputs, just which physical buttons are present differs. I will add this to the docs tonight when I have more time to clarify the state/button mappings for custom use.

sreknob commented 4 years ago

I accidentally lied. The 4-button has a different mapping. I will correct this is a PJ2-4B controller type.

xaviml commented 4 years ago

I reversed the changes, now it uses ON_FULL_BRIGHTNESS rather than just ON. Shipped in v2.3.1

mendevi commented 4 years ago

You two are killing it. The transition is something I didn't even know I liked until we bought a bunch of these switches, now I find myself custom programming it to all of my hue lights as well. @xaviml So we will be able to use transition: 1 sec or 1000ms for the time in the app.yaml?

xaviml commented 4 years ago

Yes, that is right @mendevi. With the following code you will be able to transition your light for 800ms:

example_app:
  module: controllerx
  class: LutronCasetaProPicoLightController
  integration: state
  controller: sensor.<your sensor id>
  light: light.example_light
  transititon: 800

Be default is 300, which gives a nice smooth (but quick) transition already. The attribute is on ms, so if you want 2s, it should be 2000.

mendevi commented 4 years ago

Just tried the 2.3.1v and my states reverted with the on (top '1') mapping instead of on_full_brightness I simply copied your example_app above and input my info. Everything else works as expected. Thank you

xaviml commented 4 years ago

Hi @mendevi,

So you mean that when pressing the top button, it turns on the light the the previous light state instead of full brightness?

mendevi commented 4 years ago

Yes, just double checked.

xaviml commented 4 years ago

I believe there is a bug on HACS that does not download the apps properly. Could you try the following?

Let me know if this fixed your issue.

mendevi commented 4 years ago

@xaviml That solved it. Thanks for letting me know about the bug.

mendevi commented 4 years ago

I've reinstalled, and with the update, you seem to loose the "up-arrow" being able to turn the light on. I've gone back and installed the beta and it works again. Then going back to 2.3.1 I lose it.

Sorry if I'm the only one experiencing it. If I use the custom controller I also get that functionality.

Everything else is perfect and identical to the original hub/Lutron experience.

sreknob commented 4 years ago

@mendevi do you still have smooth_power_on: true as part of your controller config?