Getting data from the Particle Cloud to RabbitMQ

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…