[vz-users] JSON parsen

Christian Wulff christianwulff at gmx.de
Sun Jul 30 16:52:45 CEST 2017


Gerne, der hat allerdings schon über 750 Zeilen, is halt noch in der Entwicklung:

 

/*  

 Test the tft.print() viz embedded tft.write() function

This sketch used font 2, 4, 7

Make sure all the display driver and pin comnenctions are correct by

editting the User_Setup.h file in the TFT_eSPI library folder.

#########################################################################

######################## Wichtige Einstellungen: ########################

1. DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY

2. für deutsche Wochentage die Datei DateStrings.cpp der Library time_master

editieren C:\Users\Chris\Documents\Arduino\libraries\Time-master 

 #########################################################################

Great HTML color picker tool: https://www.w3schools.com/colors/colors_picker.asp

### TO DO:

2. Temperaturwerte aus JSON holen

3. Farben der Kanäle aus JSON holen, und in RGB565 umrechnen?!

4. Immer nur die Texte aktualisieren, die sich auch wirklich geändert haben, die Uhr möglichst schnell.

5. Umlaufende Pixel, Sinus/Cosinus Schwingung

*/

#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip

#include <SPI.h>

#include <ArduinoJson.h>

#include <ESP8266WiFi.h>

#include <WiFiClient.h>

#include <WiFiUdp.h>

#include <TimeLib.h>  //by Paul Stoffregen, not included in the Arduino IDE !!!

#include <Timezone.h> //by Jack Christensen, not included in the Arduino IDE !!!

WiFiClient client;

TFT_eSPI tft = TFT_eSPI();  // Invoke library

const unsigned long baud_rate = 74880;     // serial connection speed

const long interval = 1000;

const long JSONinterval = 20000;           // interval at which to request JSON (milliseconds)

const unsigned long HTTP_TIMEOUT = 10000;  // max response time from server

const size_t MAX_CONTENT_SIZE = 512;       // max size of the HTTP response

const char WiFiSSID[] = "xxxxxxxxxx";     //### your Router SSID

const char WiFiPSK[]  = "xxxxxxxxxxxxxxx"; //### your Router Password

const char* server = "192.168.178.37";  // server's address

const char* resource = "/middleware.php/channel/05ce3700-97c7-11e6-acf4-754d9577033c.json";      // http resource Kanalinfo Temperatur AUSSEN

unsigned long previousMillis = 0;

unsigned long previousJSONMillis = 0;        // für Zeitschleife JSON Abfrage

volatile bool wasConnected = false;

const char* channelfolder = "/middleware.php/channel/";

const char* datafolder = "/middleware.php/data/";

const char* channelextension = ".json";

const char* dataextension = ".json?from=now";  // hier wird definiert das nur die aktuellen Daten gelesen werden sollen

char resChannel[128]="";

//int textcol[8];   // Array Variable für Textfarbe aus JSON

uint16_t textcol[8];   // Array Variable für Textfarbe aus JSON

int hh = -100;

int oldhh = -100;

int mm = -100;

int oldmm = -100;

int ss = -100;

int oldss = -100;

int ww = -100;

int oldww = -100;

int dd = -100;

int olddd = -100;

int mo = -100;

int oldmo = -100;

int yy = -100;

int oldyy = -100;

float T0 = -100;

float oldT0 = -100;

float T1 = -100;

float oldT1 = -100;

float T2 = -100;

float oldT2 = -100;

float T3 = -100;

float oldT3 = -100;

float T4 = -100;

float oldT4 = -100;

float T5 = -100;

float oldT5 = -100;

float T6 = -100;

float oldT6 = -100;

 

// Die UUID's der darzustellenden Kanäle

char *UUID[7] = { 

"05ce3700-97c7-11e6-acf4-754d9577033c",    // UUID des 0. Kanals Temperatur Aussen

"18975770-97e4-11e6-a22a-6910830732b4",    // UUID des 1. Kanals Temperatur Leni Rauchmelder

"b64be660-9915-11e6-84ac-37f3f084194e",    // UUID des 2. Kanals Temperatur Joni Rauchmelder

"e7345f40-9898-11e6-b7f6-7df31c77cfb3",    // UUID des 3. Kanals Temperatur Bad

"d08a8390-97e3-11e6-bb10-e9877a1c482b",    // UUID des 4. Kanals Temperatur Joni Rauchmelder

"4b321920-97e4-11e6-8968-99af1eb4a84a",    // UUID des 5. Kanals Temperatur Spitzboden Rauchmelder

"60b75820-97d9-11e6-8c9e-ed7c96d54c3f"     // UUID des 6. Kanals Temperatur Warmwasserspeicher

};

 

// Die Texte der darzustellenden Kanäle

char *text[7]={

"`C Aussen",     // Anzeigetext auf Display für den 0. Kanal, der "`" (Akzent Gravis) wird mit dem verwendeten Font als "°" (Grad) dargestellt

"`C Leni",       // Anzeigetext auf Display für den 1. Kanal

"`C Joni",       // Anzeigetext auf Display für den 2. Kanal

"`C Bad",        // Anzeigetext auf Display für den 3. Kanal

"`C Schlafen",   // Anzeigetext auf Display für den 4. Kanal

"`C Spitzboden", // Anzeigetext auf Display für den 5. Kanal

"`C Warmwasser"  // Anzeigetext auf Display für den 6. Kanal

};

 

// #################### Initialize Serial port ####################

void initSerial() {

  Serial.begin(baud_rate);

  while (!Serial) {

  ;                  // wait for serial port to initialize

  }

  //Serial.println("Serial ready");

}

 

// The type of data that we want to extract from the page

struct UserData {

  char color[8];   // Der HEX Farbwert ist im JSON als String mit 7 Stellen gespeichert

};

bool isConnected(long timeOutSec) {

  timeOutSec = timeOutSec * 1000;

  int z = 0;

  while (WiFi.status() != WL_CONNECTED) {

    delay(200);

    Serial.print(".");

    tft.print(".");

    if (z == timeOutSec / 200) { return false; }

    z++;

  }

  return true;

}

 

// #################### Aus JSON ausgelesenen HEX Color String in RGB565 Integer umwandeln ####################

uint16_t rgb565(const char* str)

{

  unsigned long rgb = strtoul(str + 1, NULL, 16);  // String in Integer wandeln

  uint16_t R = (rgb >> 16) & 0xFF;

  uint16_t G = (rgb >>  8) & 0xFF;

  uint16_t B = (rgb      ) & 0xFF;

  uint16_t ret  = (R & 0xF8) << 8;  // 5 Bits

           ret |= (G & 0xFC) << 3;  // 6 Bits

           ret |= (B & 0xF8) >> 3;  // 5 Bits

  return( ret);

}

 

//### NTP, TIME & TIMEZONE ###################################################################

//UDP

WiFiUDP Udp;

unsigned int localPort = 123;

//NTP Server

char ntpServerName1[] = "ntp1.t-online.de";

char ntpServerName2[] = "time.nist.gov";

//Timezone

//Central European Time (Frankfurt, Paris)

TimeChangeRule CEST = { "CEST", Last, Sonntag, Mar, 2, 120 };     //Central European Summer Time

TimeChangeRule CET = { "CET ", Last, Sonntag, Okt, 3, 60 };       //Central European Standard Time

Timezone CE(CEST, CET);

TimeChangeRule *tcr;        //pointer to the time change rule, use to get the TZ abbrev

time_t utc, local;

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message

byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

bool getNtpTime(char* ntpServerName)

{

  //Serial.print(F("NTP request..."));

  if (timeStatus() == timeSet) {

    //Serial.println(F("not necessary"));

    return true;

  }

  IPAddress ntpServerIP; // NTP server's ip address

  while (Udp.parsePacket() > 0); // discard any previously received packets

  Serial.println(F("Transmit NTP Request"));

  //tft.println(F("Transmit NTP Request"));

  // get a random server from the pool

  WiFi.hostByName(ntpServerName, ntpServerIP);

  Serial.print(ntpServerName);

  //tft.print(ntpServerName);

  Serial.print(": ");

  //tft.print(": ");

  Serial.println(ntpServerIP);

  //tft.println(ntpServerIP);

  sendNTPpacket(ntpServerIP);

  uint32_t beginWait = millis();

  while (millis() - beginWait < 1500) {

    int size = Udp.parsePacket();

    if (size >= NTP_PACKET_SIZE) {

      Serial.println(F("Receive NTP Response"));

      //tft.println(F("Receive NTP Response"));

      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer

      unsigned long secsSince1900;

      // convert four bytes starting at location 40 to a long integer

      secsSince1900 = (unsigned long)packetBuffer[40] << 24;

      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;

      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;

      secsSince1900 |= (unsigned long)packetBuffer[43];

      setTime(secsSince1900 - 2208988800UL);

      //delay(5000);   // ###########################################Damit die Meldung auf dem Display zu lesen ist

      return true;

    }

  }

  Serial.println(F("FATAL ERROR : No NTP Response."));

  tft.println(F("FATAL ERROR : No NTP Response."));

  return false; // return 0 if unable to get the time

}

