diff --git a/docs/api.md b/docs/api.md index 1d34f21d..5cac80e7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -45,7 +45,9 @@ Send the board in deep sleep mode (turns off the matrix as well), good for savin | MQTT Topic | HTTP URL | Payload/Body | HTTP Method | | ---------------- | ----------------------------- | ------------------------- | ----------- | | `[PREFIX]/sleep` | `http://[IP]/api/sleep` | `{"sleep": X}` where X is number of seconds | POST | - + +AWTRIX will only wakeup after time or if you press the middle button once. There is no way to wake up via API. + ## Sound Playback Play a RTTTL sound from the MELODIES folder: diff --git a/docs/dev.md b/docs/dev.md index 3ee9d990..71aa0857 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -30,3 +30,4 @@ The JSON object has the following properties: | `background_effect` | string | Sets an [effect](https://blueforcer.github.io/awtrix-light/#/effects) as global background layer | - | | `stats_interval` | integer | Sets the interval in milliseconds when awtrix should send its stats to HA and MQTT | 10000 | | `debug_mode` | boolean | Enables serial debug outputs. | false | +| `dfplayer` | boolean | Enables DFPLayer for Awtrix2_conversation builds. | false | \ No newline at end of file diff --git a/src/Apps.h b/src/Apps.h index d88f8c85..9655a202 100644 --- a/src/Apps.h +++ b/src/Apps.h @@ -56,7 +56,7 @@ struct CustomApp int barSize; int lineSize; long lastUpdate; - int16_t lifetime; + uint64_t lifetime; std::vector colors; std::vector fragments; int textOffset; @@ -566,7 +566,14 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState } if (!noScrolling) { - DisplayManager.drawLine(iconWidth + x + ca->iconPosition, 0 + y, iconWidth + x + ca->iconPosition, 6 + y, ca->background); + if (ca->progress > -1) + { + DisplayManager.drawLine(iconWidth + x + ca->iconPosition, 0 + y, iconWidth + x + ca->iconPosition, 6 + y, ca->background); + } + else + { + DisplayManager.drawLine(iconWidth + x + ca->iconPosition, 0 + y, iconWidth + x + ca->iconPosition, 7 + y, ca->background); + } } } @@ -865,7 +872,14 @@ void NotifyOverlay(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPl } if (!noScrolling) { - DisplayManager.drawLine(iconWidth + notifications[0].iconPosition + notifications[0].iconOffset, 0, iconWidth + notifications[0].iconPosition, 6, notifications[0].background); + if (notifications[0].progress > -1) + { + DisplayManager.drawLine(iconWidth + notifications[0].iconPosition + notifications[0].iconOffset, 0, iconWidth + notifications[0].iconPosition, 6, notifications[0].background); + } + else + { + DisplayManager.drawLine(iconWidth + notifications[0].iconPosition + notifications[0].iconOffset, 0, iconWidth + notifications[0].iconPosition, 7, notifications[0].background); + } } } diff --git a/src/AwtrixFont.h b/src/AwtrixFont.h index 738a9482..79c9b164 100644 --- a/src/AwtrixFont.h +++ b/src/AwtrixFont.h @@ -142,7 +142,7 @@ const uint8_t AwtrixBitmaps[] PROGMEM = { 0xA0, 0xA0, 0x60, 0x20, 0x40, /*[89] 0x79 y */ 0xE0, 0x60, 0xC0, 0xE0, /*[90] 0x7A z */ 0x60, 0x40, 0x80, 0x40, 0x60, /*[91] 0x7B braceleft */ - 0x80, 0x80, 0x00, 0x80, 0x80, /*[92] 0x7C bar */ + 0x80, 0x80, 0x80, 0x80, 0x80, /*[92] 0x7C bar */ 0xC0, 0x40, 0x20, 0x40, 0xC0, /*[93] 0x7D braceright */ 0x60, 0xC0, /*[94] 0x7E asciitilde */ diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp index 0b4e3895..ec04f691 100644 --- a/src/DisplayManager.cpp +++ b/src/DisplayManager.cpp @@ -611,7 +611,7 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo customApp.iconName = newIconName; customApp.icon.close(); customApp.iconPosition = 0; - customApp.currentFrame=0; + customApp.currentFrame = 0; } } else @@ -619,7 +619,7 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo customApp.icon.close(); customApp.iconName = ""; customApp.iconPosition = 0; - customApp.currentFrame=0; + customApp.currentFrame = 0; } customApp.gradient[0] = -1; @@ -1285,6 +1285,10 @@ void DisplayManager_::dismissNotify() bool wakeup; if (!notifications.empty()) { + if (notifications.size() >= 2) + { + notifications[1].startime = millis(); + } wakeup = notifications[0].wakeup; notifications[0].icon.close(); notifications.erase(notifications.begin()); @@ -1506,12 +1510,6 @@ void DisplayManager_::updateAppVector(const char *json) doc.clear(); } -double roundToDecimalPlaces(double value, int places) -{ - double factor = pow(10.0, places); - return round(value * factor) / factor; -} - String DisplayManager_::getStats() { StaticJsonDocument<1024> doc; @@ -1543,6 +1541,7 @@ String DisplayManager_::getStats() doc[F("indicator3")] = ui->indicator3State; doc[F("app")] = CURRENT_APP; doc[F("uid")] = uniqueID; + doc[F("matrix")] = !MATRIX_OFF; String jsonString; serializeJson(doc, jsonString); return jsonString; diff --git a/src/Functions.h b/src/Functions.h index 49263fd4..ae012e34 100644 --- a/src/Functions.h +++ b/src/Functions.h @@ -99,6 +99,11 @@ uint32_t getColorFromJsonVariant(JsonVariant colorVariant, uint32_t defaultColor return defaultColor; } +double roundToDecimalPlaces(double value, int places) +{ + double factor = pow(10.0, places); + return round(value * factor) / factor; +} float getTextWidth(const char *text, byte textCase) { diff --git a/src/Globals.cpp b/src/Globals.cpp index 1d22ab31..560053b7 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -76,6 +76,11 @@ void loadDevSettings() SENSOR_READING = doc["sensor_reading"].as(); } + if (doc.containsKey("dfplayer")) + { + DFPLAYER_ACTIVE = doc["dfplayer"].as(); + } + if (doc.containsKey("matrix")) { MATRIX_LAYOUT = doc["matrix"]; @@ -297,7 +302,7 @@ IPAddress gateway; IPAddress subnet; IPAddress primaryDNS; IPAddress secondaryDNS; -const char *VERSION = "0.88"; +const char *VERSION = "0.89"; String MQTT_HOST = ""; uint16_t MQTT_PORT = 1883; @@ -382,6 +387,7 @@ bool BLOCK_NAVIGATION = false; bool UPDATE_CHECK = false; float GAMMA = 0; bool SENSOR_READING = true; +bool DFPLAYER_ACTIVE = false; bool ROTATE_SCREEN = false; uint8_t TIME_MODE = 1; uint8_t SCROLL_SPEED = 100; @@ -398,7 +404,7 @@ bool MOODLIGHT_MODE; long STATS_INTERVAL = 10000; bool DEBUG_MODE = false; uint8_t MIN_BRIGHTNESS = 2; -uint8_t MAX_BRIGHTNESS = 180; +uint8_t MAX_BRIGHTNESS = 210; double movementFactor = 0.5; int8_t TRANS_EFFECT = 1; String AUTH_USER = ""; diff --git a/src/Globals.h b/src/Globals.h index 2eebf756..a48771f8 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -63,6 +63,7 @@ extern String NTP_SERVER; extern String NTP_TZ; extern bool HA_DISCOVERY; extern bool UPPERCASE_LETTERS; +extern bool DFPLAYER_ACTIVE; extern float CURRENT_TEMP; extern float CURRENT_HUM; extern float CURRENT_LUX; diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index 86d5e9dd..6121ba65 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -448,7 +448,7 @@ void MQTTManager_::sendStats() { if (HA_DISCOVERY && mqtt.isConnected()) { - char buffer[5]; + char buffer[8]; #ifndef awtrix2_upgrade snprintf(buffer, 5, "%d", BATTERY_PERCENT); battery->setValue(buffer); @@ -456,7 +456,7 @@ void MQTTManager_::sendStats() if (SENSOR_READING) { - snprintf(buffer, 5, "%.0f", CURRENT_TEMP); + snprintf(buffer, sizeof(buffer), "%.*f", TEMP_DECIMAL_PLACES, CURRENT_TEMP); temperature->setValue(buffer); snprintf(buffer, 5, "%.0f", CURRENT_HUM); humidity->setValue(buffer); @@ -469,9 +469,9 @@ void MQTTManager_::sendStats() Matrix->setState(!MATRIX_OFF, false); HALight::RGBColor color; color.isSet = true; - color.red = (TEXTCOLOR_888 >> 16) & 0xFF; // Die obersten 8 Bits für Rot - color.green = (TEXTCOLOR_888 >> 8) & 0xFF; // Die mittleren 8 Bits für Grün - color.blue = TEXTCOLOR_888 & 0xFF; // Die untersten 8 Bits für Blau + color.red = (TEXTCOLOR_888 >> 16) & 0xFF; + color.green = (TEXTCOLOR_888 >> 8) & 0xFF; + color.blue = TEXTCOLOR_888 & 0xFF; Matrix->setRGBColor(color); int8_t rssiValue = WiFi.RSSI(); char rssiString[4]; @@ -678,17 +678,6 @@ void MQTTManager_::setup() ram->setIcon(HAramIcon); ram->setName(HAramName); ram->setUnitOfMeasurement(HAramUnit); - - // sprintf(sSpeed, HASPEEDID, macStr); - // ScrollSpeed = new HANumber(sSpeed); - // ScrollSpeed->setDeviceClass(HAramClass); - // ScrollSpeed->setIcon(HASPEEDIcon); - // ScrollSpeed->setName(HASPEEDName); - // ScrollSpeed->onCommand(onNumberCommand); - // ScrollSpeed->setMin(40); - // ScrollSpeed->setMax(100); - // ScrollSpeed->setStep(1); - // ScrollSpeed->setCurrentState(SCROLL_SPEED); } else { diff --git a/src/MatrixDisplayUi.cpp b/src/MatrixDisplayUi.cpp index 902013fa..995d6085 100644 --- a/src/MatrixDisplayUi.cpp +++ b/src/MatrixDisplayUi.cpp @@ -621,35 +621,36 @@ void MatrixDisplayUi::slideTransition() void MatrixDisplayUi::curtainTransition() { - float progress = (float)this->state.ticksSinceLastStateSwitch / (float)this->ticksPerTransition; - if (this->state.ticksSinceLastStateSwitch == 0) - { - // At the beginning of the transition, copy the current app image to the ledsCopy array - (this->AppFunctions[this->state.currentApp])(this->matrix, &this->state, 0, 0, &gif1); + CRGB *leds = DisplayManager.getLeds(); + float progress = (float)this->state.ticksSinceLastStateSwitch / (float)this->ticksPerTransition; + int curtainWidth = (int)(16 * progress); // 16 ist die Hälfte der Matrix-Breite - for (int i = 0; i < 32; i++) + if (this->state.ticksSinceLastStateSwitch == 1) { - for (int j = 0; j < 8; j++) - { - ledsCopy[i + j * 32] = DisplayManager.getLeds()[this->matrix->XY(i, j)]; - } + // Kopieren Sie die aktuelle App-Ansicht in ledsCopy + (this->AppFunctions[this->state.currentApp])(this->matrix, &this->state, 0, 0, &gif1); + for (int i = 0; i < 32; i++) + { + for (int j = 0; j < 8; j++) + { + ledsCopy[i + j * 32] = leds[this->matrix->XY(i, j)]; + } + } } - } - - // Draw the new app - (this->AppFunctions[this->getnextAppNumber()])(this->matrix, &this->state, 0, 0, &gif2); + // Zeichnen Sie die neue App-Ansicht + (this->AppFunctions[this->getnextAppNumber()])(this->matrix, &this->state, 0, 0, &gif2); - // Create the curtain effect - for (int i = 0; i < 32; i++) - { - for (int j = 0; j < 8; j++) + // Anwenden des Vorhang-Effekts basierend auf dem Fortschritt + for (int i = 0; i < 32; i++) { - if (i < 16 - progress * 16 || i > 15 + progress * 16) - { - DisplayManager.getLeds()[this->matrix->XY(i, j)] = ledsCopy[i + j * 32]; - } + for (int j = 0; j < 8; j++) + { + if ((i < (16 - curtainWidth)) || (i >= (16 + curtainWidth))) + { + leds[this->matrix->XY(i, j)] = ledsCopy[i + j * 32]; + } + } } - } } void MatrixDisplayUi::zoomTransition() diff --git a/src/PeripheryManager.cpp b/src/PeripheryManager.cpp index b8abdaeb..cc57424a 100644 --- a/src/PeripheryManager.cpp +++ b/src/PeripheryManager.cpp @@ -248,6 +248,8 @@ void PeripheryManager_::playBootSound() void PeripheryManager_::stopSound() { #ifdef awtrix2_upgrade + if (!DFPLAYER_ACTIVE) + return; dfmp3.stopAdvertisement(); delay(50); dfmp3.stop(); @@ -259,6 +261,8 @@ void PeripheryManager_::stopSound() #ifdef awtrix2_upgrade void PeripheryManager_::setVolume(uint8_t vol) { + if (!DFPLAYER_ACTIVE) + return; uint8_t curVolume = dfmp3.getVolume(); // need to read volume in order to work. Donno why! :( dfmp3.setVolume(vol); delay(50); @@ -300,6 +304,8 @@ bool PeripheryManager_::playFromFile(String file) #ifdef awtrix2_upgrade if (DEBUG_MODE) DEBUG_PRINTLN(F("Playing MP3 file")); + if (!DFPLAYER_ACTIVE) + return false; dfmp3.stop(); delay(50); dfmp3.playMp3FolderTrack(file.toInt()); @@ -324,7 +330,8 @@ bool PeripheryManager_::playFromFile(String file) bool PeripheryManager_::isPlaying() { #ifdef awtrix2_upgrade - + if (!DFPLAYER_ACTIVE) + return false; if ((dfmp3.getStatus() & 0xff) == 0x01) // 0x01 = DfMp3_StatusState_Playing return true; else @@ -341,9 +348,13 @@ void PeripheryManager_::setup() startTime = millis(); pinMode(LDR_PIN, INPUT); #ifdef awtrix2_upgrade - dfmp3.begin(); - delay(100); - setVolume(VOLUME); + if (DFPLAYER_ACTIVE) + { + dfmp3.begin(); + delay(100); + setVolume(VOLUME); + } + #endif button_left.begin(); button_right.begin(); diff --git a/src/PowerManager.cpp b/src/PowerManager.cpp index 867a86f2..82a36576 100644 --- a/src/PowerManager.cpp +++ b/src/PowerManager.cpp @@ -3,7 +3,7 @@ #include "Globals.h" #define uS_TO_S_FACTOR 1000000L - +#define WAKEUP_PIN GPIO_NUM_27 // The getter for the instantiated singleton instance PowerManager_ &PowerManager_::getInstance() { @@ -39,6 +39,7 @@ void PowerManager_::sleepParser(const char *json) void PowerManager_::sleep(uint64_t seconds) { + esp_sleep_enable_ext0_wakeup(WAKEUP_PIN, 0); esp_sleep_enable_timer_wakeup(seconds * uS_TO_S_FACTOR); Serial.print("Going to sleep...\n"); esp_deep_sleep_start(); diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp index 650a546c..fce3ed52 100644 --- a/src/ServerManager.cpp +++ b/src/ServerManager.cpp @@ -52,8 +52,7 @@ void addHandler() { mws.webserver->send(200,F("text/plain"),F("OK")); DisplayManager.setPower(false); - PowerManager.sleepParser(mws.webserver->arg("plain").c_str()); - }); + PowerManager.sleepParser(mws.webserver->arg("plain").c_str()); }); mws.addHandler("/api/loop", HTTP_GET, []() { mws.webserver->send_P(200, "application/json", DisplayManager.getAppsAsJson().c_str()); }); mws.addHandler("/api/effects", HTTP_GET, []() @@ -93,7 +92,7 @@ void addHandler() { DisplayManager.nextApp(); mws.webserver->send(200,F("text/plain"),F("OK")); }); mws.addHandler("/fullscreen", HTTP_GET, []() { - String fps = mws.webserver->arg("fps"); // Hole den "fps" URL-Parameter + String fps = mws.webserver->arg("fps"); if (fps == "") { fps = "30"; } @@ -228,17 +227,18 @@ void ServerManager_::setup() mws.addHandler("/version", HTTP_GET, versionHandler); mws.begin(); - if (!MDNS.begin(uniqueID)) + if (!MDNS.begin(MQTT_PREFIX)) { if (DEBUG_MODE) DEBUG_PRINTLN(F("Error starting mDNS")); - return; } - - MDNS.addService("http", "tcp", 80); - MDNS.addService("awtrix", "tcp", 80); - MDNS.addServiceTxt("awtrix", "tcp", "id", uniqueID); - MDNS.addServiceTxt("awtrix", "tcp", "type", "awtrix_light"); + else + { + MDNS.addService("http", "tcp", 80); + MDNS.addService("awtrix", "tcp", 80); + MDNS.addServiceTxt("awtrix", "tcp", "id", MQTT_PREFIX); + MDNS.addServiceTxt("awtrix", "tcp", "type", "awtrix_light"); + } configTzTime(NTP_TZ.c_str(), NTP_SERVER.c_str()); tm timeInfo; diff --git a/src/effects.cpp b/src/effects.cpp index 8baeb179..d8d49d9f 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -1088,7 +1088,7 @@ int getEffectIndex(String name) return i; } } - return -1; + return 0; } // Loads a palette from the LittleFS filesystem diff --git a/src/main.cpp b/src/main.cpp index 7f6a5954..51c5a8cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,7 +61,7 @@ void setup() { pinMode(15, OUTPUT); digitalWrite(15, LOW); - delay(5000); + delay(2000); Serial.begin(115200); loadSettings(); PeripheryManager.setup();