v.0.2.1 ColorSerial
This commit is contained in:
398
lib/Utils/src/ColorSerial.cpp
Normal file
398
lib/Utils/src/ColorSerial.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
#include "ColorSerial.h"
|
||||
|
||||
// ANSI Escape Codes
|
||||
const char *ColorSerial::RESET = "\033[0m";
|
||||
const char *ColorSerial::BOLD = "\033[1m";
|
||||
const char *ColorSerial::UNDERLINE = "\033[4m";
|
||||
const char *ColorSerial::ITALIC = "\033[3m";
|
||||
|
||||
// Standard Colors
|
||||
const char *ColorSerial::RED = "\033[38;2;255;0;0m";
|
||||
const char *ColorSerial::GREEN = "\033[38;2;0;255;0m";
|
||||
const char *ColorSerial::BLUE = "\033[38;2;0;120;255m";
|
||||
const char *ColorSerial::YELLOW = "\033[38;2;255;255;0m";
|
||||
const char *ColorSerial::CYAN = "\033[38;2;0;255;255m";
|
||||
const char *ColorSerial::MAGENTA = "\033[38;2;255;0;255m";
|
||||
const char *ColorSerial::ORANGE = "\033[38;2;255;165;0m";
|
||||
const char *ColorSerial::WHITE = "\033[38;2;255;255;255m";
|
||||
const char *ColorSerial::GRAY = "\033[38;2;128;128;128m";
|
||||
|
||||
// Icons
|
||||
const char *ColorSerial::ICON_SUCCESS = "✅";
|
||||
const char *ColorSerial::ICON_ERROR = "❌";
|
||||
const char *ColorSerial::ICON_WARNING = "⚠️";
|
||||
const char *ColorSerial::ICON_INFO = "ℹ️";
|
||||
const char *ColorSerial::ICON_DEBUG = "🐛";
|
||||
const char *ColorSerial::ICON_WIFI = "📡";
|
||||
const char *ColorSerial::ICON_WEATHER = "🌡️";
|
||||
|
||||
// Main Logging Methods
|
||||
void ColorSerial::success(const char *message, const char *details)
|
||||
{
|
||||
Serial.print(GREEN);
|
||||
Serial.print(ICON_SUCCESS);
|
||||
Serial.print(" SUCCESS: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print(message);
|
||||
Serial.print(RESET);
|
||||
|
||||
if (strlen(details) > 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(GRAY);
|
||||
Serial.print("(");
|
||||
Serial.print(details);
|
||||
Serial.print(")");
|
||||
Serial.print(RESET);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::error(const char *message, const char *details)
|
||||
{
|
||||
Serial.print(RED);
|
||||
Serial.print(ICON_ERROR);
|
||||
Serial.print(" ERROR: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print(message);
|
||||
Serial.print(RESET);
|
||||
|
||||
if (strlen(details) > 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(RED);
|
||||
Serial.print(details);
|
||||
Serial.print(RESET);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::warning(const char *message, const char *details)
|
||||
{
|
||||
Serial.print(YELLOW);
|
||||
Serial.print(ICON_WARNING);
|
||||
Serial.print(" WARNING: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print(message);
|
||||
Serial.print(RESET);
|
||||
|
||||
if (strlen(details) > 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(GRAY);
|
||||
Serial.print("(");
|
||||
Serial.print(details);
|
||||
Serial.print(")");
|
||||
Serial.print(RESET);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::info(const char *message, const char *details)
|
||||
{
|
||||
Serial.print(CYAN);
|
||||
Serial.print(ICON_INFO);
|
||||
Serial.print(" INFO: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print(message);
|
||||
Serial.print(RESET);
|
||||
|
||||
if (strlen(details) > 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(GRAY);
|
||||
Serial.print("(");
|
||||
Serial.print(details);
|
||||
Serial.print(")");
|
||||
Serial.print(RESET);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::debug(const char *message, const char *details)
|
||||
{
|
||||
Serial.print(MAGENTA);
|
||||
Serial.print(ICON_DEBUG);
|
||||
Serial.print(" DEBUG: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(ITALIC);
|
||||
Serial.print(message);
|
||||
Serial.print(RESET);
|
||||
|
||||
if (strlen(details) > 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(GRAY);
|
||||
Serial.print("[");
|
||||
Serial.print(details);
|
||||
Serial.print("]");
|
||||
Serial.print(RESET);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// Data Display Methods
|
||||
void ColorSerial::data(const char *label, const char *value, const char *unit)
|
||||
{
|
||||
Serial.print(BLUE);
|
||||
Serial.print(label);
|
||||
Serial.print(":");
|
||||
Serial.print(RESET);
|
||||
Serial.print(" ");
|
||||
Serial.print(BOLD);
|
||||
Serial.print(WHITE);
|
||||
Serial.print(value);
|
||||
Serial.print(RESET);
|
||||
Serial.print(unit);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::data(const char *label, float value, const char *unit)
|
||||
{
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%.1f", value);
|
||||
data(label, buf, unit);
|
||||
}
|
||||
|
||||
void ColorSerial::data(const char *label, int value, const char *unit)
|
||||
{
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%d", value);
|
||||
data(label, buf, unit);
|
||||
}
|
||||
|
||||
void ColorSerial::temperature(float temp, const char *label)
|
||||
{
|
||||
const char *color;
|
||||
if (temp < 0)
|
||||
color = CYAN;
|
||||
else if (temp < 10)
|
||||
color = BLUE;
|
||||
else if (temp < 20)
|
||||
color = GREEN;
|
||||
else if (temp < 30)
|
||||
color = YELLOW;
|
||||
else
|
||||
color = RED;
|
||||
|
||||
Serial.print(BLUE);
|
||||
Serial.print(label);
|
||||
Serial.print(": ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(color);
|
||||
Serial.print(temp, 1);
|
||||
Serial.print("°C");
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::wifiStatus()
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print(GREEN);
|
||||
Serial.print(ICON_WIFI);
|
||||
Serial.print(" WiFi: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print("Connected");
|
||||
Serial.print(GRAY);
|
||||
Serial.print(" (IP: ");
|
||||
Serial.print(WiFi.localIP().toString().c_str());
|
||||
Serial.print(")");
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(RED);
|
||||
Serial.print(ICON_WIFI);
|
||||
Serial.print(" WiFi: ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print("Disconnected");
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
// Progress Bars
|
||||
void ColorSerial::progressBar(int percent, const char *label, int width)
|
||||
{
|
||||
int pos = (percent * width) / 100;
|
||||
const char *color = (percent < 30) ? RED : (percent < 70) ? YELLOW
|
||||
: GREEN;
|
||||
|
||||
Serial.print(BLUE);
|
||||
Serial.print(label);
|
||||
Serial.print(" [");
|
||||
Serial.print(RESET);
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
if (i < pos)
|
||||
{
|
||||
Serial.print(color);
|
||||
Serial.print("█");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(GRAY);
|
||||
Serial.print("░");
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print(RESET);
|
||||
Serial.print(BLUE);
|
||||
Serial.print("] ");
|
||||
Serial.print(color);
|
||||
Serial.print(percent);
|
||||
Serial.print("%");
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// Section Headers
|
||||
void ColorSerial::header(const char *title, char decorator, int width)
|
||||
{
|
||||
int titleLen = strlen(title);
|
||||
int padding = (width - titleLen - 2) / 2;
|
||||
|
||||
Serial.println();
|
||||
|
||||
// Top line
|
||||
Serial.print(MAGENTA);
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
Serial.print(decorator);
|
||||
}
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
|
||||
// Title line
|
||||
Serial.print(MAGENTA);
|
||||
Serial.print("║");
|
||||
Serial.print(RESET);
|
||||
|
||||
for (int i = 0; i < padding; i++)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
|
||||
Serial.print(BOLD);
|
||||
Serial.print(title);
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
|
||||
// Bottom line
|
||||
Serial.print(MAGENTA);
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
Serial.print(decorator);
|
||||
}
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void ColorSerial::subheader(const char *title)
|
||||
{
|
||||
Serial.print(CYAN);
|
||||
Serial.print("▶ ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(BOLD);
|
||||
Serial.print(title);
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// Weather Specific Private Methods
|
||||
const char *ColorSerial::getWeatherCondition(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0:
|
||||
return "Clear sky";
|
||||
case 1:
|
||||
return "Mainly clear";
|
||||
case 2:
|
||||
return "Partly cloudy";
|
||||
case 3:
|
||||
return "Overcast";
|
||||
case 45:
|
||||
case 48:
|
||||
return "Fog";
|
||||
case 51:
|
||||
case 53:
|
||||
case 55:
|
||||
return "Drizzle";
|
||||
case 61:
|
||||
case 63:
|
||||
case 65:
|
||||
return "Rain";
|
||||
case 71:
|
||||
case 73:
|
||||
case 75:
|
||||
return "Snow";
|
||||
case 95:
|
||||
case 96:
|
||||
case 99:
|
||||
return "Thunderstorm";
|
||||
default:
|
||||
return "Unknown weather";
|
||||
}
|
||||
}
|
||||
|
||||
const char *ColorSerial::getWeatherIcon(int code)
|
||||
{
|
||||
if (code == 0)
|
||||
return "☀️";
|
||||
if (code <= 2)
|
||||
return "⛅";
|
||||
if (code == 3)
|
||||
return "☁️";
|
||||
if (code <= 55)
|
||||
return "🌧️";
|
||||
if (code <= 65)
|
||||
return "🌧️";
|
||||
if (code <= 79)
|
||||
return "❄️";
|
||||
return "🌩️";
|
||||
}
|
||||
|
||||
const char *ColorSerial::getWeatherColor(int code)
|
||||
{
|
||||
if (code <= 2)
|
||||
return YELLOW;
|
||||
if (code == 3)
|
||||
return GRAY;
|
||||
if (code <= 55)
|
||||
return CYAN;
|
||||
if (code <= 65)
|
||||
return BLUE;
|
||||
if (code <= 79)
|
||||
return WHITE;
|
||||
return MAGENTA;
|
||||
}
|
||||
|
||||
void ColorSerial::weatherCondition(int code, const char *customLabel)
|
||||
{
|
||||
const char *label = (customLabel == nullptr || strlen(customLabel) == 0) ? "Condition" : customLabel;
|
||||
const char *condition = getWeatherCondition(code);
|
||||
const char *icon = getWeatherIcon(code);
|
||||
const char *color = getWeatherColor(code);
|
||||
|
||||
Serial.print(BLUE);
|
||||
Serial.print(label);
|
||||
Serial.print(": ");
|
||||
Serial.print(RESET);
|
||||
Serial.print(color);
|
||||
Serial.print(icon);
|
||||
Serial.print(" ");
|
||||
Serial.print(condition);
|
||||
Serial.print(RESET);
|
||||
Serial.println();
|
||||
}
|
||||
66
lib/Utils/src/ColorSerial.h
Normal file
66
lib/Utils/src/ColorSerial.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef COLORSERIAL_H
|
||||
#define COLORSERIAL_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
class ColorSerial
|
||||
{
|
||||
private:
|
||||
static const char *getWeatherCondition(int code);
|
||||
static const char *getWeatherIcon(int code);
|
||||
static const char *getWeatherColor(int code);
|
||||
|
||||
public:
|
||||
// ANSI Escape Codes
|
||||
static const char *RESET;
|
||||
static const char *BOLD;
|
||||
static const char *UNDERLINE;
|
||||
static const char *ITALIC;
|
||||
|
||||
// Standard Colors
|
||||
static const char *RED;
|
||||
static const char *GREEN;
|
||||
static const char *BLUE;
|
||||
static const char *YELLOW;
|
||||
static const char *CYAN;
|
||||
static const char *MAGENTA;
|
||||
static const char *ORANGE;
|
||||
static const char *WHITE;
|
||||
static const char *GRAY;
|
||||
|
||||
// Icons
|
||||
static const char *ICON_SUCCESS;
|
||||
static const char *ICON_ERROR;
|
||||
static const char *ICON_WARNING;
|
||||
static const char *ICON_INFO;
|
||||
static const char *ICON_DEBUG;
|
||||
static const char *ICON_WIFI;
|
||||
static const char *ICON_WEATHER;
|
||||
|
||||
// Main Logging Methods
|
||||
static void success(const char *message, const char *details = "");
|
||||
static void error(const char *message, const char *details = "");
|
||||
static void warning(const char *message, const char *details = "");
|
||||
static void info(const char *message, const char *details = "");
|
||||
static void debug(const char *message, const char *details = "");
|
||||
|
||||
// Data Display Methods
|
||||
static void data(const char *label, const char *value, const char *unit = "");
|
||||
static void data(const char *label, float value, const char *unit = "");
|
||||
static void data(const char *label, int value, const char *unit = "");
|
||||
static void temperature(float temp, const char *label = "Temperature");
|
||||
static void wifiStatus();
|
||||
|
||||
// Progress Bars
|
||||
static void progressBar(int percent, const char *label = "", int width = 20);
|
||||
|
||||
// Section Headers
|
||||
static void header(const char *title, char decorator = '═', int width = 40);
|
||||
static void subheader(const char *title);
|
||||
|
||||
// Weather Specific
|
||||
static void weatherCondition(int code, const char *customLabel = "");
|
||||
};
|
||||
|
||||
#endif
|
||||
86
src/main.cpp
86
src/main.cpp
@@ -1,6 +1,8 @@
|
||||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <LedMatrix.h>
|
||||
#include <ColorSerial.h>
|
||||
#include <FastLED.h>
|
||||
#include <MyClass.h>
|
||||
#include <BlinkInternLed.h>
|
||||
@@ -93,9 +95,26 @@ void setupMatrix()
|
||||
matrix.show();
|
||||
}
|
||||
|
||||
void get_json_data()
|
||||
void connect_wifi()
|
||||
{
|
||||
Serial.println("get_json_data()");
|
||||
// For Wokwi simulation - use simulated WiFi
|
||||
Serial.println("Connecting to WiFi...");
|
||||
|
||||
// In Wokwi, WiFi connects automatically in simulation
|
||||
WiFi.begin("Wokwi-GUEST", ""); // Wokwi's simulated WiFi
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(250);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nConnected to WiFi!");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void json_with_WiFiClient()
|
||||
{
|
||||
Serial.println("json_with_WiFiClient()");
|
||||
|
||||
WiFiClient client;
|
||||
const int timeout = 5000; // 5 second timeout
|
||||
@@ -176,21 +195,54 @@ void get_json_data()
|
||||
}
|
||||
}
|
||||
|
||||
void connect_wifi()
|
||||
void json_with_HTTPClient()
|
||||
{
|
||||
// For Wokwi simulation - use simulated WiFi
|
||||
Serial.println("Connecting to WiFi...");
|
||||
Serial.println("json_with_HTTPClient()");
|
||||
|
||||
// In Wokwi, WiFi connects automatically in simulation
|
||||
WiFi.begin("Wokwi-GUEST", ""); // Wokwi's simulated WiFi
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
HTTPClient http;
|
||||
|
||||
http.begin("http://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true");
|
||||
// http.setTimeout(5000);
|
||||
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode != HTTP_CODE_OK)
|
||||
{
|
||||
delay(250);
|
||||
Serial.print(".");
|
||||
Serial.printf("HTTP error: %d\n", httpCode);
|
||||
http.end();
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println("connected to api.open-meteo.com :-)");
|
||||
Serial.println("=== Full Response Complete ===");
|
||||
|
||||
String payload = http.getString();
|
||||
http.end();
|
||||
|
||||
Serial.println(payload);
|
||||
|
||||
// JSON parsen
|
||||
JsonDocument doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
|
||||
if (!error)
|
||||
{
|
||||
JsonObject current = doc["current_weather"];
|
||||
JsonObject units = doc["current_weather_units"];
|
||||
|
||||
float temperature = current["temperature"];
|
||||
String temp_unit = units["temperature"];
|
||||
|
||||
Serial.printf("Temperature: %.1f %s", temperature, temp_unit.c_str());
|
||||
Serial.println();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("JSON parse failed");
|
||||
Serial.println(error.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
Serial.println("\nConnected to WiFi!");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void setup()
|
||||
@@ -200,14 +252,16 @@ void setup()
|
||||
|
||||
// Wait for Serial to be ready (important for some boards)
|
||||
while (!Serial)
|
||||
{
|
||||
delay(10);
|
||||
}
|
||||
|
||||
ColorSerial::header("PICO W WEATHER STATION");
|
||||
ColorSerial::info("System starting up", "v1.0");
|
||||
|
||||
connect_wifi();
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
get_json_data();
|
||||
json_with_WiFiClient();
|
||||
json_with_HTTPClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user