// send an NTP request to the time server at the given address

void sendNTPpacket(IPAddress &address)

{

  // set all bytes in the buffer to 0

  memset(packetBuffer, 0, NTP_PACKET_SIZE);

  // Initialize values needed to form NTP request

  // (see URL above for details on the packets)

  packetBuffer[0] = 0b11100011;   // LI, Version, Mode

  packetBuffer[1] = 0;     // Stratum, or type of clock

  packetBuffer[2] = 6;     // Polling Interval

  packetBuffer[3] = 0xEC;  // Peer Clock Precision

  // 8 bytes of zero for Root Delay & Root Dispersion

  packetBuffer[12] = 49;

  packetBuffer[13] = 0x4E;

  packetBuffer[14] = 49;

  packetBuffer[15] = 52;

  // all NTP fields have been given values, now

  // you can send a packet requesting a timestamp:

  Udp.beginPacket(address, 123); //NTP requests are to port 123

  Udp.write(packetBuffer, NTP_PACKET_SIZE);

  Udp.endPacket();

}

//Function to return the compile date and time as a time_t value

time_t compileTime(void)

{

#define FUDGE 25        //fudge factor to allow for compile time (seconds, YMMV)

  char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";

  char chMon[3], *m;

  int d, y;

  tmElements_t tm;

  time_t t;

  strncpy(chMon, compDate, 3);

  chMon[3] = '\0';

  m = strstr(months, chMon);

  tm.Month = ((m - months) / 3 + 1);

  tm.Day = atoi(compDate + 4);

  tm.Year = atoi(compDate + 7) - 1970;

  tm.Hour = atoi(compTime);

  tm.Minute = atoi(compTime + 3);

  tm.Second = atoi(compTime + 6);

  t = makeTime(tm);

  return t + FUDGE;        //add fudge factor to allow for compile time

}

/* 

void printTime(time_t t)

{

  sPrintI00(hour(t));

  sPrintDigits(minute(t));

  sPrintDigits(second(t));

  Serial.print(' ');

  Serial.print(dayStr(weekday(t)));

  Serial.print(' ');

  sPrintI00(day(t));

  Serial.print('.');

            //Serial.print(monthShortStr(month(t)));   // ********** alternativ "Jul" anstatt "07"

  sPrintI00(month(t));   // ********** hier kommt "07" anstatt "Jul" raus

  Serial.print('.');

  Serial.print(year(t));

  Serial.println(' ');

}

*/ 

/*

//Print an integer in "00" format (with leading zero).

//Input value assumed to be between 0 and 99.

void sPrintI00(int val)

{

  if (val < 10) Serial.print('0');

  Serial.print(val, DEC);

  return;

}

//Print an integer in ":00" format (with leading zero).

//Input value assumed to be between 0 and 99.

void sPrintDigits(int val)

{

  Serial.print(':');

  if (val < 10) Serial.print('0');

  Serial.print(val, DEC);

}

*/

 

//Print an integer in "00" format (with leading zero).

//Input value assumed to be between 0 and 99.

void tftPrintI00(int val)

{

  if (val < 10) tft.print('0');

  tft.print(val, DEC);

  return;

}

//Print an integer in ":00" format (with leading zero).

//Input value assumed to be between 0 and 99.

void tftPrintDigits(int val)

{

  tft.print(':');

  if (val < 10) tft.print('0');

  tft.print(val, DEC);

}

 

 

// Open connection to the HTTP server

bool connect(const char* hostName) {

  //Serial.print("Connect to ");

  //Serial.println(hostName);

  bool ok = client.connect(hostName, 80);

  //Serial.println(ok ? "Connected" : "Connection Failed!");

  return ok;

}

 

// Send the HTTP GET request to the server

