[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