Getting data from the Particle Cloud to RabbitMQ

Ok, looks like I am making some progress, but I am a little stumped…

I have created my webhook, and specified JSON under Send Custom Data. I then fill in the following:

{"properties":{},"routing_key":"","payload":"my body2","payload_encoding":"string"}

After I save my webhook, and it gets triggered, I noticed a failure reported by RabbitMQ. It says that I must include “properties” in my json string. If I scroll up in the webhook, under the JSON section, I see that my “properties” key is not listed. This is what it shows:

{
  "routing_key": "",
  "payload": "my body2",
  "payload_encoding": "string"
}

Playing around with Curl, I have discovered that I must have the properties key listed, or I can not sent data to the server. I also tried removing the {} after the properties key, and replacing with “” but that causes an error.

Thoughts?

Can you post your complete webhook definition/configuration JSON? I’m sorry for not responding till now; been swamped with family & holiday stuff.

No problem, I completely understand about the holidays…

I am not sure if I understand your request 100%… But, the JSON I am trying to pass, is the following:

{"properties":{},"routing_key":"","payload":"my body2","payload_encoding":"string"}

But, only the following is showing up after I create the webhook is:

{
  "routing_key": "",
  "payload": "my body2",
  "payload_encoding": "string"
}

For some reason, it keeps dropping my “properties” line… Ultimately, I will replace “my body2” with the actual payload from the Particle Electron…

Ok, I was able to resolve the issue of my “properties” key not being accepted. To fix this, I used the following JSON:

{"properties":[],"routing_key":"","payload":"my body2","payload_encoding":"string"}

I changes the {} to [], and it works. Also, in the headers I had to use the two following lines:

content-type:application/json
and
accept:text/html

Now, I am trying to replace my payload with the actual data coming from the Electron. Based on my understanding, it should look like:

{"properties":[],"routing_key":"","payload":"{{PARTICLE_EVENT_VALUE}}","payload_encoding":"string"}

But, this does not work. It literally sends the line {{PARTICLE_EVENT_VALUE}} to RabbitMQ.

Thoughts on how to properly include the payload?

What I was asking for was either a screenshot of your webhook when you created it (in the console) or a copy of the webhook.json file you used to create the webhook using the CLI

Ahhh, Ok… I created the webhook using the web interface. Attached are the screen shots of where I am at…

Harrisonhjones, any chance you could look at why I can not pass my payload onto the webhook?

1 Like

I’m just installing a virtual RabbitMQ cluster right now, eagerly watching this thread to get the webhooks working :+1:

1 Like

Bump… Anyone around that might know why my Particle Webhook is not sending the payload? It is literally sending: {{PARTICLE_EVENT_VALUE}}

My JSON is as follows:

{“properties”:[],“routing_key”:"",“payload”:"{{PARTICLE_EVENT_VALUE}}",“payload_encoding”:“string”}

@tremmert have you had any luck yet or are you waiting for a response?

@tremmert and I ended up coming up with the following webhook definition. Still not 100% but I’d love additional help to debug it.

{
    "event": "RS232",
    "url": "URL GOES HERE",
    "requestType": "POST",
    "headers": {"accept":"application/json"},
    "json": {
        "properties": [],
        "routing_key": "",
        "payload": "{{PARTICLE_EVENT_VALUE}}",
        "payload_encoding": "string"
    },
    "auth": {
  		"username": "guest",
  		"password": "guest"
  	},
    "mydevices": true,
    "noDefaults": true
}

Still not working properly. I replaced {{PARTICLE_EVENT_VALUE}} with {{PARTICLE_DEVICE_ID}} just for a test, and it successfully replaced that variable with my device ID every time.

I then changed if back from DeviceID to EventValue, and it did not work. So, my guess is that the Particle Cloud does not like something I am sending.

For testing purposes, I have updated the code on my device to the following:

// Constants
const size_t READ_BUF_SIZE = 64;
const unsigned long CHAR_TIMEOUT = 10000;

// Global variables
char readBuf[READ_BUF_SIZE];
size_t readBufOffset = 0;
unsigned long lastCharTime = 0;

void setup() {
	Serial1.begin(9600);
	Serial.begin(9600);
}