bool sendRequest(const char* host, const char* resource) {

  //Serial.print("GET ");

  //Serial.println(resource);

  client.print("GET ");

  client.print(resource);

  client.println(" HTTP/1.0");

  client.print("Host: ");

  client.println(host);

  client.println("Connection: close");

  client.println();

  return true;

}

 

// Skip HTTP headers so that we are at the beginning of the response's body

bool skipResponseHeaders() {

  // HTTP headers end with an empty line

  char endOfHeaders[] = "\r\n\r\n";

  client.setTimeout(HTTP_TIMEOUT);

  bool ok = client.find(endOfHeaders);

  if (!ok) {

    Serial.println("No response or invalid response!");

  }

  return ok;

}

 

/*

{

  "version": "0.3",

   "entity": {

     "uuid": "05ce3700-97c7-11e6-acf4-754d9577033c",

     "type": "temperature",

     "active": false,

     "color": "#009933",

     "fillstyle": 0,

     "public": true,

     "style": "lines",

     "title": "T01 Aussen",

     "yaxis": "auto"

   }

}

JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(9)

*/

bool readReponseChannel(struct UserData* userData) {

  // Compute optimal size of the JSON buffer according to what we need to parse.

  // See https://bblanchon.github.io/ArduinoJson/assistant/

  const size_t BUFFER_SIZE =

      JSON_OBJECT_SIZE(2)    // the root object has 2 elements

      + JSON_OBJECT_SIZE(9)  // the "entity" object has 5 elements

      + MAX_CONTENT_SIZE;    // additional space for strings

  // Allocate a temporary memory pool

  DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);

  JsonObject& root = jsonBuffer.parseObject(client);

  if (!root.success()) {

    Serial.println("JSON parsing failed!");

    return false;

  }

 

  // Here were copy the strings we're interested in

  strcpy(userData->color, root["entity"]["color"]);

  //textcol[3]= strtoul (userData->color, NULL, 16);

  //strcpy(textcol[1], root["entity"]["color"]);

 

  // It's not mandatory to make a copy, you could just use the pointers

  // Since, they are pointing inside the "content" buffer, so you need to make

  // sure it's still in memory when you read the string

  return true;

}

 

/*

{

   "version":"0.3",

   "data":{

      "tuples":[

         [1501258250761,20.312,1]],

      "uuid":"05ce3700-97c7-11e6-acf4-754d9577033c",

      "from":1501258204011,

      "to":1501258250761,

      "min":[1501258250761,20.312],

      "max":[1501258250761,20.312],

      "average":20.312,

      "rows":2

      }

}

JSON_ARRAY_SIZE(1) + 2*JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(8)

*/

bool readReponseData(struct UserData* userData) {

  // Compute optimal size of the JSON buffer according to what we need to parse.

  // See https://bblanchon.github.io/ArduinoJson/assistant/

  const size_t BUFFER_SIZE =

   // JSON_OBJECT_SIZE(2)    // the root object has 2 elements

   // + JSON_OBJECT_SIZE(9)  // the "entity" object has 5 elements

   // + MAX_CONTENT_SIZE;    // additional space for strings

      JSON_ARRAY_SIZE(1)

      + 2*JSON_ARRAY_SIZE(2)

      + JSON_ARRAY_SIZE(3)

      + JSON_OBJECT_SIZE(2)

      + JSON_OBJECT_SIZE(8)

      + MAX_CONTENT_SIZE;    // additional space for strings

    

  // Allocate a temporary memory pool

  DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);

  JsonObject& root = jsonBuffer.parseObject(client);

  if (!root.success()) {

    Serial.println("JSON parsing failed!");

    return false;

  }

  // Here were copy the strings we're interested in

  strcpy(userData->color, root["data"]["tuples"]);

  Serial.println(userData->color);

  // It's not mandatory to make a copy, you could just use the pointers

  // Since, they are pointing inside the "content" buffer, so you need to make

  // sure it's still in memory when you read the string

  return true;

}

 

 

 

 

 

 

// Print the data extracted from the JSON

void printUserData(const struct UserData* userData) {

  //Serial.print("color = ");  Serial.println(userData->color);

}

 

// Close the connection with the HTTP server

void disconnect() {

  //Serial.println("Disconnect");

  client.stop();

}

 

 

 

 

 

 

 

 

 

// ARDUINO entry point #1: runs once when you press reset or power the board

void setup()

