dawidchyrzynski / arduino-home-assistant

ArduinoHA allows to integrate an Arduino/ESP based device with Home Assistant using MQTT.
https://dawidchyrzynski.github.io/arduino-home-assistant/
GNU Affero General Public License v3.0
498 stars 118 forks source link

Subscribe payload issues #176

Closed joeyjojo747 closed 8 months ago

joeyjojo747 commented 1 year ago

I have successfully subscribed to a topic and can send payloads from HA. However, when trying to print the payload I get extra characters. See below examples of publishing 4 payload; 45, 1000, 3000, hello boys. onMqttMessage code below also --------- --------- --------- Serial monitor--------- --------- --------- New message on topic: aha/esp32_servoControl_TEST/servoAngle-HA Data: 45oTest/cmd_t New message on topic: aha/esp32_servoControl_TEST/servoAngle-HA Data: 100Test/cmd_t New message on topic: aha/esp32_servoControl_TEST/servoAngle-HA Data: 3000est/cmd_t New message on topic: aha/esp32_servoControl_TEST/servoAngle-HA Data: hello boysd_t


`void onMqttMessage(const char topic, const uint8_t payload, uint16_t length) { // This callback is called when message from MQTT broker is received. // Please note that you should always verify if the message's topic is the one you expect. // For example: if (memcmp(topic, "myCustomTopic") == 0) { ... }

Serial.print("New message on topic: ");
Serial.println(topic);
Serial.print("Data: ");
Serial.println((const char*)payload);

}

void onMqttConnected() { //see setup() mqtt.onMessage(onMqttConnected); Serial.println("------ void onMqttConnected ------"); Serial.println("Connected to the broker!");

// You can subscribe to custom topic if you need
mqtt.subscribe("aha/esp32_servoControl_TEST/servoAngle-HA"); //subscribe to custom topic - 'servoAngle-HA'. See 'void onMqttMessage' for reaction

}`

MolloPaul commented 1 year ago

The payload data is specified by the length parameter.

My brute force snippet looks like

// Please note that you should always verify if the message's topic is the one you expect. // For example: if (memcmp(topic, "myCustomTopic") == 0) { ... }

char payload_data[MQQT_SENSOR_DATA_LENGTH_MAX];
strncpy(payload_data, (const char *)payload, length);
// terminate the payload_data as strncpy does not.
payload_data[length] = '\0';

Serial.print("Payload length = ");
Serial.print(length);
Serial.print(", Payload Data = ");
Serial.println(payload_data);
dawidchyrzynski commented 8 months ago

@joeyjojo747 The payload is a byte array without a null terminator at the end. You can't just treat it as string without any conversion.

char str[length + 1];
strncat(str, static_cast<const char*>(payload_data), length);

Serial.println(str);