MQTT payload comes with extra stuff from Home Assistant

I am sure I am just missing something stupid. But I am just trying to figure out this MQTT protocol stuff. I trying to send information back and forth from Home Assistant. I can send without any trouble. I have finally figured out how to receive messages. But the trouble is they come in strange. I am using the ArduinoHA library and an example from that for the start of my code.

https://dawidchyrzynski.github.io/arduino-home-assistant/documents/library/mqtt-advanced.html

Maybe there is something that the author assumes any reasonable person would know to add, well I don't. :slight_smile:

here is my stripped down code

#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoHA.h>
#include <WiFiClient.h>

String test2;


// set to true if you want to connect to wifi. You have 60 seconds to connect. Then it will go into an offline mode.
boolean connectWIFI=true;

unsigned long currentMillis = 0;

const int sendToServerInterval = 10000;
unsigned long previoussendToServer = 0;

WiFiClient client;
HADevice device("HC-12_CONTROLER");
HAMqtt mqtt(client, device);

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.
    //if (memcmp(topic, "hourslight/attribute"), 0) { 

    Serial.print("New message on topic!: ");
    Serial.println(topic);
    Serial.print("Data: ");
    Serial.println((const char*)payload);
    test2 = (const char*)payload;
    Serial.println(test2);
   // }
  
}

void onMqttConnected() {
    Serial.println("Connected to the broker!");

    // You can subscribe to custom topic if you need
    mqtt.subscribe("hourslight");
    mqtt.subscribe("sundown");
    mqtt.subscribe("testy");
}
void setup() {
    Serial.begin(115200);

    mqtt.onMessage(onMqttMessage);
    mqtt.onConnected(onMqttConnected);

        if (connectWIFI) {
    connectToWifi();
  }

    //HA
  byte mac[] = {0xA8, 0x93, 0x4A, 0x6C, 0x73, 0x31};
    WiFi.macAddress(mac);
    device.setUniqueId(mac, sizeof(mac));
    device.setName("HC-12_CONTROLER");

  //must put in your own local IP address your home assistant username and your HA secret code
  mqtt.begin("192.168.1.130", "homeassistant", "HA pass code");

   }

void loop() {
  currentMillis = millis();
  sendToServer();
   mqtt.loop();
}

void sendToServer() {
     if (currentMillis - previoussendToServer >= sendToServerInterval) {
     previoussendToServer += sendToServerInterval;

      if(WiFi.status()== WL_CONNECTED){
         
        mqtt.publish("myPublishTopic", "hello");
      }
      else {
        Serial.println("WiFi Disconnected");
      }
   }
}

// Wifi Manager
 void connectToWifi() {
   WiFiManager wifiManager;
   //WiFi.disconnect(); //to delete previous saved hotspot
   String HOTSPOT = "AG-" + String(ESP.getChipId(), HEX);
   //updateOLED2("Connect", "Wifi AG-", String(ESP.getChipId(), HEX));
   delay(2000);
   wifiManager.setTimeout(90);
   if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
     //updateOLED2("Booting", "offline", "mode");
     Serial.println("failed to connect and hit timeout");
     delay(6000);
   }
}

So if from HA I publish on one of the subscribed channels I do get results. If I publish "1" then this is what comes back.
1lishTopicNTROLER/myNumber/cmd_t
If I publish "123456789" I get
123456789cNTROLER/myNumber/cmd_t
So the published data is replacing characters in this string, but I don't understand why it doesn't just have my published data? If I publish a string that exceeds length then I get a long scrambled thing
12345678912345678912345678912345678myNumber/configHidohvahpee0Sool3iXahsoo3cheiThei3Iekieth2iquedoosh0Ga⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
So... certainly doesn't like that. I don't need anything long, for now. I am just trying to pull a number from a helper card. I have gotten all of that working, just the received data is not what I'd expect. I have looked into parsing this string and some how working with what I have, but just seems the more efficient way would be to get what I want.
I have published multiple different ways from HA and it always attaches this extra stuff.

Help please!

It's been a while since I've played around with MQTT, but if memory serves, the string sent isn't null terminated. So you have to use the length parameter to know how many characters to print (in this case).

That sounds promising. Can you give me an example? I am not good at code. I am a wanna be. I see there is a length callout in my command.
void onMqttMessage(const char* topic, const uint8_t* payload, uint16_t length)
so does that know how long the payload is? and do I then use that to trim the payload?

Well, length is a thing and it does hold the length of the message. So is the best way to use that to trim the first characters off of the payload? Just seems there should be a more elegant way. Seems it shouldn't come in with this extra baggage in the first place. Sure is nice to have the length though if trimming is the best way. Or maybe there is a better way to incorporate this length parameter?

You could try replacing

with

    while( length-- ) {
        Serial.print(*(const char *)payload);
        ++payload;
    }
    Serial.println();

And if you're not good at code, mucking around with MQTT might be something you want to reconsider until you are good at code. Learning to swim by jumping off the 10 metre diving platform and yelling "okay, now what?" is rarely a good idea...

Ha! that did it! Thank you. And yes, I am over my head. Takes me two days to make one little step of progress. Without having ever learned the basics, well it is tricky.

with that, continuation of my ignorance. I guess what I really want to do is have this in an integer or variable so that I can queue different things to happen based off of it.

I am looking at this forum

So is this bringing this data in in hex format? Seems to me that this const uint8_t is my problem. can I simply bring this in from the get go in a different way? something that is easier to work with? If not, just some way to convert it to a number.

Ok, so it is a pointer, just learned. Pointers are supposed to point to the address of an integer. Which I guess this one must. And I find that as long as I refer to it as
*payload
I can get it to work in my code. But, I can't seem to do much with it, maybe because of the excess data that is in there? If it is a pointer to an integer then I should be able, for example

  if (*payload == 10) {
    Serial.println("hello world!");
  }

While that compiles, it does not ever say hello world, even when the payload prints out (with your cool trick) as 10.

The specific question raised in your topic has been answered. Please mark the reply that solved the question as a solution as detailed in How to get the best out of this forum. If you have further questions on basic programming, please start another topic in the Programming Questions category.

Thank you for the help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.