Custom Component: Cover Time Based

Not because of time based cover custom component. I have 2 systems here, working OK.

Released v1.1.2:
Added availability_template option.
You can use a template returning True or False in order to toggle availability of the cover based on other entities. Useful to link with the connection status of your RF Bridge or relays device, or with some input boolean or binary sensor if youā€™d like to simply prevent somebody to use the cover, and make it appear disabled in the dashboards.

I just installed 2022.7.6 and can confirm that it works fine.

Hello and thanks for the script.
I have a problem using Alexa and this script. I constantly receive a message in error logs:

2022-07-21 23:00:31 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

2022-07-21 23:00:31 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

2022-07-21 23:00:31 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

2022-07-21 23:00:32 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

2022-07-21 23:00:32 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

2022-07-21 23:00:32 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport for cover.rollo_wz_b to Alexa: THROTTLING_EXCEPTION: Request could not be processed due to throttling.

Possibly it is because of the ā€œlive stateā€ information as it changes position.
Could a delay be added to ā€œcurrent_positionā€? Maybe 3 seconds or more.

My config:

mqtt:
  cover:
    -   name: "MQTT Rollo Balkon"
        object_id: mqtt_rollo_wz_b
        state_topic: "schellenberg/device/value/2298"
        command_topic: "schellenberg/device/value/update/2298"
        qos: 1
        retain: true
        payload_open:  "1"
        payload_close: "2"
        payload_stop:  "0"
        state_open: "1"
        state_closed: "2"
        state_stopped: "0"
        optimistic: false

cover:
  - platform: cover_rf_time_based
    devices:
      rollo_wz_b_based:
        name: rollo_wz_b
        travelling_time_up: 24
        travelling_time_down: 24
        cover_entity_id: cover.mqtt_rollo_wz_b
        send_stop_at_ends: False #optional
        always_confident: False #optional
        device_class: shutter #optional

alexa:
  smart_home:
    filter:
        include_entities:
        - cover.rollo_wz_b

Thank you.

Hi, nice component, thanks!

I am trying to move my old automation+scripts to this component.

Short story: Did some of you got it working with 2-button remotes?

Long story:
I have my covers controlled in HA since some years ago, using a combination of scripts, automation and timers (a total mess to maintain and make it work with all the features I need). I send and detect the codes with pilight.

My covers are controlled with a 2-button RF remote: If I press up, the cover opens, if I press up while the cover is opening, the cover stops.

To mimic this behaviour, I need to have available the old_state to the scripts. Then with a simple template I can manage this in the script.

The problem is that the old_state attribute is not exposed.

I am a complete newbie in custom_component hacking but Iā€™d appreciate some directions to make this old_state attribute available to the template.

Thanks

Hi, I have this on configuration.yaml:
homeassistant:
customize:
cover.persiana_comedor:
icon_template: >-
{% if is_state(ā€˜binary_sensor.sensor_persiana_pequena_comedor_contactā€™, ā€˜onā€™) %}
mdi:window-shutter-open
{% else %}
mdi:window-shutter
{% endif %}
no icon modification according to the current state. any idea?

hi all,
thanks to @davidramosweb,@nagyrobi,@Alfiegerner,@regevbr for this fantastic custom cover script!

