- App transistion is now inacitve if there is only 1 app
- Adds bargraph to notify and customapps
- Every awtrix now gets a unique id for AP, MQTT and HA
- Adds firmware as HA sensor
- Adds wifi strength as HA sensor
- Adds ram usage as HA sensor
- Adds version as HA sensor
- Adds uptime as ISO 8601 as HA sensot
- HA discorvery now gets correct device classes
- fixes bug where date formats are not saved

closes #24
closes #23
closes #21
This commit is contained in:
Stephan Mühl
2023-03-29 00:24:38 +02:00
parent 3de324605e
commit c51c769cb5
16 changed files with 1217 additions and 967 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -12,12 +12,17 @@
#include "Functions.h"
#include "ServerManager.h"
#include "MenuManager.h"
#include "Frames.h"
#include "Apps.h"
Ticker AlarmTicker;
Ticker TimerTicker;
#ifdef ULANZI
#define MATRIX_PIN 32
#else
#define MATRIX_PIN D2
#endif
#define MATRIX_WIDTH 32
#define MATRIX_HEIGHT 8
@@ -68,6 +73,11 @@ void DisplayManager_::MatrixState(bool on)
bool DisplayManager_::setAutoTransition(bool active)
{
if (ui.AppCount < 2)
{
ui.disablesetAutoTransition();
return false;
}
if (active && AUTO_TRANSITION)
{
ui.enablesetAutoTransition();
@@ -198,31 +208,31 @@ void DisplayManager_::HSVtext(int16_t x, int16_t y, const char *text, bool clear
matrix.show();
}
void pushCustomFrame(String name, int position)
void pushCustomApp(String name, int position)
{
if (customFrames.count(name) == 0)
if (customApps.count(name) == 0)
{
++customPagesCount;
void (*customFrames[10])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CFrame1, CFrame2, CFrame3, CFrame4, CFrame5, CFrame6, CFrame7, CFrame8, CFrame9, CFrame10};
void (*customApps[10])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CApp1, CApp2, CApp3, CApp4, CApp5, CApp6, CApp7, CApp8, CApp9, CApp10};
if (position < 0) // Insert at the end of the vector
{
Apps.push_back(std::make_pair(name, customFrames[customPagesCount]));
Apps.push_back(std::make_pair(name, customApps[customPagesCount]));
}
else if (position < Apps.size()) // Insert at a specific position
{
Apps.insert(Apps.begin() + position, std::make_pair(name, customFrames[customPagesCount]));
Apps.insert(Apps.begin() + position, std::make_pair(name, customApps[customPagesCount]));
}
else // Invalid position, Insert at the end of the vector
{
Apps.push_back(std::make_pair(name, customFrames[customPagesCount]));
Apps.push_back(std::make_pair(name, customApps[customPagesCount]));
}
ui.setApps(Apps); // Add frames
ui.setApps(Apps); // Add Apps
}
}
void removeCustomFrame(const String &name)
void removeCustomApp(const String &name)
{
auto it = std::find_if(Apps.begin(), Apps.end(), [&name](const std::pair<String, AppCallback> &appPair)
{ return appPair.first == name; });
@@ -236,10 +246,10 @@ void removeCustomFrame(const String &name)
void DisplayManager_::generateCustomPage(String name, String payload)
{
if (payload == "" && customFrames.count(name))
if (payload == "" && customApps.count(name))
{
customFrames.erase(customFrames.find(name));
removeCustomFrame(name);
customApps.erase(customApps.find(name));
removeCustomApp(name);
return;
}
@@ -248,31 +258,52 @@ void DisplayManager_::generateCustomPage(String name, String payload)
if (error)
return;
CustomFrame customFrame;
CustomApp customApp;
if (doc.containsKey("sound"))
{
customFrame.sound = ("/" + doc["sound"].as<String>() + ".txt");
customApp.sound = ("/" + doc["sound"].as<String>() + ".txt");
}
else
{
customFrame.sound = "";
customApp.sound = "";
}
customFrame.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
customFrame.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
customFrame.name = name;
customFrame.text = utf8ascii(doc["text"].as<String>());
customFrame.color = doc.containsKey("color") ? doc["color"].is<String>() ? hexToRgb565(doc["color"]) : doc["color"].is<JsonArray>() ? hexToRgb565(doc["color"].as<String>())
: TEXTCOLOR_565
: TEXTCOLOR_565;
if (currentCustomFrame != name)
if (doc.containsKey("bar"))
{
customFrame.scrollposition = 9;
JsonArray barData = doc["bar"];
int i = 0;
for (JsonVariant v : barData)
{
if (i >= 16)
{
break;
}
customApp.barData[i] = v.as<int>();
i++;
}
customApp.barSize = i;
}
else
{
customApp.barSize = 0;
}
customFrame.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint8_t>() : -1;
int pos = doc.containsKey("pos") ? doc["pos"].as<uint8_t>() : -1;
customApp.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
customApp.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
customApp.name = name;
customApp.text = utf8ascii(doc["text"].as<String>());
customApp.color = doc.containsKey("color") ? doc["color"].is<String>() ? hexToRgb565(doc["color"]) : doc["color"].is<JsonArray>() ? hexToRgb565(doc["color"].as<String>())
: TEXTCOLOR_565
: TEXTCOLOR_565;
if (currentCustomApp != name)
{
customApp.scrollposition = 9;
}
customApp.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint8_t>() : -1;
if (doc.containsKey("icon"))
{
@@ -280,20 +311,28 @@ void DisplayManager_::generateCustomPage(String name, String payload)
if (LittleFS.exists("/ICONS/" + iconFileName + ".jpg"))
{
customFrame.isGif = false;
customFrame.icon = LittleFS.open("/ICONS/" + iconFileName + ".jpg");
customApp.isGif = false;
customApp.icon = LittleFS.open("/ICONS/" + iconFileName + ".jpg");
}
else if (LittleFS.exists("/ICONS/" + iconFileName + ".gif"))
{
customFrame.isGif = true;
customFrame.icon = LittleFS.open("/ICONS/" + iconFileName + ".gif");
customApp.isGif = true;
customApp.icon = LittleFS.open("/ICONS/" + iconFileName + ".gif");
}
else
{
fs::File nullPointer;
customApp.icon = nullPointer;
}
}
else
{
fs::File nullPointer;
customApp.icon = nullPointer;
}
int pos = doc.containsKey("pos") ? doc["pos"].as<uint8_t>() : -1;
pushCustomFrame(name, pos - 1);
customFrames[name] = customFrame;
pushCustomApp(name, pos - 1);
customApps[name] = customApp;
}
void DisplayManager_::generateNotification(String payload)
@@ -318,6 +357,26 @@ void DisplayManager_::generateNotification(String payload)
PeripheryManager.playFromFile("/MELODIES/" + doc["sound"].as<String>() + ".txt");
}
if (doc.containsKey("bar"))
{
JsonArray barData = doc["bar"];
int i = 0;
for (JsonVariant v : barData)
{
if (i >= 16)
{
break;
}
notify.barData[i] = v.as<int>();
i++;
}
notify.barSize = i;
}
else
{
notify.barSize = 0;
}
notify.color = doc.containsKey("color") ? doc["color"].is<String>() ? hexToRgb565(doc["color"]) : doc["color"].is<JsonArray>() ? hexToRgb565(doc["color"].as<String>())
: TEXTCOLOR_565
: TEXTCOLOR_565;
@@ -329,17 +388,24 @@ void DisplayManager_::generateNotification(String payload)
{
notify.isGif = false;
notify.icon = LittleFS.open("/ICONS/" + iconFileName + ".jpg");
return;
}
else if (LittleFS.exists("/ICONS/" + iconFileName + ".gif"))
{
notify.isGif = true;
notify.icon = LittleFS.open("/ICONS/" + iconFileName + ".gif");
return;
}
else
{
fs::File nullPointer;
notify.icon = nullPointer;
}
}
else
{
File f;
notify.icon = f;
fs::File nullPointer;
notify.icon = nullPointer;
}
}
@@ -374,25 +440,23 @@ void DisplayManager_::loadNativeApps()
};
// Update the "time" app at position 0
updateApp("time", TimeFrame, SHOW_TIME, 0);
updateApp("time", TimeApp, SHOW_TIME, 0);
// Update the "date" app at position 1
updateApp("date", DateFrame, SHOW_DATE, 1);
updateApp("date", DateApp, SHOW_DATE, 1);
// Update the "temp" app at position 2
updateApp("temp", TempFrame, SHOW_TEMP, 2);
updateApp("temp", TempApp, SHOW_TEMP, 2);
// Update the "hum" app at position 3
updateApp("hum", HumFrame, SHOW_HUM, 3);
updateApp("hum", HumApp, SHOW_HUM, 3);
// Update the "bat" app at position 4
updateApp("bat", BatFrame, SHOW_BAT, 4);
updateApp("bat", BatApp, SHOW_BAT, 4);
ui.setApps(Apps);
if (AUTO_TRANSITION && Apps.size() == 1)
{
setAutoTransition(false);
}
setAutoTransition(true);
}
void DisplayManager_::setup()
@@ -415,12 +479,12 @@ void DisplayManager_::tick()
else
{
ui.update();
if (ui.getUiState()->frameState == IN_TRANSITION && !appIsSwitching)
if (ui.getUiState()->appState == IN_TRANSITION && !appIsSwitching)
{
appIsSwitching = true;
MQTTManager.setCurrentApp(CURRENT_APP);
}
else if (ui.getUiState()->frameState == FIXED && appIsSwitching)
else if (ui.getUiState()->appState == FIXED && appIsSwitching)
{
appIsSwitching = false;
MQTTManager.setCurrentApp(CURRENT_APP);
@@ -593,4 +657,50 @@ void DisplayManager_::drawMenuIndicator(int cur, int total, uint16_t color)
matrix.drawLine(x, 7, x + menuItemWidth - 1, 7, matrix.Color(100, 100, 100));
}
}
}
void DisplayManager_::drawBarChart(int16_t x, int16_t y, const int data[], byte dataSize, bool withIcon, uint16_t color)
{
int maximum = 0;
int newData[dataSize];
// Finde das Maximum in der Datenliste
for (int i = 0; i < dataSize; i++)
{
int d = data[i];
if (d > maximum)
{
maximum = d;
}
}
// Berechne neue Datenwerte zwischen 0 und 8 basierend auf dem Maximum
for (int i = 0; i < dataSize; i++)
{
int d = data[i];
newData[i] = map(d, 0, maximum, 0, 8);
}
// Berechne die Breite der Balken basierend auf der Anzahl der Daten und der Breite der Matrix
int barWidth;
if (withIcon)
{
barWidth = ((32 - 9) / (dataSize)-1);
}
else
{
barWidth = (32 / (dataSize)-1);
}
// Berechne die Startposition des Graphen basierend auf dem Icon-Parameter
int startX = withIcon ? 9 : 0;
// Zeichne die Balken auf die Matrix
for (int i = 0; i < dataSize; i++)
{
int x1 = x + startX + (barWidth + 1) * i;
int barHeight = newData[i];
int y1 = min(8 - barHeight, 7);
matrix.fillRect(x1, y1 + y, barWidth, barHeight, color);
}
}

