Skocz do zawartości

Darmowe miejsce na www gdzie można wrzucać swoje odczyty


SOYER

Pomocna odpowiedź

Cześć, jak w temacie. Chcę wrzucać na jakąś ogólnodostępną stronę www odczyty ze swoich czujników. Np. coś jak thing speak. Tylko z tym są jakieś problemy, za chiny ludowe nie umiem się tam zarejestrować.

Polecacie coś? Żeby też było łatwe w implementacji w szkicach dla esp. Może być oparte o API, używał bym wtedy tych z Supli.

Ktoś coś?

Link do komentarza
Share on other sites

Po pewnych bojach udało mi się dołączyć arduCloud do mojego szkicu, a nie przez ten ich dziwny generator szkiców. Połączyło się, wyświetla dane w cloudzie, chyba trochę gryzie się z Suplą, ale póki co działają oba.

Niestety nie można udostępnić tych odczytów innym za darmo. Dashoard sharing kosztuje

image.thumb.png.1eb3b6da08f1e573dd64b5d3f62fe999.png

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Ok, teraz na tapecie weathercloud, ale... nie działa(?)

W załączniku dokumentacja API(choć nie wiem czy aktualna), poniżej screeny, linki i szkice.

Zaglądnijcie do komentarzy pod tym linkiem a konkretnie do tego:

image.thumb.png.1b1f88353b30ce65ddabdc9112223c52.png

image.thumb.png.6e59b5635c3272c4ec2d0af1d475bbba.png

Ja co 10 minut w loop wykonuję funkcję:

void weathercloud(){
  Serial.print("connecting to ");
  Serial.print(server);
  Serial.println("...");
  WiFiClient client;
  if (client.connect(server, 80)) {
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
  } 
  else {
    Serial.println("connection failed");
  }
  client.print("GET /v01/set/wid/");
  client.print(IDKryry);
  client.print("/key/");
  client.print(KeyKryry);
  client.print("/temp/");
  client.print(tempSlonce);
  client.print("/wspdavg/");
  client.print(average_kmh);
  client.print("/rain/");
  client.print(mmM2);
  //client.println("/ HTTP/1.1");
  //client.println("Host: api.weathercloud.net");
  client.println("/ver/1.1/type/201");
  client.println();
  delay(1000);
 
  if (!client.connected()) {
    Serial.println("client disconected.");
      if (client.connect(server, 80)) {
    delay(100);
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
   }
   else {
    Serial.println("connection failed");
  }
  }
 delay(100);
}

Oczywiście dane nie pojawiają się na www. Teraz nie wiem czy coś robię źle, czy to po prostu już nie działa. @ethanak Ty się też znasz na tych postach i getach;)

Zastanawia mnie też sensowność tego fragmentu

  if (!client.connected()) {
    Serial.println("client disconected.");
      if (client.connect(server, 80)) {
    delay(100);
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
   }
   else {
    Serial.println("connection failed");
  }
  }

Generalnie serial co jakiś czas wypluwa, że połączono i wtedy jakieś tam IP, czasem, że failed, ale dane się nie pokazują.

API+Documentation+v1.0.pdf

Edytowano przez SOYER
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Zrobiłem jeszcze test z tym "linkiem bezpośrednim" o którym tam piszą:

https://api.weathercloud.net/v01/set/wid/xxx/key/xxx/temp/95

iksy to moje id i key

wstawiłem to w adres przeglądarki, enter i za pierwszym razem wywaliło 401 czyli błąd id, albo key, ale (po 10 min) za drugim razem już 200, czyli ok. Sprawdzam www i faktycznie jest odczyt.

Czyli musi być błąd w tej mojej funkci wysyłającej, ale nie znam się na tym...

Edytowano przez SOYER
Link do komentarza
Share on other sites

@SOYER wejdź sobie w kod mojej pogodynki, masz tam taki książkowy przykład jak się korzysta niskopoziomowo z api.

Poza tym naucz się korzystania z wget, bardzo dobrze się sprawdza przy badaniu "co ja zjeb..em" - takie podstawowe narzędzie.

