arduinomqttesp32arduino-esp32home-assistant

Arduino doesn't publish mqtt payload


I'm trying to make esp sensor with auto discovery to homeassistant:

#include <WiFi.h>
#include <PubSubClient.h>
#include "HX710B.h"

const int DOUT = 21;
const int SCLK  = 22;
int prev = 0;
int pa = 0;

HX710B pressure_sensor;

const char *WIFI_SSID = "ssid";
const char *WIFI_PASSWORD = "pass";

const char* mqttServer = "192.168.1.xx";
const int mqttPort = 1883;
const char* mqttUser = "user";
const char* mqttPassword = "pass";

float pressure;

int sensorNumber = 1;
String mqttName = "prsensor " + String(sensorNumber);
String stateTopic = "prsensor_" + String(sensorNumber) + "/pressure/state";
String statusTopic = "prsensor_" + String(sensorNumber) + "/status";
String discoveryTopic = "homeassistant/sensor/prsensor/" + String(sensorNumber) + "/pressure/config";

WiFiClient wifiClient;
PubSubClient client(wifiClient);
void setup() {
  Serial.begin(115200);
  pressure_sensor.begin(DOUT, SCLK);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);

  Serial.println("Connected to Wi-Fi");

  client.setServer(mqttServer, mqttPort);

  Serial.println("Connecting to MQTT");

}

void publishDiscoveryMessage() {

  String payload = "{";
  payload += "\"dev_cla\":\"pressure\",";
  payload += "\"unit_of_meas\":\"Pa\",";
  payload += "\"stat_cla\":\"measurement\",";
  payload += "\"name\":\"prsensor pressure\",";
  payload += "\"entity_category\":\"diagnostic\",";
  payload += "\"stat_t\":\"" + String(stateTopic) + "\",";
  payload += "\"avty_t\":\"" + String(statusTopic) + "\",";
  payload += "\"uniq_id\":\"prsensor_id\",";
  payload += "\"val_tpl\":\"{{ value_json.pressure|default(0) }}\",";
  payload += "\"dev\":{\"ids\":\"5ccf7f9b18a2\"}";
  payload += "}";

  // Publish MQTT discovery message
  bool published = client.publish(discoveryTopic.c_str(), payload.c_str(), true);

  Serial.print("published: ");
  Serial.print(published);
  Serial.printf(" Published %s to %s\n", payload.c_str(), discoveryTopic.c_str());
}


void loop() {

  while (!client.connected()) {
    Serial.print(".");

    if (client.connect(mqttName.c_str(), mqttUser, mqttPassword)) {

      Serial.println("Connected to MQTT");

    } else {

      Serial.println("failed with state ");
      Serial.print(client.state());
      delay(2000);

    }
  }

  client.loop();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("===== Sending Data =====");

    pressure = pressure_sensor.pascal();

    if (isnan(pressure)) {
      pressure = 0;
    }
    String pl = "{";
    pl += "\"pressure\":\"" + String(pressure) + "\"";
    pl += "}";

    bool plpub = client.publish(stateTopic.c_str(), pl.c_str(), true);

    client.publish(statusTopic.c_str(), String("online").c_str(), true);

    Serial.print("111published: ");
    Serial.print(plpub);
    Serial.printf(" Published %s to %s\n", pl.c_str(), stateTopic.c_str());
    publishDiscoveryMessage();

    delay(2000);
    Serial.println("pressure: ");
    Serial.println(pressure);
  }
  else {
    Serial.println("WiFi Disconnected");
  }

}

Payload with state and status publishing normally, but payload in publishDiscoveryMessage() doesn't. State of published = 0. I'm using Lolin D32 pro. Previously I've tried to use ArduinoJson library and result was the same.

here logs of publishing:

00:11:30.677 -> ===== Sending Data =====
00:11:30.677 -> 111published: 1 Published {"pressure":"462.10"} to prsensor_1/pressure/state
00:11:30.677 -> published: 0 Published {"dev_cla":"pressure","unit_of_meas":"Pa","stat_cla":"measurement","name":"prsensor pressure","entity_category":"diagnostic","stat_t":"prsensor_1/pressure/state","avty_t":"prsensor_1/status","uniq_id":"prsensor_id","val_tpl":"{{ value_json.pressure|default(0) }}","dev":{"ids":"5ccf7f9b18a2"}} to homeassistant/sensor/prsensor/1/pressure/config

If I change payload to

  String payload = "{";
  payload += "\"dev_cla\":\"signal_strength\",";
  payload += "\"unit_of_meas\":\"Pa\",";
  payload += "\"stat_cla\":\"measurement\",";
  payload += "\"name\":\"prsensor pressure\",";
  // payload += "\"entity_category\":\"diagnostic\",";
  payload += "\"stat_t\":\"" + String(stateTopic) + "\",";
  payload += "\"avty_t\":\"" + String(statusTopic) + "\",";
  payload += "\"uniq_id\":\"prsensor_id\"";
  // payload += "\"val_tpl\":\"{{ value_json.pressure|default(0) }}\",";

  // payload += "\"dev\"";
  // payload += ":{";
  // payload += "\"ids\":\"5ccf7f9b18a2\"";
  // payload += "}";

  payload += "}";

mqtt payload publishes, but it doesn't enough for auto discovery in homeassistant.


Solution

  • PubSubClient has a maximum packet size. If you read the documentation you'll find it explained there:

    MQTT_MAX_PACKET_SIZE Sets the largest packet size, in bytes, the client will handle. Any packet received that exceeds this size will be ignored. This value can be overridden by calling setBufferSize(size).

    Default: 128 bytes

    The string you're trying to publish is more than 128 bytes, so, as documented, the publish fails.

    You can override it when you set up the MQTT client:

    client.setServer(mqttServer, mqttPort);
    client.setBufferSize(400);
    

    400 is more than enough to hold the string from your code; you should change this if you need to.