Files
weather-info/lib/Utils/src/ColorSerial.cpp
2025-11-09 14:13:01 +01:00

454 lines
10 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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 *temp_unit, 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(temp_unit);
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, const 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::boxHeader(const char *title, int width)
{
int titleLen = strlen(title);
int padding = (width - titleLen - 4) / 2; // -4 für die Box-Ränder
Serial.println();
// Top line
Serial.print(MAGENTA);
Serial.print("");
for (int i = 0; i < width - 2; i++)
{
Serial.print("");
}
Serial.print("");
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);
// Padding nach dem Titel
// for (int i = 0; i < (width - titleLen - padding - 4); i++)
for (int i = 0; i < (width - titleLen - padding - 2); i++)
{
Serial.print(" ");
}
Serial.print(MAGENTA);
Serial.print("");
Serial.print(RESET);
Serial.println();
// Bottom line
Serial.print(MAGENTA);
Serial.print("");
for (int i = 0; i < width - 2; i++)
{
Serial.print("");
}
Serial.print("");
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();
}