Switch and contact sensor as cover

Hi
I have been trying to combine the a relay and contact sensor into a cover for my gate opener. I looked through the forum and found how to do but I am stuck that one of the gates operate just fine but the other gives an error. It says “Action script.main_gate_button uses action cover.open_cover which was not found”. Below is the yaml code I am using. What am I doing wrong here?

cover:
  - platform: template
    covers:
      small_gate:
        friendly_name: "Small Gate"
        value_template: "{{ is_state('binary_sensor.small_gate_contact_contact', 'on') }}"
        open_cover:
          action: script.small_gate_button
        close_cover:
          action: script.small_gate_button 
        icon_template: >-
          {% if states('binary_sensor.small_gate_contact_contact') == "on" %}
            mdi:gate-open
          {% else %}
            mdi:gate
          {% endif %}
  
  - platform: template
    covers:
      main_gate:
        friendly_name: "Main Gate"
        value_template: "{{ is_state('binary_sensor.main_gate_contact_contact', 'on') }}"
        open_cover:
          action: script.main_gate_button
        close_cover:
          action: script.main_gate_button 
        icon_template: >-
          {% if states('binary_sensor.main_gate_contact_contact') == "on" %}
            mdi:gate-open
          {% else %}
            mdi:gate
          {% endif %}  

Any help would be appreciated.
PS. I am not good with templating and coding. Just edited some template I saw in the forum

Obviously there is something wrong with the script for opening/closing the main gate (script.main_gate_button). Please post the script here to have us take a look.

1 Like

Hi Tamsy, Thank you for your response. The script is working. I use the same script for different automations. This is the same script for the small_gate as well which is working. All the script does it turn it off after 1 second, to behave like a push button So the script is working and I double checked. There is no typo either. The Small Gate template is exactly the same and it is working. Strange! I was wondering if there was any errors in the code. Am I ok to think that the code is fine?

ChatGPT says that the action: open_cover may not support a script and to try using a switch_on action, however the small gate works with script so it doesnt make sense why the other one is not working.

I spot nothing wrong with the above template. It is doing little more than just calling the respective scripts (and change icons depending on states).

Maybe you want to recheck for typos within the name of the sensor itself (binary_sensor.main_gate_contact_contact ← contact_contact?). Is the sensor available under exactly that very name?

Also I recommend to search this forum about using ChatGPT for scripting. There are some threads discussing the pros and contras using AI for scripting.

1 Like

Thanks. The sensor names are correct. Actually I copied from the eintities themselves. Yes, there is contact_contact :slight_smile:

I dont use ChatGPT for coding. I just tried to see if there is any obvious error. But I will have a look through the thread.

I may use the switch instead of a script and write an automation to turn off the relay after 1 second. So we can get away with the script and see if it works. But still a mystery why one works and the other not!

My guess is at some point you changed the entity_id of the main hate button script, and script.main_gate_button is the new entity_id.

However, when you call a script directly, you have to refer to the script’s unique_id, which does not get changed when you change the entity_id.

Go to developer tools → actions, and search for your script in the dropdown. When you select it, switch over to YAML mode and it will show what the proper action call is for that script.

You can also use the non-blocking form of calling the script, which uses the script.turn_on action and then does use the entity_id (not unique _id) as the value for the target. This format will just call the script and continue your automation without waiting for the script to complete. See the docs for detail.

2 Likes

Amazing! Yes. this was the issue. Looks like the main script.main_gate_button’s unique id was script.gate_button. Thank you!

Can I be cheeky and ask for one more help related to this.? I have a dry contact relay on the gate control panel from where I can get the status of the gate if it is open or close. I am planning to use some sort of dry contact sensor to get the status so I can get rid of the external door sensor used in the template above. However the contact opens and closes periodically during the opening and closing. Slower (>1s) while opening and faster (<1s) while closing.

My question is is it possible to create a template (or amend the above) so when the relay is opening closing slower, cover status is “opening” and if faster the cover status is “closing” and if stays off for >2s then status “closed” and if stays on for >2s then “open”?

I hope it. makes sense

There’s two ways I can think of doing this. Both require you to create another sensor entity which you can then reference in your cover template.

