Tasmota Integration - how to recognize custom/computed values in esp as sensors

I have some berry scripts (on the esp) which compute values from raw sensor data. For example I have an esp with a counter sensor and that is used to compute a wind speed.

In order to get that as an entity in HA I currently publish that to an mqtt topic and then in yaml in HA I create an mqtt platform sensor for that topic.

I would like to automate that entity creation via the tasmota integration but I don’t know how this integration determines the “sensors” on the esp to add to the list. As it is all the integration sees is for example the raw counter value which of course is pretty useless when I want is the the wind speed computed (in the esp) as a “sensor”

Is there a particular MQTT topic that the intergration uses to determine what “sensors” are on the tasmota device. if not then how? Via Berry I have access to all tasmota commands so if I just knew what to create/publish/command then maybe I can get this integration to create an entity for me

Tasmota supplemental-custom-discovery-message

You need to make a config topic to ID the sensor and the actual data should be on the sensor topic.
The integration uses the mac address as part of the topic. Have a look with mqtt explorer or similar to compare existing.

tasmota > discovery > mac > config
tasmota > discovery > mac > sensor

The Config topic is below. I have no idea of the the format of the payload when you say “config topic”. Is that supposed to be added this is existing payload (how is that done). Or can I just send another separate /config message.

An example of the json payloads would be very helpful.

{"ip":"10.0.0.150","dn":"238Weather","fn":["238weather",null,null,null,null,null,null,null],"hn":"238-Weather","mac":"C82B968E42AC","md":"238Weather","ty":0,"if":0,"ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"12.0.2","t":"weather/238mchaley","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"swn":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"btn":[0,0,0,0,0,0,0,0],"so":{"4":0,"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":0,"82":0,"114":1,"117":0},"lk":0,"lt_st":0,"sho":[0,0,0,0],"sht":[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],"ver":1}

And same with sensors topic (separate message or added to existing).

{"sn":{"Time":"2022-08-28T01:03:55","COUNTER":{"C1":0,"C2":0},"ANALOG":{"A1":3851},"ESP32":{"Temperature":128.0},"TempUnit":"F"},"ver":1}

Well if I pub/send the below (with a mqtt client to tasmota/discovery/C82B968E42AC/sensors) then the HA integration see these “sensors” and creates entities (that is good!).

BUT, in HA those entities all have an “unknown” value :frowning:

{"sn":{"Time":"2022-08-28T03:04:55","WindSpeed": {"value":11.0,"Unit":"MPH"}, "Rain":{"amount":0.2},"WindDirection":{"CCW":360,"RAW":3016,"Direction":"N","CW":0}}}

image

Also, the original one able keeps being sent. Maybe best if I can modify that original message instead of sending another (in tasmota berry)

The config topic needs to define and create the sensors.

As in the name, device class, state class, units measurement.

I haven’t actually got an example for tasmota directly, it should be similar to this. You will have to fiddle around abit, have a look at some of the other tasmota messages. they send lots of nulls… but you can ditch most of the nulls

Config message (should be retained message fyi)

TIME - These need to be unique
config topic>>> tasmota/discovery/C82B968E42AC-time/sensors/config
config msg >>>  {"name": "example Time", "state_topic": "tasmota/discovery/C82B968E42AC/sensors", "value_template": "{{ value_json.Timestamp | default() }}", "unique_id": "C82B968E42AC_Time", "icon": "mdi:clock", "device": { "identifiers": ["Bobs-Sensors"], "name": "SomeName", "model": "12121212", "manufacturer": "WindThingy", "sw_version": "03.10.37.R" }}

