Go Down

Topic: failing to make ic2cloud connection (Read 198 times) previous topic - next topic

diyhouse

I am trying to submit data to an ic2cloud server, using test code,.. However, my efforts are failing with various errors.

Code: [Select]


Requesting URL: GET http://www.ic2pro.com:80/Wire/connector/set?id=111-222-444&TEMPERATURE=26.56 HTTP/1.1
Running option1
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Sun, 14 Oct 2018 16:35:13 GMT
Content-Type: text/html
Content-Length: 138
Connection: close
// -----------------------------------
Running option2
HTTP/1.1 502 Bad Gateway
Server: awselb/2.0
Date: Sun, 14 Oct 2018 16:45:01 GMT
Content-Type: text/html
Content-Length: 138
Connection: close
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
//--------------------------------
Running option3
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Sun, 14 Oct 2018 16:42:37 GMT
Content-Type: text/html
Content-Length: 138
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
</body>
</html>
// ------------------------------
Running option4
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Sun, 14 Oct 2018 16:50:35 GMT
Content-Type: text/html
Content-Length: 138
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
</body>
</html>


and my source program is as follows:-
Code: [Select]
#include <ESP8266WiFi.h>
#include <OneWire.h>

OneWire  ds(D5);

const char* ssid     = "NULL";                     // wifi ssid
const char* password = "NULL";                 // wifi password
String auth          = "bWFyBoYW1ibGlu1lLnVrOjEyMzQ1Njc4";                // Authentication credentials Create a string from <email_address>:<API_Password> and encode it base64
// The sample:
//    String auth = "dXNlcjpwYXNzd29yZA=="
// is the encoding for "user:password"
int indx = 0;
#define SizeInputString 64
char WebInputString[SizeInputString];

const char* host      = "www.ic2pro.com";
const int   httpPort  = 80;
String devId          = "111-222-444";                      // Device ID. CREATE YOUR OWN GUID; Use this http://www.guidgenerator.com/

String getTemperature()
{
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;
  String scelsius;

  if ( !ds.search(addr)) {                                            // find chip
    if ( !ds.search(addr)) {
      ds.reset_search();
      delay(250);
      return "ERR1";
    }
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {                            // check CRC
    return "ERR2";
  }

  switch (addr[0]) {                                                  // test if it's a proper chip
    case 0x10: type_s = 1; break;
    case 0x28: type_s = 0; break;
    case 0x22: type_s = 0; break;
    default:
      Serial.println("Device is not a DS18x20 family device.");       // Not a proper chip
      return "ERR3";
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);                                                  // initiate conversion

  delay(1000); // maybe 750ms is enough, maybe not

  ds.reset();
  ds.select(addr);
  ds.write(0xBE);

  for (byte i = 0; i < 9; i++) {                                     // read data
    data[i] = ds.read();
  }


  int16_t raw = (data[1] << 8) | data[0];                            // Convert the data to temperature
  if (type_s) {
    raw = raw << 3;
    if (data[7] == 0x10) {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;                                // based on the resolution make the conversion
    else if (cfg == 0x20) raw = raw & ~3;
    else if (cfg == 0x40) raw = raw & ~1;
  }
  celsius = (float)raw / 16.0;
  scelsius = String(celsius);
  return scelsius;
}

void sendTemperature() {
  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature();

  Serial.print("Requesting URL: ");
  //  Serial.println(url);
  Serial.println("GET http://" + String(host) + ":" + String(httpPort) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature() + " HTTP/1.1");   // submit HTTP request

  // This will determine how data is sent to the server
  // ***************************
#define option4 true
  // ***************************
#ifdef option1
  Serial.println("Running option1");
  client.print("GET http://" + String(host) + ":" + String(httpPort) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature() + " HTTP/1.1");   // submit HTTP request
  client.print(String("Authorization: Basic " + auth + "\r\n" +
                      "Connection: close\r\n\r\n"));
#elif option2
  Serial.println("Running option2");
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Authorization: Basic " + auth + "\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(10);
#elif option3
  Serial.println("Running option3");
  client.print(String("GET http://" + String(host) + ":" + String(httpPort) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature() + " HTTP/1.1"));   // submit HTTP request
  client.print(String("Authorization: Basic " + auth + "\r\n" +
                      "Connection: close\r\n\r\n"));
#elif option4
  Serial.println("Running option4");
  client.print(String("GET http://" + String(host) + ":" + String(httpPort) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature() + " HTTP/1.1"));   // submit HTTP request
  client.print(String("Authorization: Basic " + auth + "\r\n" +
                      "Host: " + host + "\r\n" +
                      "Connection: close\r\n\r\n"));
#endif

  // Read all the lines of the reply from server and print them to Serial
  indx = 0;
  unsigned long waitStart = millis();     // Initialise start time for Reading
  unsigned long tooLong = 5000UL;         // Don't wait more than 5 seconds for all data

  while (client.connected() && millis() - waitStart < tooLong)  {
    while (client.available() > 0)   {
      char c = client.read();

      WebInputString[indx] = c;
      indx++;

      // Check if input stream will overflow buffer
      if ( indx > (SizeInputString - 1) ) {
        Serial.println("Input string Too Big");
        break;
      }
      //client.readStringUntil('>').

      if ( c == '\r' || c == '\n'  )    {
        // The end of the line or New Line arrived.
        WebInputString[indx - 1 ] = '\0';
        indx = 0;
        Serial.println(WebInputString);

        //        splitCommand();
        break;

      }
    } // while client available
  }  // while client connected

  Serial.println();
  Serial.println("closing connection");
}

void setup() {
  Serial.begin(57200);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  sendTemperature();
  delay(3000);
}


I have tried more variants than I care/can  list but none successfully submit data to the cloud,. is anyone able to spread some light on the error of my ways,...
Are there any things I can change to improve the error reporting,.. as I am at a loss..

Many tx

pylon

Code: [Select]
  client.print("GET http://" + String(host) + ":" + String(httpPort) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + getTemperature() + " HTTP/1.1");   // submit HTTP request


Why are you pretending to do a HTTP 1.1 request but you don't comply to the protocol? For example the "Host" header field is mandatory in HTTP 1.1.

Options 3 and 4 provide a URL and not a path on the GET line which the server correctly replies with a Bad Request.

Option 2 is probably correct but the server www.ic2pro.com seems to always reply with a 502 error (at least test with a browser indicates this). So there might be a problem on the server side or you have to provide documentation of that server application. If this is a publicly available service it doesn't seem to be standards conforming.

diyhouse

Many tx Pylon for your comments,... I have been trying to adapt some "reference" code from the ic2lcoud site and a derivative from the "instructables" web site.
The ic2cloud submission code is as follows:-
Code: [Select]
 if (eth.connect(server, port)) {                                                          // initialize HTTP connection on port 80
    eth.println("GET http://" + String(server) + ":" + String(port) + "/Wire/connector/set?id=" + devId + "&TEMPERATURE=" + temperature+ " HTTP/1.1");   // submit HTTP request
    eth.println("Authorization: Basic " + auth);
    eth.println("Connection: close");
    eth.println();
    Serial.println("Temperature sent to server.");
  }
  else {
    Serial.println("Connection Error");
  }
  eth.stop();
}


and the adapted code from the Instructables web site ( which uses the ESP8266 Module) is:-
Code: [Select]
 // We now create a URI for the request
  String url = "/Wire/connector/set?id=" + devId + "&TEMPERATURE="+getTemperature();
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Authorization: Basic " + auth + "\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(10);

I have been trying to use the ESP8266 code although I have purchased an Ethernet card for Arduino to run the reference code,.. I have tried all sorts of variations/tweaks on the submission code but nothing seems to make a successful link to the server.
based on your comments the "Option2",.. is the correct format,.. I have further tried including port numbers and varying the delay,.. but they all seem to give the 502 Bad Gateway.... response.
My Current Incarnation of the code for 8266 is as follows:-
Code: [Select]
  Serial.println("Running option2");
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Authorization: Basic " + auth + "\r\n" +
               "Host: " + host + ":" + String(httpPort) +"\r\n" +
               "Connection: close\r\n\r\n");
