Tasmota Home Assistant venetian blind

Hi,

I need some help with my mqtt cover setup for my venetian blind.
I have shelly 2.5 with custom Tasmota (because of if else function). I have configured two shutters, one for opening and closing, the second one for tilting. I use simple rule, that setcloseposition for tilting, when main shutter closing (running down). The next rule setopenposition for tilting when main shutter opening (running up). The main problem is when i use button to open shutter, tilting does not update in home assistant, but it works in tasmota.

I have tried mqtt discovery which added automatically tasmotized shelly to HA, but when tils resets by tasmota, slider does not update.
I have tried also mqtt template for cover and is has the same problem.

cover:
  - platform: mqtt
    name: "Zaluzie loznice naklapeni"
    device_class: "shutter"
    command_topic: "cmnd/shelly25/Backlog"
    availability_topic: "tele/shelly25/LWT"
    qos: 0
    retain: true
    payload_open: "ShutterOpen2"
    payload_close: "ShutterClose2"
    payload_stop: "ShutterStop2"
    state_open: "ON"
    state_closed: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    position_topic: "stat/shelly25/SHUTTER2"
    value_template: "{{ value | int }}"
    position_open: 100
    position_closed: 0
    set_position_topic: "cmnd/shelly25/ShutterPosition2"
  - platform: mqtt
    name: "Zaluzie loznice"
    device_class: "shutter"
    command_topic: "cmnd/shelly25/Backlog"
    availability_topic: "tele/shelly25/LWT"
    qos: 0
    retain: true
    payload_open: "ShutterOpen1"
    payload_close: "ShutterClose1"
    payload_stop: "ShutterStop1"
    state_open: "ON"
    state_closed: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    position_topic: "stat/shelly25/SHUTTER1"
    value_template: "{{ value | int }}"
    position_open: 100
    position_closed: 0
    set_position_topic: "cmnd/shelly25/ShutterPosition1"

Can someone help me to update slider of my tilting cover?

Yeah, I have found solution. For my code i use this configuration:

cover:
  - platform: mqtt
    name: "Balcony Blinds"
    availability_topic: "tele/%topic%/LWT"
    payload_available: "Online"
    payload_not_available: "Offline"
    position_topic: "stat/%topic%/RESULT"
    value_template: >
      {% if ('Shutter1' in value_json) and ('Position' in value_json.Shutter1) %}
        {{ value_json.Shutter1.Position }}
      {% else %}
        {% if is_state('cover.balcony_blinds', 'unknown') %}
          50
        {% else %}
          {{ state_attr('cover.balcony_blinds','current_position') }}
        {% endif %}
      {% endif %}    
    position_open: 100
    position_closed: 0
    set_position_topic: "cmnd/%topic%/ShutterPosition1"
    command_topic: "cmnd/%topic%/Backlog"
    payload_open: "ShutterOpen1"
    payload_close: "ShutterClose1"
    payload_stop: "ShutterStop1"
    retain: false
    optimistic: false
    qos: 1

And then i have automation which mqtt publish to get shutter2 position based on sensor trigger.

- id: 'xxxxxxxxx'
  alias: Shutter 2 update position
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.zaluzie_naklapeni
  condition: []
  action:
  - service: mqtt.publish
    data:
      topic: cmnd/shelly25/ShutterPosition2
  mode: single
2 Likes

Hi Zufan,

Im am glad you found your solution

Can you please post your Tasmota configuration?
I am faced with this challenge too.

My use case is venetian blinds in a fully open position or fully closed position or closed position with a specific angle to let in light but block direct sunshine.

Hi chchrlam,

i don’t have access to my computer during this weekend, but i can help give you some hints what you have to set. I know that tasmota brings better venetian blind support, but i am using my solution for about six months without issue.

  1. you must compile your own tasmota build where you allow “if else functions” (Rules - Tasmota).
  2. prepare two shutters (Shutters and Blinds - Tasmota) and do Shutter calibration. First shutter will be set with fully open and fully closed times. On second shutter set times for tilt (it could something around 1-2 seconds)
  3. you have to prepare rules:
    here are rules which i use:

My venetian blind act like this: when it goes up (fully opening) the tilt is opened, but when it goes down (closing) the tilt is closed. So this rule is used to change shutter2 (tilt) to close or open position every time when shutter1 is moving.

on Shutter2#Position DO mem1 %value% ENDON   
on Shutter1#Position DO var2 %value% ENDON   
on Shutter1#Direction!=0 DO var1 %value% ENDON   
on Shutter1#Direction=0 DO IF (var1==1) ShutterSetOpen2 ENDIF ENDON  
on Shutter1#Direction=0 DO IF (var1==1) var1 0; ShutterSetOpen2; publish stat/shelly25/SHUTTER2 ENDIF ENDON   
on Shutter1#Direction=0 DO IF (var1==-1) var1 0; ShutterSetClose2; publish stat/shelly25/SHUTTER2 ENDIF ENDON

The second rule I use for control of venetian blinds with 2 buttons - Single (tilt fully), Double (tilt for 30%) and Hold (fully open or close blinds). Double click is not very accurate and i don’t use that much. Instead of that i fully control blinds with Home Assistant automations.

on button1#state=3 do power1 toggle endon  
on button2#state=3 do power2 toggle endon  
on button1#state=10 do ShutterOpen2 endon 
on button2#state=10 do ShutterClose2 endon 
on button1#state=11 do var3=%mem1%+30 endon 
on button1#state=11 do if(var3>=100) shutterposition2 100 else shutterposition2 %var3% endif endon 
on button2#state=11 do var3=%mem1%-30 endon 
on button2#state=11 do if(var3<=0) shutterposition2 0 else shutterposition2 %var3% endif endon

Hi Zufan,

Thanks for the repsonse. It might take me a while to report on any progress I make.
I have the same continental European venetian blinds outside all my windows. But with a Swiss style button. UP and DOWN with mechanical interlock. A soft push for momentary and a hard push to make the button stay pressed which will pop the other button out. The blinds have built in end stops which stops the motor when fully open or closed position is reached.

My research so far:

Shelly 2.5 Stock firmware is useless. The relays are really fast 50ms but the firmware in Blinds mode(realay Interlock) gives very poor control over the relays when using the buttons. Feels like random delays of up to 200ms to start the relay and some random delays of up to 300 ms when you release the button. Useless for people who have fast motors. Useably for me as a tilt from closed to horizontal takes 1700ms. But far from ideal.

Compling Tasmota won’t be a problem.

Shelly 2.5 with ESPHome April 2020

I need to learn YAML. Several hard coded values that need substitution and individual tweaking for my blinds. Love the power monitoring to determine that the blind has reached the endstop and then it turns off the relay.

Shelly 2.5 with stock firmware and MQTT August 2021

Have not looked properly at this yet. Not sure if it will work with tasmotized Shelly 2.5

Sonoff 4 Relay switch with Homebrew MQTT firmware March 2020

This compiles only with older libraries from expressif for ESP in Arduino. Which means that it is vulnerable to WiFi Frag Attacks. Also the author metioned several times if he where to do it again he would do it all in ESPHome.

My nearly final solution is ESPHome using the cuurent based cover from Oct 2021 with some tilt presets and some lovelace custom goodness. Love Tasmota and the new tight integrations for it, but ESPHome rocks with HA.
I will link to my final solution here as it will be posted in a separate thread.

Hello chchrlam,

do you have now a final solution to tilt the current based cover with ESPHOME?

thanks

Yeah, would also be interested!

GUI Stuff here

Code below. It can be improved, but it works great and I don’t have the time to make it nicer.

# To do:
#   add an variable for the time it takes for the relay to close and the motor to start moving - relay_motor_reaction_time
#   this time is used in all tilt operations
#   then the tilt angle can be passed with the GUI as a 0-90 slider or presets
#   the calcuation for the tilt_motor_time is (TiltAngle/90) * (tilt_to_horizontal_duration - relay_motor_reaction_time)
#   the tilt is then acheived by activating the realy with  relay_motor_reaction_time + tilt_motor_time