It works fine, but in my integration the service set_cover_position doesnā€™t work fine :roll_eyes:.
iā€™ve add two lines inside cover.py to fix it (with comment #jump396):

    def auto_updater_hook(self, now):
        """Call for the autoupdater."""
        _LOGGER.debug(self._name + ': ' + 'auto_updater_hook')
        self.async_schedule_update_ha_state()
        if self.position_reached():
            _LOGGER.debug(self._name + ': ' + 'auto_updater_hook :: position_reached')
            self.stop_auto_updater()
            self._target_position = 0    #jump396
        self.hass.async_create_task(self.auto_stop_if_necessary())

and

   async def set_known_action(self, **kwargs):
        """We want to do a few things when we get a position"""
        if (self._target_position == 0 or self._target_position == 100):   #jump396
          action = kwargs[ATTR_ACTION]
          if action not in ["open","close","stop"]:
            raise ValueError("action must be one of open, close or cover.")
          if action == "stop":
            self._handle_stop()
            return
          if action == "open":
            self.tc.start_travel_up()
            self._target_position = 100
          if action == "close":
            self.tc.start_travel_down()
            self._target_position = 0
          self.start_auto_updater()

Thatā€™s all, thanks guys :wave:

Thanks for putting this together, got it working with my Shelly 1 first go.

In case any other Shelly users stumble by, hereā€™s the script for the Shelly

'garage_door_timer_down':
  alias: 'Shelly Garage Door - DOWN'
  mode: single
  max_exceeded: silent
  sequence:
    - service: switch.toggle
      target:
        entity_id: switch.garage_door

Pretty obvious, but might help someone.
Just copy it 3 times and rename for Up, Down, Stop

1 Like

Time Based RF covers within ESPHome on Sonoff RF Bridge with command queuing for simultaneous operation (no need for custom component):

Finally found a script that works for my roller blinds so I can control the position where they are, so thank you very much.
Unfortunately, Iā€™m very inexperience regarding programing so Iā€™m having trouble with one thing.
The slider works great, but if I physically touch the Sonoff Wall Touch Switch it moves the blind but doesnā€™t update the position. The same happens If I touch the switch entities in the HA.

11

Can you give tips on how to solve that?

It will never work like that. Add it as a cover entity, not the switch entities.

Since I moved the time-based functionality to an ESPHome node, which works much better as itā€™s being done in hardware, Iā€™m archiving this repository and stop maintaining it.

Anyone feel free to fork it and continue development as needed.

Thereā€™s also Feedback Cover ā€” ESPHome with even more advanced features.

But now I need to buy an esp hardware to use this implementation?

oh man, I used to use this integration a LOT with my covers.
NOw I am screwed!

:confused:

1 Like

Not everybody can use ESPHome because itā€™s Hardware dependant. I canā€™t either :grimacing:

I managed to reimplement the functionality of this custom component using HA core integrations. Assuming you have already learned the RF commands for Open, Close and Stop for the device RF Blind:

  1. Create helpers to record the coverā€™s state
input_number:
  rf_blind_position:
    name: RF Blind Position
    min: 0
    max: 100
    step: 1

input_select:
  rf_blind_movement:
    name: RF Blind Movement
    options:
      - opening
      - closing
      - stopped
  1. Create a script to send the relevant RF commands and correspondingly set the state of input_select.rf_blind_movement
script:
  rf_blind_set_position:
    alias: RF Blind Set Position
    fields:
      target_position:
        name: Target Position
        description: The position that the cover should move to. 0 is closed, 100 is open.
        required: true
        default: 100
        selector:
          number:
            min: 0
            max: 100
            step: 1
            unit_of_measurement: '%'
    sequence:
    - condition: template
      value_template: '{{ states(''input_number.rf_blind_position'') | int(0) != target_position }}'
    - if:
      - condition: template
        value_template: '{{ states(''input_number.rf_blind_position'') | int(0) < target_position }}'
      then:
      - service: input_select.select_option
        data:
          option: opening
        target:
          entity_id: input_select.rf_blind_movement
      - service: remote.send_command
        data:
          device: RF Blind
          command: Up
        target:
          entity_id: remote.rf_universal_remote
      - wait_template: '{{ states(''input_number.rf_blind_position'') | int(0) >= target_position }}'
        continue_on_timeout: true
        timeout: '15' # set this to the number of seconds it takes your cover to open/close + 1s
      - service: input_select.select_option
        data:
          option: stopped
        target:
          entity_id: input_select.rf_blind_movement
      - service: remote.send_command
        data:
          device: RF Blind
          command: Stop
        target:
          entity_id: remote.rf_universal_remote
      else:
      - service: input_select.select_option
        data:
          option: closing
        target:
          entity_id: input_select.rf_blind_movement
      - service: remote.send_command
        data:
          device: RF Blind
          command: Down
        target:
          entity_id: remote.rf_universal_remote
      - wait_template: '{{ states(''input_number.rf_blind_position'') | int(0) <= target_position }}'
        continue_on_timeout: true
        timeout: '15' # set this to the number of seconds it takes your cover to open/close + 1s
      - service: input_select.select_option
        data:
          option: stopped
        target:
          entity_id: input_select.rf_blind_movement
      - service: remote.send_command
        data:
          device: RF Blind
          command: Stop
        target:
          entity_id: remote.rf_universal_remote
    mode: restart
  1. Create an automation to update input_number.rf_blind_position based on the time that input_select.rf_blind_movement spends in a given state
automation:
- id: '1688177050049'
  alias: RF Blind Position
  description: Set the current position of the RF Blind based on time spent opening,
    closing or stopped.
  trigger:
  - platform: state
    entity_id:
    - input_select.rf_blind_movement
  condition: []
  action:
  - choose:
    - conditions:
      - condition: state
        entity_id: input_select.rf_blind_movement
        state: opening
      sequence:
      - repeat:
          while:
          - condition: state
            entity_id: input_select.rf_blind_movement
            state: opening
          - condition: template
            value_template: '{{ states(''input_number.rf_blind_position'') | int(0) + 1 <= 100 }}'
          sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 141 # set this to the number of seconds your blind takes to open/close divided by 100
          - service: input_number.set_value
            data:
              value: '{{ states(''input_number.rf_blind_position'') | int(0) + 1 }}'
            target:
              entity_id: input_number.rf_blind_position
    - conditions:
      - condition: state
        entity_id: input_select.rf_blind_movement
        state: closing
      sequence:
      - repeat:
          while:
          - condition: state
            entity_id: input_select.rf_blind_movement
            state: closing
          - condition: template
            value_template: '{{ states(''input_number.rf_blind_position'') | int(0) - 1 >= 0 }}'
          sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 141 # set this to the number of seconds your blind takes to open/close divided by 100
          - service: input_number.set_value
            data:
              value: '{{ states(''input_number.rf_blind_position'') | int(0) - 1 }}'
            target:
              entity_id: input_number.rf_blind_position
  mode: single
  1. Create a template cover to bring it all together!
cover:
- platform: template
  covers:
    rf_blind:
      friendly_name: RF Blind
      unique_id: cover.rf_blind
      value_template: >
        {% if states('input_select.rf_blind_movement') in ['opening','closing'] %}
          {{ states('input_select.rf_blind_movement') }}
        {% else %}
          {{ states('input_number.rf_blind_position') | int(0) > 0 }}
        {% endif %}
      position_template: "{{ states('input_number.rf_blind_position') | int(0) }}"
      open_cover:
        service: script.rf_blind_set_position
        data:
          target_position: 100
      close_cover:
        service: script.rf_blind_set_position
        data:
          target_position: 0
      stop_cover:
        service: script.rf_blind_set_position
        data:
          target_position: "{{ states('input_number.rf_blind_position') | int(0) }}"
      set_cover_position:
        service: script.rf_blind_set_position
        data:
          target_position: "{{ position }}"

With the above setup, I was able to remove the custom component safely.

The logic in automation.rf_blind_position can be further extended to set input_number.rf_blind_position to a known value if you have sensors that can give feedback when the blind actually reaches certain positions (eg. contact sensors at the 100 and 0 positions).

4 Likes

Hello
The component is working great with a 2CH Tuya Smart Wifi Switch Relay and Motor Actuator to open pergola blades. Iā€™m also able to use it with the custom:slider-entity-row to open or go to a specific position between 0 and 100. Thank you @davidramosweb !

But how can I define the position in an automation ? I canā€™t find it in the device list.

Here is my conf:

cover:
  - platform: cover_time_based_synced
    devices:
      my_pergola:
        name: "Pergola"
        travelling_time_up: 50
        travelling_time_down: 45
        close_switch_entity_id: switch.pergola_switch_1
        open_switch_entity_id: switch.pergola_switch_2
        aliases:
          - my_pergola

Other question I have : what is the best practice to define position when HA starts up?

Hello,

I use this custom component a lot as I canā€™t use esphome. Do you guys know if someone is activelly maintaining it? Or if there is any problem while using the unupdated repository? I rely a lot on this.

Hope you can help!

1 Like

The custom component still works. Iā€™ve been using it since it stopped.

Hi guys,
i try to make it work with RF Player.
Did someone try it or itā€™s already known as not working ?
Because at this time, iā€™m unable to get something working.
Thanks.