Skocz do zawartości

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


Pomocna odpowiedź

Kto mnie nauczy jak wysłać json-a POSTem na konkretny adres z konkretnym portem. 

Treść to mniej więcej coś takiego:

{"esp8266id": "123123123", "sensordatavalues":[{"value_type":"SDS_P1","value":"10"},{"value_type":"SDS_P2","value":"20"},{"value_type":"BME280_temperature","value":"25"},{"value_type":"BME280_humidity","value":"78"},{"value_type":"BME280_pressure","value":"98920.23"}]}

Oczywiście nie mam również pojęcia jak wstawić zmienną do takiego POSTa po wartości „value”

Adres musi mieć podany numer portu, czyli mniej więcej 

https:// cośtamznumeremportu

(edytowany)

Taki przykładzik na tworzenie jsona (możesz sobie skompilować na pececie):

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

char *mkmessage(const char *fmt,...)
{
    va_list ap;
    char *result;
    int size;
    // sprawdzeie ile zajmie napis wynikowy
    va_start (ap, fmt);
    size=vsnprintf(NULL, 0, fmt, ap);
    va_end(ap);
    if (size < 0) return NULL; // tak się nie powinno zdarzyć
    size++;
    result=(char *)malloc(size);
    va_start (ap, fmt);
    vsnprintf(result, size, fmt, ap);
    va_end(ap);
    return result;
}

char *makejson(const char *id, int val1, int val2, float val3)
{
    static const char *fmt=R"JSON({
    "esp8266id":"%s",
    "sensordatavalues": [
        {"value_type":"cos_int1","value":"%d"},
        {"value_type":"cos_int2","value":"%d"},
        {"value_type":"cos_flt1","value":"%f"}]
})JSON";
    return mkmessage(fmt, id, val1, val2, val3);
}


int main(int argc,char *argv[])
{

    char *c = makejson("id123",15,231,213.25);
    printf("Wynikowy json: \n%s\n", c);
    free((void *)c);
    return 0;
}

Wynik:

ethanak@darva:~/src/soyer/json$ g++ -o mkjson mkjson.cpp
ethanak@darva:~/src/soyer/json$ ./mkjson
Wynikowy json: 
{
    "esp8266id":"id123",
    "sensordatavalues": [
        {"value_type":"cos_int1","value":"15"},
        {"value_type":"cos_int2","value":"231"},
        {"value_type":"cos_flt1","value":"213.250000"}]
}

 

Arduino na 100% włącza stdio i stdlib, nie pamiętam czy również stdarg a nie chce mi się teraz szukać wolnej płytki 🙂

Edytowano przez ethanak
2 godziny temu, ethanak napisał:

Od wczoraj nic innego nie czytam... na tym też się od tygodnia opieram min. w przypadku czytania API.

Taka ścieżka wywala 404:

String serverPath_aqi = "https://api.aqi.eco/update/123456789xxxxxxxxx";

Taka podobnie:

String serverPath_aqi = "https://api.aqi.eco/update/123456789xxxxxxxxx:443";

Aktualnie mam coś takiego:

String serverPath_aqi = "https://api.aqi.eco/update/xxx1213"; 
      
jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
Serial.println(jsonBuffer);

String httpPOSTaqi(const char* serverName) {

  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"SDS_P1\",\"value\":\"10\"},{\"value_type\":\"SDS_P2\",\"value\":\"20\"}, {\"value_type\":\"BME280_temperature\",\"value\":\"25\"}]}");
  // 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;
}

Sypie:

17:31:46.370 -> HTTP Response code: 404

A mnie się nie wydaje, bo jakby nie mógł znaleźć serwera to byś miał ujemny błąd. W tym przypadku znaleziony serwer powiedział że path jest do rzyci.

GET to nie jest funkcja pobierania tylko wywołanie konkretnej metody. Tak samo działa POST. Gdzie u Santosa widziałeś takie wywołanie? Może nauczyłbyś się podstaw protokołu http, zamiast po rafalsku wstawiać losowe wartości do losowych funkcji i dziwić się że nie działa?

  • Lubię! 1
String serverPath_aqi = "https://api.aqi.eco/update/xxx1213"; 
      
jsonBuffer = httpPOSTaqi(serverPath_aqi.c_str());
      
Serial.println(jsonBuffer);

String httpPOSTaqi(const char* serverName) {

  WiFiClientSecure client1;
  HTTPClient http1;
  client1.setInsecure();
  http1.begin(client1, serverName);
  int httpResponseCode = http1.POST("{\"esp8266id\": \"123123123\",\"sensordatavalues\":[{\"value_type\":\"SDS_P1\",\"value\":\"10\"},{\"value_type\":\"SDS_P2\",\"value\":\"20\"}, {\"value_type\":\"BME280_temperature\",\"value\":\"25\"}]}");
  // Send HTTP POST request

  
  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;
}

Teraz mam 200 🙂

5 minut temu, ethanak napisał:

Może nauczyłbyś się podstaw protokołu http,

Może najwyższy czas, odpalam wieczorem coś na YT na początek...

Teraz muszę pokombinować jak tam wstawić zmienne, też String(variable)?

2 minuty temu, SOYER napisał:

Teraz muszę pokombinować jak tam wstawić zmienne

Pokazałem Ci chyba najprostszy sposób (sprintf). Przy okazji notacja RAW w C/C++ jest dość wygodna bo nie bawisz się w jakieś eskejpowanie. Patrz jak wygląda podstawienie wartości do fmt w makejson. Czyli:

R"MARKER(...)MARKER"

gdzie MARKER to jakiś napis nie występujący we wnętrzu stałej napisowej.

Poza tym po kiego grzyba pobierasz payload jeśli serwer zwrócił babola (czyli kod inny niż 200)?

 

1 godzinę temu, ethanak napisał:

Pokazałem Ci chyba najprostszy sposób (sprintf). Przy okazji notacja RAW w C/C++ jest dość wygodna bo nie bawisz się w jakieś eskejpowanie. Patrz jak wygląda podstawienie wartości do fmt w makejson. Czyli:

R"MARKER(...)MARKER"

gdzie MARKER to jakiś napis nie występujący we wnętrzu stałej napisowej.

Poza tym po kiego grzyba pobierasz payload jeśli serwer zwrócił babola (czyli kod inny niż 200)?

 

Nic z tego niestety nie kapuję...

Wstawiłem z ręki ..."+ String() +"...

https://kryry01.aqi.eco/pl

 

https://app.weathercloud.net/d4311785603#google_vignette

Dziękuję wszystkim za pomoc. Działa.

Jeszcze nie wszystko tak jak chciałem, ale jest.

Na aqi.eco nie można wstawić np. pomiarów deszczu czy wiatru, a na weathercloud żeby pokazywać wskaźniki zanieczyszczenia powietrza trzeba wykupić dodatkowy abonament. To tak informacyjnie.

 Jeszcze raz dziękuję, szczególne podziękowania oczywiście dla @ethanak

 

  • Lubię! 1

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...