not unique
sensor topic >>> tasmota/discovery/C82B968E42AC/sensors  <<< same msg and topic
sensor msg >>> {"sn":{"Time":"2022-08-28T03:04:55","WindSpeed": {"value":11.0,"Unit":"MPH"}, "Rain":{"amount":0.2},"WindDirection":{"CCW":360,"RAW":3016,"Direction":"N","CW":0}, "Temperature":"32"}}
TEMP --- unique
config topic >>> tasmota/discovery/C82B968E42AC-temp/sensors/config
config msg >>> {"name": "Running Temp", "state_topic": "tasmota/discovery/C82B968E42AC/sensors", "value_template": "{{ value_json.Temperature | default() }}", "unique_id": "C82B968E42AC_Temperature", "device_class": "temperature", "state_class": "measurement", "unit_of_measurement": "°C", "icon": "mdi:coolant-temperature", "device": { "identifiers": ["Bobs-Sensors"], "name": "SomeName", "model": "12121212", "manufacturer": "WindThingy", "sw_version": "03.10.37.R" }}

not unique
sensor topic >>> tasmota/discovery/C82B968E42AC/sensors  <<< same msg and topic
sensor msg >>> {"sn":{"Time":"2022-08-28T03:04:55","WindSpeed": {"value":11.0,"Unit":"MPH"}, "Rain":{"amount":0.2},"WindDirection":{"CCW":360,"RAW":3016,"Direction":"N","CW":0}, "Temperature":"32"}}

Thx @HasQT hat was all helpful. At this time I went with the

homeassistant/sensor/<mac>/<name>/config
topic instead of
tasmota/discovery/uniqueid/sensors/config

based on post/suggestions by blakadder. Seems to work fine with the tasmota integration. (example)

Here is a topic and json I sent to create an entity for current day’s rainfaill.

homeassistant/sensor/c82b968e42ac/todays_rain/config

{"uniq_id":"c82b968e42ac-todays_rain","state_topic":"weather/238mchaley/rain","device":{"cns":[["mac","c82b968e42ac"]]},"unit_of_measurement":"in","value_template":"{{ value_json.today }}","name":"238Weather Todays Rain","icon":"mdi:weather-pouring"}

I actually create that topic and json programatically using tasmota berry.

If anyone is interested (just make a request in this topic) and I will share the berry code that makes it easy now for me to create HA entities based on any variable value (simple or json) in my program

1 Like

I would love to see your Berry code to do this, as I’m writing an integration for a water sensor and wanting to report back to homeassistant that the value is gallons. I’ve written a Berry Driver that properly creates a new item in the web page and json, but, there’s no unit of measure or device class associated with it, which is what I’m trying to solve.

Yes please, I would like to see the code.
I have a variable ‘runtime’ which is the time my boiler is burning. It gets reset to 0 every midnight by a cron and updated at the end of each burn cycle by a Tasmota rule and a Function. I have no idea how I can get it into Home Assistant.
This all runs on a Lilygo T-Display-S3 ESP32 with Tasmota, Berry and HASPmota. These last 2 are totally new to me and yet another rabbit hole I don’t want to go too far into!

Sorry to @PeterGrace

Here is what I have. Berry is another rabbit hole. I’m not sure how useful it will be to others as it uses my “object” module which uses my “file” module which just too much to share here. There is a berry playground and if I ever get them I can share all the details there.

As least this gives you an idea. You could just hard code it instead of making a more flexible module.

import string
import mqtt
import json
import object