The first option is to use the history_stats integration to count how many times the sensor has been in a specific state in the previous few seconds. Someone else appears to have the same setup you do, and Finity detailed a nice solution in this post.

The other option would be to calculate the duration the sensor has been in the on state. If I’m thinking about this correctly, the benefit is that it won’t briefly transition through the closing state when it is actually opening.
You could do this with a trigger-based template sensor, or if you want to stay in the UI you could use an automation and an input_number helper. I think 3 triggers would suffice: off, on for more than 2 seconds, and off for more than 2 seconds.

  • If it is triggered by off the calculation is {{ (now() - trigger.from_state.last_changed).total_seconds() }}.
  • if it is triggered by on for more than 2 seconds, the value is 2
  • if it is triggered by off for more than 2 seconds the value is 0

In your cover template, you can say it is open if == 0, closing if < 1, opening if < 2, else it is closed.

1 Like

Thank you so much. I prefer to use the duration based one as you recommended. Although I understand the logic, I am not sure how to implement this :frowning: Could you give me a bit more detailed instruction? My templating skills are not great

I kind of figured out. Presume it will look like this.

actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - "Off"
        sequence:
          - target:
              entity_id: input_number.gate_status
            data:
              value: "{{ (now() - trigger.from_state.last_changed).total_seconds() }}"
            action: input_number.set_value
      - conditions:
          - condition: trigger
            id:
              - On 2 seconds
        sequence:
          - target:
              entity_id: input_number.gate_status
            data:
              value: 0
            action: input_number.set_value
      - conditions:
          - condition: trigger
            id:
              - Off for 2 seconds
        sequence:
          - target:
              entity_id: input_number.gate_status
            data:
              value: 2
            action: input_number.set_value

I am waiting for the sensor. WIll update once I get them. Thanks a lot for your help.

I think that looks good. I would have done it all with a template sensor; it would be something like:

template:
  - trigger:
      - platform: state
        entity_id: &my_contact_sensor
          - binary_sensor.door_contact_sensor
        to: "off"
        id: "off"
      - platform: state
        entity_id: *my_contact_sensor
        to: "off"
        for:
          seconds: 2
        id: "stay off"
      - platform: state
        entity_id: *my_contact_sensor
        to: "on"
        for:
          seconds: 2
        id: "stay on"
    sensor:
      - name: Garage Door Contact Duration
        unique_id: some_unique_id_here_123
        unit_of_measurement: "s"
        device_class: duration
        state_class: measurement
        state: >
          {% if trigger.id == "off" %}
            {{ (now() - trigger.from_state.last_changed).total_seconds() }}
          {% elif trigger.id == "stay off" %}
            {{ 0 }}
          {% else %}
            {{ 2 }}
          {% endif %}

Thank you! So this will be a single sensor outputting these values right? And this goes to the configuration.yaml?

Yes it will create a single sensor. And yes it will go in configuration.yaml as long as you haven’t split your configuration.

1 Like

I was wondering, <1 is also <2 right, so both these conditions could be true if the state of the sensor is <1? Should we be using <1 for closing and between 1 and 2 for opening?

It depends what logic structure you are using.

In your code, you use a choose block, which will evaluate the conditions in order and only run the actions on the first option that is true.

Likewise, in my code I’m using an if/elif/else structure, and the same logic applies: only the first condition will be executed.

So in both scenarios, as long as the conditions are placed in the correct order, there is no need to exclude the range of numbers that didn’t get matched by the previous condition.

1 Like

Alright, I received my sensors (I used zigbee water leak sensor as dry contact sensors) and wired up. I am pleased to say all working perfectly. Now I can get all the status of the gate, closed, opening, open and closing. Amazing! There was some issue as when closing just before it closes, the relay closes quite quickly which doesnt get updated quickly enough on HA, so the time just tips over 1 second. So, I had to increase the time for closing to <1.5s instead of <1s. Opening is fine as it consistently clicks at 1.7s. Thanks for your help. I am planning to make a new post with how to integrate the liftmaster gate with the relay and the sensor, which cost me under £10. As you may be aware MyQ stopped HA integration last year which has caused problems for many. ratgdo is only really compatible with garage door, and I am aware people are trying to find work around with it. I hope youn dont mind me sharing your template code.

Here’s it in action -

Sounds great, glad it’s working