How do you pass an MQTT payload to delay?

Convert whatever input you are sending into a number intended for your delay.

Sure it does.

??

It’s 100% a valid use case. You pass values along the flow to accomplish what you need. Can you please elaborate on your design and why you think it doesn’t work?

I guess the problem is decoding the payload and saving it aside to then use it in the delay.

I get the hint that is in the us of templates but there seems to be a wink wink nudge nudge in behind their use. I can certainly, with a MQTT sensor, see in logging in HA the values change.

I have found examples (or so I suspect) of use of variables in templates. So, I am suspecting that the MQTT payload (or part of it) might be assigned to a variable created by a template applied to the trigger. Is the scope of the variable persistent for the span of the automation? Do I just use the variable again in the delay field of a delay action? Would that be inside another template or would the delay action “understand” the variable?

What I suspect I need is an example of passing values between triggers and actions. I haven’t found anything yet that seems to cover that.

So sure it does, but how as the help files don’t illuminate or the jargon is obfuscating the magic.

So lets bumble through.

Say I set up my configuration.yaml with:

switch:
  - platform: mqtt
    name: zone1switch
    command_topic: "/os/12614780/1/1"

Intending to send that topic with payload of 300000.

Starting gambit for trigger (using automation hmi) is:

platform: numeric_state
entity_id: switch.zone1switch
above: '0'
below: '500000'
value_template: '{{ value_json }}'

Following the trigger in the automation I add a delay (without worrying for the moment for conversion of milliseconds):

delay: '{{ value_json }}'

Now I assume its value_jason and not value_json.payload? If I am not pulling the payload apart? Or is it something else? As tricky as “value”?

The only other idea I had was repackage the payload to be { “delay”: “300000”} to then pull the delay out of a json structure with {{ value_jason.delay }}?

That’s assuming its an MQTT switch is what I want. Still working that out. It wasn’t apparent that an MQTT trigger allowed me to use the payload in this way. The way it uses the payload appeared to suggest that the topic PLUS the specified payload were the trigger. Not much help if the range of payload values (delays) I might send vary.

Regardless, if I can get my head around passing values, I can worry about the correct gadget later. This templating is tough.

Ah! The thick plottens.

Found yet another help page clarifying data from MQTT triggers.

So, perchance, I really need do something like?:

platform: mqtt
topic: /my/topic

delay: 
  - milliseconds: '{{ trigger.payload }}'

<then post delay actions>

Not so sure of the way to format the delay. The HMI doesn’t support the YAML or at least it isn’t obvious how to use the HMI to set the delay in milliseconds. Unless milliseconds is a default? When I type in the yaml above, it got turned into [object] in HMI??

So, to factor out the delay story, I decided to try to pass to a logbook.log so tried:

alias: ''
data:
  message: trigger.payload
service: logbook.log

Got nothing in user log. Got the following in developer log:

Error while executing automation automation.new_automation. Invalid data for call_service at pos 1: required key not provided @ data['name']

Pity as I assumed the editing critique caught format problems, so apparently not.

Single or double curly braces did not help, the errors reported with slightly different is all.

Ah, some dopey formatting trick with logbook data means I need to use (notice “>”):

alias: ''
data:
  message: >
    {{ trigger.payload }}
  name: woo hoo
service: logbook.log

Now that gets me an interesting error:

Error while executing automation automation.new_automation. Error rendering template for call_service at pos 1: UndefinedError: 'trigger' is undefined

So now it seems that despite the help files indicating trigger.payload is a system variable it either isn’t or it drops out of scope between the trigger and the action so it is still not clear how to pass the payload out of the trigger into an action.

Is trigger.payload the tail of a breadcrumb? xxx.trigger.payload?

PS same problem if you swap notify.notify for logbook.log.
PS > gets converted to | by HMI editor so who know why but who cares, some dopey glitch as it otherwise appears to “work”.

Ah, so now it really doesn’t make sense. Going by another example, the following should work:

In automation under trigger:

platform: mqtt
topic: /my/topic

And then in automation under action:

alias: ''
data:
  message: >
    {{ trigger.payload }}
  name: woo hoo
service: logbook.log

Even assuming missing single quote was problem:

alias: ''
data:
  message: >
    '{{ trigger.payload }}'
  name: woo hoo
service: logbook.log

Which it is not as I still get “trigger not defined”!

So from the interpreting from the example, which is textual and in the configuration.yaml, what I am expecting the HMI to resolve to in principle is:

automation:
  trigger:
    platform: mqtt
    topic: /my/topic/
  action:
    service: logbook.log
       data:
          message: >
             '{{ trigger.payload }}'
 

Or there abouts. That is, and not getting hung up of my hack of likely configuration.yaml equivalent, the principle in the example appears upheld by what I have put into the HMI. The principle in the example appears to suggest that the scope of trigger.payload should persist between trigger and action. And yet, from the automation defined via HMI, the action when it runs reports trigger not defined.

Changing data: to data_template: gets same error report. The “trigger” is not in scope. That suggests that from the HMI the triggers and actions are not acting as if from one yaml file?

I should be in bed, so I will hold of trying this from configuration.yaml till a saner hour.

trigger not defined : an mqtt trigger needs a payload, e.g. :

  trigger:
  - payload: 'ON'
    platform: mqtt
    topic: sensor/doorbell_sensor

