How to parse a string with an unknown number of message:payload pairs

Ok, not sure why I’m having such a hard time working through this and trying all kinds of examples from google searches, but just can’t get them to work for me. What I want to do is accept a string from an RFM69 radio of known format but of unknown number of “message:payload” pairs separated by commas like this: outTemp:68,outHumidity:55,wind:3.5 which will get posted to my MQTT server over the WiFi. Now this is data from my outdoor sensors for weather, but I want to make it generic so that if I add remote sensors for whatever I can parse the radio data “message:payload” pairs and publish it to my MQTT server. The gateway is my P1 redboard with RFM69 transceiver and my remote sensors are moteinos. So that’s the plan.

I think my mental block here is how to parse a string with an unknown number of pairs and iterate through the pairs and publish each individual pair to the MQTT server until all the pairs have been processed. My thought was to determine how many commas were in the string then the number of pairs would be #commas+1, but then how to iterate this?

The string will be this:

msgpayload = “message1:payload1,message2:payload2,…messageN:payloadN”

then publish to MQTT like this:

client.publish(topic+messageN,payloadN);

The MQTT client.publish function is expecting a string for the topic+message part, so that would have to be constructed, but I need that to be dynamic based on the radio packet received. The topic is stripped out at the beginning because there will only be one topic per string, that’s easy enough to strip out, but it’s the unknown number of pairs from the remote sensor location that has me vexed. Can someone give me an idea of how to do this in the most efficient way?

1 Like

Did something like this may moons ago.
Back then I searched the string for the names since they never change, such as outTemp. once I found that I then searched the char location to the next following comma. That then told me what the data for outTemp was.

Problem with that is I want to make the gateway generic, and if I do it how you suggest, I will have to tell the gateway what each topic and message is before hand. I would like it to function so that if you throw any properly formatted message at the gateway, it will just publish those values to the correct topic and the correct message, because it will parse that information from the single string it receives. While right now I only have weather items to publish, I will have countless other things in my home automation project.

Assuming the string is a C char array (or can be converted to such), why not use strtok to separate the pairs at the commas in a for-loop? If you want to separate the pairs into their separate parts within that for-loop, you could use strtok_r.

char* rmdr;
for (char* str = strtok_r(msgPayload, ",", &rmdr); str != NULL ; str = strtok_r(NULL, ",", &rmdr)) {
    char* message = strtok(str, ":");
    char* payload = strtok(NULL, ":");
    // client.publish here or store the data (in an array of structs perhaps) for later publishing
}
4 Likes

Thanks for this, I think my struggle was understanding the differences between string types and char types. It’s quite a jungle, but your example worked like a charm for me.

1 Like

Share your rFM95 code if you can cause I’m looking to do the same thing with a photon and RFM95w radios that receive sensor data.

Will do, it’s a bit rough right now but when I polish it I will certainly post it.

Oh sorry, my radios are RFM69 not 95.

It should still be adaptable.

Yeah I realized you were asking about the gateway aspect not the radio part. When I get home I will test it out and polish up the code, then I’ll maybe create a new thread in the projects section and link it back here.

1 Like