def entity_create(Name,opts)
    # opts = { type: (sensor/binary-sensor), jsonkey: , icon:, topic_prefix, topic, unit, custom}
    if !Name 
    print('must pass a name for the home assistant entity')
    return nil
    end
    opts = object(opts)
    opts.type = opts.type ? opts.type : 'sensor'
    print('######### creating Home Assitant entity:',Name, '#############')
    var mac = string.tolower(string.split(tasmota.wifi()['mac'],':').concat())
    # var mac = '1q2w3e4r5t'
    var name =  string.tolower(string.split(Name,' ').concat('_'))
    var id = mac+'-'+name
    # print(mac,name, id)
    var topic = tasmota.cmd('topic')['Topic']
    var Device = tasmota.cmd('status')['Status']['DeviceName']
    var device = string.tolower(string.split(Device,' ').concat('_'))
    # var topic = 'tastmotatesting'
    # var dis_topic = 'tasmota/discovery/'+id+'/sensors/config'
    var dis_topic = 'homeassistant/sensor/'+mac+'/'+ name +'/config'
    print(dis_topic) 
    var p = object() # payload
    p.name = Device + ' ' + Name
    p.uniq_id = id
    p.device = {'cns': [['mac',mac]]}
    if opts.topic
        p.state_topic = opts.topic
      else 
        if opts.topic_prefix
            p.state_topic = opts.topic_prefix + '/' + device + '/' + name
        else 
            p.state_topic = 'stat/'+ topic + '/'+ name
        end    
    end  
    if opts.unit p.unit_of_measurement = opts.unit end
    if opts.icon p.icon = opts.icon end
    if opts.jsonkey  p.value_template = '{{ value_json.'+ opts.jsonkey + ' }}' end
    if opts.value_template   p.value_template = opts.value_template end   
    if opts.custom 
        # opts.custom = type(opts.custom == 'string') ? json.load(opts.custom) : opts.custom
        print('merged custom', opts.custom)
        p.merge(opts.custom,true) 
        print(p.get())
    end
    print(p.dump())
    print("############  Entity Created #######################")

    # (topic:string, payload:string[, retain:bool, start:int, len:int]) -
    mqtt.publish(dis_topic,p.dump(), true)

    return [p.get(), dis_topic, mac , device]

end

var ha = module('ha')
ha.entity_create = entity_create
return ha

usage example

debug = [false,false,false,false]

import ha

opts = {'jsonkey':'speed','icon':'mid:weather-windy','topic_prefix':'weather', 'unit':'MPH'}
custom = {'test':'another key'}
opts.setitem('custom',custom)

print(opts)

ha.entity_create('Wind Speed',opts)

Thank you.
I’m working my way through the code and can see how it assembles all the variables for then publishing with the appropriate topic.
I get the hard coding bit rather than writing it as a callable function.
I ran some of the commands through the Berry console and got, in particular, the dis_topic which I then looked for in MQTT Explorer expecting to find the original discovery topic from the Tasmota device itself. The device is discovered in HA through the Tasmota Integration and has a Control for the display, a number of Sensors (Temp and a switch I’d put on my breadboard) and some diagnostic stuff); I assumed there would be a discovery topic in MQTT Explorer. Anyway, it wasn’t there - should it have been?
Now what should I do? Do I need to put your code into my autoexec.be file (not as a function but cut down to my specific instance) and do the retained publishing thing (every time it boots up), or can I do it just the once from the Berry console?
Having done that I expect to see the new entity I’m hoping for to appear in the Sensors list along with the stuff I mentioned above; is that correct?
Thanks again. I can see it was while since you did this and if you are anything like me, you’ve totally forgotten what’s going on!

Yea I would call it from autoexec.be although If retention is set maybe the broker remembers who knows. Still it’s best just to do this.

I as I mentioned I used /homeassistant instead of /tasmota/discovery because well…it worked for me.

I used that ha module for a weather station I DIYed. I needed to interpret the raw data into something useful and thus it wasn’t something natively the tamosta device was sending out.

In the end here (below) is what showed up in the tasmota integration device as sensors.

You see for example the counter C1 was raw value (came without any coding) but the wind speed was calculated from that value (in berry) and I need the tasmota to “output” that as something the tasmota integration could discover as an entity. Otherwise you are stuck writing a custom ha mqtt sensor yaml which looks for some publish topic you used in your berry code which is the way I did it before getting this to work.

