First time with JSON

I’m trying to make some changes to how my product publishes data, the company building our database asked if I could change to the publish from an event name, data, PRIVATE to a JSON format. I didn’t find a direct example of what I’m trying to do, but from what I’ve read, this is what I came up with.

const char * key = "cardSwiped";
char cardSwiped[63];

and:

    if (cardReadStart != 0) {
		if (cardBitCount <= 47) {
			// Got a valid 47-bit card or less
			if (decodeWiegand(cardValue)) {
				// Is valid
				sprintf(cardSwiped, "<device_ID>", String(cardValue));
				Particle.publish(cardSwiped, PRIVATE);
			}

Is this the correct format, or even close? It compiles fine, but that doesn’t always mean it works, I haven’t been able to test yet.

Not really sure what you’re actually after, but having the data in the event name is somewhat uncommon.
Maybe you can ask your consutant what exactly he wants and give you a sample format of the data he expects.

However, what you are sending there is not JSON format and your sprintf() format string does not seem to feature a format placeholder for the cardValue either.

Since I’m not exactly sure what you need, I’d just suggest something I’d assume you want

  char jsonData[64];
  // assuming cardValue to be char* or similar
  snprintf(jsonData, sizeof(jsonData), "{ \"device_ID\":\"%s\" }", cardValue);
  Particle.publish("event", jsonData, PRIVATE);
2 Likes

This was his example he sent to me,

JSON {

   'device_id': '<device ID>',

   'card_data': '<card data>'

}

I’m trying to get the firmware in all devices to be the same. We are comparing the card swipe data against a database of users and changing the event name every time makes this very difficult. Changing it to something we already have to input into our system for identification purposes makes this a lot simpler, so we want to use the device ID as the event name, and the card info will still be the data field

OK, with that info I’d suggest this

  char jsonData[64];
  // assuming cardValue to be char* or similar
  snprintf(jsonData, sizeof(jsonData), "{ \"device_ID\":\"%s\", \"card_data\":\"%s\" }", deviceID, cardValue);
  Particle.publish(deviceID, jsonData, PRIVATE);

I think he means to have double quotes instead of single quotes and the leading JSON isn’t part of the actual JSON string either, right?
Otherwise it’s not really valid JSON - have a check with some online JSON validators.

3 Likes

I don’t think it is, but that is a direct copy and paste to what he sent me. However he’s wanting me to change my code on the photon, and he will modify our database however we need to to work with this. I’ll double check some Json examples to make sure everything works.

@Mjones I have had to do this for the web app that receives event messages because it is much easier and faster for the event receiving program to read in JSON structure. The following is a very helpful site to test that your JSON formatted messages (taken from the console) are valid, it is very easy to miss out a } or a ] or a , :confused:

To avoid mistakes I use the following:
const char* const mName = "{\"N\":\"";

Declared string constants which I then package into messages thus:
dataLen = snprintf(dataStr, MAXDATA, "%sF%s%s\"},%sV%s%s\"},%sH%s%s\"},%sPRC%s%s\"},%sSN%s%s\"}",mName,mValue,firmware,mName,mValue,softwarebuild,mName,mValue,hardwarebuild,mName,mValue,param.productCode,mName,mValue,param.serialNum);

Where the N is short for name of the JSON data pair and V is short for value of item. snprintf() is used to avoid message buffer overrun similar to @ScruffR example - thanks to him for advice to use snprintf!

2 Likes

Thanks @armor I’ll definitely use this, it should be extremely helpful for this.

So I’m getting an error with this. I’m making an assumption here that the device knows its own ID, is this true or do I need to input that after I get the device?
This is the error I’m getting:

janusdevicejson.cpp:138:91: 'deviceID' was not declared in this scope

I added this at the top:

String deviceID = System.deviceID();

Just wanted to make sure this is the proper way before I send it out.

I believe the compiler is throwing an error on the left side of the declaration, not the right side. Try changing the variable name to “myID” like in the docs.

I don’t think I explained my problem right. I was getting that error before I added the variable, once I added that, the error went away, I just wanted to make sure that’s correct.

Ok. That makes a lot more sense. Since the deviceID doesn’t change I would use the variable as a global and assign in setup. That’s if you can’t use deviceID() directly each time you need to reference it.

1 Like