Elegant way to send a whole sensor (inc attributes) by MQTT?

I’m trying to take the output of the met office integration and send it out via MQTT so I can display it on a separate device (a Pi Zero with a DisplayHatMini).

At the moment I’m using the automation below which is working, but it seems a bit clunky so I was wondering if there is a more concise or elegant way of doing this? At the moment it’s basically manually building up the json individually from the states of the atrributes one at a time, and would need reworking if more attributes get added in the future.

Is there an easier way to json encode the whole sensor output all at once?
I can find plenty of threads/examples of taking json data into HASS, but not much for going the other way like this…

alias: MQTT Weather - Met Office
description: Output the Met Office Gatwick Weather to MQTT
trigger:
  - platform: mqtt
    topic: displaypi/state
    payload: weather
  - platform: time_pattern
    minutes: /15
condition: []
action:
  - service: mqtt.publish
    data:
      topic: metweather/lastupdate
      retain: true
      qos: "0"
      payload: "{{ states('sensor.time_date') }}"
  - service: mqtt.publish
    data:
      topic: metweather/3-hour
      retain: true
      qos: "0"
      payload: >-
        {  "condition": {{states('sensor.london_gatwick_airport_weather') |
        string }}, 
           "temperature": {{states('sensor.london_gatwick_airport_temperature') | string }},
           "feels_like": {{states('sensor.london_gatwick_airport_feels_like_temperature') | string }},
           "humidity": {{states('sensor.london_gatwick_airport_humidity') | string }},
           "probability": {{states('sensor.london_gatwick_airport_probability_of_precipitation') | string }},
           "uv": {{states('sensor.london_gatwick_airport_uv_index') | string }},
           "visibility": {{states('sensor.london_gatwick_airport_visibility') | string }},
           "vis_dist": {{states('sensor.london_gatwick_airport_visibility_distance') | string }},
           "wind_speed": {{states('sensor.london_gatwick_airport_wind_speed') | string }},
           "wind_dir": {{states('sensor.london_gatwick_airport_wind_direction') | string }},
           "wind_gust": {{states('sensor.london_gatwick_airport_wind_gust') | string }} 
        }
  - service: mqtt.publish
    data:
      topic: metweather/daily
      retain: true
      qos: "0"
      payload: >-
        {  "condition": {{states('sensor.london_gatwick_airport_weather_daily')
        | string }}, 
           "temperature": {{states('sensor.london_gatwick_airport_temperature_daily') | string }},
           "feels_like": {{states('sensor.london_gatwick_airport_feels_like_temperature_daily') | string }},
           "humidity": {{states('sensor.london_gatwick_airport_humidity_daily') | string }},
           "probability": {{states('sensor.london_gatwick_airport_probability_of_precipitation_daily') | string }},
           "uv": {{states('sensor.london_gatwick_airport_uv_index_daily') | string }},
           "visibility": {{states('sensor.london_gatwick_airport_visibility_daily') | string }},
           "vis_dist": {{states('sensor.london_gatwick_airport_visibility_distance_daily') | string }},
           "wind_speed": {{states('sensor.london_gatwick_airport_wind_speed_daily') | string }},
           "wind_dir": {{states('sensor.london_gatwick_airport_wind_direction_daily') | string }},
           "wind_gust": {{states('sensor.london_gatwick_airport_wind_gust_daily') | string }} 
        }
mode: single

Marshall and format the data in HASS for the consumer - e.g. the RPi display.

I have an automation that publishes data from a few sensors to MQTT, for processing on a Linux box - the data consumer uses a short shell script to get the values via mosquitto_sub and process them. The payload is in CSV.

Mind you, I also have a RPi MQTT client that implements full HASS auto-discovery to publish and control an automated watering system, and that Python code is about 30% formatting into JSON!

The above does work (or at least it outputs what looks like suitable data to MQTT, I haven’t implemented the client-side decoding yet) but it seemed to me a rather inefficient and clunky way to do it.

So I thought I’d ask if there was a better route.

This is the full output from the main integration, although it does expose the individual attributes also as individual sensors which is what I’m using above. The first item is the main sensor value, below are the attributes.

state: pouring

