Node Red and Core playing nicely together

The Core and Photon support REST both incoming (through the cloud) and outgoing using a library. Node Red is REST compatible. The most basic plan is the have Node Red consuming Core/Photon services when required and Core/Photon consuming Node Red service far more regularly.

Not wanting to over stretch myself I wanted to consume a post service on my Node Red box which hopefully talking Pushover on my phone. I can use a chrome extension (Advanced REST) to do this happily enough so know it works.
I have tried using the HTTPlibary and the RESTlibrary on the Core (soon to be Photons too) and have simply failed miserably. As a developer I am finding this quite annoying as the answer is simply eluding me.
Node Red uses x-www-form-urlencoded natively and this does work (as stated earlier) but I have used both libraries to try and consume the service to no avail.
The Core is simply sending three parameters (title, priority, message) to the web service and it pings my phone.
Any ideas on what I am doing wrong?

Also does anyone know a good way to urlencode stuff parameters on the core/photon?

#include "HttpClient/HttpClient.h"
unsigned int nextTime = 0;    // Next time to contact the server
int led2 = D7;
HttpClient http;
http_header_t headers[] = {
    { "Content-Type", "application/x-www-form-urlencoded" },
    { "Accept" , "*/*"},
    { NULL, NULL }
};
http_request_t request;
http_response_t response;

void setup() {
    pinMode(led2, OUTPUT);
}

void loop() {
    request.hostname = "123.123.123.123";
    request.port = 80;
    request.path = "/pushmeover";
    request.body = "title=spark&priority=2&message=it+may+be+working";
    http.post(request, response, headers);
    digitalWrite(led2, HIGH);
    delay(1000);
    digitalWrite(led2, LOW);
    delay(10000);
}

Using the search feature helps a ton: Spark Core and Node-RED integration

2 Likes

In addition to @kennethlimcp said, you can post your Node-RED flow here. It will help to pin-point the issue. Also please check this will help or not.

1 Like

@kennthlimcp I spent all of yesterday trying suggestion (libraries, examples etc) from the search and google including the one you have linked. Infact I spent so long going through different peoples iterations of what they said worked and didn’t ended up having a headache and needing to lie down. The link is only helpful for Node Red I have already proven Node Red functional it is the Core that is not.

@krvarma As you can see I do what is recommended and it still does not work. My node red flow has three nodes. I have used the Advanced REST chrome extension successfully to transmit the converted json string over pushover using urlencoded format. Node Red is seemingly not the problem.
HTTP input node - set to post with /pushmeover
Function mode - msg.payload = msg.req.body; return msg;
Pushover node - my token details

The additions of the node produced by @krvarma would be great for a more complex situation but I am just consuming a web service with nothing else to limit additional complexity and therefore hidden situations. My current dilemma is I cannot fire a very simple web service using example code. That has even been updated with “fixes” and still fails. I will be using a local cloud for this at some point so subscription to the core/photons will not be helpful.
Can anyone spot a flaw in the spark code?

@original_pir8, the problem with you firmware code is, you are using request.hostname = "123.123.123.123";. But if you are using IP Address, then it should be request.ip = IPAddress(123,123,123,123);

I modified your code and is working fine for me.

Firmware Code

// This #include statement was automatically added by the Spark IDE.
#include "HttpClient/HttpClient.h"

unsigned int nextTime = 0;    // Next time to contact the server
int led2 = D7;
HttpClient http;

http_header_t headers[] = {
    { "Content-Type", "application/x-www-form-urlencoded" },
    { "Accept" , "*/*"},
    { NULL, NULL }
};

http_request_t request;
http_response_t response;
IPAddress noderedip = IPAddress(10,0,0,3);

void setup() {
    Serial.begin(9600);
    
    pinMode(led2, OUTPUT);
}

void loop() {
    request.ip = noderedip;
    request.port = 1880;
    request.path = "/pushmeover";
    request.body = "title=spark&priority=2&message=it+may+be+working";
    
    http.post(request, response, headers);
    
    Serial.print("Application>\tResponse status: ");
    Serial.println(response.status);

    Serial.print("Application>\tHTTP Response Body: ");
    Serial.println(response.body);
    
    digitalWrite(led2, HIGH);
    delay(1000);
    digitalWrite(led2, LOW);
    delay(10000);
}

Node-RED Flow

