Generic mqtt subscribe json sensor

I am trying to figure out how to accomplish this:

Domoticz mqtt topic format :
domoticz/in
{"idx":123,"nvalue":0,"svalue":"21.5;33.1;2","Battery":100,"RSSI":7}

I want to subscribe to that topic and extract the values

Can I use mqtt_text_sensor with (some) lambda code for that? Or any other option?

Is this what you seek? https://esphome.io/components/mqtt.html#mqtt-on-json-message

Yes. I am having trouble with this part

then:
  - light.turn_on: 
      id: living_room_lights

But I don’t want to turn something on. I want to make the value available to display later on

So something like

mqtt:

          id: example_id

if (x.containsKey("example_value"))
              value = x["example_value"];
            return value;


Sensor:
Id: example_id:
(Where value is from MQTT json)

 it.printf(0, 0, id(sz_13), "The data is: %s", id(example_id).state.c_str());

Am i thinking correctly?

You could use global variables to store the values in the on json message handler and then use the in the display lambda.

See: https://esphome.io/guides/automations.html?highlight=global#bonus-2-global-variables

Yes. Only problem I am facing is the conversion to string:
’ ’ ’
globals:

  • id: itho_mode
    type: char
    ’ ’ ’
    ’ ’ ’
    on_json_message:
    topic: domoticz/in
    then:
    - lambda: |-
    constant char *svalue = “None”;
    if (x.containsKey(“svalue”)){
    svalue = x[“svalue”];
    ESP_LOGD(“Fan”, “Itho_mode = %s”, svalue.c_str());
    }
    ’ ’ ’
    This doesn’t compile
 on_json_message:
    topic: domoticz/in
    then:
    - lambda: |-
    constant char *svalue = “None”;
    if (x.containsKey(“svalue”)){
    svalue = x[“svalue”];
    ESP_LOGD(“Fan”, “Itho_mode = %s”, svalue.c_str());
    }

There are at least two issues:

  • It has to be const char not constant char.
  • In the ESP_LOGD remove the “.c_str()” . It alreay is a c-String you can not call c_str() (that only works for std::string)

I

In the future: Please post the compile errors.

I came up with this:
’ ’ ’ ’
globals:

  • id: itho_mode
    type: std::string

  • id: itho_state
    type: std::string

mqtt:
broker: 192.168.1.102

on_json_message:
topic: domoticz/in
then:
- lambda: |-
if (x.containsKey(“idx”)){
const char *idx = x[“idx”];
const char *svalue = x[“svalue”];
id(itho_mode) = idx;
id(itho_state) = svalue;
}

//default display setup code for reference not shown

pages:
- id: page1
lambda: |-
it.image(20, 30, id(spinning_fan));
- id: page2
lambda: |-
it.printf(10, 10, id(sz_13), “IDX is: %s”, id(itho_mode).c_str());
it.printf(10, 20, id(sz_13), “The data is: %s”, id(itho_state).c_str());
’ ’ ’ ’
This does work but crahes a lot probably because it messes up the heap and stack. But maybe someone finds a improved way of doing this?

(your formating somehow got wrong)

I don’t see an obvious reason why it would crash. Does it get lots and lots of messages on that topic or are those message to big for the memory of your device?

Other then that I don’t think it messes in any way with the heap or stack. Can you provide the log (over USB) of such a crash?

Hi Daniel,

thanx for the confirmation that it looks ok.
I added a filter and now it’s rock solid!

globals:
  - id: itho_mode
    type: std::string

  - id: itho_state
    type: std::string

mqtt:
  broker: 192.168.1.102

  on_json_message:
    topic: domoticz/in
    then:
        -  lambda: |-
              if (x.containsKey("idx")){
                if (x["idx"] == 435) {
                ESP_LOGD("on_json_message", "Found");
                const char *idx = x["idx"];
                const char *svalue = x["svalue"];
                id(itho_mode) = idx;
                id(itho_state) = svalue;
                }
              }