Sending data from Home Assistant to ESP32/Tasmota for local display

I’m developing a ESP32 T-Display-S3 with tasmota (and Berry, LVGL and HASPmota!) to go on my boiler. I’ve got it displaying temperatures and whether the boiler is on or off and reporting same to HA where they appear as Entities within the “Boiler” device.
I now want to send a few values back to the Tasmota device so they can be displayed as well. Values such as ‘Litres consumed today’, ‘KWh today’, ‘Burn time today’, Cost today’ etc - not made up my mind yet but I calculate them all in HA already as I have been using a home coded ESP8266 sensor for the last couple of years but want to swap it for a Display version.
Can anyone recommend the best approach? Looks like I could send it in a Command or an MQTT message. I wondered about a TCP/UDP too! Or even ESPHome instead of Tasmota (I’ve only invested 3 days in it so far).

Edit: I’ve now cracked how to get values stored in Berry onto the screen.
Once I’ve cracked the whole thing I’ll put full details here and in the Tasmota forum.
Here’s a pic of what I’ve got so far. The left hand column is all from the sensors; the right hand column are made up numbers I put in pending working out how to get them from HA into the Tasmota device.

Solved it now.

I’ve got it totally working on my breadboard with my old ESP8266 still attached to the boiler and reporting to Home Assistant. So, as promised here’s the solution.
The autoexec.be is uploaded into the Tasmota File Management System

import haspmota
import string
haspmota.start()

tasmota.add_cmd('BoilerStats',
  def (cmd, idx, payload, raw)
    global.p1b35.text = string.format("%5.2fHrs",raw["Hours"])
    global.p1b36.text = string.format("%5.2fL",raw["Oil"])
    global.p1b37.text = string.format("%5.2fKWh",raw["KWh"])
    global.p1b38.text = string.format("£%5.2f",raw["Cost"])
    tasmota.resp_cmnd_done()
  end)

This creates a new Command (BolierStats) which when received hands control to the function defined. All that does is load the variables coming in with the command in JSON format onto the objects set up on the screen using HASPmota.

HASPmota uses the pages.jsonl file which defines all the objects on the screen. One line per object and each object takes the reference Page Number and ID in the form p#bx (ie p1b35 - object ID 35 on Page 1). Here’s my file, it was a bit daunting but you get used to it

{"page":0,"comment":"---------- Upper stat line ----------"}

{"id":11,"obj":"label","x":0,"y":0,"w":320,"pad_right":90,"h":22,"bg_color":"#D00000","bg_opa":255,"text_color":"#ffffff","radius":0,"border_side":0,"text":"Boiler Stats","text_font":"montserrat-20"}

{"id":15,"obj":"lv_wifi_arcs","x":291,"y":0,"w":29,"h":22,"radius":0,"border_side":0,"bg_color":"#000000","line_color":"#FFFFFF"}
{"id":16,"obj":"lv_clock","x":232,"y":3,"w":55,"h":16,"radius":0,"border_side":0,"text_color":"#ffffff"}

{"page":1,"comment":"---------- Page 1 ----------"}
{"id":0,"bg_color":"#0000A0","bg_grad_color":"#000000","bg_grad_dir":1,"text_color":"#FFFFFF"}

{"id":19,"obj":"label","x":10,"y":30,"w":100,"text":"Local Readings","align":2}
{"id":20,"obj":"label","x":10,"y":50,"w":70,"text":"Outflow = ","align":2}
{"id":21,"obj":"label","x":10,"y":70,"w":70,"text":"Inflow = ","align":2}
{"id":22,"obj":"label","x":10,"y":90,"w":70,"text":"Cabinet = ","align":2}
{"id":23,"obj":"label","x":10,"y":110,"w":70,"text":"Demand = ","align":2}
{"id":24,"obj":"label","x":10,"y":130,"w":70,"text":"Burn = ","align":2}

{"id":25,"obj":"label","x":80,"y":50,"w":60,"align":0,"text_rule":"DS18B20-1#Temperature","text_rule_format":"%4.1f°C"}
{"id":26,"obj":"label","x":80,"y":70,"w":60,"align":0,"text_rule":"DS18B20-2#Temperature","text_rule_format":"%4.1f°C"}
{"id":27,"obj":"label","x":80,"y":90,"w":60,"align":0,"text_rule":"DS18B20-1#Temperature","text_rule_format":"%4.1f°C"}
{"id":28,"obj":"label","x":80,"y":110,"w":60,"align":0,"text_rule":"Switch1#Action","text_rule_format":"%s"}
{"id":29,"obj":"label","x":80,"y":130,"w":60,"align":0,"text_rule":"Switch1#Action","text_rule_format":"%s"}

{"id":30,"obj":"label","x":150,"y":30,"w":100,"text":"HA Stats","align":2}
{"id":31,"obj":"label","x":150,"y":50,"w":80,"text":"Run Time = ","align":2}
{"id":32,"obj":"label","x":150,"y":70,"w":80,"text":"Oil = ","align":2}
{"id":33,"obj":"label","x":150,"y":90,"w":80,"text":"Energy = ","align":2}
{"id":34,"obj":"label","x":150,"y":110,"w":80,"text":"Cost = ","align":2}

{"id":35,"obj":"label","x":230,"y":50,"w":90,"align":0,"text":"Waiting"}
{"id":36,"obj":"label","x":230,"y":70,"w":90,"align":0,"text":"  for  "}
{"id":37,"obj":"label","x":230,"y":90,"w":90,"align":0,"text":"  next "}
{"id":38,"obj":"label","x":230,"y":110,"w":90,"align":0,"text":"report"}

I’ve separated the labels from the values. Some values get populated from Tasmota and its sensors direct, whilst the others from values calculated and sent by Home Assistant. The HA yaml for the automation that does the sending every 5 minutes is

alias: Boiler Report Stats
description: ""
trigger:
  - platform: time_pattern
    minutes: /5
condition: []
action:
  - service: mqtt.publish
    data:
      qos: 0
      retain: false
      topic: cmnd/boilerdisplay/BoilerStats
      payload_template: |-
        {{ {"Hours": states('sensor.burn_time_by_day') | float(0),
        "Oil": states('sensor.oil_litres_today') | float(0),
        "KWh": states('sensor.oil_energy') | float(0),
        "Cost": states('sensor.oil_cost_today') | float(0)} | tojson }}
    mode: single

Note that ‘BoilerStats’ is the name of the command added to Tasmota in the autoexec.be file, and ‘boilerdisplay’ is the Topic declared in the Config MQTT page within Tasmota.
And that’s it. Simples. I will tweek this a bit when I actually install it but this should help others do similar.
This is the result

Nice. And for the fast track one can just use esphome with the native api which should massively simplify the work and get one started in almost no time.

I’ve not had much experience with ESPHome so went the Tasmota route.
The Graph component of ESPHome is interesting. I’ll have a go with it and see if I can do much the same (with graph too), and report back on the experience.

1 Like