Create json request client for easy handling and memory saving
parent
6d74b4ca0c
commit
2f19bcbc1d
|
|
@ -3,6 +3,7 @@
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <base64.h>
|
#include <base64.h>
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
#include "../Network/JsonRequestClient.h"
|
||||||
|
|
||||||
class BasePrinterClient {
|
class BasePrinterClient {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
#include "BasePrinterClientImpl.h"
|
#include "BasePrinterClientImpl.h"
|
||||||
|
|
||||||
BasePrinterClientImpl::BasePrinterClientImpl(String printerType, GlobalDataController *globalDataController, DebugController *debugController) {
|
BasePrinterClientImpl::BasePrinterClientImpl(
|
||||||
|
String printerType,
|
||||||
|
GlobalDataController *globalDataController,
|
||||||
|
DebugController *debugController,
|
||||||
|
JsonRequestClient *jsonRequestClient
|
||||||
|
) {
|
||||||
this->globalDataController = globalDataController;
|
this->globalDataController = globalDataController;
|
||||||
this->debugController = debugController;
|
this->debugController = debugController;
|
||||||
this->printerType = printerType;
|
this->printerType = printerType;
|
||||||
|
this->jsonRequestClient = jsonRequestClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset all PrinterData
|
// Reset all PrinterData
|
||||||
|
|
@ -133,3 +139,15 @@ String BasePrinterClientImpl::getPrinterName() {
|
||||||
void BasePrinterClientImpl::setPrinterName(String printer) {
|
void BasePrinterClientImpl::setPrinterName(String printer) {
|
||||||
printerData.printerName = printer;
|
printerData.printerName = printer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String BasePrinterClientImpl::getInstanceServerTarget() {
|
||||||
|
String targetServer = this->globalDataController->getPrinterServer();
|
||||||
|
if (this->globalDataController->getPrinterServer() == "") {
|
||||||
|
targetServer = this->globalDataController->getPrinterHostName();
|
||||||
|
}
|
||||||
|
return targetServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasePrinterClientImpl::getInstanceServerPort() {
|
||||||
|
return this->globalDataController->getPrinterPort();
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,12 @@
|
||||||
#include "BasePrinterClient.h"
|
#include "BasePrinterClient.h"
|
||||||
#include "../Global/GlobalDataController.h"
|
#include "../Global/GlobalDataController.h"
|
||||||
|
|
||||||
|
|
||||||
class BasePrinterClientImpl : public BasePrinterClient {
|
class BasePrinterClientImpl : public BasePrinterClient {
|
||||||
protected:
|
protected:
|
||||||
GlobalDataController *globalDataController;
|
GlobalDataController *globalDataController;
|
||||||
DebugController *debugController;
|
DebugController *debugController;
|
||||||
|
JsonRequestClient *jsonRequestClient;
|
||||||
String printerType = "Octoprint";
|
String printerType = "Octoprint";
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -31,9 +33,11 @@ protected:
|
||||||
} PrinterStruct;
|
} PrinterStruct;
|
||||||
|
|
||||||
PrinterStruct printerData;
|
PrinterStruct printerData;
|
||||||
|
String result;
|
||||||
|
String encodedAuth = "";
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BasePrinterClientImpl(String printerType, GlobalDataController *globalDataController, DebugController *debugController);
|
BasePrinterClientImpl(String printerType, GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
|
||||||
|
|
||||||
void getPrinterJobResults() {};
|
void getPrinterJobResults() {};
|
||||||
void getPrinterPsuState() {};
|
void getPrinterPsuState() {};
|
||||||
|
|
@ -64,4 +68,8 @@ public:
|
||||||
int getPrinterPort();
|
int getPrinterPort();
|
||||||
String getPrinterName();
|
String getPrinterName();
|
||||||
void setPrinterName(String printer);
|
void setPrinterName(String printer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
String getInstanceServerTarget();
|
||||||
|
int getInstanceServerPort();
|
||||||
};
|
};
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "DuetClient.h"
|
#include "DuetClient.h"
|
||||||
|
|
||||||
DuetClient::DuetClient(GlobalDataController *globalDataController, DebugController *debugController)
|
DuetClient::DuetClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient)
|
||||||
: BasePrinterClientImpl("Duet", globalDataController, debugController) {
|
: BasePrinterClientImpl("Duet", globalDataController, debugController, jsonRequestClient) {
|
||||||
this->updatePrintClient();
|
this->updatePrintClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ private:
|
||||||
String result;
|
String result;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DuetClient(GlobalDataController *globalDataController, DebugController *debugController);
|
DuetClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
|
||||||
|
|
||||||
void getPrinterJobResults() override;
|
void getPrinterJobResults() override;
|
||||||
void getPrinterPsuState() override;
|
void getPrinterPsuState() override;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "KlipperClient.h"
|
#include "KlipperClient.h"
|
||||||
|
|
||||||
KlipperClient::KlipperClient(GlobalDataController *globalDataController, DebugController *debugController)
|
KlipperClient::KlipperClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient)
|
||||||
: BasePrinterClientImpl("Klipper", globalDataController, debugController) {
|
: BasePrinterClientImpl("Klipper", globalDataController, debugController, jsonRequestClient) {
|
||||||
this->updatePrintClient();
|
this->updatePrintClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +31,11 @@ boolean KlipperClient::validate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
|
WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WiFiClient printClient;
|
WiFiClient printClient;
|
||||||
printClient.setTimeout(5000);
|
printClient.setTimeout(5000);
|
||||||
String targetServer = this->globalDataController->getPrinterServer();
|
String targetServer = this->globalDataController->getPrinterServer();
|
||||||
|
|
@ -151,16 +156,54 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody)
|
||||||
return printClient;
|
return printClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void KlipperClient::getPrinterJobResults() {
|
void KlipperClient::getPrinterJobResults() {
|
||||||
if (!validate()) {
|
if (!validate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(9) + 426;
|
||||||
|
DynamicJsonDocument *jsonDoc = this->jsonRequestClient->requestJson(
|
||||||
|
PRINTER_REQUEST_GET,
|
||||||
|
this->getInstanceServerTarget(),
|
||||||
|
this->getInstanceServerPort(),
|
||||||
|
this->encodedAuth,
|
||||||
|
"/printer/objects/query?heater_bed&extruder&webhooks&virtual_sdcard&print_stats&toolhead&display_status",
|
||||||
|
"",
|
||||||
|
bufferSize,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if (this->jsonRequestClient->getLastError() != "") {
|
||||||
|
this->debugController->printLn("Get Klipper Data: " + this->getInstanceServerTarget() + ":" + String(this->getInstanceServerPort()));
|
||||||
|
this->debugController->printLn(this->jsonRequestClient->getLastError());
|
||||||
|
printerData.error = this->jsonRequestClient->getLastError();
|
||||||
|
printerData.state = "";
|
||||||
|
printerData.isPrinting = false;
|
||||||
|
printerData.toolTemp = "";
|
||||||
|
printerData.toolTargetTemp = "";
|
||||||
|
printerData.bedTemp = "";
|
||||||
|
printerData.bedTargetTemp = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
String targetServer = this->globalDataController->getPrinterServer();
|
String targetServer = this->globalDataController->getPrinterServer();
|
||||||
if (this->globalDataController->getPrinterServer() == "") {
|
if (this->globalDataController->getPrinterServer() == "") {
|
||||||
targetServer = this->globalDataController->getPrinterHostName();
|
targetServer = this->globalDataController->getPrinterHostName();
|
||||||
}
|
}
|
||||||
|
|
||||||
//**** get the Printer Job status
|
// get the Printer Job status
|
||||||
String apiGetData = "GET /printer/objects/query?heater_bed&extruder&webhooks&virtual_sdcard&print_stats&toolhead&display_status";
|
String apiGetData = "GET /printer/objects/query?heater_bed&extruder&webhooks&virtual_sdcard&print_stats&toolhead&display_status";
|
||||||
WiFiClient printClient = getSubmitRequest(apiGetData);
|
WiFiClient printClient = getSubmitRequest(apiGetData);
|
||||||
if (printerData.error != "") {
|
if (printerData.error != "") {
|
||||||
|
|
@ -193,7 +236,7 @@ void KlipperClient::getPrinterJobResults() {
|
||||||
printerData.progressPrintTime = (const char*)jsonBuffer["result"]["status"]["print_stats"]["print_duration"];
|
printerData.progressPrintTime = (const char*)jsonBuffer["result"]["status"]["print_stats"]["print_duration"];
|
||||||
printerData.progressPrintTimeLeft = (const char*)jsonBuffer["progress"]["printTimeLeft"];
|
printerData.progressPrintTimeLeft = (const char*)jsonBuffer["progress"]["printTimeLeft"];
|
||||||
printerData.filamentLength = (const char*)jsonBuffer["result"]["status"]["job"]["print_stats"]["filament_used"];
|
printerData.filamentLength = (const char*)jsonBuffer["result"]["status"]["job"]["print_stats"]["filament_used"];
|
||||||
printerData.state = (const char*)jsonBuffer["result"]["status"]["print_stats"]["state"];
|
printerData.state = (const char*)jsonBuffer["result"]["status"]["print_stats"]["state"];*/
|
||||||
/**
|
/**
|
||||||
printerData.progressPrintTimeLeft :
|
printerData.progressPrintTimeLeft :
|
||||||
If no metadata is available, print duration and progress can be used to calculate the ETA:
|
If no metadata is available, print duration and progress can be used to calculate the ETA:
|
||||||
|
|
@ -205,13 +248,13 @@ let total_time = pstats.print_duration / vsd.progress;
|
||||||
let eta = total_time - pstats.print_duration; */
|
let eta = total_time - pstats.print_duration; */
|
||||||
|
|
||||||
|
|
||||||
if (BasePrinterClientImpl::isOperational()) {
|
/*if (BasePrinterClientImpl::isOperational()) {
|
||||||
this->debugController->printLn("Status: " + printerData.state);
|
this->debugController->printLn("Status: " + printerData.state);
|
||||||
} else {
|
} else {
|
||||||
this->debugController->printLn("Printer Not Operational");
|
this->debugController->printLn("Printer Not Operational");
|
||||||
}
|
}
|
||||||
|
|
||||||
//**** get the fileseize
|
// get the fileseize
|
||||||
apiGetData = "GET /server/files/metadata?filename=" + printerData.fileName;
|
apiGetData = "GET /server/files/metadata?filename=" + printerData.fileName;
|
||||||
printClient = getSubmitRequest(apiGetData);
|
printClient = getSubmitRequest(apiGetData);
|
||||||
if (printerData.error != "") {
|
if (printerData.error != "") {
|
||||||
|
|
@ -245,7 +288,7 @@ let eta = total_time - pstats.print_duration; */
|
||||||
|
|
||||||
if (BasePrinterClientImpl::isOperational()) {
|
if (BasePrinterClientImpl::isOperational()) {
|
||||||
this->debugController->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
|
this->debugController->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void KlipperClient::getPrinterPsuState() {
|
void KlipperClient::getPrinterPsuState() {
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,14 @@
|
||||||
|
|
||||||
class KlipperClient : public BasePrinterClientImpl {
|
class KlipperClient : public BasePrinterClientImpl {
|
||||||
private:
|
private:
|
||||||
String encodedAuth = "";
|
|
||||||
boolean pollPsu;
|
boolean pollPsu;
|
||||||
|
|
||||||
boolean validate();
|
boolean validate();
|
||||||
WiFiClient getSubmitRequest(String apiGetData);
|
WiFiClient getSubmitRequest(String apiGetData);
|
||||||
WiFiClient getPostRequest(String apiPostData, String apiPostBody);
|
WiFiClient getPostRequest(String apiPostData, String apiPostBody);
|
||||||
|
|
||||||
String result;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KlipperClient(GlobalDataController *globalDataController, DebugController *debugController);
|
KlipperClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
|
||||||
|
|
||||||
void getPrinterJobResults() override;
|
void getPrinterJobResults() override;
|
||||||
void getPrinterPsuState() override;
|
void getPrinterPsuState() override;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "Network/TimeClient.h"
|
#include "Network/TimeClient.h"
|
||||||
#include "Network/OpenWeatherMapClient.h"
|
#include "Network/OpenWeatherMapClient.h"
|
||||||
|
#include "Network/JsonRequestClient.h"
|
||||||
#if (PRINTERCLIENT == REPETIER_CLIENT)
|
#if (PRINTERCLIENT == REPETIER_CLIENT)
|
||||||
#include "Clients/RepetierClient.h"
|
#include "Clients/RepetierClient.h"
|
||||||
#elif (PRINTERCLIENT == KLIPPER_CLIENT)
|
#elif (PRINTERCLIENT == KLIPPER_CLIENT)
|
||||||
|
|
@ -28,8 +29,9 @@
|
||||||
|
|
||||||
// Initilize all needed data
|
// Initilize all needed data
|
||||||
DebugController debugController(DEBUG_MODE_ENABLE);
|
DebugController debugController(DEBUG_MODE_ENABLE);
|
||||||
|
JsonRequestClient jsonRequestClient(&debugController);
|
||||||
TimeClient timeClient(TIME_UTCOFFSET, &debugController);
|
TimeClient timeClient(TIME_UTCOFFSET, &debugController);
|
||||||
OpenWeatherMapClient weatherClient(WEATHER_APIKEY, WEATHER_CITYID, 1, WEATHER_METRIC, WEATHER_LANGUAGE, &debugController);
|
OpenWeatherMapClient weatherClient(WEATHER_APIKEY, WEATHER_CITYID, 1, WEATHER_METRIC, WEATHER_LANGUAGE, &debugController, &jsonRequestClient);
|
||||||
GlobalDataController globalDataController(&timeClient, &weatherClient, &debugController);
|
GlobalDataController globalDataController(&timeClient, &weatherClient, &debugController);
|
||||||
WebServer webServer(&globalDataController, &debugController);
|
WebServer webServer(&globalDataController, &debugController);
|
||||||
|
|
||||||
|
|
@ -37,7 +39,7 @@ WebServer webServer(&globalDataController, &debugController);
|
||||||
#if (PRINTERCLIENT == REPETIER_CLIENT)
|
#if (PRINTERCLIENT == REPETIER_CLIENT)
|
||||||
//RepetierClient printerClient(&globalDataController);
|
//RepetierClient printerClient(&globalDataController);
|
||||||
#elif (PRINTERCLIENT == KLIPPER_CLIENT)
|
#elif (PRINTERCLIENT == KLIPPER_CLIENT)
|
||||||
KlipperClient printerClient(&globalDataController, &debugController);
|
KlipperClient printerClient(&globalDataController, &debugController, &jsonRequestClient);
|
||||||
#elif (PRINTERCLIENT == DUET_CLIENT)
|
#elif (PRINTERCLIENT == DUET_CLIENT)
|
||||||
//DuetClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle);
|
//DuetClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle);
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include "JsonRequestClient.h"
|
||||||
|
|
||||||
|
DynamicJsonDocument *JsonRequestClient::lastJsonDocument = NULL;
|
||||||
|
|
||||||
|
JsonRequestClient::JsonRequestClient(DebugController *debugController) {
|
||||||
|
this->debugController = debugController;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClient JsonRequestClient::requestWifiClient(
|
||||||
|
int requestType,
|
||||||
|
String server,
|
||||||
|
int port,
|
||||||
|
String encodedAuth,
|
||||||
|
String httpPath,
|
||||||
|
String apiPostBody
|
||||||
|
) {
|
||||||
|
WiFiClient requestClient;
|
||||||
|
requestClient.setTimeout(5000);
|
||||||
|
httpPath = (requestType == PRINTER_REQUEST_POST ? "POST " : "GET ") + httpPath;
|
||||||
|
String fullTarget = server + ":" + String(port) + httpPath;
|
||||||
|
|
||||||
|
this->debugController->print("Request data from ");
|
||||||
|
this->debugController->print(httpPath);
|
||||||
|
if (requestType == PRINTER_REQUEST_POST) {
|
||||||
|
this->debugController->print(" | " + apiPostBody);
|
||||||
|
}
|
||||||
|
this->debugController->printLn("");
|
||||||
|
|
||||||
|
if (requestClient.connect(server, port)) { //starts client connection, checks for connection
|
||||||
|
requestClient.println(httpPath);
|
||||||
|
requestClient.println("Host: " + server + ":" + String(port));
|
||||||
|
if (encodedAuth != "") {
|
||||||
|
requestClient.print("Authorization: ");
|
||||||
|
requestClient.println("Basic " + encodedAuth);
|
||||||
|
}
|
||||||
|
requestClient.println("User-Agent: ArduinoWiFi/1.1");
|
||||||
|
requestClient.println("Connection: close");
|
||||||
|
if (requestType == PRINTER_REQUEST_POST) {
|
||||||
|
requestClient.println("Content-Type: application/json");
|
||||||
|
requestClient.print("Content-Length: ");
|
||||||
|
requestClient.println(apiPostBody.length());
|
||||||
|
requestClient.println();
|
||||||
|
requestClient.println(apiPostBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestClient.println() == 0) {
|
||||||
|
this->debugController->printLn("Connection to " + fullTarget + " failed.");
|
||||||
|
this->debugController->printLn("");
|
||||||
|
this->lastError = "Connection to " + fullTarget + " failed.";
|
||||||
|
return requestClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// error message if no client connect
|
||||||
|
this->debugController->printLn("Connection failed: " + fullTarget);
|
||||||
|
this->debugController->printLn("");
|
||||||
|
this->lastError = "Connection failed: " + fullTarget;
|
||||||
|
return requestClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(requestClient.connected() && !requestClient.available()) delay(1);
|
||||||
|
|
||||||
|
// Check HTTP status
|
||||||
|
char status[32] = {0};
|
||||||
|
requestClient.readBytesUntil('\r', status, sizeof(status));
|
||||||
|
if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) {
|
||||||
|
this->debugController->print("Unexpected response: ");
|
||||||
|
this->debugController->printLn(status);
|
||||||
|
this->lastError = "Response: " + String(status);
|
||||||
|
return requestClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip HTTP headers
|
||||||
|
char endOfHeaders[] = "\r\n\r\n";
|
||||||
|
if (!requestClient.find(endOfHeaders)) {
|
||||||
|
this->debugController->printLn("Invalid response");
|
||||||
|
this->lastError = "Invalid response from " + fullTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument *JsonRequestClient::requestJson(
|
||||||
|
int requestType,
|
||||||
|
String server,
|
||||||
|
int port,
|
||||||
|
String encodedAuth,
|
||||||
|
String httpPath,
|
||||||
|
String apiPostBody,
|
||||||
|
size_t bufferSize,
|
||||||
|
bool withResponse = false
|
||||||
|
) {
|
||||||
|
// Request data
|
||||||
|
this->resetLastError();
|
||||||
|
WiFiClient reqClient = this->requestWifiClient(requestType, server, port, encodedAuth, httpPath, apiPostBody);
|
||||||
|
if ((this->lastError != "") || !withResponse) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse JSON object
|
||||||
|
DynamicJsonDocument *returnJson = this->createNewJsonDocument(bufferSize);
|
||||||
|
DeserializationError error = deserializeJson(*returnJson, reqClient);
|
||||||
|
if (error) {
|
||||||
|
this->debugController->printLn("Data Parsing failed: " + server + ":" + String(port));
|
||||||
|
this->lastError = "Klipper Data Parsing failed: " + server + ":" + String(port);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return returnJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
String JsonRequestClient::getLastError() {
|
||||||
|
return this->lastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonRequestClient::resetLastError() {
|
||||||
|
this->lastError = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument *JsonRequestClient::createNewJsonDocument(size_t bufferSize) {
|
||||||
|
if (JsonRequestClient::lastJsonDocument != NULL) {
|
||||||
|
this->freeLastJsonDocument();
|
||||||
|
}
|
||||||
|
JsonRequestClient::lastJsonDocument = new DynamicJsonDocument(bufferSize);
|
||||||
|
return JsonRequestClient::lastJsonDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonRequestClient::freeLastJsonDocument() {
|
||||||
|
if (JsonRequestClient::lastJsonDocument != NULL) {
|
||||||
|
free(JsonRequestClient::lastJsonDocument);
|
||||||
|
JsonRequestClient::lastJsonDocument = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <base64.h>
|
||||||
|
#include "Debug.h"
|
||||||
|
#include "../Global/DebugController.h"
|
||||||
|
|
||||||
|
#define PRINTER_REQUEST_GET 0
|
||||||
|
#define PRINTER_REQUEST_POST 1
|
||||||
|
|
||||||
|
class JsonRequestClient {
|
||||||
|
private:
|
||||||
|
DebugController *debugController;
|
||||||
|
String lastError = "";
|
||||||
|
|
||||||
|
static DynamicJsonDocument* lastJsonDocument;
|
||||||
|
public:
|
||||||
|
JsonRequestClient(DebugController *debugController);
|
||||||
|
|
||||||
|
DynamicJsonDocument *requestJson(int requestType, String server, int port, String encodedAuth, String httpPath, String apiPostBody, size_t bufferSize, bool withResponse);
|
||||||
|
String getLastError();
|
||||||
|
void resetLastError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WiFiClient requestWifiClient(int requestType, String server, int port, String encodedAuth, String httpPath, String apiPostBody);
|
||||||
|
void freeLastJsonDocument();
|
||||||
|
DynamicJsonDocument *createNewJsonDocument(size_t bufferSize);
|
||||||
|
};
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
#include "OpenWeatherMapClient.h"
|
#include "OpenWeatherMapClient.h"
|
||||||
|
|
||||||
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityID, int cityCount, boolean isMetric, String language, DebugController *debugController) {
|
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityID, int cityCount, boolean isMetric, String language, DebugController *debugController, JsonRequestClient *jsonRequestClient) {
|
||||||
this->debugController = debugController;
|
this->debugController = debugController;
|
||||||
updateCityId(CityID);
|
this->jsonRequestClient = jsonRequestClient;
|
||||||
updateLanguage(language);
|
this->updateCityId(CityID);
|
||||||
myApiKey = ApiKey;
|
this->updateLanguage(language);
|
||||||
|
this->myApiKey = ApiKey;
|
||||||
this->isMetric = false;
|
this->isMetric = false;
|
||||||
setMetric(isMetric);
|
this->setMetric(isMetric);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
|
void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
|
||||||
|
|
@ -21,77 +22,46 @@ void OpenWeatherMapClient::updateLanguage(String language) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenWeatherMapClient::updateWeather() {
|
void OpenWeatherMapClient::updateWeather() {
|
||||||
WiFiClient weatherClient;
|
|
||||||
String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1";
|
|
||||||
|
|
||||||
|
String apiGetData = "/data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1";
|
||||||
this->debugController->printLn("Getting Weather Data");
|
this->debugController->printLn("Getting Weather Data");
|
||||||
this->debugController->printLn(apiGetData);
|
this->debugController->printLn(apiGetData);
|
||||||
result = "";
|
const size_t bufferSize = 1024;
|
||||||
if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection
|
|
||||||
weatherClient.println(apiGetData);
|
|
||||||
weatherClient.println("Host: " + String(servername));
|
|
||||||
weatherClient.println("User-Agent: ArduinoWiFi/1.1");
|
|
||||||
weatherClient.println("Connection: close");
|
|
||||||
weatherClient.println();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this->debugController->printLn("connection for weather data failed"); //error message if no client connect
|
|
||||||
this->debugController->printLn("");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data
|
|
||||||
|
|
||||||
this->debugController->printLn("Waiting for data");
|
|
||||||
|
|
||||||
// Check HTTP status
|
|
||||||
char status[32] = {0};
|
|
||||||
weatherClient.readBytesUntil('\r', status, sizeof(status));
|
|
||||||
this->debugController->printLn("Response Header: " + String(status));
|
|
||||||
if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
|
|
||||||
this->debugController->print("Unexpected response: ");
|
|
||||||
this->debugController->printLn(status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip HTTP headers
|
|
||||||
char endOfHeaders[] = "\r\n\r\n";
|
|
||||||
if (!weatherClient.find(endOfHeaders)) {
|
|
||||||
this->debugController->printLn(F("Invalid response"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
weathers[0].cached = false;
|
weathers[0].cached = false;
|
||||||
weathers[0].error = "";
|
weathers[0].error = "";
|
||||||
|
|
||||||
const size_t bufferSize = 1024;
|
DynamicJsonDocument *jsonBuffer = this->jsonRequestClient->requestJson(
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
PRINTER_REQUEST_GET,
|
||||||
|
String(servername),
|
||||||
// Parse JSON object
|
80,
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, weatherClient);
|
"",
|
||||||
if (error) {
|
apiGetData,
|
||||||
|
"",
|
||||||
|
bufferSize,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if ((jsonBuffer == NULL) || (this->jsonRequestClient->getLastError() != "")) {
|
||||||
this->debugController->printLn("Weather Data Parsing failed!");
|
this->debugController->printLn("Weather Data Parsing failed!");
|
||||||
this->debugController->printLn(error.c_str());
|
this->debugController->printLn(this->jsonRequestClient->getLastError());
|
||||||
weathers[0].error = "Weather Data Parsing failed!";
|
weathers[0].error = this->jsonRequestClient->getLastError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
weatherClient.stop(); //stop client
|
int count = (*jsonBuffer)["cnt"];
|
||||||
int count = jsonBuffer["cnt"];
|
|
||||||
|
|
||||||
for (int inx = 0; inx < count; inx++) {
|
for (int inx = 0; inx < count; inx++) {
|
||||||
weathers[inx].lon = (float)jsonBuffer["list"][inx]["coord"]["lon"];
|
weathers[inx].lon = (float)(*jsonBuffer)["list"][inx]["coord"]["lon"];
|
||||||
weathers[inx].lat = (float)jsonBuffer["list"][inx]["coord"]["lat"];
|
weathers[inx].lat = (float)(*jsonBuffer)["list"][inx]["coord"]["lat"];
|
||||||
weathers[inx].dt = (long)jsonBuffer["list"][inx]["dt"];
|
weathers[inx].dt = (long)(*jsonBuffer)["list"][inx]["dt"];
|
||||||
weathers[inx].city = (const char*)jsonBuffer["list"][inx]["name"];
|
weathers[inx].city = (const char*)(*jsonBuffer)["list"][inx]["name"];
|
||||||
weathers[inx].country = (const char*)jsonBuffer["list"][inx]["sys"]["country"];
|
weathers[inx].country = (const char*)(*jsonBuffer)["list"][inx]["sys"]["country"];
|
||||||
weathers[inx].temp = (float)jsonBuffer["list"][inx]["main"]["temp"];
|
weathers[inx].temp = (float)(*jsonBuffer)["list"][inx]["main"]["temp"];
|
||||||
weathers[inx].humidity = (int)jsonBuffer["list"][inx]["main"]["humidity"];
|
weathers[inx].humidity = (int)(*jsonBuffer)["list"][inx]["main"]["humidity"];
|
||||||
weathers[inx].condition = (const char*)jsonBuffer["list"][inx]["weather"][0]["main"];
|
weathers[inx].condition = (const char*)(*jsonBuffer)["list"][inx]["weather"][0]["main"];
|
||||||
weathers[inx].wind = (float)jsonBuffer["list"][inx]["wind"]["speed"];
|
weathers[inx].wind = (float)(*jsonBuffer)["list"][inx]["wind"]["speed"];
|
||||||
weathers[inx].weatherId = (int)jsonBuffer["list"][inx]["weather"][0]["id"];
|
weathers[inx].weatherId = (int)(*jsonBuffer)["list"][inx]["weather"][0]["id"];
|
||||||
weathers[inx].description = (const char*)jsonBuffer["list"][inx]["weather"][0]["description"];
|
weathers[inx].description = (const char*)(*jsonBuffer)["list"][inx]["weather"][0]["description"];
|
||||||
weathers[inx].icon = (const char*)jsonBuffer["list"][inx]["weather"][0]["icon"];
|
weathers[inx].icon = (const char*)(*jsonBuffer)["list"][inx]["weather"][0]["icon"];
|
||||||
|
|
||||||
this->debugController->printLn("lat: " + weathers[inx].lat);
|
this->debugController->printLn("lat: " + weathers[inx].lat);
|
||||||
this->debugController->printLn("lon: " + weathers[inx].lon);
|
this->debugController->printLn("lon: " + weathers[inx].lon);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <base64.h>
|
#include <base64.h>
|
||||||
#include "../Global/DebugController.h"
|
#include "../Global/DebugController.h"
|
||||||
|
#include "JsonRequestClient.h"
|
||||||
|
|
||||||
class OpenWeatherMapClient {
|
class OpenWeatherMapClient {
|
||||||
private:
|
private:
|
||||||
|
|
@ -36,9 +37,10 @@ private:
|
||||||
|
|
||||||
String roundValue(String value);
|
String roundValue(String value);
|
||||||
DebugController *debugController;
|
DebugController *debugController;
|
||||||
|
JsonRequestClient *jsonRequestClient;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenWeatherMapClient(String ApiKey, int CityID, int cityCount, boolean isMetric, String language, DebugController *debugController);
|
OpenWeatherMapClient(String ApiKey, int CityID, int cityCount, boolean isMetric, String language, DebugController *debugController, JsonRequestClient *jsonRequestClient);
|
||||||
void updateWeather();
|
void updateWeather();
|
||||||
void updateWeatherApiKey(String ApiKey);
|
void updateWeatherApiKey(String ApiKey);
|
||||||
void updateCityId(int CityID);
|
void updateCityId(int CityID);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue