I have a rather simple automation that worked flawlessly for months and has suddenly stopped working.
There is a small electric space heater in my office that I use on cold days. Sometimes I leave the office and forget to turn it off, heating an empty room for hours and wasting energy. I created an automation that would control the receptacle the heater is plugged into via a Sonoff S31 Lite zigbee smartplug. The smartplug cycles on and off during my typical office hours, ensuring the maximum amount of time I’m heating an empty room is less than one hour.
When the smartplug is first switched on at 6 am, the space heater turns on in a standby mode, with the heating element off. If I want heat, I then manually turn on the heating element. If not, the heater stays in a standby mode with the heating element off. After a one hour delay, the smartplug switches off, turning the heater completely off. After a 15 second delay, the smartplug turns back on, and the heater turns on in standby mode again. This cycle repeats fourteen times until the smartplug turns off and stays off at my end of my day.
The automation now only makes it completely through two cycles before it stops. The error message is “Stopped because an error was encountered at November 16, 2025 at 7:59:46 AM (runtime: 7185.78 seconds)
tuple index out of range”. As I said in the beginning, this automation has worked perfectly for months, until a few days ago.
Have you considered using the Generic Thermostat integration to control your heater? All you need is a temperature sensor in the room and the Generic Thermostat integration will turn the heater on/off to maintain a desired temperature.
You can use the Schedule integration to create a schedule to determine when the room should or shouldn’t be heated (and/or when to change the desired temperature).
Another benefit of using the Generic Thermostat integration is that it will produce a climate entity which you can display in the UI using the Thermostat card (so, if you wish, you can manually adjust the desired target temperature or turn heating off altogether).
Thanks Didgeridrew, I appreciate your comments and the yaml automation.
I’ve only used the UI tool in my automations, so I’m looking at your code now to understand the flow. Also looking at the HA documentation to understand a couple of the more advanced features not in the UI automation tool. Let me walk through your code to make sure I understand what you’ve done.
The automation starts with a time trigger at 6am and a trigger id of “cycle”. At the “choose” branch action, any trigger with the id of “cycle” sets the smartplug to off (this is not needed in the initial 6am cycle, but is required in subsequent cycles).
The next action checks the trigger type, to differentiate whether this is the first 6am cycle or a subsequent cycle. If it is the 6am cycle, the trigger type is “time” which sets the off delay to zero seconds. The smartplug is immediately turned on and a timer started for an hour (actually 59’ 45", but who is counting?). When the timer completes, the timer state goes idle and fires a “timer.finished” event. The smartplug is still in the on state.
The automation continues when the “timer.finished” event triggers the automation a second time. The trigger id is “cycle”, so the first action is to set the smartplug to off. The next action checks the trigger type, checking to see if this is the first 6am cycle. Since the trigger type of the current trigger is “event”, this is not the 6am cycle and the off delay is set to 15 seconds. After the delay, the smartplug is turned on and a timer is started for an hour (actually 59’ 45"). When the timer completes, the timer state goes idle and fires another “timer.finished” event.
The automation ends with a time trigger at 6pm and trigger id of “end”. At the “choose” branch action, any trigger with the id of “end” sets the smartplug to off. Nothing should happen until the following morning at 6 am.
Here are some of the things I don’t understand:
It looks like you created an entity_id that describes a timer associated with the smartplug. Is this a helper? Is there any other thing needed to define and use that timer other than what you show in the yaml?
You use multiple (three) triggers that each have been given trigger ids. Two of the triggers share the same id (cycle). It looks like sharing the same id allows the first cycle (at 6am) to share the same automation as the subsequent cycles.
The 15 second delay sequence uses an if/then/else condition to disregard the delay on the initial 6am cycle and only use it on subsequent cycles. Is there any reason this if/then/else couldn’t be eliminated and just delay all cycles?
I’m not sure how the automation ends after running all day. There should be a timer.finished event trigger attempting to keep things going and a second time trigger attempting to end things for the day. Both are arriving about the same time. Do you just insure the ending time trigger occurs after the last desired timer.finished event to abort the automation?
Yes, its a Timer Helper. You need to create it either through the Helpers tab or in YAML, as described in the link in my first post.
Yes. If desired you could set up a unique action sequence for each trigger ID, or you could use an If/Then action to check the trigger again before performing the “turn off” action… but it’s not really necessary since the initial “turn off” action will have no effect at 6am since the switch should already be off.
No, you can use a static delay on all cycles. I was just trying to match the outcomes of your original automation.
That’s a good point. I used a Time trigger, but you could use any trigger that makes sense for your situation. And, we could make it more flexible by adding an action to that sequence to stop the timer. I’ll add that in the post above.
Thinking about it a bit more, a better automation overall would be to use the plug’s power monitoring instead of a static time cycle. For example, if the switch turns on at 6am but you never actually run the heater, all the turning on and off is just pointless traffic on your mesh and creates small down times when you can’t start the heater.
Here is an edit on the yaml from Didgeridrew. I use the 15 sec delay for all cycles, eliminating the if/then/else based on trigger types. I also force the end of the automation by sending the end time trigger a minute after last cycle has started (6:01pm). The actions of this last trigger cancel the timer and turn off the smartplug. Since this is my first yaml experience, I expect some errors in there. Please comment.
OP explained that turning the switch on places the heater into an idle/standby mode then they make it heat as needed… it doesn’t actually run for most of the 12 hours.
I assumed they press a button… … but it is unclear.
Plenty of newer-but-not-smart devices have digital on/off controls that would reset to idle/off by a power cycle. I’ve got a couple area fans that I use a similar smart-plug based method to reset them to standby when they are left running and their area is empty.
Yes Taras. By cycling power to the heater the automation simply puts the heater in a standby mode every hour on the hour during the day.
This automation only powers the heater (in standby mode) during the hours I typically use the office. It also assures if I turn on the heating element and happen to leave the area, the heater will not continue to run all day. It will only run until the next even hour (e.g. 8am, 9am, 10am, etc.). The slight inconvenience is I need to manually turn on the heating element when I’m cold. A positive side effect happens every hour when the heater enters standby, it puts out a single “beep” to remind me of the time, like an old grandfather clock.
There is a crude thermostat on the space heater, but it does a poor job controlling room temperature, so I just run the heater periodically to take the chill off my immediate work area. I’m sure there are more elegant solutions to this problem, but this works for me. Thanks.