Post sensor values to MQTT

Correct.

If you want to publish your RESTful sensor’s state to an MQTT topic, use an automation.

- alias: 'Publish sensor value'
  trigger:
    platform: state
    entity_id: sensor.my_sensor
  action:
    service: mqtt.publish
    data_template:
      payload: "{{trigger.to_state.state}}"
      topic: whatever/topic/you/want

If you want to publish the states of several sensors yet with only one automation, you could use something like this:

- alias: 'Publish multiple sensor values'
  trigger:
    platform: state
    entity_id: sensor.my_sensor1, sensor.my_sensor2, sensor.my_sensor3
  action:
    service: mqtt.publish
    data_template:
      payload: "{{trigger.to_state.state}}"
      topic: "sensor/{{trigger.to_state.object_id}}"
9 Likes

I’m presuming the OP is wanting ot publish every, or at least, most sensors. Is there a way of grouping a bunch of sensors and if they’re a member of that group they’re all published?

Not really, I create a lot of my sensors by the MQTT platform. Some data sources are slightly easier to get using the RESTful sensor (especially if in XML format), but I was looking to publish (some of) that data.

Yes I do that extensively already.

I was aware I could publish by polling HA with NR, I just wondered if there was an easier way.

Use the right tool for the job!

Cheers all.

On a related issue, can you get a notification when a service is run? I’m using the speedtestdotnet component and I want to publish the result. I don’t want to poll the sensor, I want to know when it has run then publish the latest value.

Not really Sort of. If you have a group of sensors called group.all_sensors and do this:

  trigger:
    platform: state
    entity_id: group.all_sensors

all it will accomplish is to trigger when the group’s state changes; you won’t know which member of the group changed its state. You would have to blindly publish the states of all group members regardless if the member had changed its state or not. That’s not a recommended design pattern.


EDIT
There’s no guarantee that bad practice will even work properly. Here’s a simple failure scenario:

  • You have a group of binary_sensors, they are all off, so the group’s state is also off.
  • One of the binary_sensors turns on so now the group’s state is on.
  • The group’s state-change causes the ‘bad practice’ Template Sensor to publish the state of the group’s members (so far, so good).
  • Another binary_sensor in the group turns on.
  • The group’s state is already on so there’s no state-change.
  • The Template Sensor doesn’t publish anything and there’s the flaw.

You can monitor events and detect when a specific service call is executed (see: Event Call_Service).

The speedtestdotnet component exposes one service:

speedtestdotnet.speedtest

However all of this amounts to creating an automation that’s triggered by an event, which is effectively equivalent to an automation that is triggered by a sensor’s state-change (namely the speedtestdotnet sensor you already have).

Assuming the value returned is different or is a ‘state change’ any update (even if the value doesn’t change)?

Effectively equivalent, meaning in both cases you need to use an automation.

Not sure why you would need to publish a value that hasn’t changed since the last time it was published but, yes, triggering based on event detection of the speedtest service will allow you to do that.

What about

@hsepm, ah, that might do the job. Thanks I’ll experiment tonight.

If its for speedtestdotnet, you may wish to explore at MQTT Eventstream.

FWIW, if there’s only one sensor, or just one service, that needs to be published then it seems to me that firing up an entire new integration (either MQTT Statestream or Eventstream) is overkill. A single automation will get the job done equally well.

This is a bit OT, but how do I trigger an automation when a service is run? I must be missing something…

As described in one of my earlier posts.

Try this experiment:

  • Go to Developer Tools > Events
  • Scroll down to Listen to an event
  • Enter call_service in Event to subscribe to
  • Click Start Listening
  • In another browser tab (or window) open the Lovelace UI and turn on a light.
  • Return to the browser pane containing Developer tools > Events and you’ll see the call_service event details for the service that turned on the light (i.e. light.turn_on).

For example, I have a patio light and here’s the event reported when I turned on the light:

Event 0 fired 3:10 PM:

{
    "event_type": "call_service",
    "data": {
        "domain": "light",
        "service": "turn_on",
        "service_data": {
            "entity_id": "light.patio"
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-03-10T19:10:16.090753+00:00",
    "context": {
        "id": "redacted",
        "parent_id": null,
        "user_id": "redacted"
    }
}

I can use that information to create an automation with an Event Trigger that fires only for that specific service call. Something like this:

  trigger:
    platform: event
    event_type: call_service
    event_data:
      domain: light
      service: turn_on

For your application, I imagine it would look like this:

  trigger:
    platform: event
    event_type: call_service
    event_data:
      domain: speedtestdotnet
      service: speedtest
1 Like

@123, Thanks for the help.

The final solution is this (from the automation UI);

Trigger

platform: event
event_type: state_changed
event_data:
  domain: speedtestdotnet
  attributes: last_updated
  entity_id: sensor.speedtest_download

Action

data_template:
  payload_template: '{{ states.sensor.speedtest_download.state }}'
  topic: emon/speedtest
service: mqtt.publish
3 Likes

I think you missed the spirit of what constitutes the “Solution”.

Have I? In what way?

The answer will reveal itself to you eventually.

Thank’s. This is the easiest way I found :slight_smile:

1 Like

You just posted in a thread that had been dead for over a year and I have no idea what you’re talking about.

Thank you @baz123 for posting your solution here :slight_smile:

2 Likes