{

  initSerial();

  Serial.setDebugOutput(true);

  tft.init();

  tft.setRotation(1);     // Ausrichtung des Displays: 0,1,2 oder 3, Querformat = 1 oder 3

  tft.fillScreen(TFT_BLACK);   // Clear Screen

  tft.setTextColor(TFT_WHITE);

  tft.setTextFont(1);

  tft.println("connecting to WLAN");

  WiFi.mode(WIFI_STA);

  WiFi.begin(WiFiSSID, WiFiPSK);

  if (isConnected(30)) {

    wasConnected = true;

    Serial.println(F("Starting UDP"));

    tft.println(" ");

    tft.println(F("Starting UDP"));

    Udp.begin(localPort);

    Serial.print(F("Local port: "));

    Serial.println(Udp.localPort());

    Serial.println(F("waiting for sync"));

    tft.print(F("Local port: "));

    tft.println(Udp.localPort());

    tft.println(F("waiting for sync"));

  }

 

// ######################## Hier müssen die Farben 1x gelesen werden und die Texte 1x geschrieben werden

tft.fillScreen(TFT_BLACK);   // Clear Screen

 

for (int pos=0; pos<7; pos++){    // Schleife 0-6

strcpy(resChannel,channelfolder);

strcat(resChannel,UUID[pos]);

strcat(resChannel,channelextension);

//Serial.println(resChannel);

if (connect(server)) {

  if (sendRequest(server, resChannel) && skipResponseHeaders()) {

    UserData userData;

      if (readReponseChannel(&userData)) {

        textcol[pos]=rgb565(userData.color);   // hier werden die 7 Farben in das textcol[] Array geschrieben

        //printUserData(&userData);

      }

    }

  }

  disconnect();

}

 

 

   

 

  for (int i=0; i<7; i++){    // Schleife 0-6

    tft.setTextFont(4);  // Favorit 4, sonst auch 1, 2, 4, 6, 7 oder 8

    tft.setTextColor(textcol[i]);  // hier werden die 7 Textfarben nacheinander gesetzt

    tft.setCursor(60, 55+i*26);    //Startcursorposition x=60, y=55 plus i Zeilen á 26 Pixel

    tft.println(text[i]);   // hier werden die 7 Texte nacheinander auf das Display geschrieben

  }

}

 

 

 

 

 

 

 

 

 

 

 

// ARDUINO entry point #2: runs over and over again forever

void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {

    previousMillis = currentMillis;

    if (!isConnected(10) && wasConnected) { delay(200); ESP.restart(); }

    if (!getNtpTime(ntpServerName1)) { getNtpTime(ntpServerName2); }

    local = CE.toLocal(now(), &tcr);

    //printTime(local);

  }

  hh = hour(local);

  mm = minute(local);

  ss = second(local);

  ww = weekday(local);

  dd = day(local);

  mo = month(local);

  yy = year(local);

 

while (hh != oldhh) {

   tft.setTextFont(7);   // Uhr mit Font wie 7-Segmentanzeige

   tft.setTextSize(1); 

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(0, 0);    // Cursor auf x=0, y=0 setzen für die Stunden

   tftPrintI00(oldhh); // Stunden

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(0, 0);    // Cursor auf x=0, y=0 setzen für die Stunden

   tftPrintI00(hh); // Stunden 

   oldhh=hh;

}

 

while (mm != oldmm) {

   tft.setTextFont(7);   // Uhr mit Font wie 7-Segmentanzeige

   tft.setTextSize(1); 

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(64, 0);    // Cursor auf x=64, y=0 setzen für die Minuten

   tftPrintDigits(oldmm);  // Minuten

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(64, 0);    // Cursor auf x=64, y=0 setzen für die Minuten

   tftPrintDigits(mm);  // Minuten

   oldmm=mm;

}

   

while (ss != oldss) {

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(140, 0);    // Cursor auf x=140, y=0 setzen für die Sekunden

   tftPrintDigits(oldss);    // Sekunden

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(140, 0);    // Cursor auf x=140, y=0 setzen für die Sekunden

   tftPrintDigits(ss);    // Sekunden

   oldss=ss;

}

 