[

fyi I used the MAC address of the device in the topic (see code) I think that’s the trick to getting it to appear in the tasmota integration.

oh in berry you should trigger running the code based on mqtt being connected. If you run it immediately maybe the broker never gets the topic/payload. I just can’t remember if berry code gets executed after broker is connected by default.

Thanks. That all makes sense, is really useful, and I’ve just noticed the tasmota/discovery/mac/sensors in MQTT Explorer where I can see the main retained message. I’ll work on it tomorrow as after a few whiskys my head isn’t too good!
The whole thing I’m working on is a ESP32 with display (Lilygo T-Display-S3) monitoring my boiler and reporting all sorts of stuff on the display. I intend to post the whole thing as a project since there’s lots of stuff in there others will find useful I’m sure. Cheers.

great, please consider a PR to the berry playground for your project since there will be berry code involved. You could always post that link back here at HA community.

1 Like

Will do, when I’ve got the whole project sorted.
Thanks.

I just tried to go through all your stuff again in the Berry console but it fell over on

var p = object()

I note that is something of yours, and file too, so I guess I need some more of your code.
But if you gave me an example of what the final

p.dump

object string looks like, I could just hard code it perhaps? Is it just a typical json string?

{"key1":numeric_value,"key2":"str_value",...}

I tried to work on that assumption and got as far as

 {"name":"Boiler-Burn Since New","uniq_id":"4827e2ea5880 burn_since_new","unit_of_measurement":"Hrs",

but then stalled on

p.device = {'cns': [['mac',mac]]}

as not sure what the result should look like. I wasn’t going to include any of the other keys as they look optional.
If it help, the 2 MQTT messages I can see in MQTT Explorer are

tasmota/discovery/48272E2A5880/config {"ip":"192.168.x.x","dn":"Boiler","fn":["Boiler",null,null,null,null,null,null,null],"hn":"boilerdisplay-6272","mac":"48272E2A5880","md":"Lilygo S3 Display","ty":0,"if":0,"ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"13.3.0.1","t":"boilerdisplay","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"swc":[2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"swn":["Switch1",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"btn":[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"so":{"4":0,"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":1,"82":0,"114":1,"117":0},"lk":0,"lt_st":0,"bat":0,"dslp":0,"sho":[],"sht":[],"ver":1}

and

tasmota/discovery/48272E2A5880/sensors {"sn":{"Time":"2023-12-27T00:26:03","Switch1":"OFF","ANALOG":{"Range1":4716},"DS18B20-1":{"Id":"3E66CC0664FF","Temperature":23.1},"DS18B20-2":{"Id":"87F0CD0664FF","Temperature":23.1},"TempUnit":"C"},"ver":1}

I found your example in post 6 (I think) so followed it and published this

{"uniq_id":"48272e2a5880-burn_since_new","name":"Boiler Burn Since New","device":{"cns":[["mac","48272e2a5880"]]},"state_topic":"tele/boilerdisplay/TOTHRS","unit_of_measurement":"Hrs"}

with topic

homeassistant/sensor/48272e2a5880/burn_since_new/config

Home assistant has discovered the Entity and picks up the values when published by

tele/boilerdisplay/TOTHRS 1877.55

However it is not being added to the Tasmota Integration discover device.

@Wingnut I sent you a private message with more info and access to all the code. We can pick more disucssion from there.

I can’t really say why it didn’t pick that up. I’d try deleting the device in the tasmota integration then restart that tasmota (with that topic/payload publish in autoexec.be) and see it if doesn’t work. Be sure though that you are getting the right mac address as I think that’s how the integration knows what device goes with what topic.

It’s crazy how simple things sometimes can be so complicated to implement that it can take hours or even days to be finally solved.

I actually do exactly the same with my boiler but luckily have the right component (esphome) at hand so it doesn’t take more than a minute to setup

I’ve only started using ESPHome recently for HA Voice things and not found it (the voice stuff) that successful. I guess I could have tried it with the T-Display-S3 but Tasmota 32 got me going quickly once I discovered Berry, LVGL and HASPmota. It’s pretty powerful but not much stuff out there to plagiarize. I’ll be putting my boiler monitor up as a project when finished.