!> This feature is not included in precompiled binaries.
To use it you must compile your build. Add the following to user_config_override.h
:
#ifndef USE_SHUTTER
#define USE_SHUTTER // Add Shutter support (+6k code)
#endif
?> Control blinds and roller shades connected to regular ON/OFF motors or stepper motors.
The device must have at least two relays (e.g., a Sonoff Dual R2). Otherwise the shutter feature will not work.
First enable shutter support with SetOption80 1
Complete list of commands is available at Blinds, Shutters and Roller Shades Commands.
There are three shutter modes which are defined according to the PulseTime and Interlock settings. The examples below are for a ShutterRelay1 1
configuration (using Relay1 and Relay2).
-
ShutterMode 0 - Normal Operation
First relay: OFF/DOWN, Second relay: OFF/UPBacklog PulseTime1 0; PulseTime2 0
Backlog Interlock 1,2; Interlock ON
(Interlocked relay pair)
-
ShutterMode 1 - Circuit Safe First relay: ON/OFF, Second relay: UP/DOWN
Backlog PulseTime1 0; PulseTime2 0
Interlock OFF
-
ShutterMode 2 - Pulse Motors
First relay: OFF/DOWN PULSE, Second relay: OFF/UP PULSEBacklog PulseTime1 2; PulseTime2 2
Backlog Interlock 1,2; Interlock ON
(Interlocked relay pair)
-
ShutterMode 3 - Stepper Motors
First relay: ON/OFF, Second relay: UP/DOWN PWM: Stepper signal, COUNTER: Stepper position signalBacklog PulseTime1 0; PulseTime2 0
Interlock OFF
- PWM and COUNTER defined
Wiring diagrams for Normal, Stepper motor, and Short Circuit-Safe configurations are available at the end of this page. Even if the shutter does not have two motors, three wires have to be connected.
[!NOTE] After setting the options for shutter mode, the device must be rebooted. Otherwise, the sliders won't be available in the web UI, and the
ShutterOpenDuration<x>
andShutterCloseDuration<x>
commands will report "Shutter unknown".
Issue ShutterRelay<x> 1
command and check in console which ShutterMode is displayed:
Shutter accuracy digits: 1
Shutter 0 (Relay:1): Init. Pos: 20000 [100 %], Open Vel.: 100 Close Vel.: 100 , Max Way: 20000, Opentime 10.0 [s], Closetime 10.0 [s], CoedffCalc: c0: 0, c1 200, c2: 200, c3: 0, c4: 0, binmask 3, is inverted 1, ShutterMode 0, motordelay 0
Turning a device relay on or off directly (i.e., using Power
) will function to affect a shutter's movement. In momentary mode (i.e., stepper motor), the relays start or stop the motor. The driver takes care of the direction and proper update of the shutter position.
The shutter reports its position and can also be sent to a dedicated position. ShutterPosition
= 0
means the shutter is closed and ShutterPosition
= 100
means the shutter is open. If you need the position values reversed (0
= open, 100
= closed), define and calibrate your shutter as documented below. Then tell Tasmota to reverse the shutter position meaning via the ShutterInvert<x> 1
command. All internal calculations are the same (the log output is the same). Only the interaction with the user and other systems changes. Now ShutterPosition<x> 0
will open the shutter and ShutterPosition<x> 100
will close the shutter.
By default, only Shutter1
is enabled when SetOption80 1
is invoked.
A maximum of four shutters per device are supported.
To enable additional shutters, ShutterRelay<x> <value>
must be executed for each additional shutter. Additional shutter declarations must be sequentially numbered, and without gaps (i.e., second shutter is 2, then shutter 3, and finally shutter 4).
Disabling a shutter in the middle of the defined set of shutters will disable all other higher numbered shutters. If the disabled shutter is restored, the higher numbered shutters previously declared will also be restored. When a shutter is added or removed, a list of the active shutters, with their parameters, is output to the log. If you intend to remove shutters, explicitly remove each one beginning with the highest numbered shutter.
With four shutters, eight Relay<x>
components are needed. If manual operation switches (Switch<x>
or Button<x>
pairs) are also used, additional input GPIO are required. The ESP82xx device may not have enough free GPIO to support all the shutter connections required. A GPIO expander such as a PCF8574 or MCP230xx can be used.
Using manual operation Switch<x>
pairs may require setting SwitchMode<x> 4
(inverse follow) for proper switch behavior.
Any shutter positioning can be locked ShutterLock<x> 1
. Once executed an ongoing movement is finished while further positioning commands like ShutterOpen<x>
, ShutterClose<x>
, ShutterStop<x>
, and ShutterPosition<x>
, as well as web UI buttons, web UI sliders, and shutter buttons are disabled. This can be used to lock an outdoor blind in case of high wind or rain. You may also disable shutter positioning games by your children. Shutter positioning can be unlocked using ShutterLock<x> 0
. Please be aware that the shutter can still be moved by direct relay control (i.e., power<x>
), or physical switches and buttons. Use hte ShutterButton<x>
command prior to ShutterLock
to be able to lock buttons.
There are shutters that have two relays but only need a pulse to start or stop. Depending on the current situation a pulse will stop the shutter or send it into a specific direction. To use these kinds of shutters a PulseTime
must be defined on each relay. The minimum setting that seems to make it work consistently is 2
. A setting of 1
does not work. If the shutter moves too fast and does not react to a stop command, increase the setting to 3
or 4
.
Stepper motors can also be used to operate shutters and blinds. Additionally you can operate sliding doors with this configuration.
Please refer to Shutters and Steppers for details.
Shutter calibration video tutorial
- Set the
ShutterOpenDuration<x>
to the time the shutter needs to open completely. - Set the
ShutterCloseDuration<x>
at least to the time the shutter needs to close completely. If the shutter does not close completely or runs too long, the calibration point of a closed shutter can be defined withShutterSetClose<x>
. Move the shutter to the close position and executeShutterSetClose<x>
command.ShutterPosition<x>
will be reset to 0 (ShutterClose<x>
). - Set the 50% open position of the shutter. Some shutters need some time from totally closed until they begin moving the bottom-most part and opening. This often results a shutter that is less than 50% open when the shutter has been operating for 50% of the set duration. This can be corrected by using
ShutterSetHalfway<x>
. Use this procedure to calibrate the half-open position:ShutterClose<x>
(confirm that the shutter is completely closed)ShutterSetHalfway<x> 50
(reset to default)- Move the shutter to actual 50% open position.
- Use
ShutterPosition<x>
to inquire the shutter's current position and record the value. This value is a percentage of the total opening (e.g.,63
= 63% of opening). ShutterClose<x>
ShutterSetHalfway<x> 63
(using the value from step #4 above)Restart 1
- After calibration you might want to enable an additional 1s motor movement by
ShutterEnableEndStopTime<x> 1
when the shutter is asked to move to its end positions (0% and 100%). By this you can guarantee that end positions are still reached in case of inaccuracies. Take care to disable this byShutterEnableEndStopTime<x> 0
before further open or close duration measurements.
If you desire that the %-opening closely match what ShutterPosition<x>
and web UI indicate, there is a granular calibration matrix available. Ensure that ShutterClose<x>
and ShutterOpen<x>
moves the shutter more or less to the limit positions and follow this procedure:
ShutterSetHalfway<x> 50
(reset to default)ShutterCalibration<x> 30 50 70 90 100
Restart 1
ShutterClose<x>
- Move the shutter to each of the following opening percentages and measure the shutter's position for each.
ShutterPosition<x> 30
(e.g., measurement =15
)ShutterPosition<x> 50
(e.g., measurement =50
)ShutterPosition<x> 70
(e.g., measurement =100
)ShutterPosition<x> 90
(e.g., measurement =150
)ShutterPosition<x> 100
(e.g., measurement =180
)
- Finally, enter the position measurements as the calibration values:
ShutterCalibration<x> 15 50 100 150 180
ShutterCalibration<x>
takes position measurements (not the time it takes to move). During calibration you position the shutter to an indicated percentage (e.g., 30%
) of opening and measure the shutter position (e.g., 15
). Use the same unit of measure for all your measurements (e.g., centimeters, inches, etc.). After calibration ShutterPosition<x> 30
will move to 30%
opening which will correspond to the position you provided (15
).
Notice that there is no calibration for the 10% position. On many shutters, there is no movement during the initial phase (i.e., nearly 10% of total time). Therefore the opening could be 0
. This measurement would cause an execution DIV 0 exception. Therefore the first calibration point is 30%. In most cases this is not a large opening so the calibration will be near enough. Yes, until ~10%, the position will be a bit "off" but not enough for concern.
Some motors need up to one second after power is turned on before they start moving. You can confirm if you are having this issue if opening and closing as a single action works properly but doing this in smaller steps result in a shift of the position.
Shutterposition<x> 30
Measure the shutter position. This is thereference_position
Shutterposition<x> 80
Measure the shutter position. This is themax_position
Shutterposition<x> 30
Return the shutter to starting position. This must be the same position as measured in step #1 (reference_position
). If not,ShutterCloseDuration
must be adjusted.Shutterposition<x> 50
Shutterposition<x> 70
Shutterposition<x> 80
If you do not reachmax_position
you have a motor delay problem. Measure the shutter position. This is thereal_max
. Use this value in the calculation below.ShutterMotorDelay<x> <delay>
Motor<delay>
calculation - fine tune in 0.05 second increments (e.g.0.65
) as required.
<delay> = ((max_position-real_max) / 2) / (((100/80) * max_position) / ShutterOpenDuration)
Close the shutter and repeat this procedure until the motor delay is set properly.
When shutter is running in normal ShutterMode: 0
, you already have basic control over the shutter movement using tasmota switches or tasmota buttons in the module configuration to directly drive the shutter relays. For short circuit safe operation ShutterMode: 1
direct control of the relays will not give you a nice user interface since you have to 1st set the direction with one switch or button and 2nd switch on the power by the other switch or button.
To have shutter mode independent button control over the shutter and not over its relays one can use the ShutterButton<x>
command. It also introduces some more features, see below:
ShutterButton<x> <button> <func> <mqtt>
This assigns a tasmota button <button>
to control your shutter <x>
having functionality <func>
. The tasmota button <button>
must already be configured in the module configuration. You can assign multiple buttons to a single shutter. Any button can only control one shutter (beside the <mqtt>
broadcast feature, see description below). Any press of the button while the shutter is moving will immediately stop the shutter.
One can remove all button control for shutter <x>
by ShutterButton<x> 0
.
The assigned button can have one of the following functionalities:
-
Setup for an "up" button:
ShutterButton<x> <button> up <mqtt>
Single press will move shutter to 100%, double press to 50% and tripple press to 74%. Holding the button for more than the hold time (SetOption32) moves all shutters with same<grouptopic>
to 100% when<mqtt>
is equal to1
. When<mqtt>
is equal to0
hold action of this button is same as single press. -
Setup for a "down" button:
ShutterButton<x> <button> down <mqtt>
Single press will move shutter to 0%, double press to 50% and tripple press to 24%. Holding the button for more than the hold time (SetOption32) moves all shutters with same<grouptopic>
to 0% when<mqtt>
is equal to1
. When<mqtt>
is equal to0
hold action of this button is same as single press. -
Setup for an "updown" button:
ShutterButton<x> <button> updown <mqtt>
Single press will move shutter to 100%, double press down to 0% and tripple press to 50%. No hold action and no other shutter control by MQTT,<mqtt>
is don't care here.
More advanced control of the button press actions is given by the following ShutterButton<x>
command syntax:
ShutterButton<x> <button> <p1> <p2> <p3> <ph> <m1> <m2> <m3> <mh> <mi>
<button>
1..4
: Button number, 0/-
: disable buttons for this shutter<p1>
0..100
: single press position, -
: disable<p2>
0..100
: double press position, -
: disable<p3>
0..100
: tripple press position, -
: disable<ph>
0..100
: hold press position, -
: disable<m1>
1
: enable single press position MQTT broadcast, 0/-
: disable<m2>
1
: enable double press position MQTT broadcast, 0/-
: disable<m3>
1
: enable tripple press position MQTT broadcast, 0/-
: disable<mh>
1
: enable hold press position MQTT broadcast, 0/-
: disable<mi>
1
: enable MQTT broadcast to all shutter indices, 0/-
: disable
Any parameters are optional: when missing all subsequent parameters are set to disable
.
By a button single press the shutter is set to position <p1>
. Double press will drive the shutter to position <p2>
and tripple press to position <p3>
. Holding the button for more than the SetOption32
time sets the shutter position to <ph>
. Any button action <p1>
to <ph>
can be disabled by setting the parameter to -
. Independent from configuration <p1>
to <ph>
any press of the button while the shutter is moving will immediately stop the shutter.
Global steering of all your shutters at home is supported by additional MQTT broadcast. By any button action a corresponding MQTT command can be initiated to the <grouptopic>
of the device. For single press this can be enabled by <m1>
equal to 1
, disabling is indicated by -
. Double to hold MQTT configurations are given by <m2>
to <mh>
, correspondingly. When <mi>
is equal to -
only cmnd/<grouptopic>/Shutterposition<x> <p1..h>
is fired. When <mi>
is equal to 1
, <x>
=1..4
is used to control any shutter number of a tasmota device having same <grouptopic>
.
Examples:
ShutterButton<x> <button> 100 50 74 100 0 0 0 1 1
is same asShutterButton<x> <button> up 1
.ShutterButton<x> <button> 0 50 24 0 0 0 0 1 1
is same asShutterButton<x> <button> down 1
.ShutterButton<x> <button> 100 0 50 - 0 0 0 0 0
is same asShutterButton<x> <button> updown 0
.
Module WiFi setup, restart, upgrade and reset according to Buttons and Switches are supported "child and fool save" only when no button restriction (SetOption1) is given and when all configured shutter buttons of that shutter are pressed simultaneously.
If using a Sonoff Dual R2, use the following Template:
{"NAME":"Sonoff Dual R2","GPIO":[17,255,0,255,0,22,18,0,21,56,0,0,0,0],"FLAG":0,"BASE":39}
- Ensure that the first relay opens the shutter
- Ensure that the second relay closes the shutter
- Set
ShutterRelay<x>
- Set
ShutterOpenDuration<x>
- Set
ShutterCloseDuration<x>
- Set
ShutterSetHalfway<x>
(optional) - Set
ShutterInvert<x>
(optional) - If the shutter uses a pulse motor instead of a motors with one wire for each direction (i.e., duration based), define
PulseTime<x> 2
on both relays. The driver's behavior will change to a pulse motor that needs pulses to start and stop.
Tasmota rule triggers:
Shutter<x>#Position
Shutter<x>#Open
andShutter<x>#Close
Shutter#Moving
is triggered every second if the shutter is movingShutter#Moved
is triggered ONCE after the shutter stoppedShutter<x>#Button<button>=0
is triggered whenbutton
is holdShutter<x>#Button<button>=<n>
is triggered whenbutton
is pressedn
timesShutter<x>#Button0=0
is triggered when all buttons of that shutter are hold simultaneouslyShutter<x>#Button0=<n>
is triggered when all buttons of that shutter are pressed simultaneouslyn
times
If more than one shutter is configured, it is not possible to know which shutter is moving.
Examples:
-
Publish a message with the position of the shutter:
Rule1 ON Shutter1#Position DO Publish status/%topic%/level {"%value%"} ENDON
-
Open/Close or set a specific position for a shutter. This example drives the second shutter to the same position as the first shutter:
Rule1 ON Shutter1#Position DO ShutterPosition2 %value%" ENDON
For shutter position to persist in Home Assistant through device reboots, execute PowerRetain 1
.
These sample configurations should allow the shutter work in Home Assistant. Change the device MQTT topic and templates to match your settings. This is only an example and may need further modification to work in your environment.
The configuration requirements changed starting with Home Assistant version 0.82.0. This example uses a new configuration for roller shutters with options for positioning. It assumes that %prefix%/%topic%/
is configured in the Tasmota Full Topic MQTT parameter.
cover:
- platform: mqtt
name: "Balcony Blinds"
availability_topic: "tele/%topic%/LWT"
payload_available: "Online"
payload_not_available: "Offline"
position_topic: stat/%topic%/Shutter1
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
Check Issue 130 for more information about this configuration.
Another Home Assistant integration example:
cover:
- platform: mqtt
name: "Test"
availability_topic: "tele/%topic%/LWT"
state_topic: "stat/%topic%/RESULT"
command_topic: "cmnd/%topic%/Backlog"
value_template: '{{ value | int }}'
qos: 1
retain: false
payload_open: "ShutterOpen1"
payload_close: "ShutterClose1"
payload_stop: "ShutterStop1"
state_open: "ON"
state_closed: "OFF"
payload_available: "Online"
payload_not_available: "Offline"
optimistic: false
tilt_command_topic: 'cmnd/%topic%/ShutterPosition1'
tilt_status_topic: 'cmnd/%topic%/ShutterPosition1'
set_position_topic: 'cmnd/%topic%/ShutterPosition1'
position_topic: "stat/sonoff-cletto/SHUTTER1"
tilt_min: 0
tilt_max: 100
tilt_closed_value: 0
tilt_opened_value: 100
This example works with Home Assistant versions prior to 0.82:
cover:
- platform: template
covers:
studio_shutter:
friendly_name: "Studio Shutter"
position_template: "{{ states.sensor.studio_shutter_position.state | int }}"
open_cover:
service: mqtt.publish
data:
topic: 'cmnd/%topic%/ShutterOpen1'
close_cover:
service: mqtt.publish
data:
topic: 'cmnd/%topic%/ShutterClose1'
stop_cover:
service: mqtt.publish
data:
topic: 'cmnd/%topic%/shutterstop1'
set_cover_position:
service: mqtt.publish
data_template:
topic: 'cmnd/%topic%/ShutterPosition1'
payload: '{{position}}'
Typical log output (log level 3
) when starting from ShutterOpen1
. The first command is ShutterClose1
. After closing, open it to 50% with ShutterPosition1 50
SHT: Accuracy digits: 1
SHT: Shutter 0 (Relay:1): Init. Pos: 20000 [100 %], Open Vel.: 100 Close Vel.: 100 , Max Way: 20000, Opentime 10.0 [s], Closetime 10.0 [s], CoedffCalc: c0: 0, c1 200, c2: 200, c3: 0, c4: 0, binmask 3, is inverted 0, ShutterMode 0
....
CMD: ShutterClose
SRC: Serial
SHT: Position in: payload 0, index 1, source 7
SHT: lastsource 7:, realpos 20000, target 0, payload 0
SHT: Start shutter in direction -1
SRC: Shutter
MQT: stat/%topic%/RESULT = {"POWER2":"ON"}
MQT: stat/%topic%/POWER2 = ON
MQT: stat/%topic%/RESULT = {"ShutterClose1":0}
SHT: Shutter 0: Real Pos: 19000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 0.5 [s]
CFG: Saved to flash at F5, Count 725, Bytes 4096
SHT: Shutter 0: Real Pos: 17000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 1.5 [s]
SHT: Shutter 0: Real Pos: 15000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 2.5 [s]
SHT: Shutter 0: Real Pos: 13000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 3.5 [s]
SHT: Shutter 0: Real Pos: 11000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 4.5 [s]
SHT: Shutter 0: Real Pos: 9000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 5.5 [s]
SHT: Shutter 0: Real Pos: 7000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 6.5 [s]
SHT: Shutter 0: Real Pos: 5000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 7.5 [s]
SHT: Shutter 0: Real Pos: 3000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 8.5 [s]
SHT: Shutter 0: Real Pos: 1000, Target 0, source: Shutter, start-pos: 100 %, direction: -1, rtcshutter: 9.5 [s]
SHT: Shutter 0: Real Pos. 0, Stoppos: 0, relay: 1, direction -1, pulsetimer: 0, rtcshutter: 10.1 [s], operationtime 0
MQT: stat/%topic%/SHUTTER1 = 0
SRC: Shutter
MQT: stat/%topic%/RESULT = {"POWER2":"OFF"}
MQT: stat/%topic%/POWER2 = OFF
MQT: tele/%topic%/RESULT = {"Shutter1":{"Position":0,"direction":0}}
CFG: Saved to flash at F4, Count 726, Bytes 4096
....
CMD: ShutterPosition 50
SRC: Serial
SHT: Position in: payload 50, index 1, source 23
SHT: lastsource 23:, realpos 0, target 10000, payload 50
SHT: Start shutter in direction 1
SRC: Shutter
MQT: stat/%topic%/RESULT = {"POWER1":"ON"}
MQT: stat/%topic%/POWER1 = ON
MQT: stat/%topic%/RESULT = {"ShutterPosition1":50}
SHT: Shutter 0: Real Pos: 1500, Target 10000, source: Shutter, start-pos: 0 %, direction: 1, rtcshutter: 0.8 [s]
CFG: Saved to flash at FB, Count 727, Bytes 4096
SHT: Shutter 0: Real Pos: 3500, Target 10000, source: Shutter, start-pos: 0 %, direction: 1, rtcshutter: 1.8 [s]
SHT: Shutter 0: Real Pos: 5500, Target 10000, source: Shutter, start-pos: 0 %, direction: 1, rtcshutter: 2.7 [s]
SHT: Shutter 0: Real Pos: 7500, Target 10000, source: Shutter, start-pos: 0 %, direction: 1, rtcshutter: 3.7 [s]
SHT: Shutter 0: Real Pos: 9500, Target 10000, source: Shutter, start-pos: 0 %, direction: 1, rtcshutter: 4.7 [s]
SHT: Shutter 0: Real Pos. 10000, Stoppos: 50, relay: 0, direction 1, pulsetimer: 0, rtcshutter: 5.0 [s], operationtime 2
MQT: stat/%topic%/SHUTTER1 = 50
SRC: Shutter
MQT: stat/%topic%/RESULT = {"POWER1":"OFF"}
MQT: stat/%topic%/POWER1 = OFF
MQT: tele/%topic%/RESULT = {"Shutter1":{"Position":50,"direction":0}}
CFG: Saved to flash at FA, Count 728, Bytes 4096