while (ww != oldww) {

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(186, 0);    // Cursor auf x=186, y=0 setzen für den Wochentag

   tft.println(dayStr(oldww));   //dayStr für ausgeschriebene Wochentage, daysShortStr für kurze Wochentage

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(186, 0);    // Cursor auf x=186, y=0 setzen für den Wochentag

   tft.println(dayStr(ww));   //dayStr für ausgeschriebene Wochentage, daysShortStr für kurze Wochentage

   oldww=ww;

}

 

while (dd != olddd) {

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(186, 28);    // Cursor auf x=186, y=28 setzen für den Tag

   tftPrintI00(olddd);    // Tag

   tft.print(".");

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(186, 28);    // Cursor auf x=186, y=28 setzen für den Tag

   tftPrintI00(dd);    // Tag

   tft.print(".");

   olddd=dd;

}

 

while (mo != oldmo) {

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(221, 28);    // Cursor auf x=186, y=28 setzen für den Monat

   tftPrintI00(oldmo);    // Monat

   tft.print(".");

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(221, 28);    // Cursor auf x=186, y=28 setzen für den Monat

   tftPrintI00(mo);    // Monat

   tft.print(".");

   oldmo=mo;

}

 

while (yy != oldyy) {

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.setCursor(256, 28);    // Cursor auf x=256, y=28 setzen für das Jahr

   tft.print(oldyy);    // Jahr

   tft.setTextColor(TFT_WHITE);

   tft.setCursor(256, 28);    // Cursor auf x=256, y=28 setzen für das Jahr

   tft.print(yy);    // Jahr

   oldyy=yy;

}

 

while (T0 != oldT0) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT0, 1, 57, 55+0*26, 4);

   tft.setTextColor(textcol[0]); 

   tft.drawFloat(T0, 1, 57, 55+0*26, 4);

   oldT0=T0;

}

 

while (T1 != oldT1) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT1, 1, 57, 55+1*26, 4);

   tft.setTextColor(textcol[1]); 

   tft.drawFloat(T1, 1, 57, 55+1*26, 4);

   oldT1=T1;

}

 

while (T2 != oldT2) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

  tft.drawFloat(oldT2, 1, 57, 55+2*26, 4);

   tft.setTextColor(textcol[2]); 

   tft.drawFloat(T2, 1, 57, 55+2*26, 4);

   oldT2=T2;

}

 

while (T3 != oldT3) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT3, 1, 57, 55+3*26, 4);

   tft.setTextColor(textcol[3]); 

   tft.drawFloat(T3, 1, 57, 55+3*26, 4);

   oldT3=T3;

}

 

while (T4 != oldT4) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT4, 1, 57, 55+4*26, 4);

   tft.setTextColor(textcol[4]); 

   tft.drawFloat(T4, 1, 57, 55+4*26, 4);

   oldT4=T4;

}

 

while (T5 != oldT5) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT5, 1, 57, 55+5*26, 4);

   tft.setTextColor(textcol[5]); 

   tft.drawFloat(T5, 1, 57, 55+5*26, 4);

   oldT5=T5;

}

 

while (T6 != oldT6) {

   tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

   tft.setTextFont(4);

   tft.setTextSize(1);

   tft.setTextColor(TFT_BLACK);

   tft.drawFloat(oldT6, 1, 57, 55+6*26, 4);

   tft.setTextColor(textcol[6]); 

   tft.drawFloat(T6, 1, 57, 55+6*26, 4);

   oldT6=T6;

}

 

  float test = -99.9;

  tft.setTextDatum(TR_DATUM);  // Text rechtsbündig ausrichten

  tft.setCursor(0, 55);    // Cursor auf x=0, y=55 setzen

/* 

  tft.setTextColor(textcol[0]); 

  tft.drawFloat(test, 1, 57, 55+0*26, 4);

 

  test = -98.9;

  tft.setTextColor(textcol[1]);

  tft.drawFloat(test, 1, 57, 55+1*26, 4);

 

  test = -97.9;

  tft.setTextColor(textcol[2]);  

  tft.drawFloat(test, 1, 57, 55+2*26, 4);

*/  

  test = -96.9;

  tft.setTextColor(textcol[3]);

  tft.drawFloat(test, 1, 57, 55+3*26, 4);

  

  test = -95.9;

  tft.setTextColor(textcol[4]);

  tft.drawFloat(test, 1, 57, 55+4*26, 4);

  

  test = -94.9;

  tft.setTextColor(textcol[5]); 

  tft.drawFloat(test, 1, 57, 55+5*26, 4);

  

  test = -93.9;

  tft.setTextColor(textcol[6]);

  tft.drawFloat(test, 1, 57, 55+6*26, 4);

 