void loop() {
	// Read data from serial
	while(Serial1.available()) {
		if (readBufOffset < READ_BUF_SIZE) {
			char c = Serial1.read();
			if (c != '\n') {
				// Add character to buffer
				readBuf[readBufOffset++] = c;
				lastCharTime = millis();
			}
			else {
				// End of line character found, process line
				readBuf[readBufOffset] = 0;
				Serial.printlnf("got: %s", readBuf);
				Particle.publish("RS232", readBuf);
				readBufOffset = 0;
			}
		}
		else {
			Serial.println("readBuf overflow, emptying buffer");
			readBufOffset = 0;
		}
	}
	if (millis() - lastCharTime >= CHAR_TIMEOUT) {
		lastCharTime = millis();
		readBuf[readBufOffset] = 0;
		Serial.printlnf("got timeout: %s", readBuf);
		readBufOffset = 0;
	}
}

I am sending sample data to the Serial1 port on the device, and monitoring the results on Serial. Here is the output from my terminal:

got timeout:
got: testing
got: testing
got timeout:

So, I know that the device is receiving my data/payload which is currently set to “testing”.

If I check the Particle console, and look at the log in my Webhook, I see the following:

Event
The source event that triggered the webhook

{
  "event": "RS232",
  "data": "testing\r",
  "published_at": "2017-01-18T15:53:53.108Z",
  "coreid": "44004a000d51363034323832"
}

So that tells me that my data/payload is making it to the particle cloud successfully.

But if I check Requestb.in I can see that {{PARTICLE_EVENT_VALUE}} is not being replaced with my value “testing”, and it is literally sending {{PARTICLE_EVENT_VALUE}}.

RAW BODY

{"payload_encoding":"string","payload":"{{PARTICLE_EVENT_VALUE}}","routing_key":"","properties":[]}

The issue is the \r character in your data. I found this earlier this morning with \n characters. Looks like escaped characters like that break the JSON parser the webhook bot uses. Can you take that \r out?

Hmmm… I guess so, but I would probably need a little assistance in the code that runs on the Electron…

Reason being, is the Electron will be connecting to 3rd party hardware, which uses either a \r or a \n as the End Of Line character. I guess on the Electron, we could still use the \n or \r to detect EoL, but then strip that character before publishing to the cloud.

Based on my Electron code above, do you know how we could go about trying that?

Take a look at the strncpy command. Docs here. Make sure to null terminate the string!

Actually you might be able to just replace the \r or \n with \0 and it would do exactly what you want to do. Give that a try

Ok, doing some testing, it looks like a Line Termination Character that starts with a \ break the webhook bot. I changed it over to a \c and that broke the bot also…

Working on updated code to strip the line termination character, and will post soon…

Take a look at this working example I put together.

1 Like

Based on your example, I came up with the following code… And the good news is that ITS WORKING! Looks like the problem the whole time was the Line Termination Character…

// Constants
const size_t READ_BUF_SIZE = 64;
const unsigned long CHAR_TIMEOUT = 10000;

// Global variables
char readBuf[READ_BUF_SIZE];
size_t readBufOffset = 0;
unsigned long lastCharTime = 0;

void setup() {
	Serial1.begin(9600);
	Serial.begin(9600);
}

void loop() {
	// Read data from serial
	while(Serial1.available()) {
		if (readBufOffset < READ_BUF_SIZE) {
			char c = Serial1.read();
			if (c != '\n') {
				// Add character to buffer
				readBuf[readBufOffset++] = c;
				lastCharTime = millis();
			}
			else {
				// End of line character found, process line
				readBuf[readBufOffset] = 0;
				Serial.printf ("readBuf = \"%s\"\n",readBuf);
				readBuf[strlen(readBuf)-1] = '\0';
				Serial.printf ("readBuf = \"%s\"\n",readBuf);
				Serial.printlnf("got: %s", readBuf);
				Particle.publish("RS232", readBuf);
				readBufOffset = 0;
			}
		}
		else {
			Serial.println("readBuf overflow, emptying buffer");
			readBufOffset = 0;
		}
	}
	if (millis() - lastCharTime >= CHAR_TIMEOUT) {
		lastCharTime = millis();
		readBuf[readBufOffset] = 0;
		Serial.printlnf("got timeout: %s", readBuf);
		readBufOffset = 0;
	}
}

@tremmert I’ve got the webhook setup using harrisonhjones webhook definition but, I’m not seeing any connections in my RabbitMQ management console…

The URL I am using is the external static IP address of my router with the management console port number on the end, which I’m NAT Port forwarding to the local IP address of my RabbitMQ Server.

I know my NAT is setup correct as I can login in to the RabbitMQ Management console using my external IP address in a web browser, so its not that.

Could you explain how you’ve got your RabbitMQ server setup please?

Alph,
Sorry for the delay in getting back to you…

Your webhook needs to point to something like:

http://www.yourURL.com:15672/api/exchanges/EXCHANGENAME/QUEUENAME/publish

That should get data into Rabbitmq…