Custom MQTT component

Hi there!

I want to create my mqtt component. I’m trying to compile the code from the example, but the compilation only happens when I remove the ability to work with json. Otherwise an error. What am I doing wrong ?

test.h

#include "esphome.h"

class MyCustomComponent : public Component, public CustomMQTTDevice {
 public:
  void setup() override {
    // This will be called once to set up the component
    // think of it as the setup() call in Arduino
    pinMode(6, OUTPUT);

    subscribe("the/topic", &MyCustomComponent::on_message);

    // also supports JSON messages
    subscribe_json("the/json/topic", &MyCustomComponent::on_json_message);
  }
  void on_message(const std::string &payload) {
    if (payload == "ON") {
      digitalWrite(6, HIGH);
      publish("the/other/topic", "Hello World!");
    } else {
      digitalWrite(6, LOW);
      publish("the/other/topic", 42);
    }
  }
 void on_json_message(JsonObject &root) {
    if (!root.containsKey("key"))
      return;

    int value = root["key"];
    // do something with Json Object

    // publish JSON using lambda syntax
    publish_json("the/other/json/topic", [=](JsonObject &root2) {
      root2["key"] = "Hello World";
    });
  }

};

test.yaml

esphome:
  name: test
  includes:
  - test.h

esp8266:
  board: nodemcuv2

mqtt:
  topic_prefix: test
  discovery: false
  broker: ххх
  port: ****
  username: ****
  password: !secret mqtt_password
  discovery_prefix: homeassistant

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: !secret api_password

ota:
  password: !secret ota_password
  
web_server:
  port: 8080
  auth:
    username: !secret web_user
    password: !secret web_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-433MHz Fallback Hotspot"
    password: !secret fail_password

captive_portal:

custom_component:
- lambda: |-
    auto my = new MyCustomComponent();
    return {my};

log

INFO Reading configuration /config/esphome/test.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing test (board: nodemcuv2; framework: arduino; platform: platformio/espressif8266 @ 3.2.0)
--------------------------------------------------------------------------------
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
LDF: Library Dependency Finder -> https://недопустимая ссылка/configure-pio-ldf
Dependency Graph
|-- <ESPAsyncTCP-esphome> 1.2.3
|-- <ESPAsyncWebServer-esphome> 2.1.0
|   |-- <ESPAsyncTCP-esphome> 1.2.3
|   |-- <Hash> 1.0
|   |-- <ESP8266WiFi> 1.0
|-- <DNSServer> 1.1.1
|-- <ESP8266WiFi> 1.0
|-- <ESP8266mDNS> 1.2
|-- <AsyncMqttClient-esphome> 0.8.6
|   |-- <ESPAsyncTCP-esphome> 1.2.3
|-- <ArduinoJson> 6.18.5
Compiling /data/test/.pioenvs/test/src/main.cpp.o
In file included from src/main.cpp:28:
src/test.h: In member function 'virtual void MyCustomComponent::setup()':
src/test.h:13:73: error: no matching function for call to 'MyCustomComponent::subscribe_json(const char [15], void (MyCustomComponent::*)(ArduinoJson::JsonObject&))'
   13 |     subscribe_json("the/json/topic", &MyCustomComponent::on_json_message);
      |                                                                         ^
In file included from src/esphome.h:25,
                 from src/main.cpp:3:
src/esphome/components/mqtt/custom_mqtt_device.h:96:8: note: candidate: 'template<class T> void esphome::mqtt::CustomMQTTDevice::subscribe_json(const string&, void (T::*)(const string&, ArduinoJson::JsonObject), uint8_t)'
   96 |   void subscribe_json(const std::string &topic, void (T::*callback)(const std::string &, JsonObject), uint8_t qos = 0);
      |        ^~~~~~~~~~~~~~
src/esphome/components/mqtt/custom_mqtt_device.h:96:8: note:   template argument deduction/substitution failed:
In file included from src/main.cpp:28:
src/test.h:13:73: note:   types 'const string' {aka 'const std::__cxx11::basic_string<char>'} and 'ArduinoJson::JsonObject' {aka 'ArduinoJson6185_D1::ObjectRef'} have incompatible cv-qualifiers
   13 |     subscribe_json("the/json/topic", &MyCustomComponent::on_json_message);
      |                                                                         ^
In file included from src/esphome.h:25,
                 from src/main.cpp:3:
src/esphome/components/mqtt/custom_mqtt_device.h:98:29: note: candidate: 'template<class T> void esphome::mqtt::CustomMQTTDevice::subscribe_json(const string&, void (T::*)(ArduinoJson::JsonObject), uint8_t)'
   98 |   template<typename T> void subscribe_json(const std::string &topic, void (T::*callback)(JsonObject), uint8_t qos = 0);
      |                             ^~~~~~~~~~~~~~
src/esphome/components/mqtt/custom_mqtt_device.h:98:29: note:   template argument deduction/substitution failed:
In file included from src/main.cpp:28:
src/test.h:13:73: note:   mismatched types 'ArduinoJson::JsonObject' {aka 'ArduinoJson6185_D1::ObjectRef'} and 'ArduinoJson::JsonObject&' {aka 'ArduinoJson6185_D1::ObjectRef&'}
   13 |     subscribe_json("the/json/topic", &MyCustomComponent::on_json_message);
      |                                                                         ^
src/test.h: In member function 'void MyCustomComponent::on_json_message(ArduinoJson::JsonObject&)':
src/test.h:34:6: error: no matching function for call to 'MyCustomComponent::publish_json(const char [21], MyCustomComponent::on_json_message(ArduinoJson::JsonObject&)::<lambda(ArduinoJson::JsonObject&)>)'
   34 |     });
      |      ^
In file included from src/esphome.h:25,
                 from src/main.cpp:3:
src/esphome/components/mqtt/custom_mqtt_device.h:167:8: note: candidate: 'bool esphome::mqtt::CustomMQTTDevice::publish_json(const string&, const json_build_t&, uint8_t, bool)'
  167 |   bool publish_json(const std::string &topic, const json::json_build_t &f, uint8_t qos, bool retain);
      |        ^~~~~~~~~~~~
src/esphome/components/mqtt/custom_mqtt_device.h:167:8: note:   candidate expects 4 arguments, 2 provided
src/esphome/components/mqtt/custom_mqtt_device.h:184:8: note: candidate: 'bool esphome::mqtt::CustomMQTTDevice::publish_json(const string&, const json_build_t&)'
  184 |   bool publish_json(const std::string &topic, const json::json_build_t &f);
      |        ^~~~~~~~~~~~
src/esphome/components/mqtt/custom_mqtt_device.h:184:73: note:   no known conversion for argument 2 from 'MyCustomComponent::on_json_message(ArduinoJson::JsonObject&)::<lambda(ArduinoJson::JsonObject&)>' to 'const json_build_t&' {aka 'const std::function<void(ArduinoJson6185_D1::ObjectRef)>&'}
  184 |   bool publish_json(const std::string &topic, const json::json_build_t &f);
      |                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~^
*** [/data/test/.pioenvs/test/src/main.cpp.o] Error 1
========================== [FAILED] Took 7.52 seconds ==========================

The way to refer to a JsonObject has changed and the documentation has not been updated.
To fix, remove the ‘&’ after JsonObject in two places.
ie (JsonObject &root) → (JsonObject root)