Each time I run this sketch it works OK for about 10 seconds, then the core LED starts flashing RED, turns off, flashes red again, turns off and the core restarts. Sometimes when the core restarts, the loop() is still running, but the HTTP requests are no longer coming through. In this case, it never restarts (but isn’t very useful in this state)
- Using RestClient library from @mwdll
- Talking to a lifx-http web server ( https://github.com/chendo/lifx-http )
I’ve built it locally and using the cloud editor and the results are the same.
Code:
RestClient.h
#include "application.h"
class RestClient {
public:
RestClient(const char* host);
RestClient(const char* _host, int _port);
//Client Setup
void dhcp();
int begin(byte*);
//Generic HTTP Request
int request(const char* method, const char* path,
const char* body, String* response);
// Set a Request Header
void setHeader(const char*);
// GET path
int get(const char*);
// GET path and response
int get(const char*, String*);
// POST path and body
int post(const char* path, const char* body);
// POST path and body and response
int post(const char* path, const char* body, String*);
// PUT path and body
int put(const char* path, const char* body);
// PUT path and body and response
int put(const char* path, const char* body, String*);
// DELETE path
int del(const char*);
// DELETE path and body
int del(const char*, const char*);
// DELETE path and response
int del(const char*, String*);
// DELETE path and body and response
int del(const char*, const char*, String*);
private:
TCPClient client;
int readResponse(String*);
void write(const char*);
const char* host;
int port;
int num_headers;
const char* headers[10];
boolean contentTypeSet;
};
RestClient.cpp
/**
******************************************************************************
* @file RestClient.cpp
*
* details: https://github.com/llad/spark-restclient
*
* credit: https://github.com/csquared/arduino-restclient
*
******************************************************************************
*/
#include "RestClient.h"
#ifdef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string) (Serial.print(string))
#endif
#ifndef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string)
#endif
RestClient::RestClient(const char* _host){
host = _host;
port = 80;
num_headers = 0;
contentTypeSet = false;
}
RestClient::RestClient(const char* _host, int _port){
host = _host;
port = _port;
num_headers = 0;
contentTypeSet = false;
}
// GET path
int RestClient::get(const char* path){
return request("GET", path, NULL, NULL);
}
//GET path with response
int RestClient::get(const char* path, String* response){
return request("GET", path, NULL, response);
}
// POST path and body
int RestClient::post(const char* path, const char* body){
return request("POST", path, body, NULL);
}
// POST path and body with response
int RestClient::post(const char* path, const char* body, String* response){
return request("POST", path, body, response);
}
// PUT path and body
int RestClient::put(const char* path, const char* body){
return request("PUT", path, body, NULL);
}
// PUT path and body with response
int RestClient::put(const char* path, const char* body, String* response){
return request("PUT", path, body, response);
}
// DELETE path
int RestClient::del(const char* path){
return request("DELETE", path, NULL, NULL);
}
// DELETE path and response
int RestClient::del(const char* path, String* response){
return request("DELETE", path, NULL, response);
}
// DELETE path and body
int RestClient::del(const char* path, const char* body ){
return request("DELETE", path, body, NULL);
}
// DELETE path and body with response
int RestClient::del(const char* path, const char* body, String* response){
return request("DELETE", path, body, response);
}
void RestClient::write(const char* string){
HTTP_DEBUG_PRINT(string);
client.print(string);
}
void RestClient::setHeader(const char* header){
headers[num_headers] = header;
num_headers++;
}
// The mother- generic request method.
//
int RestClient::request(const char* method, const char* path,
const char* body, String* response){
HTTP_DEBUG_PRINT("HTTP: connect\n");
if(client.connect(host, port)){
HTTP_DEBUG_PRINT("HTTP: connected\n");
HTTP_DEBUG_PRINT("REQUEST: \n");
// Make a HTTP request line:
write(method);
write(" ");
write(path);
write(" HTTP/1.1\r\n");
for(int i=0; i<num_headers; i++){
write(headers[i]);
write("\r\n");
}
write("Host: ");
write(host);
write("\r\n");
write("Connection: close\r\n");
if(body != NULL){
char contentLength[30];
sprintf(contentLength, "Content-Length: %d\r\n", strlen(body));
write(contentLength);
if(!contentTypeSet){
write("Content-Type: application/x-www-form-urlencoded\r\n");
}
}
write("\r\n");
if(body != NULL){
write(body);
write("\r\n");
write("\r\n");
}
//make sure you write all those bytes.
delay(100);
HTTP_DEBUG_PRINT("HTTP: call readResponse\n");
int statusCode = readResponse(response);
HTTP_DEBUG_PRINT("HTTP: return readResponse\n");
//cleanup
HTTP_DEBUG_PRINT("HTTP: stop client\n");
num_headers = 0;
client.stop();
delay(50);
HTTP_DEBUG_PRINT("HTTP: client stopped\n");
return statusCode;
}else{
HTTP_DEBUG_PRINT("HTTP Connection failed\n");
return 0;
}
}
int RestClient::readResponse(String* response) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean httpBody = false;
boolean inStatus = false;
char statusCode[4];
int i = 0;
int code = 0;
if(response == NULL){
HTTP_DEBUG_PRINT("HTTP: NULL RESPONSE POINTER: \n");
}else{
HTTP_DEBUG_PRINT("HTTP: NON-NULL RESPONSE POINTER: \n");
}
HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n");
while (client.connected()) {
HTTP_DEBUG_PRINT(".");
if (client.available()) {
HTTP_DEBUG_PRINT(",");
char c = client.read();
HTTP_DEBUG_PRINT(c);
if(c == ' ' && !inStatus){
inStatus = true;
}
if(inStatus && i < 3 && c != ' '){
statusCode[i] = c;
i++;
}
if(i == 3){
statusCode[i] = '\0';
code = atoi(statusCode);
}
//only write response if its not null
if(httpBody){
if(response != NULL) response->concat(c);
}
if (c == '\n' && httpBody){
HTTP_DEBUG_PRINT("HTTP: return readResponse2\n");
return code;
}
if (c == '\n' && currentLineIsBlank) {
httpBody = true;
}
if (c == '\n') {
// you're starting a new lineu
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
HTTP_DEBUG_PRINT("HTTP: return readResponse3\n");
return code;
}
sketch.ino
#include "RestClient.h"
RestClient lightServer = RestClient("10.0.0.6",56780);
String response;
void setup()
{
}
void loop()
{
delay(2000);
lightServer.put("/lights/all/toggle", "", &response);
}