454 lines
10 KiB
C++
454 lines
10 KiB
C++
#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();
|
||
} |