Link do komentarza
Share on other sites

16 godzin temu, ethanak napisał:

@SOYER wejdź sobie w kod mojej pogodynki, masz tam taki książkowy przykład jak się korzysta niskopoziomowo z api.

Poza tym naucz się korzystania z wget, bardzo dobrze się sprawdza przy badaniu "co ja zjeb..em" - takie podstawowe narzędzie.

Hello, przeglądnąłem cały wątek, potem poszedłem na githuba. Powiem, że to zupełnie nie mój poziom. Nie potrafię nawet znaleźć w tym gąszczu tego wysyłania przez URL, a jeszcze jakbym miał to  odnieść do tego konkretnego mojego przypadku powyżej...

Nie wiem np. dlaczego ktoś na końcu tego URL wstawia np.:

//client.println("/ HTTP/1.1");
//client.println("Host: api.weathercloud.net");
client.println("/ver/1.1/type/201");

Nic nie piszą o tym, chyba, że to jakaś "pozycja obowiązkowa" przy takim wysyłaniu...

Link do komentarza
Share on other sites

Zmieniłem funkcję wywoływaną co 10 min na:

void weathercloud(){

      String serverPath = "https://api.weathercloud.net/v01/set/wid/xx/key/xx/temp/35";
      
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer);
      JSONVar myObject = JSON.parse(jsonBuffer);
      
       if (JSON.typeof(myObject) == "undefined") {
             Serial.println("Parsing input failed!");
        return;
       }
}

String httpGETRequest(const char* serverName) {
  WiFiClient client1;
  HTTPClient http1;
    
  // Your Domain name with URL path or IP address with path
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http1.end();

  return payload;
}

otrzymuję:

HTTP Response code: 400
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>

Parsing input failed!

bad request

Nie wiem czy tu może być winą, że teraz robię to jsonem? O ile w ogóle robę to dobrze...

Ktoś coś?

Link do komentarza
Share on other sites

Popatrz dokładniej na mój kod w pliku getwea.cpp.

Jeśli łączysz się przez https musisz użyć WiFiClientSecure a nie WiFiClient. Dodatkowo musisz ustawić client.setInsecure() - nie będę wnikał w szczegóły, ale bez specjalnych zabiegów ESP nie jest w stanie zweryfikować certyfikatu SSL, ta funkcja po prostu wyłącza weryfikację.

A komunikat błędu masz jasny -  wysłałeś żądanie nieszyfrowane na port wymagający szyfrowania.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

(edytowany)

Bardzo dziękuję. Oczywiście zadziałało.

Miałem jeszcze problem z wstawieniem zmiennych do mojego zapytania, ale okazało się, że wystarczy dodać "String";), dzięki @rziomber.

Teraz ładnie wysyła dane:

https://app.weathercloud.net/d4311785603

Na razie tylko opady, średnia prędkość wiatru i temperatura.

Mam zajęcie na ten tydzień żeby przerobić soft dla reszty czujników.

Szkic funkcji wysyłającej:

#include <ESP8266HTTPClient.h>
#include <Arduino_JSON.h>

String jsonBuffer;
char server [] = "https://api.weathercloud.net";
char IDKryry [] = "xx";
char KeyKryry [] = "xx";

void weathercloud(){
  
  String serverPath = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) + "/temp/" + String(tempSlonce) + "/wspdavg/" + String(average_kmh) + "/rain/" + String(mmM2);
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer);
      JSONVar myObject = JSON.parse(jsonBuffer);
      
       if (JSON.typeof(myObject) == "undefined") {
             Serial.println("Parsing input failed!");
        return;
       }
}

String httpGETRequest(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}

Dla tej konkretnej strony/serwera należy pamiętać by nie wysyłać częściej niż co 10 min.

Dziękuję jeszcze raz.

Edytowano przez SOYER
  • Lubię! 1
Link do komentarza
Share on other sites

