xaviml / controllerx

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

[QUESTION] PTM215X Multifunction Button #673

Closed SeanNazareth closed 1 year ago

SeanNazareth commented 1 year ago

Question

Hello,

I've used your plug in for AppDaemon successfully for a few months. However, I was just now getting around to trying to duplicate a functionality I had previously with the Hue app. I didn't succeed, so I figure I'd ask if you thought this feature was possible, and if so, any ideas on how.

I'm currently using a RunLessWire HUE switch (PTM215XController). This switch can either be configured as a standard decora switch (1 paddle), or converted to control 2 sets of lights (2 narrow paddles). When paired with the HUE app, this switch allows control of a single or double set of lights, where a single press of the top turns on the light, a single press of the bottom turns off the light, and a hold with either increase or decrease the brightness. I've now moved most of my Hue bulbs to Z2M.

The PTM215X is already supported by your plug-in. There are 4 buttons, and several different events. However, in the application I'm trying to achieve, I'd like to use a "pair" of the buttons (say 1 and 2, OR 3 and 4). Using the 1-2 pair as an example, I'd like a single tap of button 1 (press_1) to turn the light on, and a single tap of button 2 (press_2) to turn the light off. I can achieve this successfully. However, the next part I want is that a press-and-hold of button1 should do an "ramp" type increase of the brightness, while a press-and-hold of button2 should do a "ramp" type decrease of the brightness. Right now, I can take the "other" pair (say buttons3/4) and implement the brightness ramp. Unfortunately, this configuration implies that I can only control the on-off and brightness for a single set of lights. Also, when I use the additional pair, I see two behaviors. A press and release gives a step increment/decrement, and a hold gives the "gradual" ramp up/down. I'd like to sacrifice the step increment/decrement, and replace that with the on/off.

I tried to add a merge mapping with the action "click" and attribute "on", and the action: "hold" being the brightness, but it seemed to ignore the "on" and implement the step and ramp brightness.

Hopefully, the question is clear.

Thanks,

Sean

Additional information

AppDaemon app configuration

(optional) Insert your appdaemon app configuration here (apps.yaml content).
Insert only the configuration relative to the controllerx app you're asking the question for.

Logs

(optional) Add relevant AppDaemon / Home Assistant logs which could help answering the question.

Additional Context

Add any other context or screenshots about the question here.

xaviml commented 1 year ago

Hi @SeanNazareth ,

Thank you for your detailed explanation of your question. I see that this controller does not support hold actions for Zigbee2MQTT. This is because at the time this controller was added, those actions did not exist.

Could you please send the Zigbee2MQTT logs of this controller when buttons 1,2,3,4 are held? Also, does zigbee2MQTT provide a release event?

If there are hold and release action, I will update this controller as well as letting you know how the mapping can be used as you tried.

Regards, Xavi M.

SeanNazareth commented 1 year ago

Hi Xavi, I'd be happy to provide the logs.  Is there a description somewhere of how to collect them?  I can try and play around with it to see if I can figure it out, but if you have a pointer, that would be helpful. I'm not the expert that you are, but my understanding is that you only get press and release events.  Your current controller is able to detect and handle the difference between a "press" and a "hold".  However, what I think I observe, is that you have a "parameter" known as the "attribute".  In my case, I'm talking about "brightness".  Right now, the configuration can seem to handle press and hold as separate operations if they both apply to brightness.  So, I can do a "ramp" with a hold, and a brightness increment/decrement with a press.  In my case, I want the press to be on/off instead of brightness. I tried to use the merge_mapping so that the press (for buttons 1-2) would be on/off, and hold would be ramp brightness.  But when I tried it, the press became incremental/decremental brightness instead of on/off.  Maybe when I get home I can provide the merge-mapping that I tried and you can tell me if maybe I configured it wrong. Sean On Wednesday, January 25, 2023, 02:34:26 PM PST, Xavi Moreno @.***> wrote:

Hi @SeanNazareth ,

Thank you for your detailed explanation of your question. I see that this controller does not support hold actions for Zigbee2MQTT. This is because at the time this controller was added, those actions did not exist.

