Setting Time Based Automation via MQTT Sensor

I have an automation which I’d like to trigger at a specific time. The catch is that I want to set the time for it to trigger from MQTT. I believe this is doable using a template trigger but this old post has warned me that using template triggers is a bad practice.

Is there a better way to do this?

just set up a cron job to do a mosquitto_pub at that time from any machine that supports both. i dunno, any system would probably work, maybe even raspi?

Just to clarify the question getting the time into MQTT is not a problem, I already have that. What I’m wondering about is how to setup the automation in Home Assistant to trigger at a time to be determined from a sensor (MQTT in this case) instead of a fixed time.

just write the automation based on the payload of the message

Can you give an example of an automation written that way? I haven’t been able to find one.

first you need to create a sensor, I’ll use one of mine for instance

- platform: mqtt
  name: Downstairs Motion
  state_topic: "/ha/motion/downstairs"
  retain: true

then you create the automation

- alias: Downstairs Motion Foyer On
  trigger:
    platform: state
    entity_id: sensor.downstairs_motion
    from: 'false'
    to: 'true'
  condition:
    - condition: time
      after: '22:30:00'
      before: '05:30:00'
  action:
    - service: light.turn_on
      data:
        entity_id:
          - light.foyer_lamp

so, this just takes an mqtt state and when it changes it turns the light on. You pretty much just run your automation based on sensor state. Is this what you’re looking for?

Not really, that’s a pretty standard automation which triggers based on a state change. I want an automation which triggers based on a time. Think like an alarm clock. So far that would be pretty standard you would use an automation like:

- action:
  - data:
      entity_id: light.master_bedroom_light
    service: light.turn_on
  alias: Master Bedroom On Morning
  condition: []
  id: '1515013646654'
  trigger:
  - at: '10:09:00'
    platform: time

Except I don’t want it to be 10:09 every morning. Instead I want to read the trigger time from another sensor (MQTT in this case) which is carrying the time to trigger in the payload of the sensor. So instead of:

  trigger:
  - at: '10:09:00'
    platform: time

it would be something more like:

  trigger:
  - at: {{ states('sensor.wake_alarm_time') }}
    platform: time

But this does not work obviously.

Hey don’t have much time right now but I have done something like this check this package out. https://github.com/PhyberApex/homeassistant-config/blob/master/config/packages/alarm_clock_janis.yaml

Let me know if you need further assistance!

~Cheers

Per this post I think you’ll need to use the time & date sensor. Add the time & date sensor to your config, and then use a template trigger with a template that I think will be:

value_template: '{{ sensor.time == states.sensor.wake_alarm_time }}'

You might have to iron out the syntax for sensor.time half of that, but the templating page of the dev tools should be able to help you with that process.

@Dolores see my original post though, it seems like there is a strong suggestion to avoid using template triggers unless there is no other way to accomplish something (see the original post linked to for the reason why which involves the template being re-rendered every time any state on the system changes). I do suspect I could make it work with a template trigger similar to what you posted but probably with a little more manipulation of the data e.g. some strftime etc.

I took a look at @PhyberApex’s solution which is something I actually had considered. To summarize it is to create an automation which is triggered once every minute ("/1") and then create a condition to the automation which checks the time of the sensor against the current time. This does avoid using a trigger template though the engineer inside me thinks there has got to be a less “wasteful” way than running an automation every minute which will then be blocked by a condition 1,439 times a day. If it turns out that’s not the case though this may be a “less wasteful” solution than a trigger template which renders every time any state on the system changes.

Anyone have an explanation for why trigger templates are re-rendered any time any state on the system changes and not just when one of the states mentioned in the template changes? I must be missing something as that seems unnecessary.

For those doing additional research on this I have since turned up a couple more older questions about this here and here. One suggests using a trigger template as the solution, the other more-or less as indicated above where the check is a condition to a trigger which runs more frequently.

I have heard template triggers are to be avoided as well, but am using a few with no noticeable performance impact on my pi3. I think if the feature were that bad, it probably wouldn’t be included in home assistant. But maybe yours would be worse because it’s being evaluated against a time sensor?

How often do you expect the mqtt value to change? Perhaps you could indeed run the automation to update it at some regular interval, but the interval could be rather large.

To counter your engineer self, channel your engineering manager self and stop letting perfect get in the way of good enough. :stuck_out_tongue:

1 Like

I only expect the MQTT value to change once a day, though I expect to use several automations which do things X minutes before or after the time value and probably several different time values as well.

As it stands it really seems to be a question of whether automations triggering every minute and then blocking based on a condition or whether re-rendering templates on the change of state for all states on the system is less wasteful. There are a lot of states being tracked so my first inclination is that triggering every minute and then blocking on the condition is the better of two bad choices.

I do hope for two improvements to future versions of HA though. The first is that template triggers should really only be re-rendered on a state change for a state which is listed in the template. The second is that there should be a programmatic way to set timer automations. As I’ve dug further into this I’ve found a fair number of people who want to do this sort of thing so I have some hope for that.

1 Like

Okay so at the top of my head I could think of a way to may satisfy your inner engineer. If you make one template sensor which renders to true/false or on/off or something like that depending on the condition you can give this sensor one or multiple entity_ids which means it only updates if those change their state. You can then make an automation depending on that template sensor. It would add one more sensor or even multiple sensors if I understood what you want to do correctly.

On the other topic of template trigger being able to be given an entity_id I actually agree…this should be possible the same way as for template sensors.

~Cheers

Excellent! Even though it’s a bit kludgy (what complicated thing isn’t?) that’s the sort of solution I was looking for. I’ll have to do some experimenting with it over the next few days. If I make the extra sensors hidden sensors it’s sort of messy in the configuration file but it does accomplish the goal. Thanks @PhyberApex!

1 Like