Release v0.4.0: complete rewrite #1
8 changed files with 221 additions and 183 deletions
|
@ -1,29 +0,0 @@
|
||||||
#ifndef __WIFIHANDLER_HPP__
|
|
||||||
#define __WIFIHANDLER_HPP__
|
|
||||||
|
|
||||||
#include <WiFiManager-esp32.h> // https://github.com/admarschoonen/WiFiManager
|
|
||||||
|
|
||||||
#define TICKER_RATE_CONNECTING 0.6
|
|
||||||
#define TICKER_RATE_CONFIG 0.2
|
|
||||||
#define TICKER_RATE_ERASE 0.05
|
|
||||||
|
|
||||||
#ifndef LED_BUILTIN
|
|
||||||
#define LED_BUILTIN 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BUTTON_BUILTIN
|
|
||||||
#define BUTTON_BUILTIN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONNECT_BUTTON BUTTON_BUILTIN
|
|
||||||
|
|
||||||
void wifiManagerCb(WiFiManager::Status status);
|
|
||||||
|
|
||||||
void set_blink_rate(float interval);
|
|
||||||
|
|
||||||
void connect();
|
|
||||||
void resetSettings();
|
|
||||||
|
|
||||||
String getMac(bool insertColons);
|
|
||||||
|
|
||||||
#endif // __WIFIHANDLER_HPP__
|
|
|
@ -1,21 +0,0 @@
|
||||||
#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__
|
|
38
include/backend_communication.hpp
Normal file
38
include/backend_communication.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef __BACKEND_HPP__
|
||||||
|
#define __BACKEND_HPP__
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#include "../include/root_ca.hpp"
|
||||||
|
#include "../include/wifi_handler.hpp"
|
||||||
|
|
||||||
|
class BackendCommunication {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
BackendCommunication(WifiHandler& p_wifi_handler);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public methods
|
||||||
|
bool parseJsonConfig(String& payload);
|
||||||
|
bool getConfig();
|
||||||
|
|
||||||
|
bool getWeatherData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private methods
|
||||||
|
String urlencode(String str);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public member objects
|
||||||
|
JsonDocument m_config;
|
||||||
|
bool m_is_config_valid;
|
||||||
|
|
||||||
|
JsonDocument m_weather_data;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private member objects
|
||||||
|
WifiHandler& m_wifi_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __BACKEND_HPP__
|
33
include/wifi_handler.hpp
Normal file
33
include/wifi_handler.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef __WIFIHANDLER_HPP__
|
||||||
|
#define __WIFIHANDLER_HPP__
|
||||||
|
|
||||||
|
#include <WiFiManager-esp32.h> // https://github.com/admarschoonen/WiFiManager
|
||||||
|
|
||||||
|
class WifiHandler {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
WifiHandler(uint8_t p_led_pin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public static methods
|
||||||
|
static void setBlinkRate(float p_interval);
|
||||||
|
static void wifiManagerCb(WiFiManager::Status p_status);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public methods
|
||||||
|
void connect();
|
||||||
|
void resetSettings();
|
||||||
|
String getMac(bool insertColons);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public static objects
|
||||||
|
constexpr static float BLINK_RATE_CONNECTING = 0.6f;
|
||||||
|
constexpr static float BLINK_RATE_CONFIG = 0.2f;
|
||||||
|
constexpr static float BLINK_RATE_ERASE = 0.05f;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private objects
|
||||||
|
WiFiManager m_wifiManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __WIFIHANDLER_HPP__
|
|
@ -1,86 +0,0 @@
|
||||||
#include <Ticker.h>
|
|
||||||
#include <WiFiManager-esp32.h> // https://github.com/admarschoonen/WiFiManager
|
|
||||||
|
|
||||||
#include "../include/WifiHandler.hpp"
|
|
||||||
|
|
||||||
WiFiManager wifiManager;
|
|
||||||
Ticker ticker;
|
|
||||||
|
|
||||||
static void tick(void) {
|
|
||||||
int state = 0;
|
|
||||||
|
|
||||||
if (LED_BUILTIN >= 0) {
|
|
||||||
state = digitalRead(LED_BUILTIN);
|
|
||||||
digitalWrite(LED_BUILTIN, !state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_blink_rate(float interval) {
|
|
||||||
if (ticker.active()) {
|
|
||||||
ticker.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interval > 0.0f) {
|
|
||||||
ticker.attach(interval, tick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wifiManagerCb(WiFiManager::Status status) {
|
|
||||||
if (status.mode == WiFiManager::Mode::CONNECTING) {
|
|
||||||
set_blink_rate(TICKER_RATE_CONNECTING);
|
|
||||||
} else if (status.mode == WiFiManager::Mode::SCANNING) {
|
|
||||||
set_blink_rate(TICKER_RATE_CONNECTING);
|
|
||||||
} else if (status.mode == WiFiManager::Mode::PORTAL) {
|
|
||||||
set_blink_rate(TICKER_RATE_CONFIG);
|
|
||||||
} else if (status.mode == WiFiManager::Mode::ERASING) {
|
|
||||||
set_blink_rate(TICKER_RATE_ERASE);
|
|
||||||
} else if (status.mode == WiFiManager::Mode::CONNECTED) {
|
|
||||||
set_blink_rate(0.0f);
|
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
|
||||||
} else if (status.mode == WiFiManager::Mode::DISCONNECTED) {
|
|
||||||
set_blink_rate(0.0f);
|
|
||||||
digitalWrite(LED_BUILTIN, LOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
wifiManager.configure("Claire", wifiManagerCb);
|
|
||||||
|
|
||||||
// fetches ssid and pass and tries to connect
|
|
||||||
// if it does not connect it starts an access point
|
|
||||||
// and goes into a blocking loop awaiting configuration
|
|
||||||
if (!wifiManager.autoConnect()) {
|
|
||||||
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(String(millis()) + " Connected with address: ");
|
|
||||||
Serial.println(WiFi.localIP());
|
|
||||||
|
|
||||||
// keep LED on
|
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetSettings() {
|
|
||||||
WiFiManager::Status status = {.wifi_status = 0U, .mode = WiFiManager::Mode::ERASING};
|
|
||||||
|
|
||||||
Serial.println(String(millis()) + " Resetting wifi settings...");
|
|
||||||
|
|
||||||
wifiManagerCb(status);
|
|
||||||
wifiManager.resetSettings();
|
|
||||||
delay(1000);
|
|
||||||
status.mode = WiFiManager::Mode::DISCONNECTED;
|
|
||||||
wifiManagerCb(status);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getMac(bool insertColons) {
|
|
||||||
String mac = wifiManager.getMacAsString(insertColons);
|
|
||||||
return mac;
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
#include "../include/WifiHandler.hpp"
|
#include "../include/backend_communication.hpp"
|
||||||
#include "../include/backend.hpp"
|
#include "../include/wifi_handler.hpp"
|
||||||
|
|
||||||
JsonDocument config;
|
|
||||||
bool isConfigValid = false;
|
bool isConfigValid = false;
|
||||||
String configTimestamp = "";
|
String configTimestamp = "";
|
||||||
|
|
||||||
|
@ -11,19 +10,22 @@ static HTTPClient http;
|
||||||
|
|
||||||
JsonDocument weatherData;
|
JsonDocument weatherData;
|
||||||
|
|
||||||
bool parseJsonConfig(String& payload) {
|
BackendCommunication::BackendCommunication(WifiHandler& p_wifi_handler) : m_wifi_handler(p_wifi_handler) { return; }
|
||||||
|
|
||||||
|
bool BackendCommunication::parseJsonConfig(String& payload) {
|
||||||
bool isSuccess = false;
|
bool isSuccess = false;
|
||||||
|
|
||||||
config.clear();
|
m_config.clear();
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(config, payload);
|
DeserializationError error = deserializeJson(m_config, payload);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
||||||
} else {
|
} else {
|
||||||
if (config["config version"] != "0.0.1") {
|
if (m_config["config version"] != "0.0.1") {
|
||||||
Serial.println(String(millis()) + " Unsupported config version");
|
Serial.println(String(millis()) + " Unsupported config version");
|
||||||
} else {
|
} else {
|
||||||
|
m_is_config_valid = true;
|
||||||
isSuccess = true;
|
isSuccess = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +33,10 @@ bool parseJsonConfig(String& payload) {
|
||||||
return isSuccess;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getConfig() {
|
bool BackendCommunication::getConfig() {
|
||||||
String mac = getMac(false);
|
String mac = m_wifi_handler.getMac(false);
|
||||||
String url = "https://target.luon.net/~admar/Claire/" + mac + "/config.json";
|
String url = "https://target.luon.net/~admar/Claire/" + urlencode(mac) + "/config.json";
|
||||||
|
|
||||||
String payload = "";
|
String payload = "";
|
||||||
bool isSuccess = false;
|
bool isSuccess = false;
|
||||||
|
|
||||||
|
@ -68,8 +71,30 @@ bool getConfig() {
|
||||||
return isSuccess;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
bool BackendCommunication::getWeatherData() {
|
||||||
String urlencode(String str) {
|
String url = "https://sinoptik.luon.net/forecast?address=" + urlencode(m_config["address"]) +
|
||||||
|
"&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;
|
||||||
|
}
|
||||||
|
|
||||||
|
String BackendCommunication::urlencode(String str) {
|
||||||
|
// From https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
||||||
String encodedString = "";
|
String encodedString = "";
|
||||||
char c;
|
char c;
|
||||||
char code0;
|
char code0;
|
||||||
|
@ -102,30 +127,3 @@ String urlencode(String str) {
|
||||||
|
|
||||||
return encodedString;
|
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;
|
|
||||||
}
|
|
31
src/main.cpp
31
src/main.cpp
|
@ -1,15 +1,29 @@
|
||||||
#include <dESPatch.h>
|
#include <dESPatch.h>
|
||||||
|
|
||||||
#include "../include/WifiHandler.hpp"
|
#include "../include/backend_communication.hpp"
|
||||||
#include "../include/backend.hpp"
|
#include "../include/wifi_handler.hpp"
|
||||||
|
|
||||||
|
#ifndef LED_BUILTIN
|
||||||
|
#define LED_BUILTIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUTTON_BUILTIN
|
||||||
|
#define BUTTON_BUILTIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONNECT_BUTTON BUTTON_BUILTIN
|
||||||
|
|
||||||
DESPatch dESPatch;
|
DESPatch dESPatch;
|
||||||
|
WifiHandler wifi_handler(LED_BUILTIN);
|
||||||
|
|
||||||
|
BackendCommunication backend_communication(wifi_handler);
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
set_blink_rate(TICKER_RATE_CONNECTING);
|
|
||||||
|
wifi_handler.setBlinkRate(WifiHandler::BLINK_RATE_CONNECTING);
|
||||||
|
|
||||||
pinMode(CONNECT_BUTTON, INPUT);
|
pinMode(CONNECT_BUTTON, INPUT);
|
||||||
|
|
||||||
|
@ -18,11 +32,11 @@ void setup() {
|
||||||
Serial.println(String(millis()) + " 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);
|
delay(3000);
|
||||||
if (not digitalRead(CONNECT_BUTTON)) {
|
if (not digitalRead(CONNECT_BUTTON)) {
|
||||||
resetSettings();
|
wifi_handler.resetSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect();
|
wifi_handler.connect();
|
||||||
|
|
||||||
const char url[] =
|
const char url[] =
|
||||||
"https://apikey:cqprlgiafadnidsgeqozcpldkaeqimqw@despatch.luon.net/"
|
"https://apikey:cqprlgiafadnidsgeqozcpldkaeqimqw@despatch.luon.net/"
|
||||||
|
@ -35,12 +49,13 @@ void setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(void) {
|
void loop(void) {
|
||||||
isConfigValid = getConfig();
|
backend_communication.getConfig();
|
||||||
|
|
||||||
if (not isConfigValid) {
|
if (not backend_communication.m_is_config_valid) {
|
||||||
Serial.println(String(millis()) + " Invalid config");
|
Serial.println(String(millis()) + " Invalid config");
|
||||||
} else {
|
} else {
|
||||||
Serial.println(String(millis()) + " Address: " + String(static_cast<const char*>(config["address"])));
|
Serial.println(String(millis()) +
|
||||||
|
" Address: " + String(static_cast<const char*>(backend_communication.m_config["address"])));
|
||||||
// getWeatherData();
|
// getWeatherData();
|
||||||
}
|
}
|
||||||
dESPatch.checkForUpdate(true);
|
dESPatch.checkForUpdate(true);
|
||||||
|
|
90
src/wifi_handler.cpp
Normal file
90
src/wifi_handler.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#include <Ticker.h>
|
||||||
|
|
||||||
|
#include "../include/wifi_handler.hpp"
|
||||||
|
|
||||||
|
static uint8_t g_led_pin;
|
||||||
|
static Ticker g_ticker;
|
||||||
|
|
||||||
|
WifiHandler::WifiHandler(uint8_t p_led_pin) {
|
||||||
|
g_led_pin = p_led_pin;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tick() {
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
if (g_led_pin >= 0) {
|
||||||
|
state = digitalRead(g_led_pin);
|
||||||
|
digitalWrite(g_led_pin, !state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiHandler::setBlinkRate(float p_interval) {
|
||||||
|
if (g_ticker.active()) {
|
||||||
|
g_ticker.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_interval > 0.0f) {
|
||||||
|
g_ticker.attach(p_interval, tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiHandler::wifiManagerCb(WiFiManager::Status p_status) {
|
||||||
|
if (p_status.mode == WiFiManager::Mode::CONNECTING) {
|
||||||
|
WifiHandler::setBlinkRate(WifiHandler::BLINK_RATE_CONNECTING);
|
||||||
|
} else if (p_status.mode == WiFiManager::Mode::SCANNING) {
|
||||||
|
WifiHandler::setBlinkRate(WifiHandler::BLINK_RATE_CONNECTING);
|
||||||
|
} else if (p_status.mode == WiFiManager::Mode::PORTAL) {
|
||||||
|
WifiHandler::setBlinkRate(WifiHandler::BLINK_RATE_CONFIG);
|
||||||
|
} else if (p_status.mode == WiFiManager::Mode::ERASING) {
|
||||||
|
WifiHandler::setBlinkRate(WifiHandler::BLINK_RATE_ERASE);
|
||||||
|
} else if (p_status.mode == WiFiManager::Mode::CONNECTED) {
|
||||||
|
WifiHandler::setBlinkRate(0.0f);
|
||||||
|
digitalWrite(g_led_pin, HIGH);
|
||||||
|
} else if (p_status.mode == WiFiManager::Mode::DISCONNECTED) {
|
||||||
|
WifiHandler::setBlinkRate(0.0f);
|
||||||
|
digitalWrite(g_led_pin, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiHandler::connect() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
m_wifiManager.configure("Claire", WifiHandler::wifiManagerCb);
|
||||||
|
|
||||||
|
// fetches ssid and pass and tries to connect
|
||||||
|
// if it does not connect it starts an access point
|
||||||
|
// and goes into a blocking loop awaiting configuration
|
||||||
|
if (!m_wifiManager.autoConnect()) {
|
||||||
|
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(String(millis()) + " Connected with address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// keep LED on
|
||||||
|
digitalWrite(g_led_pin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiHandler::resetSettings() {
|
||||||
|
WiFiManager::Status status = {.wifi_status = 0U, .mode = WiFiManager::Mode::ERASING};
|
||||||
|
|
||||||
|
Serial.println(String(millis()) + " Resetting wifi settings...");
|
||||||
|
|
||||||
|
wifiManagerCb(status);
|
||||||
|
m_wifiManager.resetSettings();
|
||||||
|
delay(1000);
|
||||||
|
status.mode = WiFiManager::Mode::DISCONNECTED;
|
||||||
|
wifiManagerCb(status);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String WifiHandler::getMac(bool p_insertColons) {
|
||||||
|
String mac = m_wifiManager.getMacAsString(p_insertColons);
|
||||||
|
return mac;
|
||||||
|
}
|
Loading…
Reference in a new issue