Jeden drobiazg: prawidłowy kod odpowiedzi serwera to 200 a nie "większe od zera". Szczególnie 4xx i 5xx oznaczają jakiś błąd. Tak że tylko w przypadku otrzymania kodu 200 zwracasz payload z odpowiedzi serwera.

  • Lubię! 1
Link do komentarza
Share on other sites

Dobra, jedziemy dalej i kolejna prośba o pomoc w ładnym napisaniu kodu.

Założenie: miałem aktualizować kod we wszystkich urządzeniach z których chcę upublicznić dane na weathercloud, jednak na ten serwer można wysyłać dane raz na 10min. Pojawił się problem, jak to zrobić, żeby, co najmniej, 4 esp wysyłało dane, oraz żeby było to aktualne. No niewykonalne.

Postanowiłem pobrać na jedno esp dane z serwera Supli, dotyczące potrzebnych mi danych, a następnie tym jednym esp wysłać wszystko razem, co 10min, na serwer weathercloud.

Przerobiłem moją funkcję wysyłającą na pobierającą, za pomocą linków bezpośrednich, interesujące mnie dane.

void weathercloud(){

  String serverPathZEW_press =  "https://xxx.supla.org/direct/880/xxx/read?format=json"; 
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      Serial.println(jsonBuffer);
}

String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    float pressure = doc["value"]; 
    char charVal[10];
    dtostrf(pressure, 6, 2, charVal);
    Serial.println(charVal);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}

Może być? Działa, zmienna charVal ładnie wyświetla ciśnienie.

Teraz prośba, będę miał ok 7-8 takich linków bezpośrednich, jak to ładnie napisać, żeby nie robić 8 prawie identycznych funkcji i dziewiątej wysyłającej?

Link do komentarza
Share on other sites

(edytowany)

Chyba też niepotrzebna jest aż tak skomplikowana procedura:

float pressure = doc["value"]; 
    char charVal[10];
    dtostrf(pressure, 6, 2, charVal);
    Serial.println(charVal);

może wystarczy

float pressure = doc["value"]; 
Serial.println(pressure);

Czy nie wiem co piszę...?

Nie sprawdzałem.

Edytowano przez SOYER
Link do komentarza
Share on other sites

Aktualnie to wygląda tak:

void weathercloud(){
  int WCtempSlonce = tempSlonce * 10;
  int WCaverage_kmh = (average_kmh * 10) / 3.6; //km/h->m/s
  int WCmmM2 = mmM2 *10;

  String serverPathZEW_press = "https://xx.supla.org/direct/880/xx/read?format=json"; 
  String serverPathZEW_hum = "https://xx.supla.org/direct/881/xx/read?format=json";
  String serverPathWC = String(server) + "/v01/set/wid/" + String(IDKryry) + "/key/" + String(KeyKryry) + "/temp/" + String(WCtempSlonce) + "/wspd/" + String(WCaverage_kmh) + "/rain/" + String(WCmmM2) + "/bar/" + String(WCpressure) + "/hum/" + String(WChumidity);

      jsonBuffer = httpGET_ZEW_hum(serverPathZEW_hum.c_str());
      jsonBuffer = httpGET_ZEW_press(serverPathZEW_press.c_str());
      jsonBuffer = httpGETWC(serverPathWC.c_str());
      
      Serial.println(jsonBuffer);
}

String httpGETWC(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_press(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    float pressure = doc["value"]; 
    WCpressure = pressure *10;
    Serial.println(pressure);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}
String httpGET_ZEW_hum(const char* serverName) {
  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http1.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, payload);
    float humidity = doc["humidity"]; 
    WChumidity = humidity *10;
    Serial.println(humidity);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  
  http1.end();
  return payload;
}

Mało elegancko, prawda @ethanak, a jeszcze co najmniej 5 linków...

Link do komentarza
Share on other sites

A powinno mniej więcej:

if (httpResponseCode == 200) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http1.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }

Sprawdź jaki kod podaje serwer (czy przypadkiem nie 201 albo 202, nie znam tego api), ale w razie czego:

if (httpResponseCode >= 200 && httpResponseCode <= 202) {
  ...

 

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.