//  delay(2);
  Serial.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Authorization: Basic " + auth + "\r\n" +
               "Host: " + host + ":" + String(httpPort) +"\r\n" +
               "Connection: close\r\n\r\n");


which produces the following response ( additional CR removed to save space):-
Code: [Select]
Running option2
GET /Wire/connector/set?id=111-222-444&TEMPERATURE=23.4 HTTP/1.1
Authorization: Basic a0ediughj8375kjhb4356cvb1lLnVrOjEyMzQ4
Host: www.ic2pro.com:80
Connection: close
HTTP/1.1 502 Bad Gateway
Server: awselb/2.0
Date: Tue, 16 Oct 2018 07:19:05 GMT
Content-Type: text/html
Content-Length: 138
Connection: close
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>


Am I being a dummy and doing something stupid?... as the really dumb thing is I had the code working,.. and then somewhere along the way the code stopped working,.. I assume because I did something dumb,.. but going back to previous backups,.. I cannot make the code work... and now I am struggling to get the reference code working...  :smiley-confuse:

I have attached my full esp8266 code,.. which basically reads temperatures,. displays them on an i2c display, submits (tries) to the cloud, and controls a fan.

Any help,..  humbly received

pylon

That server seems to always return 502 "Bad Gateway". Try that stuff in your browser first, once you got it running there go to the Arduino.

Post a link to the site's documentation.

diyhouse

Many Tx Pylon for responding,..  But without sounding a little dumb,.. what should cut and paste into the browser..
as some lines contain the web address,. some open the connection 1st,.. I can see many ways of formatting to paste into the browser..
What would be a correctly formatted example stream.. from the data I am using... and what should I expect back...

Many thanks

pylon

Quote
What would be a correctly formatted example stream.. from the data I am using... and what should I expect back...
I don't use an example stream or the like. I simply enter the URL:

http://www.ic2pro.com/Wire/connector/set?id=111-222-444&TEMPERATURE=23.4

I know that this is missing the authentication but if the server responds with an 502 that's not the problem (correct answer would be 401 Authentication Required). So it seems that this server is broken.

diyhouse

Thankyou thankyou thankyou,.. Ah yes,.. that was what I did not understand,.. was how to feed the authentication in,.. and what should be a correct response,... let me see if the actual server people have any comment...

Go Up