Release v0.4.0: complete rewrite #1
7 changed files with 180 additions and 14 deletions
|
@ -24,4 +24,6 @@ void set_blink_rate(float interval);
|
|||
void connect();
|
||||
void resetSettings();
|
||||
|
||||
String getMac(bool insertColons);
|
||||
|
||||
#endif // __WIFIHANDLER_HPP__
|
21
include/backend.hpp
Normal file
21
include/backend.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef __BACKEND_HPP__
|
||||
#define __BACKEND_HPP__
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include "../include/root_ca.hpp"
|
||||
|
||||
extern JsonDocument config;
|
||||
extern bool isConfigValid;
|
||||
|
||||
extern JsonDocument weatherData;
|
||||
|
||||
bool parseJsonConfig(String& payload);
|
||||
bool getConfig();
|
||||
|
||||
String urlencode(String str);
|
||||
|
||||
bool getWeatherData();
|
||||
|
||||
#endif // __BACKEND_HPP__
|
6
include/root_ca.hpp
Normal file
6
include/root_ca.hpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __ROOT_CA_H__
|
||||
#define __ROOT_CA_H__
|
||||
|
||||
extern const char* root_ca;
|
||||
|
||||
#endif // __ROOT_CA_H__
|
|
@ -52,14 +52,14 @@ void connect() {
|
|||
// if it does not connect it starts an access point
|
||||
// and goes into a blocking loop awaiting configuration
|
||||
if (!wifiManager.autoConnect()) {
|
||||
Serial.println("failed to connect and hit timeout");
|
||||
Serial.println(String(millis()) + " Failed to connect and hit timeout");
|
||||
// reset and try again, or maybe put it to deep sleep
|
||||
ESP.restart();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// if you get here you have connected to the WiFi
|
||||
Serial.print("connected with address: ");
|
||||
Serial.print(String(millis()) + " Connected with address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// keep LED on
|
||||
|
@ -69,7 +69,7 @@ void connect() {
|
|||
void resetSettings() {
|
||||
WiFiManager::Status status = {.wifi_status = 0U, .mode = WiFiManager::Mode::ERASING};
|
||||
|
||||
Serial.println("resetting wifi settings...");
|
||||
Serial.println(String(millis()) + " Resetting wifi settings...");
|
||||
|
||||
wifiManagerCb(status);
|
||||
wifiManager.resetSettings();
|
||||
|
@ -79,3 +79,8 @@ void resetSettings() {
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
String getMac(bool insertColons) {
|
||||
String mac = wifiManager.getMacAsString(insertColons);
|
||||
return mac;
|
||||
}
|
131
src/backend.cpp
Normal file
131
src/backend.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include <HTTPClient.h>
|
||||
|
||||
#include "../include/WifiHandler.hpp"
|
||||
#include "../include/backend.hpp"
|
||||
|
||||
JsonDocument config;
|
||||
bool isConfigValid = false;
|
||||
String configTimestamp = "";
|
||||
|
||||
static HTTPClient http;
|
||||
|
||||
JsonDocument weatherData;
|
||||
|
||||
bool parseJsonConfig(String& payload) {
|
||||
bool isSuccess = false;
|
||||
|
||||
config.clear();
|
||||
|
||||
DeserializationError error = deserializeJson(config, payload);
|
||||
|
||||
if (error) {
|
||||
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
||||
} else {
|
||||
if (config["config version"] != "0.0.1") {
|
||||
Serial.println(String(millis()) + " Unsupported config version");
|
||||
} else {
|
||||
isSuccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
bool getConfig() {
|
||||
String mac = getMac(false);
|
||||
String url = "https://target.luon.net/~admar/Claire/" + mac + "/config.json";
|
||||
String payload = "";
|
||||
bool isSuccess = false;
|
||||
|
||||
http.begin(url, root_ca);
|
||||
if (isConfigValid) {
|
||||
http.addHeader("If-Modified-Since", configTimestamp);
|
||||
}
|
||||
|
||||
const char* headerKeys[] = {"Last-Modified"};
|
||||
const size_t headerKeysCount = sizeof(headerKeys) / sizeof(headerKeys[0]);
|
||||
http.collectHeaders(headerKeys, headerKeysCount);
|
||||
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode == 200) {
|
||||
// Content is in payload
|
||||
payload = http.getString();
|
||||
isSuccess = parseJsonConfig(payload);
|
||||
|
||||
if (isSuccess) {
|
||||
configTimestamp = http.header("Last-Modified");
|
||||
Serial.println(String(millis()) + " ConfigTimestamp: " + configTimestamp);
|
||||
}
|
||||
} else if (httpCode == 304) {
|
||||
// Content did not change
|
||||
isSuccess = true;
|
||||
} else {
|
||||
Serial.println(String(millis()) + " Got http code " + httpCode);
|
||||
}
|
||||
http.end();
|
||||
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
// From https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
||||
String urlencode(String str) {
|
||||
String encodedString = "";
|
||||
char c;
|
||||
char code0;
|
||||
char code1;
|
||||
char code2;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
c = str.charAt(i);
|
||||
if (c == ' ') {
|
||||
encodedString += '+';
|
||||
} else if (isalnum(c)) {
|
||||
encodedString += c;
|
||||
} else {
|
||||
code1 = (c & 0xf) + '0';
|
||||
if ((c & 0xf) > 9) {
|
||||
code1 = (c & 0xf) - 10 + 'A';
|
||||
}
|
||||
c = (c >> 4) & 0xf;
|
||||
code0 = c + '0';
|
||||
if (c > 9) {
|
||||
code0 = c - 10 + 'A';
|
||||
}
|
||||
code2 = '\0';
|
||||
encodedString += '%';
|
||||
encodedString += code0;
|
||||
encodedString += code1;
|
||||
// encodedString+=code2;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
return encodedString;
|
||||
}
|
||||
|
||||
bool getWeatherData() {
|
||||
String encodedAddress = urlencode(config["address"]);
|
||||
String url =
|
||||
"https://sinoptik.luon.net/"
|
||||
"forecast?address=" +
|
||||
encodedAddress +
|
||||
"&metrics=precipitation&metrics=UVI&metrics=AQI&metrics="
|
||||
"pollen&metrics=PAQI";
|
||||
|
||||
String payload = "";
|
||||
bool isSuccess = false;
|
||||
|
||||
http.begin(url, root_ca);
|
||||
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode > 0) {
|
||||
payload = http.getString();
|
||||
// isSuccess = parseJsonConfig(payload);
|
||||
} else {
|
||||
Serial.println(String(millis()) + " Got http code " + httpCode);
|
||||
}
|
||||
http.end();
|
||||
|
||||
return isSuccess;
|
||||
}
|
18
src/main.cpp
18
src/main.cpp
|
@ -1,7 +1,7 @@
|
|||
#include <dESPatch.h>
|
||||
|
||||
#include "../include/WifiHandler.hpp"
|
||||
#include "../include/root_ca.h"
|
||||
#include "../include/backend.hpp"
|
||||
|
||||
DESPatch dESPatch;
|
||||
|
||||
|
@ -15,7 +15,7 @@ void setup() {
|
|||
|
||||
if (CONNECT_BUTTON >= 0) {
|
||||
// Give user 3 second chance to press button and reset settings
|
||||
Serial.println("Waiting 3 seconds to check if user presses the button");
|
||||
Serial.println(String(millis()) + " Waiting 3 seconds to check if user presses the button");
|
||||
delay(3000);
|
||||
if (not digitalRead(CONNECT_BUTTON)) {
|
||||
resetSettings();
|
||||
|
@ -31,12 +31,18 @@ void setup() {
|
|||
|
||||
int x = dESPatch.configure(url, true, false, interval, false, root_ca);
|
||||
|
||||
Serial.print("dESPatch.configure() returned with code ");
|
||||
Serial.println(x);
|
||||
Serial.println(String(millis()) + " dESPatch.configure() returned with code " + String(x));
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
Serial.println("hello :-)");
|
||||
isConfigValid = getConfig();
|
||||
|
||||
if (not isConfigValid) {
|
||||
Serial.println(String(millis()) + " Invalid config");
|
||||
} else {
|
||||
Serial.println(String(millis()) + " Address: " + String(static_cast<const char*>(config["address"])));
|
||||
// getWeatherData();
|
||||
}
|
||||
dESPatch.checkForUpdate(true);
|
||||
delay(5000);
|
||||
delay(2000);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
#ifndef __ROOT_CA_H__
|
||||
#define __ROOT_CA_H__
|
||||
|
||||
const char* root_ca =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
|
||||
|
@ -33,5 +30,3 @@ const char* root_ca =
|
|||
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n"
|
||||
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
#endif // __ROOT_CA_H__
|
Loading…
Reference in a new issue