/*

 for (int pos=0; pos<7; pos++){    // Schleife 0-6

strcpy(result,channelfolder);

strcat(result,UUID[pos]);

strcat(result,channelextension);

Serial.println(result);

 

strcpy(result,datafolder);

strcat(result,UUID[pos]);

strcat(result,dataextension);

Serial.println(result);

}

*/

 

unsigned long currentJSONMillis = millis();

   if (currentJSONMillis - previousJSONMillis >= JSONinterval) {

     // save the last time you requested the JSON

     previousJSONMillis = currentJSONMillis;

     if (connect(server)) {

       if (sendRequest(server, resource) && skipResponseHeaders()) {

       UserData userData;

       if (readReponseChannel(&userData)) {

       printUserData(&userData);

         }

      }

     }

  disconnect();

   }

 

  delay(500);  // Eine halbe Sekunde warten, 500 ist perfekt (Die Sekunden werden gut genug angezeigt, wenn es schneller läuft (ohne delay) kommt es zu Problemen, vermutlich weil die http requests zu schnell hintereinander kommen)

}

 

Von: Frank Richter [mailto:frank.richter83 at gmail.com] 
Gesendet: Sonntag, 30. Juli 2017 16:12
An: volkszaehler.org - users
Betreff: Re: [vz-users] JSON parsen

 

Hi Christian,

 

zeig mal deinen ganzen Code, mit diesem Schnipsel kann ich nicht nachvollziehen was du da treibst.

 

Ansonsten sieht man doch in dem von mir geposteten Assistant-Code sehr gut wie Arrays adressiert werden: Index in eckigen Klammern, so wie man das erwarten würde.

 

Grüße

Frank

 

Am 30.07.2017 14:29 schrieb "Christian Wulff" <christianwulff at gmx.de>:

Moin Frank,

 

nee, den Hinweis brauche ich nicht. Das weiss ich selber.

Ich habe mir von beiden JSONs die Parsing programs von dem Assistant ausgedruckt und nebeneinandergelegt und mit dem funktionierenden Arduino Programm vom ersten JSON verglichen.

Was soll ich sagen?! Ich kann das nicht nachvollziehen.

 

Das erste JSON hat nur JSON Objects. Ich denke das verstehe ich. Jedenfalls funktioniert mein Programm damit.

Das zweite JSON hat aber JSON Arrays. Damit komme ich nicht klar.

 

Das mag aber vielleicht daran liegen, das mein original Beispiel Parsing Program von der Library völlig anders aussieht, als das vom Assistant?!

 

So sieht mein Parsing Program aus:

 

strcpy(userData->color, root["entity"]["color"]);

 

for (int pos=0; pos<7; pos++){ 

strcpy(resChannel,channelfolder);

strcat(resChannel,UUID[pos]);

strcat(resChannel,channelextension);

if (connect(server)) {

  if (sendRequest(server, resChannel) && skipResponseHeaders()) {

    UserData userData;

      if (readReponseChannel(&userData)) {

        textcol[pos]=rgb565(userData.color);

      }

    }

  }

  disconnect();

}

 

So sieht das vom Assistant aus:

 

const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(9) + 190;

DynamicJsonBuffer jsonBuffer(bufferSize);

 

const char* json = "{\"version\":\"0.3\",\"entity\":{\"uuid\":\"05ce3532-97c7-1356-a454-754d9534563c\",\"type\":\"temperature\",\"active\":false,\"color\":\"#009933\",\"fillstyle\":0,\"public\":true,\"style\":\"lines\",\"title\":\"T01 Aussen\",\"yaxis\":\"auto\"}}";

 

JsonObject& root = jsonBuffer.parseObject(json);

 

const char* version = root["version"]; // "0.3"

 

JsonObject& entity = root["entity"];

const char* entity_uuid = entity["uuid"]; // "05ce3532-97c7-1356-a454-754d9534563c"

const char* entity_type = entity["type"]; // "temperature"

bool entity_active = entity["active"]; // false

const char* entity_color = entity["color"]; // "#009933"

int entity_fillstyle = entity["fillstyle"]; // 0

bool entity_public = entity["public"]; // true

const char* entity_style = entity["style"]; // "lines"

const char* entity_title = entity["title"]; // "T01 Aussen"