temperature: 10
temperature_unit: °C
humidity: 83
pressure_unit: mbar
wind_bearing: SW
wind_speed: 11
wind_speed_unit: mph
visibility_unit: mi
precipitation_unit: mm
forecast:
  - datetime: '2022-11-01T21:00:00+00:00'
    condition: pouring
    precipitation_probability: 71
    wind_bearing: SW
    temperature: 10
    wind_speed: 11
  - datetime: '2022-11-02T00:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 0
    wind_bearing: WSW
    temperature: 9
    wind_speed: 13
  - datetime: '2022-11-02T03:00:00+00:00'
    condition: clear-night
    precipitation_probability: 0
    wind_bearing: WSW
    temperature: 7
    wind_speed: 9
  - datetime: '2022-11-02T06:00:00+00:00'
    condition: clear-night
    precipitation_probability: 0
    wind_bearing: SW
    temperature: 7
    wind_speed: 7
  - datetime: '2022-11-02T09:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 1
    wind_bearing: SSW
    temperature: 11
    wind_speed: 7
  - datetime: '2022-11-02T12:00:00+00:00'
    condition: cloudy
    precipitation_probability: 5
    wind_bearing: SSW
    temperature: 14
    wind_speed: 13
  - datetime: '2022-11-02T15:00:00+00:00'
    condition: cloudy
    precipitation_probability: 10
    wind_bearing: SSW
    temperature: 14
    wind_speed: 13
  - datetime: '2022-11-02T18:00:00+00:00'
    condition: rainy
    precipitation_probability: 53
    wind_bearing: SSW
    temperature: 14
    wind_speed: 16
  - datetime: '2022-11-02T21:00:00+00:00'
    condition: pouring
    precipitation_probability: 91
    wind_bearing: SSW
    temperature: 13
    wind_speed: 16
  - datetime: '2022-11-03T00:00:00+00:00'
    condition: pouring
    precipitation_probability: 88
    wind_bearing: SW
    temperature: 12
    wind_speed: 11
  - datetime: '2022-11-03T03:00:00+00:00'
    condition: pouring
    precipitation_probability: 88
    wind_bearing: SSW
    temperature: 11
    wind_speed: 9
  - datetime: '2022-11-03T06:00:00+00:00'
    condition: rainy
    precipitation_probability: 59
    wind_bearing: SSW
    temperature: 11
    wind_speed: 7
  - datetime: '2022-11-03T09:00:00+00:00'
    condition: pouring
    precipitation_probability: 88
    wind_bearing: S
    temperature: 11
    wind_speed: 7
  - datetime: '2022-11-03T12:00:00+00:00'
    condition: rainy
    precipitation_probability: 61
    wind_bearing: WSW
    temperature: 11
    wind_speed: 7
  - datetime: '2022-11-03T15:00:00+00:00'
    condition: rainy
    precipitation_probability: 50
    wind_bearing: WSW
    temperature: 11
    wind_speed: 7
  - datetime: '2022-11-03T18:00:00+00:00'
    condition: cloudy
    precipitation_probability: 7
    wind_bearing: WSW
    temperature: 10
    wind_speed: 4
  - datetime: '2022-11-03T21:00:00+00:00'
    condition: clear-night
    precipitation_probability: 3
    wind_bearing: SW
    temperature: 8
    wind_speed: 4
  - datetime: '2022-11-04T00:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 5
    wind_bearing: WNW
    temperature: 6
    wind_speed: 4
  - datetime: '2022-11-04T03:00:00+00:00'
    condition: clear-night
    precipitation_probability: 3
    wind_bearing: NW
    temperature: 6
    wind_speed: 4
  - datetime: '2022-11-04T06:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 5
    wind_bearing: NW
    temperature: 6
    wind_speed: 4
  - datetime: '2022-11-04T09:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 3
    wind_bearing: WNW
    temperature: 8
    wind_speed: 7
  - datetime: '2022-11-04T12:00:00+00:00'
    condition: sunny
    precipitation_probability: 4
    wind_bearing: NW
    temperature: 11
    wind_speed: 11
  - datetime: '2022-11-04T15:00:00+00:00'
    condition: rainy
    precipitation_probability: 34
    wind_bearing: NW
    temperature: 11
    wind_speed: 9
  - datetime: '2022-11-04T18:00:00+00:00'
    condition: clear-night
    precipitation_probability: 0
    wind_bearing: WNW
    temperature: 9
    wind_speed: 7
  - datetime: '2022-11-04T21:00:00+00:00'
    condition: clear-night
    precipitation_probability: 0
    wind_bearing: WNW
    temperature: 7
    wind_speed: 4
  - datetime: '2022-11-05T00:00:00+00:00'
    condition: clear-night
    precipitation_probability: 0
    wind_bearing: W
    temperature: 6
    wind_speed: 4
  - datetime: '2022-11-05T03:00:00+00:00'
    condition: clear-night
    precipitation_probability: 1
    wind_bearing: WSW
    temperature: 5
    wind_speed: 4
  - datetime: '2022-11-05T06:00:00+00:00'
    condition: partlycloudy
    precipitation_probability: 2
    wind_bearing: SW
    temperature: 5
    wind_speed: 2
  - datetime: '2022-11-05T09:00:00+00:00'
    condition: cloudy
    precipitation_probability: 10
    wind_bearing: SSW
    temperature: 8
    wind_speed: 4
  - datetime: '2022-11-05T12:00:00+00:00'
    condition: cloudy
    precipitation_probability: 17
    wind_bearing: SSW
    temperature: 12
    wind_speed: 9
  - datetime: '2022-11-05T15:00:00+00:00'
    condition: rainy
    precipitation_probability: 63
    wind_bearing: SSW
    temperature: 12
    wind_speed: 11
  - datetime: '2022-11-05T18:00:00+00:00'
    condition: rainy
    precipitation_probability: 57
    wind_bearing: SSW
    temperature: 12
    wind_speed: 9
  - datetime: '2022-11-05T21:00:00+00:00'
    condition: rainy
    precipitation_probability: 43
    wind_bearing: SSW
    temperature: 11
    wind_speed: 7
attribution: Data provided by the Met Office
friendly_name: Met Office London Gatwick Airport 3-Hourly