[{"id":"c4d83818.3b27c8","type":"function","name":"Simple Processing","func":"msg.statusCode = 200;\n\nreturn msg;","outputs":1,"valid":true,"x":423,"y":129,"z":"cd34a0db.32cb6","wires":[["323c7ac7.cdc386"]]},{"id":"e4d4e22e.1b2b2","type":"http in","name":"Push Me Over","url":"/pushmeover","method":"post","x":187,"y":230,"z":"cd34a0db.32cb6","wires":[["1be7b569.e4184b","c4d83818.3b27c8"]]},{"id":"323c7ac7.cdc386","type":"http response","name":"","x":643,"y":258,"z":"cd34a0db.32cb6","wires":[]},{"id":"1be7b569.e4184b","type":"debug","name":"","active":true,"console":"false","complete":"payload","x":317,"y":463,"z":"cd34a0db.32cb6","wires":[]}]

You can copy past the above flow.

Screenshot

Hope this helps, let us know the progress.

3 Likes

Thank you sir.
I will crack on with my efforts. I hope to use your node too once I am further along.
8 photons, 2 cores pinging away to each other should be fun.

I have been using your code exclusively and it seems to be a problem with the HTTP “stuff”.
It is either not working (status -1) or working but timing out with hitting the 5s limit then waiting 200ms to close.
Oddly it seems to fail at the start and then without provocation begin working but timing out.

I am suspecting the HTTP response node is actually not doing its job properly.

@original_pir8, can you share some more info, like screenshots or your code? I haven’t experienced this issue. Can you share the complete debug output?

I can just not currently as I am at work.
The code is what you put up except it has my IP address.
Its a very odd circumstance really but with the Serial debug from the core when it fails it actually fails but when it succeeds it timesout :frowning:

I am using the code you stated worked for you in an effort to minimise changes. This is the output from the serial monitor after the spark core boots. It does seem to be completing the post request it just seems to not complete the actual response properly.

First Output

HttpClient> Connection failed.
Application> Response status: -1
Application> HTTP Response Body:

Second Output

HttpClient> Connecting to IP: 0.0.0.0:80
HttpClient> Start of HTTP Request.
POST /pushmeover HTTP/1.0
Connection: close
Content-Length: 48
Content-Type: application/x-www-form-urlencoded
Accept: /
title=spark&priority=2&message=it+may+be+working
HttpClient> End of HTTP Request.

HttpClient> Receiving TCP transaction of 128 bytes.
HTTP/1.1 200 OK
X-Powered-By: Express
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
Content-Length: 75
Date: Tue, 09 Jun 2015 21:07:07 GMT
Connection: close

{
"title": "spark",
"priority": "2",
"message": "it may be working"
}
HttpClient> End of TCP transaction.
HttpClient> Error: Timeout while reading response.

HttpClient> End of HTTP Response (5381ms).
HttpClient> Status Code: 200
Application> Response status: 200
Application> HTTP Response Body: {
"title": "spark",
"priority": "2",
"message": "it may be working"
}

@original_pir8, from log it seems that first the system was not able connect to your server (in this case 94.174.44.159:80), second time it is connecting and proper response is send back. You should see the Node-RED debug out.

That is what has happened but should not have.
It should have connected both times without problem and should not have timed out.

I am seeing things in the debug but something (either in the http out node of node red or the http client of the core) is wrong.
I should have connected first and second time. As well as not timing out. The flow takes less than a second so the response should not take be more than a second either.

I would like help on:

  • why it failed (for no reason)?
  • why the response timed out (as this is
    continual)?

@original_pir8, by saying “I am seeing things in the debug but…”, can you explain what is happening at your end. You said you can see the debug output, but something is wrong. Can you explain what went wrong. The application simply prints the debug output and does nothing.

When you run for the first time, your Node-RED is running is it? The first output says the connection to the Node-RED failed. I am able to run this without any issues.

There is no difference in setup or services available when the two requests go through. Node Red is running happily all the time. Have you checked the serial monitor output from you core during the request? I suspect you are receiving the same time out during your transactions also.

What has gone wrong is:

  1. the failure of the first attempt
  2. the second attempt (and all others) time out.

I’ve written a .net client that works fine (not timing out) and used the Chrome extension (also doesn’t timeout).
The Spark Core HTTPlibrary is seemingly to blame for the failures I just don’t know JS well enough to fix it yet. Node Red is working fine as previously stated.

@original_pir8, not sure what happened in your case but my setup works correctly. It is not timing out or failed to connect. I tested it for almost 1 hour.