substitutions:
  devicename: shelly-25-blinds-bedroom-1
  upper_devicename: "Shelly 25 Blinds Bedroom 1"
  open_duration: 40s # Slider in Lovelace. 40s for Bedroom 1, 2, 3
  close_duration: 40s # Slider in Lovelace. 40s for Bedroom 1, 2, 3
  open_moving_current_threshold: "0.3" # 0.3 Amps = 75 Watts (Normal operation is ~105 Watts)
  close_moving_current_threshold: "0.3" # 0.3 Amps = 75 Watts (Normal operation is ~105 Watts)
  tilt_to_horizontal_duration: 1700ms # maximum time needed for blind to go to horizontal tilt
  long_press_threshold: 2000ms # after this the blind will open or close without holding the button

esphome:
  name: ${devicename}
  platform: ESP8266
  board: esp01_1m
  esp8266_restore_from_flash: true

# Chris notes
# This is based off the Shelly 2.5 example in the current_based cover
#   https://esphome.io/components/cover/current_based.html
#   https://esphome.io/components/sensor/ade7953.html?highlight=ade7953
#   The obstacle detection amperage is not set in the example
#   Shelly 2.5 current measurement with ade7953 has Relay 2 on Channel A and 1 on B - the example is incorrect
#   The samnple code has the open and close realys reversed which is incorrect

# The operation of the cover:
#   GUI - The time in open_duration and close_duration is used for the slider
#   GUI - When a hardware end stop (current_a or current_b below threshold) is reached the slider will jump to 0 or 100, self calibrating itself
#   Hardware switch - A long (>2000ms) momentary push will activate the realy until an end stop is reached. A momentary Up or Down push will stop the relay
#   Hardware switch - the Feller Storen switches can be set to momentary only. This is the reccomended way for OCD people like me who don't like pushed in switches

# Getting some Tilt functionality
# Option 1 - Tilt % preset buttons in the GUI using Down relay for 1700ms followed by up Realy for x ms. Not sure how to do this best. Exposing relays OR sending Down 1700ms Up x ms in Lovelace with automation or something
# Option 2 - use template cover with modified github.com/InToSSH Tilt Code
# Option 3 - Build presets into the ESPHome YAML and expose them somehow as buttons in Lovelace  Use Switch Template for this for virtual switches.
# cover.on_open and cover.on_closed trigger when endstops are reached use with text sensor to show status


#Chris - CopyPasta block START###################
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: HIGH # for ESP8266 LOW/HIGH are mixed up, esphome/issues/issues/1532
  manual_ip:
    static_ip: 192.168.1.188
    gateway: 192.168.1.254
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Shelly25Esphome Fallback Hotspot"
    password: "AtvB12345678"

# Enable logging
logger:
  level: WARN
  esp8266_store_log_strings_in_flash: False

# Enable Home Assistant API
api:

ota:
  password: "8fd9b1017b04f02b64f6d68712345678"
#Chris - CopyPasta block END#####################

i2c:
  sda: GPIO12
  scl: GPIO14

sensor:
  - platform: ade7953 # Some Shelly 2.5 weirdness here https://esphome.io/components/sensor/ade7953.html
    irq_pin: GPIO16
    voltage:
      name: Shelly 2.5 Mains Voltage
      internal: true
      filters:
        - throttle: 5s
    current_b:
      name: Shelly 2.5 Open Current
      id: open_current
      internal: true
    current_a:
      name: Shelly 2.5 Close Current
      id: close_current
      internal: true
    active_power_b:
      name: Shelly 2.5 Open Power
      filters:
       - multiply: -1
      id: open_power
      internal: true
    active_power_a:
      name: Shelly 2.5 Close Power
      filters:
        - multiply: -1
      id: close_power
      internal: true
    update_interval: 0.5s

  # NTC Temperature
  - platform: ntc
    sensor: temp_resistance_reading
    name: Shelly 2.5 Temperature
    internal: true
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    calibration:
      b_constant: 3350
      reference_resistance: 10kOhm
      reference_temperature: 298.15K
    on_value_range:
      above: 75 # Chris - Shelly default firmware has 90°C. Use case for venetian blinds needs max 75
      then: # Security shutdown by overheating
        - switch.turn_on: _shutdown # Chris - this sends the shelly into a deep sleep that requires a reset button or a hard power cycle

  - platform: resistance
    id: temp_resistance_reading
    sensor: temp_analog_reading
    configuration: DOWNSTREAM
    resistor: 32kOhm
    internal: true
  - platform: adc
    id: temp_analog_reading
    pin: A0
    update_interval: 30s
    internal: true

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO13
    name: ${upper_devicename} Open Button
    internal: false
    on_press:
      then:
        cover.open: blind
    on_click: # Chris - added on_click section for Swiss style buttons short push to tilt and long to move until end stop reached
      - min_length: 1ms
        max_length: ${long_press_threshold} # hold time for activate relay until end stop
        then:
          - cover.stop: blind
  - platform: gpio
    pin:
      number: GPIO5
    name: ${upper_devicename} Close Button
    internal: false
    on_press:
      then:
        cover.close: blind
    on_click: # Chris - added on_click section for Swiss style buttons short push to tilt and long to move until end stop reached
      - min_length: 1ms
        max_length: ${long_press_threshold} # hold time for activate relay until end stop
        then:
          - cover.stop: blind