const char* entity_yaxis = entity["yaxis"]; // "auto"

 

 

 

…..da versteh ich leider nur Bahnhof. Da ist ja nichts vergleichbar/nachvollziehbar

 

Deswegen kann ich für das zwei JSON die Agfrage von einem JSON Object nicht auf ein JSON Array umbauen, weil ich nicht weiss, wie ich die Einträge addressiere?!

 

Lieben Gruß,

Chris

 

 

 

 

 

Von: Frank Richter [mailto:frank.richter83 at gmail.com] 
Gesendet: Sonntag, 30. Juli 2017 02:19
An: volkszaehler.org - users
Betreff: Re: [vz-users] JSON parsen

 

Moin Christian,

 

brauchst du echt nochmal einen Hinweis auf https://bblanchon.github.io/ArduinoJson/assistant/ ?

 

Wenn du dort das fragliche JSON reinkopierst, komm folgendes raus:

 

const size_t bufferSize = JSON_ARRAY_SIZE(1) + 2*JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(8) + 220;
DynamicJsonBuffer jsonBuffer(bufferSize);

const char* json = "{\"version\":\"0.3\",\"data\":{\"tuples\":[[1501258250761,20.312,1]],\"uuid\":\"05ce3700-97c7-11e6-acf4-754d9577033c\",\"from\":1501258204011,\"to\":1501258250761,\"min\":[1501258250761,20.312],\"max\":[1501258250761,20.312],\"average\":20.312,\"rows\":2}}";

JsonObject& root = jsonBuffer.parseObject(json);

const char* version = root["version"]; // "0.3"

JsonObject& data = root["data"];

JsonArray& data_tuples0 = data["tuples"][0];
long data_tuples00 = data_tuples0[0]; // 1501258250761
float data_tuples01 = data_tuples0[1]; // 20.312
int data_tuples02 = data_tuples0[2]; // 1

const char* data_uuid = data["uuid"]; // "05ce3700-97c7-11e6-acf4-754d9577033c"
long data_from = data["from"]; // 1501258204011
long data_to = data["to"]; // 1501258250761

long data_min0 = data["min"][0]; // 1501258250761
float data_min1 = data["min"][1]; // 20.312

long data_max0 = data["max"][0]; // 1501258250761
float data_max1 = data["max"][1]; // 20.312

float data_average = data["average"]; // 20.312
int data_rows = data["rows"]; // 2

 

Was ist denn da noch unklar?

 

Gruß

Frank

 

Am 30.07.2017 01:39 schrieb "Christian Wulff" <christianwulff at gmx.de>:

Moin,

 

Ich komme leider beim JSON parsen nicht weiter.

 

Das JSON des Channels habe ich inzwischen gut genug unter Kontrolle:

{

  "version": "0.3",

   "entity": {

     "uuid": "05ce3532-97c7-1356-a454-754d9534563c",

     "type": "temperature",

     "active": false,

     "color": "#009933",

     "fillstyle": 0,

     "public": true,

     "style": "lines",

     "title": "T01 Aussen",

     "yaxis": "auto"

   }

}

Dies hat die Expression:

JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(9)

 

Da lese ich die "color" aus.

Die Adresse ist root["entity"]["color"]

 

Soweit kann ich das nachvollziehen.

 

Nun habe ich das Data JSON:

{

   "version":"0.3",

   "data":{

      "tuples":[

         [1501258250761,20.312,1]],

      "uuid":"05ce3700-97c7-11e6-acf4-754d9577033c",

      "from":1501258204011,

      "to":1501258250761,

      "min":[1501258250761,20.312],

      "max":[1501258250761,20.312],

      "average":20.312,

      "rows":2

      }

}

Dies hat die Expression:

JSON_ARRAY_SIZE(1) + 2*JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(8)

 

Da möchte ich aus dem Tuple in der 4. Zeile "1501258250761" (das ist der Timestamp) und "20.312" (das ist die Temperatur) auslesen.

Wie lauten denn davon die Adressen?

root["data"]["tuples ....... und da verließen sie mich?!

 

Könnte mir da jemand weiterhelfen?

 

Danke und lieben Gruß,

Chris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://demo.volkszaehler.org/pipermail/volkszaehler-users/attachments/20170730/7ebd0bad/attachment-0001.html>


More information about the volkszaehler-users mailing list