Parsing multiple values from subscribed topics

photon
Tags: #<Tag:0x00007fe220b2d428>

#1

diving further into my MQTT study, i want to have my photon use multiple values from a string. for simplicity of discussion, kets use a rgb led as an example.

topic message = “r=255, b=255, g=255, l=255,p=s”

in photon i want to have it do the following:
r=255 becomes red=255
b=…
g=…
l=255 becomes luminosity=255
p=s becomes pattern=solid, additional options would be chase, rainbow, etc, all referencing their own voids.


#2

The simplest (yet with much internal overhead) would be this

  int  R = 0;
  int  G = 0;
  int  B = 0;
  int  L = 0;
  char P = '\0';
  int ret = sscanf(message, "r=%d, b=%d, g=%d, l=%d, p=%c", &R, &B, &G, &L, &P);

By checking ret you will know how many of the items could be parsed successfully.

Other options would be using strtok() or reformatting your payload as JSON string and use a JSON parser.

You mean functions or values, right?


#3

holy crap that was fast help. that should work perfectly, i don’t know json, so skipping that. yes , i meant functions, it’s late, i’m going to bed now, lol.


#4

ok, hving issues geeting the code to compile due to conversions from char to const, int to char, etc. getting cross-eyed trying to figure this out.


#5

Single characters would require single quotes, just the way as I have used above.
And the backslash ( \ ) in my example is the escape character to tell the compiler not to take the following character literally but has a special meaning (in this case a zero-byte).
For your literal s case you’d just write

char pattern = 's';

You also haven’t copied my sscanf() statement correctly :wink:
the first parameter cannot be an integer but must be a pointer to a string/character array.
Try that instead

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  returned = sscanf(p, "r=%d, g=%d, b=%d, l=%d, r=%d, p=%c", &red, &green, &blue, &luminosity, &remote, &pattern);
}

void loop() {
  if (remote == 1) { // if we got new data from remote
    remote = 0;      // mark done
    // do the rest
  }
}

Also note that equality checks are not done like this

But with with double equal signs (==).


#6

awesome, i’ll give this a try in the morning, thank you. and yes, i am aware of the ==, i was just creating filler text for the post, sorry.


#7

Alright, uploaded, compiled, but not “working” published the message from my client, and nadda, values aren’t updated (verified by the publishing of current values on the photon). It was working before the sscanf change when i just used atoi on a single parameter, so i think its jsut a formatting issue.

attempted to publish
r=255
r=100, g=200, b=255, l=100, r=1, p=s

values on the photon stayed at the int parameters


#8

For me it works, but I actually send the payload the exact way the code is expecting it.
Can you spot the difference?

returned = sscanf(p, "r=%d, g=%d, b=%d, l=%d, r=%d, p=%c", &red, &green, &blue, &luminosity, &remote, &pattern);

vs.

r=100, b=200, g=255, l=100, r=1, p=s

#9

typo in this site only. r g b l r p on my client :wink:

FIXED… Case sensitivity matter :stuck_out_tongue_winking_eye: