Hold action keep firing until I let go?

Below is a screenshot for part of a dashboard I am working on for my iPhone. The code is for the volume up button. I have a neurological disease which makes repeatedly hitting physical button difficult and digital buttons even more challenging. The 4 arrow keys and select are integrated via apple tv integration and the three volume keys are via the harmony integration. My question is is there anyway to have the hold action keep firing until I let go?

type: buttonyn
tap_action:
  action: call-service
  service: remote.send_command
  service_data:
    command: VolumeUp
    device: '34843360'
  target:
    entity_id:
      - remote.bed_room
show_name: false
icon: 'mdi:volume-plus'
show_icon: true
hold_action:
  action: none

Not sure that is possible.
But perhaps the hold action triggers a script that does two or three volume up?

Another possible solution is that the hold action toggles a boolean, the boolean is part of an automation.
The automation triggers on boolean on, and action is to repeat the volume up until the boolean is off.

There is no button release event. So unfortunately this is not possible.

Thanks for the quick reply. If I were to go the Boolean route how would I turn it off automatically when I’m done? Also, this may be a stupid question, but would there be any difference if I used the custom button card?

I believe the toggle on click will be the easiest.

You click once and the action is to toggle input_boolean.volumeup. This starts the automation.
Next time you click it the automation stops.

The automation trigger is on the boolean and the action part could be something like:

action:
  - repeat:
      while:
        - condition: state
          entity_id: input_boolean.volumeup
          state: 'on'
      sequence:
        - service: script.volumeup
        - delay:
            hours: 0
            minutes: 0
            seconds: 1
            milliseconds: 0

Change the delay to suit your needs.

I was able to achieve this exact use case using the node-red plugin. I am doing something similar for a winch setup. here is what i did.

My setup required me to do this with two switches - meaning i have an individual flow for “up” and another for “down” because this is how my physical switches work. I assume the same is true for you.

things you will need:

  • custom:button-card
  • node-red integration with HA

thats about it… node-red can be a bit difficult to get up and integrated, but there are a lot of youtube tutorials to get you going.

let’s get started. The general idea is this

  1. set up input_numbers that will be used as placeholder values which will inform node-red the button is depressed
  2. Use the repeat functionality of the custom:button-card to continuously increment the input_number every ~100 milliseconds
  3. Start a flow in node-red that will fire an event when the number has changed
  4. Run the flow through a trigger node which will go high when a value as come through, then go low after ~200 milliseconds. Note this is double the time of the repeat` setting above. Setting it higher will ensure that if for some reason the one of the state change events is missed, it still has time to register the next state change. this ALSO becomes how long the switch will remain on AFTER you release the button, so play with these 2 values. I should probably use 250 or drop my 100ms to 80ms, but i haven’t had issues yet.
  5. you can then use a switch control to route to the call_service node for turning the switch on or off based on the trigger state (high or low).
  6. Be sure to reset the input_number back to 0 after the “off” call is made
  7. Be sure you do nothing when the “value” of the input_number == 0.

Here are some of my configs.
configuration.yaml in HA

input_number:
  winch_rhode_button_down_pressing:
    name: Winch Button "Down" Is Depressed
    initial: 0
    min: 0
    max: 2500
    step: .5
  winch_rhode_button_up_pressing:
    name: Winch Button "Up" Is Depressed
    initial: 0
    min: 0
    max: 2500
    step: .5

my HA dashboard using the custom:button-card card. Note i utilize the tap_action as well as the hold_action in this. The only difference is the hold_action uses the repeat to keep the value changing continuously

                  - entity: holder
                    type: custom:button-card
                    template: container
                    color: '#EDE7B0'
                    custom_fields:
                      buttons:
                        card:
                          type: horizontal-stack
                          cards:
                            - entity: switch.sonoff_1001423223_2
                              name: Down
                              icon: mdi:arrow-down-bold
                              type: custom:button-card
                              tap_action:
                                action: call-service
                                service: input_number.increment
                                service_data:
                                  entity_id: input_number.winch_rhode_button_down_pressing
                              hold_action:
                                action: call-service
                                service: input_number.increment
                                repeat: 100
                                service_data:
                                  entity_id: input_number.winch_rhode_button_down_pressing
                            - entity: switch.sonoff_1001423223_1
                              name: Up
                              icon: mdi:arrow-up-bold
                              type: custom:button-card
                              tap_action:
                                action: call-service
                                service: input_number.increment
                                service_data:
                                  entity_id: input_number.winch_rhode_button_up_pressing
                              hold_action:
                                action: call-service
                                service: input_number.increment
                                repeat: 100
                                service_data:
                                  entity_id: input_number.winch_rhode_button_up_pressing

This is everything on the HA side.

On to node-red. I’m too new to upload a bunch of photos or this would be easier… i’ll try to explain…

Here is my flow for the “Up” button - you will repeat this for “Down” as well

Starting with the left side is my config for the state changed - i am monitoring the input_number only. Also, i ignore the value “0” so that when i reset it to 0 after turning the switch off i do not fire another event. This is done by setting the “State type” to “number” and adding a condition of “is not”: 0. Finally the custom output needs to be added where the custom payload is {"reset": true}. This is important to keep the trigger from going low while you are holding the button down

Next is the trigger node. Because of the {"reset": true} above, this will keep reseting itself every time the input_number changes, then it will not go “low” again until 200ms after the last number changes. I have it Send 1 then wait for 200 milliseconds and the checkbox extend delay if new message arrives checked. Thats all.

the switch node is quite basic, trigger one output on a 1 and the other on a 0 by adding an == 1 and == 0. Simple.

Call the service for either turning your switch on or off. I have a switch.turn_off and a switch.turn_on for each the up and down directions.

And finally, if it is turning off, i reset the input_number value by calling the input_number.set_value with a payload of {"value": 0}

Hope this helps!

1 Like

The comment above is actually the solution, which is to use custom:button-card’s repeat field. It has nothing to do with node-red.

3 Likes

i’m coming back to this, because I find it hard to believe there is no solution. I’m pretty sure you could run a script in repeat until condition is met? no?