View File

@@ -56,6 +56,7 @@ public:
void drawProgressBar(int cur, int total);
void drawMenuIndicator(int cur, int total, uint16_t color);
void drawBMP(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h);
void drawBarChart(int16_t x, int16_t y,const int data[], byte dataSize, bool withIcon, uint16_t color);
};
extern DisplayManager_ &DisplayManager;

View File

@@ -528,7 +528,7 @@ public:
}
}
needNewFrame = false;
lastFrameTime = millis();
lastFrameTime = millis();
}
public:
@@ -612,7 +612,6 @@ public:
byte b = readByte();
if (b == 0x2c)
{
Serial.println("Parse");
parseTableBasedImage();
return 0;
}
@@ -641,11 +640,10 @@ public:
{
done = true;
file.seek(0);
Serial.println("Finished");
parseGifHeader();
parseLogicalScreenDescriptor();
parseGlobalColorTable();
drawFrame(offsetX,offsetY);
drawFrame(offsetX, offsetY);
return ERROR_FINISHED;
}
}

View File

@@ -1,8 +1,18 @@
#include "Globals.h"
#include "Preferences.h"
#include <WiFi.h>
Preferences Settings;
char *getID()
{
uint8_t mac[6];
WiFi.macAddress(mac);
char *macStr = new char[24];
snprintf(macStr, 24, "awtrix_%02x%02x%02x", mac[3], mac[4], mac[5]);
return macStr;
}
void loadSettings()
{
Settings.begin("awtrix", false);
@@ -23,6 +33,8 @@ void loadSettings()
SHOW_HUM = Settings.getBool("HUM", true);
SHOW_BAT = Settings.getBool("BAT", true);
Settings.end();
uniqueID = getID();
MQTT_PREFIX = String(uniqueID);
}
void saveSettings()
@@ -39,7 +51,6 @@ void saveSettings()
Settings.putString("DFORMAT", DATE_FORMAT);
Settings.putBool("SOM", START_ON_MONDAY);
Settings.putBool("CEL", IS_CELSIUS);
Settings.putBool("TIM", SHOW_TIME);
Settings.putBool("DAT", SHOW_DATE);
Settings.putBool("TEMP", SHOW_TEMP);
@@ -48,17 +59,18 @@ void saveSettings()
Settings.end();
}
const char *uniqueID;
IPAddress local_IP;
IPAddress gateway;
IPAddress subnet;
IPAddress primaryDNS;
IPAddress secondaryDNS;
const char *VERSION = "0.41";
const char *VERSION = "0.42";
String MQTT_HOST = "";
uint16_t MQTT_PORT = 1883;
String MQTT_USER;
String MQTT_PASS;
String MQTT_PREFIX = "AwtrixLight";
String MQTT_PREFIX;
String CITY = "Berlin,de";
bool IO_BROKER = false;
bool NET_STATIC = false;