switch:
  - platform: shutdown
    id: _shutdown
    name: Shelly 2.5 Shutdown
    internal: true

  - platform: gpio
    id: open_relay
    name: ${upper_devicename} Open Relay
    internal: true
    pin: GPIO4 # Chris - swap was 15 - the example code is incorrect
    restore_mode: RESTORE_DEFAULT_OFF
    interlock: &interlock [open_relay, close_relay]
    interlock_wait_time: 150ms # Chris - change from 200 to 150

  - platform: gpio
    id: close_relay
    name: ${upper_devicename} Close Relay
    internal: true
    pin: GPIO15 # Chris - swap was 4 - the example code is incorrect
    restore_mode: RESTORE_DEFAULT_OFF
    interlock: *interlock
    interlock_wait_time: 150ms # Chris - change from 200 to 150
    
  - platform: template
    name: ${upper_devicename} Tilt-500
    turn_on_action:
      then:
        - lambda: |-
            id(close_relay).turn_on();
        - delay: ${tilt_to_horizontal_duration}
        - lambda: |-
            id(close_relay).turn_off();
            id(open_relay).turn_on();
        - delay: 500ms
        - lambda: |-
            id(open_relay).turn_off();

  - platform: template
    name: ${upper_devicename} Tilt-800
    turn_on_action:
      then:
        - lambda: |-
            id(close_relay).turn_on();
        - delay: ${tilt_to_horizontal_duration}
        - lambda: |-
            id(close_relay).turn_off();
            id(open_relay).turn_on();
        - delay: 800ms
        - lambda: |-
            id(open_relay).turn_off();

  - platform: template
    name: ${upper_devicename} Tilt-1100
    turn_on_action:
      then:
        - lambda: |-
            id(close_relay).turn_on();
        - delay: ${tilt_to_horizontal_duration}
        - lambda: |-
            id(close_relay).turn_off();
            id(open_relay).turn_on();
        - delay: 1100ms
        - lambda: |-
            id(open_relay).turn_off();

  - platform: template
    name: ${upper_devicename} Tilt-Horizontal
    turn_on_action:
      then:
        - lambda: |-
            id(close_relay).turn_on();
        - delay: ${tilt_to_horizontal_duration}
        - lambda: |-
            id(close_relay).turn_off();
            
# Example configuration entry
cover:
  - platform: current_based
    name: ${upper_devicename} Blind
    id: blind

    open_sensor: open_current
    open_moving_current_threshold: ${open_moving_current_threshold}
    open_duration: ${open_duration}
    open_action:
      - switch.turn_on: open_relay
    close_sensor: close_current
    close_moving_current_threshold: ${close_moving_current_threshold}
    close_duration: ${close_duration}
    close_action:
      - switch.turn_on: close_relay
    stop_action:
      - switch.turn_off: close_relay
      - switch.turn_off: open_relay
    obstacle_rollback: 30%
    start_sensing_delay: 0.8s
    malfunction_detection: true
    malfunction_action:
      then:
        - logger.log: "Malfunction detected. Relay welded."

status_led:
  pin:
    number: GPIO0
    inverted: yes
    
text_sensor:
  - platform: wifi_info
    mac_address:
      name: ${upper_devicename} MAC Address
      internal: false