Could you please send the Zigbee2MQTT logs of this controller when buttons 1,2,3,4 are held? Also, does zigbee2MQTT provide a release event?

If there are hold and release action, I will update this controller as well as letting you know how the mapping can be used as you tried.

Regards, Xavi M.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

xaviml commented 1 year ago

Hi @SeanNazareth ,

Is there a description somewhere of how to collect them?

Assuming you are using the Zigbee2MQTT addon from HA, I recommend you opening the addon and going to the "log" tab. In there, if you hold the button and then release, you should be able to see the commands that are fired. You can also try just clicking. Once you have those logs, please send those to me. They will look like something like:

Zigbee2MQTT:info  2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller', payload '{"action":"on","battery":100,"linkquality":255,"update":{"installed_version":65572,"latest_version":581,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller', payload '{"action":"","battery":100,"linkquality":255,"update":{"installed_version":65572,"latest_version":581,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller/action', payload 'on'

ControllerX is able to manage presses and hold actions. However, the controllers (devices) need to have the capatibility to send those events. Otherwise, ControllerX will not know if there has been a hold action or not. This is an example of using this controller with z2m and a custom mapping:

example_app:
  module: controllerx
  class: PTM215XLightController
  integration: z2m
  controller: sensor.my_controller_action
  light: light.my_entity_id
  mapping:
    press_1: "on"  # This is already part of the default mapping
    press_2: "off"  # This is already part of the default mapping
    press_3: "on"
    press_4: "off"

When you have time, please provide logs and the configuration you have tried.

Regards, Xavi M.

SeanNazareth commented 1 year ago

Hi Xavi, Here's the log of trying 2 "press" events, and 1 hold event, all for button 3. Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"press_3","linkquality":127}'Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'press_3'Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"release_3","linkquality":127}'Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:42MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'release_3'Info 2023-01-25 19:21:43MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"press_3","linkquality":127}'Info 2023-01-25 19:21:43MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:43MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'press_3'Info 2023-01-25 19:21:44MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"release_3","linkquality":127}'Info 2023-01-25 19:21:44MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:44MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'release_3'Info 2023-01-25 19:21:45MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"press_3","linkquality":127}'Info 2023-01-25 19:21:45MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:45MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'press_3'Info 2023-01-25 19:21:49MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"release_3","linkquality":127}'Info 2023-01-25 19:21:49MQTT publish: topic 'zigbee2mqtt/OfficeSwitch', payload '{"action":"","linkquality":127}'Info 2023-01-25 19:21:49MQTT publish: topic 'zigbee2mqtt/OfficeSwitch/action', payload 'release_3'You can see about 4sec from press-to-release message for the Hold, while <1sec press to release message for a "press".  The 4sec came from me holding it for about that time. With regard to my mapping, here's an example... Sean

On Wednesday, January 25, 2023 at 02:50:06 PM PST, Xavi Moreno ***@***.***> wrote:  

Hi @SeanNazareth ,

Is there a description somewhere of how to collect them?

Assuming you are using the Zigbee2MQTT addon from HA, I recommend you opening the addon and going to the "log" tab. In there, if you hold the button and then release, you should be able to see the commands that are fired. You can also try just clicking. Once you have those logs, please send those to me. They will look like something like: Zigbee2MQTT:info 2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller', payload '{"action":"on","battery":100,"linkquality":255,"update":{"installed_version":65572,"latest_version":581,"state":"idle"},"update_available":false}' Zigbee2MQTT:info 2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller', payload '{"action":"","battery":100,"linkquality":255,"update":{"installed_version":65572,"latest_version":581,"state":"idle"},"update_available":false}' Zigbee2MQTT:info 2023-01-25 23:45:12: MQTT publish: topic 'zigbee2mqtt/office_controller/action', payload 'on'

ControllerX is able to manage presses and hold actions. However, the controllers (devices) need to have the capatibility to send those events. Otherwise, ControllerX will not know if there has been a hold action or not. This is an example of using this controller with z2m and a custom mapping: example_app: module: controllerx class: PTM215XLightController integration: z2m controller: sensor.my_controller_action light: light.my_entity_id mapping: press_1: "on" # This is already part of the default mapping press_2: "off" # This is already part of the default mapping press_3: "on" press_4: "off" When you have time, please provide logs and the configuration you have tried.

Regards, Xavi M.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

xaviml commented 1 year ago

Hi @SeanNazareth ,

There seems to be a limitation from the controller. You can see that even you are doing 3 actions (click, hold and release), there are only 2 events in the logs: press_3 and release_3. This means that the click and hold action fire the same event (press_X). Unfortunately, you cannot achieve what you want with this controller on Zigbee2MQTT. I can see that deCONZ integration supports the 3 actions (click, hold and release).

However, you still have options:

Multiple click is the only way to differentiate clicks and holds. I would recommend you going with a solution like the following:

example_app:
  module: controllerx
  class: PTM215XLightController
  integration: z2m
  controller: sensor.my_controller_action
  light: light.my_entity_id
  mapping:
    press_1$2: "on"
    press_1: hold_brightness_up
    release_1: release
    press_2$2: "off"
    press_2: hold_brightness_down
    release_2: release

This mapping will:

You can read more about multiple clicks here. Note that you can add the mutplie_click_delay (as shown in the link shared) to loosen the delay to recognize the multi clicks.

P.S.: I see you said: "With regard to my mapping, here's an example...", but then you copied the same message I left you, so I do not see your mapping example.

Regards, Xavi M.

SeanNazareth commented 1 year ago

Hi Xavi, Thank you for your continued support.  My apologies for the following long email.. I just wanted to make sure I communicate clearly. I'm sorry you didn't see my configuration example.  At the time I couldn't cut-and-paste the text, so I took a screenshot and inserted it into the email. I guess the image didn't show up.  I've now gotten an SSH session so can give you the configuration now.

This configuration only gives ramp dim/bright, and incremental dim/bright.  On/off functionality doesn't work, but you can "ramp" with a hold from OFF to some brightness.  Ramp down doesn't turn light all the way off.  Light brightness goes to 1 which is still visible light.

office_dimmer:                                                                    module: controllerx                                                            

class: RunlesswireClickLightController                                        

class: PTM215XLightController                                                   controller: sensor.officeswitch_action                                          integration: z2m                                                                light: light.office_lights                                                      merge_mapping:                                                                    press_1:                                                                            action: click                                                                   attribute: on                                                               press_1:                                                                            action: hold                                                                    attribute: brightness                                                           direction: up                                                                   mode: stop                                                                      steps: 10                                                                   press_2:                                                                            action: click                                                                   attribute: off                                                              press_2:                                                                            action: hold                                                                    attribute: brightness                                                           direction: down                                                                 mode: stop                                                                      steps: 10                   

This configuration works in principle, but needs both switches... and this doesn't work for me (I need the other switch for a different set of lights)

office_dimmer:                                                                    module: controllerx                                                            

class: RunlesswireClickLightController                                        

class: PTM215XLightController                                                   controller: sensor.officeswitch_action                                          integration: z2m                                                                light: light.office_lights                                                      merge_mapping:   press_1:                                                                            action: click                                                                   attribute: on                                                               press_3:                                                                            action: hold                                                                    attribute: brightness                                                           direction: up                                                                   mode: stop                                                                      steps: 10                                                                   press_2:                                                                            action: click                                                                   attribute: off                                                              press_4:                                                                            action: hold                                                                    attribute: brightness                                                           direction: down                                                                 mode: stop                                                                      steps: 10                        Questions:

  1. I don't quite understand why you say what I want isn't doable.  Your controller detects the "hold" condition, and specify a hold attribute as separate from the "press".  Is there some requirement that both the "press" and "hold" operations use the same "attribute?  I do understand that the z2m integration only provides press and release events, but somehow, you must detect a "lack" of release over a specific interval to be a "hold" in this case.  Specifically, if one paddle is brightness attribute, you currently can simulate a "press" as an incremental bright/dim, and a "hold" as a ramp bright/dim.  Are you processing the first "press" based on the press event, and then subsequently a hold because of the "missing or delayed" release?  Or do you have some timer that fires some delay after the press to trigger and process the press event?  Since you simulate the hold detection for the brightness function, it isn't clear why we couldn't do what I want.  Maybe the implementation is that "press" and the "hold" have to both issue the same command, but the simulated "hold" just repeats the "press" command with some frequency?

  2. I think I understand the mapping vs merge_mapping in that the latter (merge_mapping) lets you just "override" a few of the settings while keeping the defaults for the unmodified presses, while "mapping" requires you to define the operation of all the features/events you want to use.  I got really confused last night because I had forgotten this, and tried your "mapping" technique, but found that the "ramp" wouldn't stop.  While I'm only reading your email this morning, I think I didn't define the "release" operation so it couldn't detect the release wouldn't know when to stop the ramp.  But is there something else I should know about mapping vs merge_mapping? I didn't troubleshoot, but when I was trying the mapping method for on/off, my controlled lights (hue) lost the ramp on/ramp off feature when you turned them on/off.  This ramp on/off seems to be automatic with the merge_mapping.  Losing the ramp is very jarring as compared to a standard incandescent bulb.  Only after restoring the merge_mapping on/off did that feature come back.

  3. I had tried the multiple presses similar as you mention as an option to solve my issue, but I had tried this with the merge_mapping attribute, and I couldn't get it to work.  Is that expected?  Do I need to use the "mapping" option to make this work?  While the multipress may be an option, it's kind of confusing to use as mentioned.  99% of the time, I want the users to do an on/off.  Ramp dim/brignt would be rare.  Most users wouldn't know (or remember) to do a double press.  Worse, after doing single press or press-and-hold (the incremental or ramp function) would leave the light at a random brightness setting, the subsequent double-press on/off will keep using that same setting instead of resetting it.  Is there any way to reverse whether the dim/bright is on the double-press or the single press?  Can you assign a hold version  to the double-press? This didnt work for me (but I used merge_mapping) office_dimmer:  module: controllerx  class: PTM215XLightController  controller: sensor.officeswitch_action  integration: z2m  light: light.office_lights  merge_mapping:    press_1$2:        action: on   press_1:                                                                            action: hold                                                                    attribute: brightness                                                           direction: up                                                                   mode: stop                                                                      steps: 10                                                                   press_2$2:                                                                            action: click                                                                   attribute: off                                                              press_2:                                                                            action: hold                                                                    attribute: brightness                                                           direction: down                                                                 mode: stop                                                                      steps: 10                      

  4. I do have an option for what I need, that could work... but I'd only like to do this as a last resort.  This particular controller has a press_1/press_2 that corresponds to 1 paddle, press_3/press_4 that corresponds to the 2nd paddle, and a press_1_and_press_3/press_2_and_press_4 that corresponds to both paddles pressed at the same time and the same direction.  I could use that one for the rare brightness feature.  But, I was really hoping to duplicate the press on/off and hold_for_dim feature I can do with a single paddle with the same switch and the hue hub.

  5. When we do the "on", is there a way to pass an attribute to turn the light on to a specific brightness setting instead of the "last"? And set a specific ramp rate?

Thanks, Sean

Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

xaviml commented 1 year ago

Hi @SeanNazareth,

Let me answer your questions one by one.

I don't quite understand why you say what I want isn't doable. Your controller detects the "hold" condition, and specify a hold attribute as separate from the "press". Is there some requirement that both the "press" and "hold" operations use the same "attribute? I do understand that the z2m integration only provides press and release events, but somehow, you must detect a "lack" of release over a specific interval to be a "hold" in this case. Specifically, if one paddle is brightness attribute, you currently can simulate a "press" as an incremental bright/dim, and a "hold" as a ramp bright/dim. Are you processing the first "press" based on the press event, and then subsequently a hold because of the "missing or delayed" release? Or do you have some timer that fires some delay after the press to trigger and process the press event? Since you simulate the hold detection for the brightness function, it isn't clear why we couldn't do what I want. Maybe the implementation is that "press" and the "hold" have to both issue the same command, but the simulated "hold" just repeats the "press" command with some frequency?

When I said in my previous comment that is not doable is because if ControllerX receives a press_1 event, it cannot not if it is a hold or a click. It will know that is a hold once a release event has been received, but in that moment it would be too late to start doing the hold action. However, if the release is always triggered (no matter if it is clicked or hold), then it would be possible to set some capability to trigger a click event if the release and the press event are together in time, and trigger a hold event otherwise. I see in the logs you sent that the release is always sent, so it would be doable for your use case. However, it is a capability that ControllerX does not support. FYI, it is not normal that a controller supports a release event, but not a hold one. In general all devices support 3 distinct events for click, hold and release. This is why this is not supported by ControllerX, because it is a specific use case from this specific controller. I will give it a think to add support for this feature, but I would not wait for it since I cannot commit to it.

  1. I think I understand the mapping vs merge_mapping in that the latter (merge_mapping) lets you just "override" a few of the settings while keeping the defaults for the unmodified presses, while "mapping" requires you to define the operation of all the features/events you want to use. I got really confused last night because I had forgotten this, and tried your "mapping" technique, but found that the "ramp" wouldn't stop. While I'm only reading your email this morning, I think I didn't define the "release" operation so it couldn't detect the release wouldn't know when to stop the ramp. But is there something else I should know about mapping vs merge_mapping? I didn't troubleshoot, but when I was trying the mapping method for on/off, my controlled lights (hue) lost the ramp on/ramp off feature when you turned them on/off. This ramp on/off seems to be automatic with the merge_mapping. Losing the ramp is very jarring as compared to a standard incandescent bulb. Only after restoring the merge_mapping on/off did that feature come back.

All you need to know about the mapping and merge_mapping can be found in this section of the documentation: https://xaviml.github.io/controllerx/advanced/.

  1. I had tried the multiple presses similar as you mention as an option to solve my issue, but I had tried this with the merge_mapping attribute, and I couldn't get it to work. Is that expected? Do I need to use the "mapping" option to make this work? While the multipress may be an option, it's kind of confusing to use as mentioned. 99% of the time, I want the users to do an on/off. Ramp dim/brignt would be rare. Most users wouldn't know (or remember) to do a double press. Worse, after doing single press or press-and-hold (the incremental or ramp function) would leave the light at a random brightness setting, the subsequent double-press on/off will keep using that same setting instead of resetting it. Is there any way to reverse whether the dim/bright is on the double-press or the single press? Can you assign a hold version to the double-press?

It should not matter if you use mapping or merge_mapping. The only difference between the 2 is that mapping allows you to define your own mapping by completely overwriting all the default mappings for that controller. Then, merge_mapping allows you to only overwrite the events you specify in the configuration, the rest will still be using the default mapping for that controller. My recommendation (if confused) is to use the mapping option so you do not get any surprises. Especially for your controller which is a controller whose default mapping does not make much sense. Default mappings make sense for controllers which have a defined purpose, like:

You can reverse the behaviour of the double press, by just inverting the actions:

office_dimmer: 
  module: controllerx 
  class: PTM215XLightController 
  controller: sensor.officeswitch_action 
  integration: z2m
  light: light.office_lights 
  merge_mapping:   
     press_1: "on"
     press_1$2:                                                                           
       action: hold                                                                   
       attribute: brightness                                                          
       direction: up                                                                  
       mode: stop                                                                     
       steps: 10                                                                  
    press_2: "off"                                                            
    press_2$2:                                                                           
       action: hold                                                                   
       attribute: brightness                                                          
       direction: down                                                                
       mode: stop                                                                     
       steps: 10       

Important note: if you use the words on and off, make sure to wrap them up with ". E.g.: "on", "off".

  1. I do have an option for what I need, that could work... but I'd only like to do this as a last resort. This particular controller has a press_1/press_2 that corresponds to 1 paddle, press_3/press_4 that corresponds to the 2nd paddle, and a press_1_and_press_3/press_2_and_press_4 that corresponds to both paddles pressed at the same time and the same direction. I could use that one for the rare brightness feature. But, I was really hoping to duplicate the press on/off and hold_for_dim feature I can do with a single paddle with the same switch and the hue hub.

That is correct, those events (press_1_and_3 and press_2_and_4) can be used for the brighten/dim the light. You could use the hold_brightness_toggle predefined action to brighten up/down the light. Each time the button is hold, it will alternate the direction of the brightness:

office_dimmer: 
  module: controllerx 
  class: PTM215XLightController 
  controller: sensor.officeswitch_action 
  integration: z2m
  light: light.office_lights 
  merge_mapping:   
     press_1: "on"
     press_1_and_3:                                                                           
       action: hold                                                                   
       attribute: brightness                                                          
       direction: toggle                                                                  
       mode: stop                                                                     
       steps: 10                                                                  
    press_3: "off"
  1. When we do the "on", is there a way to pass an attribute to turn the light on to a specific brightness setting instead of the "last"? And set a specific ramp rate?

You can set the light to a spcific brightness with the on or toggle action:

office_dimmer: 
  module: controllerx 
  class: PTM215XLightController 
  controller: sensor.officeswitch_action 
  integration: z2m
  light: light.office_lights 
  merge_mapping:   
     press_1: 
        action: "on"
        attributes:
           brightness: 128

You can pass any attribute that the light supports. You can see an example here.

Regarding the "ramp" rate, you can configure it through this attributes:

In general the automatic_steps is enough to tweak, but delay can be used to sent the commands faster.

I hope I answered all your questions.

Regards, Xavi M.

SeanNazareth commented 1 year ago

Thank you so much for your response. Let me try these out today.

Here are a few follow up questions..

  1. I think I mostly understand you comments on why the "Hold" and the "click" shouldn't work. What I don't quite understand is why it works if the "click" corresponds to brightness increment/decrement, then the "hold" also works as a hold ramp increment/decrement. Is it because both the press and the hold both issue the same command, i.e. inc/dec brightness, but the "hold" just keeps repeating that command?

  2. with regard to the "multi"-press operation, Does the controller issue the "single" press operation on the first press of a multi-press event, and "then" issue the intended multi-press operation? Or does the system delay until it can detect whether the operation is a multi-press, and then issue only the multi-press operation? I guess I can try this, but it might be helpful to others if this is specified in the description.

For example you provided for me, if press_1 is "on", and press_1$2 is hold increment with brightness attribute, press_2 is "off", and press_2$2 is hold decrement with brightness attribute, if the light is currently in state on, would we expect the first press of the double-click brightness decrement to turn off the light? Or would it work logically.

  1. Is there any way to implement a "stateful" operation.... as described below? Define state variable "state" state=0. (i.e. on-off mode) state=1 (i.e. brightness mode) In state=0: press_1="on", press_2="off" In state=1: press_1/press_2 have click/hold for brightness

Use press_1_and_press_3 to toggle state (if 0, make 1, if 1 make 0)

  1. Is there a good way to "debug" or "see" what the controllerx plug is seeing and doing?

Thanks.

xaviml commented 1 year ago

Hi @SeanNazareth ,

Please, find my answers below,

I think I mostly understand you comments on why the "Hold" and the "click" shouldn't work. What I don't quite understand is why it works if the "click" corresponds to brightness increment/decrement, then the "hold" also works as a hold ramp increment/decrement. Is it because both the press and the hold both issue the same command, i.e. inc/dec brightness, but the "hold" just keeps repeating that command?

That is correct. The click just sends one command to HA to change thr brightness. The hold keep sending command to HA to change the brightness gradually. Then, it stops either when:

with regard to the "multi"-press operation, Does the controller issue the "single" press operation on the first press of a multi-press event, and "then" issue the intended multi-press operation? Or does the system delay until it can detect whether the operation is a multi-press, and then issue only the multi-press operation? I guess I can try this, but it might be helpful to others if this is specified in the description.

ControllerX records in the initialization which commands need multiple clicks by checking which commands have the $. For those, the clicks will always be delayed by the mutliple_click_delay (500ms) by default since it needs to detect if there will be any more clicks or not. The multiple-click functionality is a virtualization since the multiple clicks do not come from the controller, but ControllerX is the one registering them. You can read more about this functionality here. So, if the command has multiple click registered, then the clicks will be issued after the mutlitple_click_delay is passed. This is barely noticeable when the mutliple_click_delay is set to the default value (500ms), this is why it is not specified in the wiki since it is a technicality on how it works. I will, however, add it, so tech people understand how it works.

For example you provided for me, if press_1 is "on", and press_1$2 is hold increment with brightness attribute, press_2 is "off", and press_2$2 is hold decrement with brightness attribute, if the light is currently in state on, would we expect the first press of the double-click brightness decrement to turn off the light? Or would it work logically.

For that configuration to work correctly, you would need to do a double-click, but maintain the button until the brightness is set to the right level. The first press of the double-click would not do anything if the second click is triggered within the 500ms (mutlitple_click_delay). If no second click is registered, then the action from press_1/press_2 would be issued.

Is there any way to implement a "stateful" operation.... as described below? Define state variable "state" state=0. (i.e. on-off mode) state=1 (i.e. brightness mode) In state=0: press_1="on", press_2="off" In state=1: press_1/press_2 have click/hold for brightness

ControllerX does not register this type of state. However, it can be done together with input_select (from HA) and constrain_input_select (from AppDaemon). First, you need to create an input_select on HA like the following (you can do it on the UI):

input_select:
  controller_state:
    options:
       - state_0
       - state_1

Then, you just need to create 2 ControllerX apps:

office_dimmer_0: 
  module: controllerx 
  class: PTM215XLightController 
  controller: sensor.officeswitch_action 
  integration: z2m
  light: light.office_lights 
  mapping:   
    press_1: "on"
    press_2: "off"
    press_1_and_3:
      service: input_select.select_next
      entity_id: input_select.controller_state
  constrain_input_select: input_select.controller_state,state_0

office_dimmer_1: 
  module: controllerx 
  class: PTM215XLightController 
  controller: sensor.officeswitch_action 
  integration: z2m
  light: light.office_lights 
  mapping:   
    press_1: hold_brightness_up
    release_1: release
    press_2: hold_brightness_down
    release_2: release
    press_1_and_3:
      service: input_select.select_next
      entity_id: input_select.controller_state
  constrain_input_select: input_select.controller_state,state_1

I get this question quite a lot, so I will try to create an article in the documentation to give an example like this. This feature is not a ControllerX feature, but an AppDaemon one. However, I do think it would be nice to have an article to guide user through this.

Is there a good way to "debug" or "see" what the controllerx plug is seeing and doing?

Yes, you can check the AppDaemon logs. You will see in there the ControllerX logs (e.g. which event was triggered, which action was issued, etc). In addition, you can see extra logs if you add log_level: DEBUG at the same level as module or class in the AppDaemon app (ControllerX config).

Regards, Xavi M.

xaviml commented 1 year ago

Hi @SeanNazareth ,

I have added the following to the documentation:

Note that the link is from the development documentation. These changes will be released to the main documentation site once a new ControllerX version is released.

Regards, Xavi M.

SeanNazareth commented 1 year ago

Thanks so much for your help and explanations. I think this clarifies things. I didn't get a chance to work on this today, but I'll try to do it later this evening or tomorrow. I suspect I'll be able to do what I want given this info. I really like the idea of the constrained input option.

I think I'll have to play around with things to figure out how to set up the state variable in HA. I think you described the concept well, but I'm not yet quite sure how to do that. But at least you've given me a good direction. I'll verify the other options as well... just for completeness.

Thanks again, Sean

xaviml commented 1 year ago

Glad to help. Let me know if you have anymore questions.