View File

@@ -2,6 +2,7 @@
#define GLOBALS_H
#include <Arduino.h>
extern const char *uniqueID;
extern const char *VERSION;
extern IPAddress local_IP;
extern IPAddress gateway;

View File

@@ -6,24 +6,32 @@
#include <WiFi.h>
#include <ArduinoJson.h>
unsigned long startTime;
WiFiClient espClient;
uint8_t lastBrightness;
HADevice device;
HAMqtt mqtt(espClient, device, 15);
HAMqtt mqtt(espClient, device, 18);
unsigned long reconnectTimer = 0;
const unsigned long reconnectInterval = 30000; // 30 Sekunden
HALight Matrix("bri", HALight::BrightnessFeature | HALight::RGBFeature);
HASelect BriMode("BriMode");
HAButton dismiss("myButtonA");
HAButton nextApp("myButtonB");
HAButton prevApp("myButtonC");
HASensor curApp("curApp");
HASensor battery("battery");
HASensor temperature("temperature");
HASensor humidity("huminity");
HASensor illuminance("illuminance");
HALight *Matrix = nullptr;
HASelect *BriMode = nullptr;
HAButton *dismiss = nullptr;
HAButton *nextApp = nullptr;
HAButton *prevApp = nullptr;
HASensor *curApp = nullptr;
HASensor *battery = nullptr;
HASensor *temperature = nullptr;
HASensor *humidity = nullptr;
HASensor *illuminance = nullptr;
HASensor *uptime = nullptr;
HASensor *strength = nullptr;
HASensor *version = nullptr;
HASensor *ram = nullptr;
// The getter for the instantiated singleton instance
MQTTManager_ &MQTTManager_::getInstance()
@@ -37,15 +45,15 @@ MQTTManager_ &MQTTManager = MQTTManager.getInstance();
void onButtonCommand(HAButton *sender)
{
if (sender == &dismiss)
if (sender == dismiss)
{
DisplayManager.dismissNotify();
}
else if (sender == &nextApp)
else if (sender == nextApp)
{
DisplayManager.nextApp();
}
else if (sender == &prevApp)
else if (sender == prevApp)
{
DisplayManager.previousApp();
}
@@ -66,7 +74,7 @@ void onSelectCommand(int8_t index, HASelect *sender)
AUTO_BRIGHTNESS = true;
return;
}
Matrix.setBrightness(BRIGHTNESS);
Matrix->setBrightness(BRIGHTNESS);
saveSettings();
sender->setState(index); // report the selected option back to the HA panel
}
@@ -203,71 +211,128 @@ void connect()
}
}
char matID[40], briID[40];
char btnAID[40], btnBID[40], btnCID[40], appID[40], tempID[40], humID[40], luxID[40], verID[40], batID[40], ramID[40], upID[40], sigID[40];
void MQTTManager_::setup()
{
byte mac[6];
WiFi.macAddress(mac);
startTime = millis();
if (HA_DISCOVERY)
{
Serial.println("Starting Homeassistant discorvery");
uint8_t mac[6];
WiFi.macAddress(mac);
char *macStr = new char[18 + 1];
snprintf(macStr, 24, "%02x%02x%02x", mac[3], mac[4], mac[5]);
device.setUniqueId(mac, sizeof(mac));
device.setName(MQTT_PREFIX.c_str());
device.setName(uniqueID);
device.setSoftwareVersion(VERSION);
device.setManufacturer("Blueforcer");
device.setModel("AWTRIX Light");
device.setAvailability(true);
Matrix.setIcon("mdi:lightbulb");
Matrix.setName("Matrix");
Matrix.onStateCommand(onStateCommand);
Matrix.onBrightnessCommand(onBrightnessCommand);
Matrix.onRGBColorCommand(onRGBColorCommand);
Matrix.setCurrentState(true);
Matrix.setBRIGHTNESS(BRIGHTNESS);
String uniqueIDWithSuffix;
sprintf(matID, "%s_mat", macStr);
Matrix = new HALight(matID, HALight::BrightnessFeature | HALight::RGBFeature);
Matrix->setIcon("mdi:lightbulb");
Matrix->setName("Matrix");
Matrix->onStateCommand(onStateCommand);
Matrix->onBrightnessCommand(onBrightnessCommand);
Matrix->onRGBColorCommand(onRGBColorCommand);
Matrix->setCurrentState(true);
Matrix->setBRIGHTNESS(BRIGHTNESS);
HALight::RGBColor color;
color.red = (TEXTCOLOR_565 >> 11) << 3;
color.green = ((TEXTCOLOR_565 >> 5) & 0x3F) << 2;
color.blue = (TEXTCOLOR_565 & 0x1F) << 3;
Matrix.setCurrentRGBColor(color);
Matrix.setState(true, true);
Matrix->setCurrentRGBColor(color);
Matrix->setState(true, true);
BriMode.setOptions("Manual;Auto"); // use semicolons as separator of options
BriMode.onCommand(onSelectCommand);
BriMode.setIcon("mdi:brightness-auto"); // optional
BriMode.setName("Brightness mode"); // optional
BriMode.setState(AUTO_BRIGHTNESS, true);
sprintf(briID, "%s_bri", macStr);
BriMode = new HASelect(briID);
BriMode->setOptions("Manual;Auto"); // use semicolons as separator of options
BriMode->onCommand(onSelectCommand);
BriMode->setIcon("mdi:brightness-auto"); // optional
BriMode->setName("Brightness mode"); // optional
BriMode->setState(AUTO_BRIGHTNESS, true);
dismiss.setIcon("mdi:bell-off");
dismiss.setName("Dismiss notification");
nextApp.setIcon("mdi:arrow-right-bold");
nextApp.setName("Next app");
prevApp.setIcon("mdi:arrow-left-bold");
prevApp.setName("Previous app");
sprintf(btnAID, "%s_btna", macStr);
dismiss = new HAButton(btnAID);
dismiss->setIcon("mdi:bell-off");
dismiss->setName("Dismiss notification");
dismiss.onCommand(onButtonCommand);
nextApp.onCommand(onButtonCommand);
prevApp.onCommand(onButtonCommand);
sprintf(btnBID, "%s_btnb", macStr);
nextApp = new HAButton(btnBID);
nextApp->setIcon("mdi:arrow-right-bold");
nextApp->setName("Next app");
curApp.setIcon("mdi:apps");
curApp.setName("Current app");
sprintf(btnCID, "%s_btnc", macStr);
prevApp = new HAButton(btnCID);
prevApp->setIcon("mdi:arrow-left-bold");
prevApp->setName("Previous app");
temperature.setIcon("mdi:thermometer");
temperature.setName("Temperature");
temperature.setUnitOfMeasurement("°C");
dismiss->onCommand(onButtonCommand);
nextApp->onCommand(onButtonCommand);
prevApp->onCommand(onButtonCommand);
humidity.setIcon("mdi:water-percent");
humidity.setName("humidity");
humidity.setUnitOfMeasurement("%");
sprintf(appID, "%s_app", macStr);
curApp = new HASensor(appID);
curApp->setIcon("mdi:apps");
curApp->setName("Current app");
battery.setIcon("mdi:battery-90");
battery.setName("Battery");
battery.setUnitOfMeasurement("%");
sprintf(tempID, "%s_temp", macStr);
temperature = new HASensor(tempID);
temperature->setIcon("mdi:thermometer");
temperature->setName("Temperature");
temperature->setDeviceClass("temperature");
temperature->setUnitOfMeasurement("°C");
illuminance.setIcon("mdi:sun-wireless");
illuminance.setName("Illuminance");
illuminance.setUnitOfMeasurement("lx");
sprintf(humID, "%s_hum", macStr);
humidity = new HASensor(humID);
humidity->setIcon("mdi:water-percent");
humidity->setName("humidity");
humidity->setDeviceClass("humidity");
humidity->setUnitOfMeasurement("%");
sprintf(batID, "%s_bat", macStr);
battery = new HASensor(batID);
battery->setIcon("mdi:battery-90");
battery->setName("Battery");
battery->setDeviceClass("battery");
battery->setUnitOfMeasurement("%");
sprintf(luxID, "%s_lux", macStr);
illuminance = new HASensor(luxID);
illuminance->setIcon("mdi:sun-wireless");
illuminance->setName("Illuminance");
illuminance->setDeviceClass("illuminance");
illuminance->setUnitOfMeasurement("lx");
sprintf(verID, "%s_ver", macStr);
version = new HASensor(verID);
version->setName("Version");
sprintf(sigID, "%s_sig", macStr);
strength = new HASensor(sigID);
strength->setName("WiFi strength");
strength->setDeviceClass("signal_strength");
strength->setUnitOfMeasurement("dB");
sprintf(upID, "%s_up", macStr);
uptime = new HASensor(upID);
uptime->setName("Uptime");
uptime->setDeviceClass("duration");
sprintf(ramID, "%s_ram", macStr);
ram = new HASensor(ramID);
ram->setDeviceClass("data_size");
ram->setIcon("mdi:application-cog");
ram->setName("Free ram");
ram->setUnitOfMeasurement("B");
}
else
{
@@ -299,7 +364,23 @@ void MQTTManager_::publish(const char *topic, const char *payload)
void MQTTManager_::setCurrentApp(String value)
{
if (HA_DISCOVERY)
curApp.setValue(value.c_str());
curApp->setValue(value.c_str());
}
const char *readUptime()
{
static char uptime[25]; // Make the array static to keep it from being destroyed when the function returns
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - startTime;
unsigned long uptimeSeconds = elapsedTime / 1000;
unsigned long uptimeMinutes = uptimeSeconds / 60;
unsigned long uptimeHours = uptimeMinutes / 60;
unsigned long uptimeDays = uptimeHours / 24;
unsigned long hours = uptimeHours % 24;
unsigned long minutes = uptimeMinutes % 60;
unsigned long seconds = uptimeSeconds % 60;
sprintf(uptime, "P%dDT%dH%dM%dS", uptimeDays, hours, minutes, seconds);
return uptime;
}
void MQTTManager_::sendStats()
@@ -308,20 +389,32 @@ void MQTTManager_::sendStats()
{
char buffer[5];
snprintf(buffer, 5, "%d", BATTERY_PERCENT);
battery.setValue(buffer);
battery->setValue(buffer);
snprintf(buffer, 5, "%.0f", CURRENT_TEMP);
temperature.setValue(buffer);
temperature->setValue(buffer);
snprintf(buffer, 5, "%.0f", CURRENT_HUM);
humidity.setValue(buffer);
humidity->setValue(buffer);
snprintf(buffer, 5, "%.0f", CURRENT_LUX);
illuminance.setValue(buffer);
illuminance->setValue(buffer);
BriMode.setState(AUTO_BRIGHTNESS, true);
Matrix.setBRIGHTNESS(BRIGHTNESS);
Matrix.setState(!MATRIX_OFF, false);
BriMode->setState(AUTO_BRIGHTNESS, true);
Matrix->setBRIGHTNESS(BRIGHTNESS);
Matrix->setState(!MATRIX_OFF, false);
int8_t rssiValue = WiFi.RSSI();
char rssiString[4];
snprintf(rssiString, sizeof(rssiString), "%d", rssiValue);
strength->setValue(rssiString);
char rambuffer[10];
int freeHeapBytes = ESP.getFreeHeap();
itoa(freeHeapBytes, rambuffer, 10);
ram->setValue(rambuffer);
uptime->setValue(readUptime());
version->setValue(VERSION);
}
StaticJsonDocument<200> doc;
@@ -336,6 +429,8 @@ void MQTTManager_::sendStats()
doc["temp"] = buffer;
snprintf(buffer, 5, "%.0f", CURRENT_HUM);
doc["hum"] = buffer;
doc["uptime"] = readUptime();
doc["wifi"] = WiFi.RSSI();
String jsonString;
serializeJson(doc, jsonString);
char topic[50];

View File

@@ -135,26 +135,20 @@ String MenuManager_::menutext()
return String(TIME_PER_APP / 1000.0, 0) + "s";
case TimeFormatMenu:
DisplayManager.drawMenuIndicator(timeFormatIndex, timeFormatCount, 0xFBC0);
char display[9];
if (timeFormat[timeFormatIndex][2] == ' ')
{
strcpy(display, timeFormat[timeFormatIndex]);
if (now % 2)
{
display[2] = ' ';
}
else
{
display[2] = ':';
}
strftime(t, sizeof(t), display, localtime(&now));
return t;
snprintf(display, sizeof(display), "%s", timeFormat[timeFormatIndex]);
display[2] = now % 2 ? ' ' : ':';
}
else
{
strftime(t, sizeof(t), timeFormat[timeFormatIndex], localtime(&now));
return t;
snprintf(display, sizeof(display), "%s", timeFormat[timeFormatIndex]);
}
strftime(t, sizeof(t), display, localtime(&now));
return t;
case DateFormatMenu:
DisplayManager.drawMenuIndicator(dateFormatIndex, dateFormatCount, 0xFBC0);
strftime(t, sizeof(t), dateFormat[dateFormatIndex], localtime(&now));
@@ -427,6 +421,8 @@ void MenuManager_::selectButtonLong()
saveSettings();
break;
case DateFormatMenu:
DATE_FORMAT = dateFormat[dateFormatIndex];
saveSettings();
case WeekdayMenu:
case TempMenu:
saveSettings();

View File

@@ -10,12 +10,25 @@
#include <MenuManager.h>
#define SOUND_OFF false
#define BATTERY_PIN 34
#define BUZZER_PIN 15
#define LDR_PIN 35
#define BUTTON_UP_PIN 26
#define BUTTON_DOWN_PIN 14
#define BUTTON_SELECT_PIN 27
#ifdef ULANZI
// Pinouts für das ULANZI-Environment
#define BATTERY_PIN 34
#define BUZZER_PIN 15
#define LDR_PIN 35
#define BUTTON_UP_PIN 26
#define BUTTON_DOWN_PIN 14
#define BUTTON_SELECT_PIN 27
#else
// Pinouts für das WEMOS_D1_MINI32-Environment
#define BATTERY_PIN -1
#define BUZZER_PIN -1
#define LDR_PIN A0
#define BUTTON_UP_PIN D0
#define BUTTON_DOWN_PIN D4
#define BUTTON_SELECT_PIN D8
#endif
Adafruit_SHT31 sht31;
EasyButton button_left(BUTTON_UP_PIN);
@@ -45,7 +58,7 @@ float sampleSum = 0.0;
float sampleAverage = 0.0;
float brightnessPercent = 0.0;
unsigned long startTime;
// The getter for the instantiated singleton instance
PeripheryManager_ &PeripheryManager_::getInstance()
@@ -100,7 +113,6 @@ void PeripheryManager_::playBootSound()
const int nNotes = 6;
String notes[nNotes] = {"E5", "C5", "G4", "E4", "G4", "C5"};
const int timeUnit = 150;
// create a melody
Melody melody = MelodyFactory.load("Nice Melody", timeUnit, notes, nNotes);
player.playAsync(melody);
}
@@ -128,7 +140,7 @@ void fistStart()
uint16_t ADCVALUE = analogRead(BATTERY_PIN);
BATTERY_PERCENT = min((int)map(ADCVALUE, 510, 660, 0, 100), 100);
BATTERY_PERCENT = min((int)map(ADCVALUE, 490, 660, 0, 100), 100);
sht31.readBoth(&CURRENT_TEMP, &CURRENT_HUM);
uint16_t LDRVALUE = analogRead(LDR_PIN);
@@ -167,7 +179,7 @@ void PeripheryManager_::tick()
{
previousMillis_BatTempHum = currentMillis_BatTempHum;
uint16_t ADCVALUE = analogRead(BATTERY_PIN);
BATTERY_PERCENT = min((int)map(ADCVALUE, 510, 665, 0, 100), 100);
BATTERY_PERCENT = min((int)map(ADCVALUE, 475, 665, 0, 100), 100);
BATTERY_RAW = ADCVALUE;
sht31.readBoth(&CURRENT_TEMP, &CURRENT_HUM);
CURRENT_TEMP -= 9.0;
@@ -200,16 +212,7 @@ void PeripheryManager_::tick()
}
}
void readUptime()
{
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - startTime;
int hours = (elapsedTime / 1000) / 3600;
int minutes = ((elapsedTime / 1000) % 3600) / 60;
int seconds = (elapsedTime / 1000) % 60;
char timeString[10];
sprintf(timeString, "%02d:%02d:%02d", hours, minutes, seconds);
}
const int MIN_ALARM_INTERVAL = 60; // 1 Minute
time_t lastAlarmTime = 0;

View File

@@ -63,7 +63,7 @@ void ServerManager_::setup()
{
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
}
IPAddress myIP = mws.startWiFi(150000, "AWTRIX LIGHT", "12345678");
IPAddress myIP = mws.startWiFi(150000, uniqueID, "12345678");
isConnected = !(myIP == IPAddress(192, 168, 4, 1));
Serial.println(myIP.toString());
@@ -99,7 +99,7 @@ void ServerManager_::setup()
mws.addHandler("/version", HTTP_GET, versionHandler);
mws.begin();
if (!MDNS.begin(MQTT_PREFIX.c_str()))
if (!MDNS.begin(uniqueID))
{
Serial.println("Error starting mDNS");
return;