If you don’t have a payload in your trigger, how do you want the action to have a ‘{{ trigger.payload }}’ ?

@francisp I am missing the point then. Since the mqtt topic sends a payload from a different server. It will be variable number of milliseconds and it won’t be the string “ON”.

So are you saying that this is a state thing and ‘ON’ indicates a payload is attached/available?

If the payload is variable, you can’t use an mqtt trigger. The mqtt trigger checks for a specific payload.

You could try a mqtt sensor and a numeric trigger on that sensor.

@francisp You’re funny. I did get close with that approach previously, I could see the result in the log but couldn’t get it through to action, but (in hindsight) I was using wrong template in that experiment, so I will try again after I have had a sleep (4:30am here yawn). Thanks.

DOH! Double DOH!

In configuration.yaml I have:

sensor:
  - platform: mqtt
    name: zone1sensor
    state_topic: "/os/12614780/1/1"

In automation the defined trigger in HMI displays as a “Numeric state” in yaml with:

above: '0'
below: '500000'
entity_id: sensor.zone1sensor
platform: numeric_state

The defined action as a “call service” is:

alias: ''
data:
  message: |
    '{{ trigger.payload }}'
service: logbook.log

So, no problem with the script.py reporting “trigger not defined”.

I am getting the following in logbook:

9:46 PM zone1sensor changed to 300000

But, as you might understand, I would get that without setting the action or automation. So, the payload is not being sent to logbook. And to confirm, same problem with the notify.notify as “Call service”.

So, even if the payload is sitting in trigger.payload, it doesn’t seem to be used?

And, while that is tantalisingly close. If I want to send the same payload twice, the sensor state only reports on change. So, it seems I might look at a custom component. I might have more luck with straight python.

If it helps, pseudo-code for the automation that I actually want to get to is:

- trigger> on mqtt topic
- action>turn ESPHome based relay on
- action> wait for delay passed as payload on mqtt topic
- action>turn ESPHome based relay off

ESPHome stuff works a treat, it’s just trying to use the mqtt payloads as millisecond based delays has me drinking heavily … hic.

Why would you need to send the same payload twice? You use the state of the sensor to trigger.

You keep trying to use a template in a normal data: section, when you need to be using data_template:, just like the docs tell you.

Literally the first rule.

There are a few very important rules to remember when writing automation templates:

  1. You must use data_template in place of data when using templates in the data section of a service call.

@ flamingm0e What do you mean “same payload”? It is A payload and can have potentially different numeric values each time it is sent since I am trying to send different delays between ESPHome relay on/off as per pseudo code. You’re hung up on the payload being state and not data. Which is you taking the payload as part of the state I assume?

I did actually try the data_template at one point. I will try again to see if that helps.

Nope! Same thing. Oh, What? HA seems to have stopped. Just a mo.

Nope. Using data_template raises error in datalog:

Error while executing automation automation.new_automation. Invalid data for call_service at pos 1: required key not provided @ data['name']

Returning to data: returns to inert response (nothing in log when using logbook.log and nothing in notification panel when using notify.notify). Which is actually something I reported a few slots above in the thread, that is I have already used the “help” file you referred to to no avail. Since that help file does not talk about name: being mandatory field for logbook.log message. There isn’t much discussion in the logbook.log help on name: field being mandatory either, but I get that this is a yaml/json field thing so makes sense now with that error display.

It might help if you showed the full configuration of your sensor and your automation, instead of just snippets.

This works for me:

  - alias: mqtt_trigger_test
    trigger:
      - platform: mqtt
        topic: "mqtt_test/trigger" 
    action:
      service: logbook.log
      data_template:
        name: '{{ trigger.topic }}'
        message: '{{ trigger.payload }}'

sending a message with mosquitto_pub:

mosquitto_pub -t "mqtt_test/trigger" -m "300"

Result:
Auswahl_253

@francisp I haven’t shown “snippets”, there is no “full” configuration. Expect for the sensor: definition, in the configurtion.yaml, the rest is clipped of the HA automation HMI as yaml as I have actually stated. So, I did try to lead in with explanations of that but I guess that is part of the problem with the code in a couple of places. It might have made more sense for me to snip out the info in the automation.yaml file instead of out of the HMI, so I will try that approach from now on.

@VDRainer yep, I suspect that if I do set this up in the configuration.yaml it may well work. Where it is not coming together is by use of the automation editor. Though I do now get I may have missed the name: field which seems to be the “problem” I was chasing with the debugging using logbook. Learning heaps.

That’s why i don’t use it. :upside_down_face:

BTW, this automation works with the delay:

  - alias: mqtt_trigger_test
    initial_state: True
    hide_entity: False
    trigger:
      - platform: mqtt
        topic: "mqtt_test/trigger" 
    action:
      - service: logbook.log
        data_template:
          name: '{{ trigger.topic }}'
          message: '{{ trigger.payload }}'
      - service: switch.toggle
        entity_id: switch.test_switch
      - delay: '{{ trigger.payload }}'
      - service: switch.toggle
        entity_id: switch.test_switch
mosquitto_pub -t "mqtt_test/trigger" -m "00:00:03"
1 Like

@VDRainer I am getting that drift about the HMI, believe me :wink:

Thanks for the help. I was not likely to get there. What you have provided I can use to go back to help files to get better picture of how some of the subtleties work. Good job you.