Added Display class; Neopixel is disabled for now
This commit is contained in:
parent
388bd0a84c
commit
3aecd54880
9 changed files with 326 additions and 34 deletions
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
|
@ -11,6 +11,7 @@
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/include",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/include",
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/src",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/src",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
||||||
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/Adafruit NeoPixel",
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/dESPatch",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/dESPatch",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
||||||
|
@ -250,6 +251,7 @@
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/include",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/include",
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/src",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/src",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
||||||
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/Adafruit NeoPixel",
|
||||||
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/dESPatch",
|
"/home/admar/Documents/Arduino/buienradarklok/Claire/.pio/libdeps/esp32dev/dESPatch",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
||||||
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
"/home/admar/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
||||||
|
@ -505,7 +507,7 @@
|
||||||
""
|
""
|
||||||
],
|
],
|
||||||
"cStandard": "gnu99",
|
"cStandard": "gnu99",
|
||||||
"cppStandard": "gnu++11",
|
"cppStandard": "gnu++20",
|
||||||
"compilerPath": "/home/admar/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc",
|
"compilerPath": "/home/admar/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc",
|
||||||
"compilerArgs": [
|
"compilerArgs": [
|
||||||
"-mlongcalls",
|
"-mlongcalls",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef __BACKEND_HPP__
|
#ifndef __BACKEND_COMMUNICATION_HPP__
|
||||||
#define __BACKEND_HPP__
|
#define __BACKEND_COMMUNICATION_HPP__
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
@ -14,13 +14,16 @@ class BackendCommunication {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Public methods
|
// Public methods
|
||||||
bool parseJsonConfig(String& payload);
|
|
||||||
bool getConfig();
|
bool getConfig();
|
||||||
|
|
||||||
bool getWeatherData();
|
bool getWeatherData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Private methods
|
// Private methods
|
||||||
|
bool parseConfig(String& p_payload);
|
||||||
|
|
||||||
|
bool parseWeatherData(String& p_payload);
|
||||||
|
|
||||||
String urlencode(String str);
|
String urlencode(String str);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -35,4 +38,4 @@ class BackendCommunication {
|
||||||
WifiHandler& m_wifi_handler;
|
WifiHandler& m_wifi_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __BACKEND_HPP__
|
#endif // __BACKEND_COMMUNICATION_HPP__
|
48
include/display.hpp
Normal file
48
include/display.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef __DISPLAY_HPP__
|
||||||
|
#define __DISPLAY_HPP__
|
||||||
|
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class Display {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
Display();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Public methods
|
||||||
|
void setPollenPlusAQIForecastLeds(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_aqi,
|
||||||
|
ArduinoJson::V710PB22::JsonArray p_pollen);
|
||||||
|
void setPrecipitationForecastLeds(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_precipitation);
|
||||||
|
void setUVIForecastLed(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_uvi);
|
||||||
|
void setLocalAirQualityLed();
|
||||||
|
void setWifiStatusLed(bool p_enable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private methods
|
||||||
|
float findMaxValueInTwelveHourInterval(uint32_t p_time_stamp, ArduinoJson::V710PB22::JsonArray p_array);
|
||||||
|
std::vector<float> mergeJsonArraysFromTimestamp(uint32_t p_time_stamp, ArduinoJson::V710PB22::JsonArray p_array_a,
|
||||||
|
ArduinoJson::V710PB22::JsonArray p_array_b);
|
||||||
|
std::tuple<uint8_t, uint8_t, uint8_t> mapValueToColorRGB(float p_value);
|
||||||
|
std::tuple<uint8_t, uint8_t, uint8_t, uint8_t> mapValueToColorRGBW(float p_value);
|
||||||
|
void setPixelToColorMappedValue(uint8_t index, float p_value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private static members
|
||||||
|
constexpr static uint16_t m_NUM_LEDS_PROTO_V1 = 29U;
|
||||||
|
constexpr static int16_t m_DATA_PIN_PROTO_V1 = 14;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private members
|
||||||
|
Adafruit_NeoPixel m_leds;
|
||||||
|
std::array<uint8_t, 12U> m_precipitation_forecast_map;
|
||||||
|
std::array<uint8_t, 12U> m_air_quality_forecast_map;
|
||||||
|
uint8_t m_max_pollen_map;
|
||||||
|
uint8_t m_max_air_qualilty_map;
|
||||||
|
uint8_t m_uvi_map;
|
||||||
|
uint8_t m_local_air_quality_map;
|
||||||
|
uint8_t m_wifi_status_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __DISPLAY_HPP__
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#include <WiFiManager-esp32.h> // https://github.com/admarschoonen/WiFiManager
|
#include <WiFiManager-esp32.h> // https://github.com/admarschoonen/WiFiManager
|
||||||
|
|
||||||
|
#include "display.hpp"
|
||||||
|
|
||||||
class WifiHandler {
|
class WifiHandler {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
WifiHandler(uint8_t p_led_pin);
|
WifiHandler(uint8_t p_led_pin, Display p_display);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Public static methods
|
// Public static methods
|
||||||
|
@ -28,6 +30,7 @@ class WifiHandler {
|
||||||
private:
|
private:
|
||||||
// Private objects
|
// Private objects
|
||||||
WiFiManager m_wifiManager;
|
WiFiManager m_wifiManager;
|
||||||
|
Display& m_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __WIFIHANDLER_HPP__
|
#endif // __WIFIHANDLER_HPP__
|
|
@ -12,7 +12,10 @@
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
build_unflags = -std=gnu++11
|
||||||
|
build_flags = -std=gnu++2a
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/admarschoonen/WIFIMANAGER-ESP32.git#v0.100.0
|
https://github.com/admarschoonen/WIFIMANAGER-ESP32.git#v0.100.0
|
||||||
https://github.com/admarschoonen/dESPatch.git#v0.9.5
|
https://github.com/admarschoonen/dESPatch.git#v0.9.5
|
||||||
bblanchon/ArduinoJson @ ^7.1.0
|
bblanchon/ArduinoJson@^7.1.0
|
||||||
|
adafruit/Adafruit NeoPixel@^1.12.3
|
||||||
|
|
|
@ -12,27 +12,6 @@ JsonDocument weatherData;
|
||||||
|
|
||||||
BackendCommunication::BackendCommunication(WifiHandler& p_wifi_handler) : m_wifi_handler(p_wifi_handler) { return; }
|
BackendCommunication::BackendCommunication(WifiHandler& p_wifi_handler) : m_wifi_handler(p_wifi_handler) { return; }
|
||||||
|
|
||||||
bool BackendCommunication::parseJsonConfig(String& payload) {
|
|
||||||
bool isSuccess = false;
|
|
||||||
|
|
||||||
m_config.clear();
|
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(m_config, payload);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
|
||||||
} else {
|
|
||||||
if (m_config["config version"] != "0.0.1") {
|
|
||||||
Serial.println(String(millis()) + " Unsupported config version");
|
|
||||||
} else {
|
|
||||||
m_is_config_valid = true;
|
|
||||||
isSuccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BackendCommunication::getConfig() {
|
bool BackendCommunication::getConfig() {
|
||||||
String mac = m_wifi_handler.getMac(false);
|
String mac = m_wifi_handler.getMac(false);
|
||||||
String url = "https://target.luon.net/~admar/Claire/" + urlencode(mac) + "/config.json";
|
String url = "https://target.luon.net/~admar/Claire/" + urlencode(mac) + "/config.json";
|
||||||
|
@ -54,11 +33,10 @@ bool BackendCommunication::getConfig() {
|
||||||
if (httpCode == 200) {
|
if (httpCode == 200) {
|
||||||
// Content is in payload
|
// Content is in payload
|
||||||
payload = http.getString();
|
payload = http.getString();
|
||||||
isSuccess = parseJsonConfig(payload);
|
isSuccess = parseConfig(payload);
|
||||||
|
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
configTimestamp = http.header("Last-Modified");
|
configTimestamp = http.header("Last-Modified");
|
||||||
Serial.println(String(millis()) + " ConfigTimestamp: " + configTimestamp);
|
|
||||||
}
|
}
|
||||||
} else if (httpCode == 304) {
|
} else if (httpCode == 304) {
|
||||||
// Content did not change
|
// Content did not change
|
||||||
|
@ -84,7 +62,7 @@ bool BackendCommunication::getWeatherData() {
|
||||||
|
|
||||||
if (httpCode > 0) {
|
if (httpCode > 0) {
|
||||||
payload = http.getString();
|
payload = http.getString();
|
||||||
// isSuccess = parseJsonConfig(payload);
|
isSuccess = parseWeatherData(payload);
|
||||||
} else {
|
} else {
|
||||||
Serial.println(String(millis()) + " Got http code " + httpCode);
|
Serial.println(String(millis()) + " Got http code " + httpCode);
|
||||||
}
|
}
|
||||||
|
@ -93,6 +71,44 @@ bool BackendCommunication::getWeatherData() {
|
||||||
return isSuccess;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BackendCommunication::parseConfig(String& payload) {
|
||||||
|
bool isSuccess = false;
|
||||||
|
|
||||||
|
m_config.clear();
|
||||||
|
|
||||||
|
DeserializationError error = deserializeJson(m_config, payload);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
||||||
|
} else {
|
||||||
|
if (m_config["config version"] != "0.0.1") {
|
||||||
|
Serial.println(String(millis()) + " Unsupported config version");
|
||||||
|
} else {
|
||||||
|
m_is_config_valid = true;
|
||||||
|
isSuccess = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BackendCommunication::parseWeatherData(String& payload) {
|
||||||
|
bool isSuccess = false;
|
||||||
|
|
||||||
|
m_weather_data.clear();
|
||||||
|
|
||||||
|
DeserializationError error = deserializeJson(m_weather_data, payload);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
Serial.print(String(millis()) + " DeserializeJson() failed: " + String(error.f_str()));
|
||||||
|
} else {
|
||||||
|
m_is_config_valid = true;
|
||||||
|
isSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
String BackendCommunication::urlencode(String str) {
|
String BackendCommunication::urlencode(String str) {
|
||||||
// From https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
// From https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
||||||
String encodedString = "";
|
String encodedString = "";
|
||||||
|
|
185
src/display.cpp
Normal file
185
src/display.cpp
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#include "../include/display.hpp"
|
||||||
|
|
||||||
|
Display::Display() {
|
||||||
|
// m_leds = Adafruit_NeoPixel(m_NUM_LEDS_PROTO_V1, m_DATA_PIN_PROTO_V1, NEO_RGBW + NEO_KHZ800);
|
||||||
|
|
||||||
|
m_precipitation_forecast_map = {11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
m_air_quality_forecast_map = {23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
|
||||||
|
m_max_pollen_map = 26;
|
||||||
|
m_max_air_qualilty_map = 24;
|
||||||
|
m_uvi_map = 27;
|
||||||
|
m_local_air_quality_map = 25;
|
||||||
|
m_wifi_status_map = 28;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setPollenPlusAQIForecastLeds(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_aqi,
|
||||||
|
ArduinoJson::V710PB22::JsonArray p_pollen) {
|
||||||
|
uint32_t first_aqi_time = p_pollen[0]["aqi"].as<uint32_t>();
|
||||||
|
uint32_t first_pollen_time = p_pollen[0]["time"].as<uint32_t>();
|
||||||
|
|
||||||
|
std::vector<float> merged_array = {};
|
||||||
|
|
||||||
|
if (first_aqi_time <= first_pollen_time) {
|
||||||
|
merged_array = mergeJsonArraysFromTimestamp(p_current_time, p_aqi, p_pollen);
|
||||||
|
} else {
|
||||||
|
merged_array = mergeJsonArraysFromTimestamp(p_current_time, p_pollen, p_aqi);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
for (float value : merged_array) {
|
||||||
|
setPixelToColorMappedValue(m_air_quality_forecast_map.at(index), value);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
float max_aqi = findMaxValueInTwelveHourInterval(p_current_time, p_aqi);
|
||||||
|
setPixelToColorMappedValue(m_max_air_qualilty_map, max_aqi);
|
||||||
|
|
||||||
|
float max_pollen = findMaxValueInTwelveHourInterval(p_current_time, p_pollen);
|
||||||
|
setPixelToColorMappedValue(m_max_pollen_map, max_pollen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setPrecipitationForecastLeds(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_precipitation) {
|
||||||
|
float previous_value = 0.0f;
|
||||||
|
|
||||||
|
uint32_t index = 0U;
|
||||||
|
for (JsonObject elem : p_precipitation) {
|
||||||
|
uint32_t time = elem["time"].as<uint32_t>();
|
||||||
|
float value = elem["value"].as<float>();
|
||||||
|
|
||||||
|
if ((index == 0U) and (time > p_current_time)) {
|
||||||
|
setPixelToColorMappedValue(m_precipitation_forecast_map.at(index), previous_value);
|
||||||
|
index = 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > 0U) {
|
||||||
|
setPixelToColorMappedValue(m_precipitation_forecast_map.at(index), value);
|
||||||
|
index += 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setUVIForecastLed(uint32_t p_current_time, ArduinoJson::V710PB22::JsonArray p_uvi) {
|
||||||
|
for (JsonObject elem : p_uvi) {
|
||||||
|
uint32_t time = elem["time"].as<uint32_t>();
|
||||||
|
float value = elem["value"].as<float>();
|
||||||
|
|
||||||
|
if (time > p_current_time) {
|
||||||
|
setPixelToColorMappedValue(m_uvi_map, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setLocalAirQualityLed() {}
|
||||||
|
|
||||||
|
void Display::setWifiStatusLed(bool p_enable) {}
|
||||||
|
|
||||||
|
float Display::findMaxValueInTwelveHourInterval(uint32_t p_time_stamp, ArduinoJson::V710PB22::JsonArray p_array) {
|
||||||
|
float max_value = 0.0f;
|
||||||
|
|
||||||
|
for (auto elem : p_array) {
|
||||||
|
uint32_t time = elem["time"].as<uint32_t>();
|
||||||
|
constexpr uint32_t TWELVE_HOURS_IN_SECONDS = 12U * 60U * 60U;
|
||||||
|
if ((time >= p_time_stamp) and (time < p_time_stamp + TWELVE_HOURS_IN_SECONDS)) {
|
||||||
|
max_value = std::max(max_value, elem["value"].as<float>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> Display::mergeJsonArraysFromTimestamp(uint32_t p_time_stamp,
|
||||||
|
ArduinoJson::V710PB22::JsonArray p_array_a,
|
||||||
|
ArduinoJson::V710PB22::JsonArray p_array_b) {
|
||||||
|
// Assumption: timestamp in p_array_a <= p_array_b
|
||||||
|
|
||||||
|
std::vector<float> merged_vector = {};
|
||||||
|
size_t start_point_b = 0;
|
||||||
|
|
||||||
|
for (auto elem_a : p_array_a) {
|
||||||
|
uint32_t time_a = elem_a["time"].as<uint32_t>();
|
||||||
|
|
||||||
|
if (time_a >= p_time_stamp) {
|
||||||
|
float merged_value = elem_a["value"].as<float>();
|
||||||
|
|
||||||
|
for (size_t index_b = start_point_b; index_b < p_array_b.size(); index_b++) {
|
||||||
|
uint32_t time_b = p_array_b[index_b]["time"].as<uint32_t>();
|
||||||
|
|
||||||
|
if (time_b >= time_a) {
|
||||||
|
float value_b = p_array_b[index_b]["value"].as<float>();
|
||||||
|
merged_value = std::max(merged_value, value_b);
|
||||||
|
merged_vector.push_back(merged_value);
|
||||||
|
start_point_b = index_b + 1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t index_b = start_point_b; index_b < p_array_b.size(); index_b++) {
|
||||||
|
float value_b = p_array_b[index_b]["value"].as<float>();
|
||||||
|
merged_vector.push_back(value_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<uint8_t, uint8_t, uint8_t> Display::mapValueToColorRGB(float p_value) {
|
||||||
|
if (p_value < 1.0) {
|
||||||
|
return {0, 0, 0}; // black (good)
|
||||||
|
} else if (p_value < 2.0) {
|
||||||
|
return {0, 0, 160}; // blue (good)
|
||||||
|
} else if (p_value < 3.0) {
|
||||||
|
return {0, 255, 255}; // cyan (good)
|
||||||
|
} else if (p_value < 4.0) {
|
||||||
|
return {255, 255, 255}; // white (mediocre)
|
||||||
|
} else if (p_value < 5.0) {
|
||||||
|
return {200, 200, 32}; // light yellow (mediocre)
|
||||||
|
} else if (p_value < 6.0) {
|
||||||
|
return {120, 120, 0}; // yellow (mediocre)
|
||||||
|
} else if (p_value < 7.0) {
|
||||||
|
return {200, 80, 0}; // orange (inadequate)
|
||||||
|
} else if (p_value < 8.0) {
|
||||||
|
return {255, 50, 0}; // red-orange (inadequate)
|
||||||
|
} else if (p_value < 9.0) {
|
||||||
|
return {180, 0, 0}; // red (bad)
|
||||||
|
} else if (p_value < 10.0) {
|
||||||
|
return {200, 0, 160}; // magenta (bad)
|
||||||
|
} else {
|
||||||
|
return {60, 0, 210}; // purple (terrible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<uint8_t, uint8_t, uint8_t, uint8_t> Display::mapValueToColorRGBW(float p_value) {
|
||||||
|
if (p_value < 1.0) {
|
||||||
|
return {0, 0, 0, 0}; // black (good)
|
||||||
|
} else if (p_value < 2.0) {
|
||||||
|
return {0, 0, 255, 0}; // blue (good)
|
||||||
|
} else if (p_value < 3.0) {
|
||||||
|
return {0, 255, 255, 0}; // cyan (good)
|
||||||
|
} else if (p_value < 4.0) {
|
||||||
|
return {255, 255, 255, 0}; // white (mediocre)
|
||||||
|
} else if (p_value < 5.0) {
|
||||||
|
return {200, 200, 32, 0}; // light yellow (mediocre)
|
||||||
|
} else if (p_value < 6.0) {
|
||||||
|
return {120, 120, 0, 0}; // yellow (mediocre)
|
||||||
|
} else if (p_value < 7.0) {
|
||||||
|
return {200, 80, 0, 0}; // orange (inadequate)
|
||||||
|
} else if (p_value < 8.0) {
|
||||||
|
return {255, 50, 0, 0}; // red-orange (inadequate)
|
||||||
|
} else if (p_value < 9.0) {
|
||||||
|
return {180, 0, 0, 0}; // red (bad)
|
||||||
|
} else if (p_value < 10.0) {
|
||||||
|
return {200, 0, 160, 0}; // magenta (bad)
|
||||||
|
} else {
|
||||||
|
return {60, 0, 210, 0}; // purple (terrible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setPixelToColorMappedValue(uint8_t p_index, float p_value) {
|
||||||
|
auto [red, green, blue, white] = mapValueToColorRGBW(p_value);
|
||||||
|
m_leds.setPixelColor(p_index, m_leds.Color(red, green, blue, white));
|
||||||
|
}
|
36
src/main.cpp
36
src/main.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include <dESPatch.h>
|
#include <dESPatch.h>
|
||||||
|
|
||||||
#include "../include/backend_communication.hpp"
|
#include "../include/backend_communication.hpp"
|
||||||
|
#include "../include/display.hpp"
|
||||||
#include "../include/wifi_handler.hpp"
|
#include "../include/wifi_handler.hpp"
|
||||||
|
|
||||||
#ifndef LED_BUILTIN
|
#ifndef LED_BUILTIN
|
||||||
|
@ -14,7 +15,8 @@
|
||||||
#define CONNECT_BUTTON BUTTON_BUILTIN
|
#define CONNECT_BUTTON BUTTON_BUILTIN
|
||||||
|
|
||||||
DESPatch dESPatch;
|
DESPatch dESPatch;
|
||||||
WifiHandler wifi_handler(LED_BUILTIN);
|
Display display;
|
||||||
|
WifiHandler wifi_handler(LED_BUILTIN, display);
|
||||||
|
|
||||||
BackendCommunication backend_communication(wifi_handler);
|
BackendCommunication backend_communication(wifi_handler);
|
||||||
|
|
||||||
|
@ -56,7 +58,37 @@ void loop(void) {
|
||||||
} else {
|
} else {
|
||||||
Serial.println(String(millis()) +
|
Serial.println(String(millis()) +
|
||||||
" Address: " + String(static_cast<const char*>(backend_communication.m_config["address"])));
|
" Address: " + String(static_cast<const char*>(backend_communication.m_config["address"])));
|
||||||
// getWeatherData();
|
|
||||||
|
backend_communication.getWeatherData();
|
||||||
|
|
||||||
|
String text = String(millis()) + " Precipitation:";
|
||||||
|
for (JsonObject elem : backend_communication.m_weather_data["precipitation"].as<JsonArray>()) {
|
||||||
|
text += " " + String(elem["value"].as<float>());
|
||||||
|
}
|
||||||
|
Serial.println(text);
|
||||||
|
|
||||||
|
text = String(millis()) + " AQI:";
|
||||||
|
for (JsonObject elem : backend_communication.m_weather_data["AQI"].as<JsonArray>()) {
|
||||||
|
text += " " + String(elem["value"].as<float>());
|
||||||
|
}
|
||||||
|
Serial.println(text);
|
||||||
|
|
||||||
|
text = String(millis()) + " Pollen:";
|
||||||
|
for (JsonObject elem : backend_communication.m_weather_data["pollen"].as<JsonArray>()) {
|
||||||
|
text += " " + String(elem["value"].as<float>());
|
||||||
|
}
|
||||||
|
Serial.println(text);
|
||||||
|
text = String(millis()) + " UVI:";
|
||||||
|
for (JsonObject elem : backend_communication.m_weather_data["UVI"].as<JsonArray>()) {
|
||||||
|
text += " " + String(elem["value"].as<float>());
|
||||||
|
}
|
||||||
|
Serial.println(text);
|
||||||
|
|
||||||
|
uint32_t time = backend_communication.m_weather_data["time"].as<JsonInteger>();
|
||||||
|
text = String(millis()) + " time: " + std::to_string(time).c_str();
|
||||||
|
Serial.println(text);
|
||||||
|
|
||||||
|
// display.setUVIForecastLed(time, backend_communication.m_weather_data["UVI"].as<JsonArray>());
|
||||||
}
|
}
|
||||||
dESPatch.checkForUpdate(true);
|
dESPatch.checkForUpdate(true);
|
||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
static uint8_t g_led_pin;
|
static uint8_t g_led_pin;
|
||||||
static Ticker g_ticker;
|
static Ticker g_ticker;
|
||||||
|
|
||||||
WifiHandler::WifiHandler(uint8_t p_led_pin) {
|
WifiHandler::WifiHandler(uint8_t p_led_pin, Display p_display) : m_display(p_display) {
|
||||||
g_led_pin = p_led_pin;
|
g_led_pin = p_led_pin;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue