From 7074dd5757d56cb8afd443d9d6dd93d04636ae2d Mon Sep 17 00:00:00 2001 From: dAjaY85 Date: Tue, 17 Jan 2023 23:51:53 +0100 Subject: [PATCH 01/25] Display init zum Zweiten chango to full Buffer Mode, remove picture loop, because it's not worked. look: https://github.com/olikraus/u8glib/wiki/tpictureloop snprintf + public vars - dispPowerSafe => true: PowerSafe Mode on - dispLogo => true: showing Logo upper right corner - dispContrast => possible to adjust the Display Contrast change in date time, buffer deleted Display-Constructor changed, reset goes to front Arrow and Logo only shown, when production is on Refactor OLEDDisplayClass to DisplayGraphicClass --- include/Display_Graphic.h | 41 ++++++++ platformio.ini | 1 + src/Display_Graphic.cpp | 195 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 8 ++ 4 files changed, 245 insertions(+) create mode 100644 include/Display_Graphic.h create mode 100644 src/Display_Graphic.cpp diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h new file mode 100644 index 00000000..9b57aabc --- /dev/null +++ b/include/Display_Graphic.h @@ -0,0 +1,41 @@ +#ifndef Display_Graphic_H +#define Display_Graphic_H + +#include +#include +#include +#include +#include +#include + +class DisplayGraphicClass { +public: + DisplayGraphicClass(); + ~DisplayGraphicClass(); + + void init(uint8_t type); + void loop(); + + bool dispPowerSafe = true; + bool dispLogo = true; + uint8_t dispContrast = 60; + +private: + void printText(const char* text, uint8_t line); + + U8G2* _display; + + uint8_t _mExtra; + uint8_t _display_type = 0; + uint16_t _dispX = 0; + uint16_t _dispY = 0; + uint16_t _period = 1000; + uint16_t _interval = 60000; // interval at which to power save (milliseconds) + uint32_t _lastPublish = 0; + uint32_t _previousMillis = 0; + char _fmtText[32]; +}; + +extern DisplayGraphicClass Display; + +#endif diff --git a/platformio.ini b/platformio.ini index 4bbc0691..12faba04 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,6 +26,7 @@ lib_deps = bblanchon/ArduinoJson @ ^6.20.0 https://github.com/bertmelis/espMqttClient.git#v1.3.3 nrf24/RF24 @ ^1.4.5 + olikraus/U8g2 @ ^2.34.13 extra_scripts = pre:auto_firmware_version.py diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp new file mode 100644 index 00000000..2de27adf --- /dev/null +++ b/src/Display_Graphic.cpp @@ -0,0 +1,195 @@ +#include "Display_Graphic.h" + +static uint8_t bmp_logo[] PROGMEM = { + B00000000, B00000000, // ................ + B11101100, B00110111, // ..##.######.##.. + B11101100, B00110111, // ..##.######.##.. + B11100000, B00000111, // .....######..... + B11010000, B00001011, // ....#.####.#.... + B10011000, B00011001, // ...##..##..##... + B10000000, B00000001, // .......##....... + B00000000, B00000000, // ................ + B01111000, B00011110, // ...####..####... + B11111100, B00111111, // ..############.. + B01111100, B00111110, // ..#####..#####.. + B00000000, B00000000, // ................ + B11111100, B00111111, // ..############.. + B11111110, B01111111, // .##############. + B01111110, B01111110, // .######..######. + B00000000, B00000000 // ................ +}; + +static uint8_t bmp_arrow[] PROGMEM = { + B00000000, B00011100, B00011100, B00001110, B00001110, B11111110, B01111111, + B01110000, B01110000, B00110000, B00111000, B00011000, B01111111, B00111111, + B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000 +}; + +std::map> display_types = { + { 0, []() { return new U8G2_PCD8544_84X48_F_4W_HW_SPI(U8G2_R0, /*cs*/ 5, /*dc*/ 4, /*reset*/ 16); } }, + { 1, []() { return new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, /*reset*/ U8X8_PIN_NONE, /*clock*/ SCL, /*data*/ SDA); } }, + { 2, []() { return new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, /*reset*/ U8X8_PIN_NONE, /*clock*/ SCL, /*data*/ SDA); } }, +}; + +DisplayGraphicClass::DisplayGraphicClass() +{ + init(_display_type); +} + +DisplayGraphicClass::~DisplayGraphicClass() +{ + delete _display; +} + +void DisplayGraphicClass::init(uint8_t type) +{ + _display_type = type; + int const_type = type - 1; + if (const_type >= 0) { + auto constructor = display_types[const_type]; + _display = constructor(); + _display->begin(); + } +} + +void DisplayGraphicClass::printText(const char* text, uint8_t line) +{ + // get the width and height of the display + uint16_t maxWidth = _display->getWidth(); + uint16_t maxHeight = _display->getHeight(); + + // pxMovement +x (0 - 6 px) + uint8_t ex = (_mExtra % 7); + + // set the font size based on the display size + switch (line) { + case 1: + if (maxWidth > 120 && maxHeight > 60) { + _display->setFont(u8g2_font_ncenB14_tr); // large display + } else { + _display->setFont(u8g2_font_logisoso16_tr); // small display + } + break; + case 4: + if (maxWidth > 120 && maxHeight > 60) { + _display->setFont(u8g2_font_5x8_tr); // large display + } else { + _display->setFont(u8g2_font_5x8_tr); // small display + } + break; + default: + if (maxWidth > 120 && maxHeight > 60) { + _display->setFont(u8g2_font_ncenB10_tr); // large display + } else { + _display->setFont(u8g2_font_5x8_tr); // small display + } + break; + } + + // get the font height, to calculate the textheight + _dispY += (_display->getMaxCharHeight()) + 1; + + // calculate the starting position of the text + if (line == 1) { + _dispX = 20 + ex; + } else { + _dispX = 5 + ex; + } + + // draw the Text, on the calculated pos + _display->drawStr(_dispX, _dispY, text); +} + +void DisplayGraphicClass::loop() +{ + if (_display_type == 0) { + return; + } + + if ((millis() - _lastPublish) > _period) { + float totalPower = 0; + float totalYieldDay = 0; + float totalYieldTotal = 0; + + uint8_t isprod = 0; + + for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { + auto inv = Hoymiles.getInverterByPos(i); + if (inv == nullptr) { + continue; + } + + if (inv->isProducing()) { + isprod++; + } + + totalPower += inv->Statistics()->getChannelFieldValue(CH0, FLD_PAC); + totalYieldDay += inv->Statistics()->getChannelFieldValue(CH0, FLD_YD); + totalYieldTotal += inv->Statistics()->getChannelFieldValue(CH0, FLD_YT); + } + + _display->clearBuffer(); + + // set Contrast of the Display to raise the lifetime + _display->setContrast(dispContrast); + + //=====> Logo and Lighting ========== + // pxMovement +x (0 - 6 px) + uint8_t ex = (_mExtra % 7); + if (isprod > 0) { + _display->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow); + if (dispLogo) + _display->drawXBMP(_display->getWidth() - 24 + ex, 2, 16, 16, bmp_logo); + } + //<======================= + + //=====> Actual Production ========== + if ((totalPower > 0) && (isprod > 0)) { + _display->setPowerSave(false); + if (totalPower > 999) { + snprintf(_fmtText, sizeof(_fmtText), "%2.1f kW", (totalPower / 1000)); + } else { + snprintf(_fmtText, sizeof(_fmtText), "%3.0f W", totalPower); + } + printText(_fmtText, 1); + _previousMillis = millis(); + } + //<======================= + + //=====> Offline =========== + else { + printText("offline", 1); + // check if it's time to enter power saving mode + if (millis() - _previousMillis >= (_interval * 2) && (dispPowerSafe)) { + _display->setPowerSave(true); + } + } + //<======================= + + //=====> Today & Total Production ======= + snprintf(_fmtText, sizeof(_fmtText), "today: %4.0f Wh", totalYieldDay); + printText(_fmtText, 2); + + snprintf(_fmtText, sizeof(_fmtText), "total: %.1f kWh", totalYieldTotal); + printText(_fmtText, 3); + //<======================= + + //=====> IP or Date-Time ======== + if (!(_mExtra % 10) && NetworkSettings.localIP()) { + printText(NetworkSettings.localIP().toString().c_str(), 4); + } else { + // Get current time + time_t now = time(nullptr); + strftime(_fmtText, sizeof(_fmtText), "%a %d.%m.%Y %H:%M", localtime(&now)); + printText(_fmtText, 4); + } + _display->sendBuffer(); + + _dispX = 0; + _dispY = 0; + _mExtra++; + _lastPublish = millis(); + } +} + +DisplayGraphicClass Display; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c74b45dd..f1b1ec05 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2022 Thomas Basler and others */ #include "Configuration.h" +#include "Display_Graphic.h" #include "MessageOutput.h" #include "MqttHandleDtu.h" #include "MqttHandleHass.h" @@ -90,6 +91,11 @@ void setup() WebApi.init(); MessageOutput.println(F("done")); + // Initialize Display + MessageOutput.print(F("Initialize Display... ")); + Display.init(3); // 1 Nokia 5110, 2 for SSD1306, 3 for for SH1106 ... + MessageOutput.println(F("done")); + // Check for default DTU serial MessageOutput.print(F("Check for default DTU serial... ")); CONFIG_T& config = Configuration.get(); @@ -160,6 +166,8 @@ void loop() yield(); WebApi.loop(); yield(); + Display.loop(); + yield(); MessageOutput.loop(); yield(); } \ No newline at end of file From e572e711a48ab89bed34c4ac88b772f995836816 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Wed, 18 Jan 2023 21:25:30 +0100 Subject: [PATCH 02/25] Code Style Changes * Add License Identifier * Move non public required includes to cpp * Add curly brackets --- include/Display_Graphic.h | 13 +++---------- src/Display_Graphic.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index 9b57aabc..b5f0d5d3 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -1,12 +1,7 @@ -#ifndef Display_Graphic_H -#define Display_Graphic_H +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once -#include -#include -#include #include -#include -#include class DisplayGraphicClass { public: @@ -36,6 +31,4 @@ private: char _fmtText[32]; }; -extern DisplayGraphicClass Display; - -#endif +extern DisplayGraphicClass Display; \ No newline at end of file diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 2de27adf..1c6d9ac7 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -1,4 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #include "Display_Graphic.h" +#include +#include +#include +#include static uint8_t bmp_logo[] PROGMEM = { B00000000, B00000000, // ................ @@ -138,8 +143,9 @@ void DisplayGraphicClass::loop() uint8_t ex = (_mExtra % 7); if (isprod > 0) { _display->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow); - if (dispLogo) + if (dispLogo) { _display->drawXBMP(_display->getWidth() - 24 + ex, 2, 16, 16, bmp_logo); + } } //<======================= From 1d07574f8a157ef72603ceab783214c566c48830 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Wed, 18 Jan 2023 21:28:41 +0100 Subject: [PATCH 03/25] Rename _lastPublish to _lastDisplayUpdate --- include/Display_Graphic.h | 2 +- src/Display_Graphic.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index b5f0d5d3..f216c38a 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -26,7 +26,7 @@ private: uint16_t _dispY = 0; uint16_t _period = 1000; uint16_t _interval = 60000; // interval at which to power save (milliseconds) - uint32_t _lastPublish = 0; + uint32_t _lastDisplayUpdate = 0; uint32_t _previousMillis = 0; char _fmtText[32]; }; diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 1c6d9ac7..5a74babe 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -111,7 +111,7 @@ void DisplayGraphicClass::loop() return; } - if ((millis() - _lastPublish) > _period) { + if ((millis() - _lastDisplayUpdate) > _period) { float totalPower = 0; float totalYieldDay = 0; float totalYieldTotal = 0; @@ -194,7 +194,7 @@ void DisplayGraphicClass::loop() _dispX = 0; _dispY = 0; _mExtra++; - _lastPublish = millis(); + _lastDisplayUpdate = millis(); } } From 592dd73fca18553aa3e1d8a2af73ee6b251cb61b Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Wed, 18 Jan 2023 21:34:20 +0100 Subject: [PATCH 04/25] Implement _dispX as function local variable --- include/Display_Graphic.h | 1 - src/Display_Graphic.cpp | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index f216c38a..02c70cfa 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -22,7 +22,6 @@ private: uint8_t _mExtra; uint8_t _display_type = 0; - uint16_t _dispX = 0; uint16_t _dispY = 0; uint16_t _period = 1000; uint16_t _interval = 60000; // interval at which to power save (milliseconds) diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 5a74babe..4c768c07 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -91,18 +91,19 @@ void DisplayGraphicClass::printText(const char* text, uint8_t line) break; } - // get the font height, to calculate the textheight + // get the font height, to calculate the textheight _dispY += (_display->getMaxCharHeight()) + 1; // calculate the starting position of the text + uint16_t dispX; if (line == 1) { - _dispX = 20 + ex; + dispX = 20 + ex; } else { - _dispX = 5 + ex; + dispX = 5 + ex; } // draw the Text, on the calculated pos - _display->drawStr(_dispX, _dispY, text); + _display->drawStr(dispX, _dispY, text); } void DisplayGraphicClass::loop() @@ -191,7 +192,6 @@ void DisplayGraphicClass::loop() } _display->sendBuffer(); - _dispX = 0; _dispY = 0; _mExtra++; _lastDisplayUpdate = millis(); From bb3e12814d149a06da475c4a6d476717c1cb8f66 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 20:12:16 +0100 Subject: [PATCH 05/25] Move display pin assignment to main function --- include/Display_Graphic.h | 11 +++++++++-- src/Display_Graphic.cpp | 23 ++++++++++------------- src/main.cpp | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index 02c70cfa..4a21ee84 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -3,12 +3,19 @@ #include +enum DisplayType_t { + None, + PCD8544, + SSD1306, + SH1106, +}; + class DisplayGraphicClass { public: DisplayGraphicClass(); ~DisplayGraphicClass(); - void init(uint8_t type); + void init(DisplayType_t type, uint8_t data, uint8_t clk, uint8_t cs, uint8_t reset); void loop(); bool dispPowerSafe = true; @@ -20,8 +27,8 @@ private: U8G2* _display; + DisplayType_t _display_type = DisplayType_t::None; uint8_t _mExtra; - uint8_t _display_type = 0; uint16_t _dispY = 0; uint16_t _period = 1000; uint16_t _interval = 60000; // interval at which to power save (milliseconds) diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 4c768c07..cdff677a 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -30,29 +30,26 @@ static uint8_t bmp_arrow[] PROGMEM = { B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000 }; -std::map> display_types = { - { 0, []() { return new U8G2_PCD8544_84X48_F_4W_HW_SPI(U8G2_R0, /*cs*/ 5, /*dc*/ 4, /*reset*/ 16); } }, - { 1, []() { return new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, /*reset*/ U8X8_PIN_NONE, /*clock*/ SCL, /*data*/ SDA); } }, - { 2, []() { return new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, /*reset*/ U8X8_PIN_NONE, /*clock*/ SCL, /*data*/ SDA); } }, +std::map> display_types = { + { DisplayType_t::PCD8544, [](uint8_t reset, uint8_t clock, uint8_t data, uint8_t cs) { return new U8G2_PCD8544_84X48_F_4W_HW_SPI(U8G2_R0, cs, data, reset); } }, + { DisplayType_t::SSD1306, [](uint8_t reset, uint8_t clock, uint8_t data, uint8_t cs) { return new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, reset, clock, data); } }, + { DisplayType_t::SH1106, [](uint8_t reset, uint8_t clock, uint8_t data, uint8_t cs) { return new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, reset, clock, data); } }, }; DisplayGraphicClass::DisplayGraphicClass() -{ - init(_display_type); -} +{} DisplayGraphicClass::~DisplayGraphicClass() { delete _display; } -void DisplayGraphicClass::init(uint8_t type) +void DisplayGraphicClass::init(DisplayType_t type, uint8_t data, uint8_t clk, uint8_t cs, uint8_t reset) { _display_type = type; - int const_type = type - 1; - if (const_type >= 0) { - auto constructor = display_types[const_type]; - _display = constructor(); + if (_display_type > DisplayType_t::None) { + auto constructor = display_types[_display_type]; + _display = constructor(reset, clk, data, cs); _display->begin(); } } @@ -108,7 +105,7 @@ void DisplayGraphicClass::printText(const char* text, uint8_t line) void DisplayGraphicClass::loop() { - if (_display_type == 0) { + if (_display_type == DisplayType_t::None) { return; } diff --git a/src/main.cpp b/src/main.cpp index f1b1ec05..eccac5bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,7 +93,7 @@ void setup() // Initialize Display MessageOutput.print(F("Initialize Display... ")); - Display.init(3); // 1 Nokia 5110, 2 for SSD1306, 3 for for SH1106 ... + Display.init(DisplayType_t::SSD1306, SDA, SCL, 255, 255); MessageOutput.println(F("done")); // Check for default DTU serial From b96d87b933638b127d7060ed458e8b4319797666 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 20:50:57 +0100 Subject: [PATCH 06/25] Read display pinmapping from json file --- include/PinMapping.h | 5 +++++ src/PinMapping.cpp | 33 +++++++++++++++++++++++++++++++++ src/main.cpp | 9 +++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/include/PinMapping.h b/include/PinMapping.h index 163dbbe5..1d0ad4d9 100644 --- a/include/PinMapping.h +++ b/include/PinMapping.h @@ -24,6 +24,11 @@ struct PinMapping_t { int eth_mdio; eth_phy_type_t eth_type; eth_clock_mode_t eth_clk_mode; + uint8_t display_type; + uint8_t display_data; + uint8_t display_clk; + uint8_t display_cs; + uint8_t display_reset; }; class PinMappingClass { diff --git a/src/PinMapping.cpp b/src/PinMapping.cpp index 2fccabd3..a0f09f77 100644 --- a/src/PinMapping.cpp +++ b/src/PinMapping.cpp @@ -10,6 +10,26 @@ #define JSON_BUFFER_SIZE 6144 +#ifndef DISPLAY_TYPE +#define DISPLAY_TYPE 0 +#endif + +#ifndef DISPLAY_DATA +#define DISPLAY_DATA 255 +#endif + +#ifndef DISPLAY_CLK +#define DISPLAY_CLK 255 +#endif + +#ifndef DISPLAY_CS +#define DISPLAY_CS 255 +#endif + +#ifndef DISPLAY_RESET +#define DISPLAY_RESET 255 +#endif + PinMappingClass PinMapping; PinMappingClass::PinMappingClass() @@ -34,6 +54,13 @@ PinMappingClass::PinMappingClass() _pinMapping.eth_mdio = ETH_PHY_MDIO; _pinMapping.eth_type = ETH_PHY_TYPE; _pinMapping.eth_clk_mode = ETH_CLK_MODE; + + _pinMapping.display_type = DISPLAY_TYPE; + _pinMapping.display_data = DISPLAY_DATA; + _pinMapping.display_clk = DISPLAY_CLK; + _pinMapping.display_cs = DISPLAY_CS; + _pinMapping.display_reset = DISPLAY_RESET; + } PinMapping_t& PinMappingClass::get() @@ -80,6 +107,12 @@ bool PinMappingClass::init(const String& deviceMapping) _pinMapping.eth_type = doc[i]["eth"]["type"] | ETH_PHY_TYPE; _pinMapping.eth_clk_mode = doc[i]["eth"]["clk_mode"] | ETH_CLK_MODE; + _pinMapping.display_type = doc[i]["display"]["type"] | DISPLAY_TYPE; + _pinMapping.display_data = doc[i]["display"]["data"] | DISPLAY_DATA; + _pinMapping.display_clk = doc[i]["display"]["clk"] | DISPLAY_CLK; + _pinMapping.display_cs = doc[i]["display"]["cs"] | DISPLAY_CS; + _pinMapping.display_reset = doc[i]["display"]["reset"] | DISPLAY_RESET; + return true; } } diff --git a/src/main.cpp b/src/main.cpp index eccac5bc..2535e000 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,6 +65,7 @@ void setup() } else { MessageOutput.print(F("using default config ")); } + const PinMapping_t& pin = PinMapping.get(); MessageOutput.println(F("done")); // Initialize WiFi @@ -93,7 +94,12 @@ void setup() // Initialize Display MessageOutput.print(F("Initialize Display... ")); - Display.init(DisplayType_t::SSD1306, SDA, SCL, 255, 255); + Display.init( + static_cast(pin.display_type), + pin.display_data, + pin.display_clk, + pin.display_cs, + pin.display_reset); MessageOutput.println(F("done")); // Check for default DTU serial @@ -114,7 +120,6 @@ void setup() MessageOutput.print(F("Initialize Hoymiles interface... ")); if (PinMapping.isValidNrf24Config()) { SPIClass* spiClass = new SPIClass(HSPI); - PinMapping_t& pin = PinMapping.get(); spiClass->begin(pin.nrf24_clk, pin.nrf24_miso, pin.nrf24_mosi, pin.nrf24_cs); Hoymiles.setMessageOutput(&MessageOutput); Hoymiles.init(spiClass, pin.nrf24_en, pin.nrf24_irq); From e3d2de03191da5f306057df363ddea82cf6f26d0 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 21:01:30 +0100 Subject: [PATCH 07/25] webapp: Show display pin mapping in device manager --- src/WebApi_device.cpp | 7 +++++++ webapp/src/components/PinInfo.vue | 27 +++++++++++++++++++++++++++ webapp/src/types/PinMapping.ts | 9 +++++++++ 3 files changed, 43 insertions(+) diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index e3638696..ab403b1e 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -55,6 +55,13 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) ethObj[F("type")] = pin.eth_type; ethObj[F("clk_mode")] = pin.eth_clk_mode; + JsonObject displayObj = curPin.createNestedObject("display"); + displayObj[F("type")] = pin.display_type; + displayObj[F("data")] = pin.display_data; + displayObj[F("clk")] = pin.display_clk; + displayObj[F("cs")] = pin.display_cs; + displayObj[F("reset")] = pin.display_reset; + response->setLength(); request->send(response); } diff --git a/webapp/src/components/PinInfo.vue b/webapp/src/components/PinInfo.vue index e3946b57..de7524b7 100644 --- a/webapp/src/components/PinInfo.vue +++ b/webapp/src/components/PinInfo.vue @@ -80,6 +80,33 @@ {{ currentPinAssignment?.eth?.clk_mode }} + + Display + type + {{ selectedPinAssignment?.display?.type }} + {{ currentPinAssignment?.display?.type }} + + + data + {{ selectedPinAssignment?.display?.data }} + {{ currentPinAssignment?.display?.data }} + + + clk + {{ selectedPinAssignment?.display?.clk }} + {{ currentPinAssignment?.display?.clk }} + + + cs + {{ selectedPinAssignment?.display?.cs }} + {{ currentPinAssignment?.display?.cs }} + + + reset + {{ selectedPinAssignment?.display?.reset }} + {{ currentPinAssignment?.display?.reset }} + + diff --git a/webapp/src/types/PinMapping.ts b/webapp/src/types/PinMapping.ts index fa7bf493..0445c1f8 100644 --- a/webapp/src/types/PinMapping.ts +++ b/webapp/src/types/PinMapping.ts @@ -17,10 +17,19 @@ export interface Ethernet { clk_mode: number; } +export interface Display { + type: number; + data: number; + clk: number; + cs: number; + reset: number; +} + export interface Device { name: string; nrf24: Nrf24; eth: Ethernet; + display: Display; } export interface PinMapping extends Array{} \ No newline at end of file From d1483468c624d23e6d99a9360692e3388dd87d24 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 22:43:36 +0100 Subject: [PATCH 08/25] Rename Display properties and apply power safe immediatly --- include/Display_Graphic.h | 6 +++--- src/Display_Graphic.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index 4a21ee84..591e73b8 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -18,9 +18,9 @@ public: void init(DisplayType_t type, uint8_t data, uint8_t clk, uint8_t cs, uint8_t reset); void loop(); - bool dispPowerSafe = true; - bool dispLogo = true; - uint8_t dispContrast = 60; + bool enablePowerSafe = true; + bool showLogo = true; + uint8_t contrast = 60; private: void printText(const char* text, uint8_t line); diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index cdff677a..4b32a5d1 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -134,14 +134,14 @@ void DisplayGraphicClass::loop() _display->clearBuffer(); // set Contrast of the Display to raise the lifetime - _display->setContrast(dispContrast); + _display->setContrast(contrast); //=====> Logo and Lighting ========== // pxMovement +x (0 - 6 px) uint8_t ex = (_mExtra % 7); if (isprod > 0) { _display->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow); - if (dispLogo) { + if (showLogo) { _display->drawXBMP(_display->getWidth() - 24 + ex, 2, 16, 16, bmp_logo); } } @@ -164,8 +164,8 @@ void DisplayGraphicClass::loop() else { printText("offline", 1); // check if it's time to enter power saving mode - if (millis() - _previousMillis >= (_interval * 2) && (dispPowerSafe)) { - _display->setPowerSave(true); + if (millis() - _previousMillis >= (_interval * 2)) { + _display->setPowerSave(enablePowerSafe); } } //<======================= From f7fb9a2bd6640b7eadbef74b3eb508ae8af94687 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 23:10:41 +0100 Subject: [PATCH 09/25] Display: Add property to enable or disable the screensaver --- include/Display_Graphic.h | 1 + src/Display_Graphic.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/Display_Graphic.h b/include/Display_Graphic.h index 591e73b8..13f6c62d 100644 --- a/include/Display_Graphic.h +++ b/include/Display_Graphic.h @@ -19,6 +19,7 @@ public: void loop(); bool enablePowerSafe = true; + bool enableScreensaver = true; bool showLogo = true; uint8_t contrast = 60; diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 4b32a5d1..aa192b92 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -61,7 +61,7 @@ void DisplayGraphicClass::printText(const char* text, uint8_t line) uint16_t maxHeight = _display->getHeight(); // pxMovement +x (0 - 6 px) - uint8_t ex = (_mExtra % 7); + uint8_t ex = enableScreensaver ? (_mExtra % 7) : 0; // set the font size based on the display size switch (line) { @@ -138,7 +138,7 @@ void DisplayGraphicClass::loop() //=====> Logo and Lighting ========== // pxMovement +x (0 - 6 px) - uint8_t ex = (_mExtra % 7); + uint8_t ex = enableScreensaver ? (_mExtra % 7) : 0; if (isprod > 0) { _display->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow); if (showLogo) { From e89fd64439bb353b2fa14cef7a1d8c8d3a1eff8b Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 23:14:08 +0100 Subject: [PATCH 10/25] Added WebAPI to setup display settings. Also reboot only if device profile was changed. --- include/Configuration.h | 5 +++ include/defaults.h | 7 +++- src/Configuration.cpp | 12 +++++++ src/WebApi_device.cpp | 73 ++++++++++++++++++++++++++--------------- src/main.cpp | 6 +++- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/include/Configuration.h b/include/Configuration.h index fc4867fc..c4e5d267 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -92,6 +92,11 @@ struct CONFIG_T { bool Security_AllowReadonly; char Dev_PinMapping[DEV_MAX_MAPPING_NAME_STRLEN + 1]; + + bool Display_PowerSafe; + bool Display_ScreenSaver; + bool Display_ShowLogo; + uint8_t Display_Contrast; }; class ConfigurationClass { diff --git a/include/defaults.h b/include/defaults.h index 1009ca51..69ec960b 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -79,4 +79,9 @@ #define MQTT_HASS_TOPIC "homeassistant/" #define MQTT_HASS_INDIVIDUALPANELS false -#define DEV_PINMAPPING "" \ No newline at end of file +#define DEV_PINMAPPING "" + +#define DISPLAY_POWERSAFE true +#define DISPLAY_SCREENSAVER true +#define DISPLAY_SHOWLOGO true +#define DISPLAY_CONTRAST 60 \ No newline at end of file diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 9998cf55..47142e73 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -83,6 +83,12 @@ bool ConfigurationClass::write() JsonObject device = doc.createNestedObject("device"); device["pinmapping"] = config.Dev_PinMapping; + JsonObject display = device.createNestedObject("display"); + display["powersafe"] = config.Display_PowerSafe; + display["screensaver"] = config.Display_ScreenSaver; + display["showlogo"] = config.Display_ShowLogo; + display["contrast"] = config.Display_Contrast; + JsonArray inverters = doc.createNestedArray("inverters"); for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { JsonObject inv = inverters.createNestedObject(); @@ -207,6 +213,12 @@ bool ConfigurationClass::read() JsonObject device = doc["device"]; strlcpy(config.Dev_PinMapping, device["pinmapping"] | DEV_PINMAPPING, sizeof(config.Dev_PinMapping)); + JsonObject display = device["display"]; + config.Display_PowerSafe = display["powersafe"] | DISPLAY_POWERSAFE; + config.Display_ScreenSaver = display["screensaver"] | DISPLAY_SCREENSAVER; + config.Display_ShowLogo = display["showlogo"] | DISPLAY_SHOWLOGO; + config.Display_Contrast = display["contrast"] | DISPLAY_CONTRAST; + JsonArray inverters = doc["inverters"]; for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { JsonObject inv = inverters[i].as(); diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index ab403b1e..44f6824a 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -4,6 +4,7 @@ */ #include "WebApi_device.h" #include "Configuration.h" +#include "Display_Graphic.h" #include "PinMapping.h" #include "WebApi.h" #include "WebApi_errors.h" @@ -38,29 +39,35 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) JsonObject curPin = root.createNestedObject("curPin"); curPin[F("name")] = config.Dev_PinMapping; - JsonObject nrfObj = curPin.createNestedObject("nrf24"); - nrfObj[F("clk")] = pin.nrf24_clk; - nrfObj[F("cs")] = pin.nrf24_cs; - nrfObj[F("en")] = pin.nrf24_en; - nrfObj[F("irq")] = pin.nrf24_irq; - nrfObj[F("miso")] = pin.nrf24_miso; - nrfObj[F("mosi")] = pin.nrf24_mosi; + JsonObject nrfPinObj = curPin.createNestedObject("nrf24"); + nrfPinObj[F("clk")] = pin.nrf24_clk; + nrfPinObj[F("cs")] = pin.nrf24_cs; + nrfPinObj[F("en")] = pin.nrf24_en; + nrfPinObj[F("irq")] = pin.nrf24_irq; + nrfPinObj[F("miso")] = pin.nrf24_miso; + nrfPinObj[F("mosi")] = pin.nrf24_mosi; - JsonObject ethObj = curPin.createNestedObject("eth"); - ethObj[F("enabled")] = pin.eth_enabled; - ethObj[F("phy_addr")] = pin.eth_phy_addr; - ethObj[F("power")] = pin.eth_power; - ethObj[F("mdc")] = pin.eth_mdc; - ethObj[F("mdio")] = pin.eth_mdio; - ethObj[F("type")] = pin.eth_type; - ethObj[F("clk_mode")] = pin.eth_clk_mode; + JsonObject ethPinObj = curPin.createNestedObject("eth"); + ethPinObj[F("enabled")] = pin.eth_enabled; + ethPinObj[F("phy_addr")] = pin.eth_phy_addr; + ethPinObj[F("power")] = pin.eth_power; + ethPinObj[F("mdc")] = pin.eth_mdc; + ethPinObj[F("mdio")] = pin.eth_mdio; + ethPinObj[F("type")] = pin.eth_type; + ethPinObj[F("clk_mode")] = pin.eth_clk_mode; - JsonObject displayObj = curPin.createNestedObject("display"); - displayObj[F("type")] = pin.display_type; - displayObj[F("data")] = pin.display_data; - displayObj[F("clk")] = pin.display_clk; - displayObj[F("cs")] = pin.display_cs; - displayObj[F("reset")] = pin.display_reset; + JsonObject displayPinObj = curPin.createNestedObject("display"); + displayPinObj[F("type")] = pin.display_type; + displayPinObj[F("data")] = pin.display_data; + displayPinObj[F("clk")] = pin.display_clk; + displayPinObj[F("cs")] = pin.display_cs; + displayPinObj[F("reset")] = pin.display_reset; + + JsonObject display = root.createNestedObject("display"); + display[F("show_logo")] = config.Display_ShowLogo; + display[F("power_safe")] = config.Display_PowerSafe; + display[F("screensaver")] = config.Display_ScreenSaver; + display[F("contrast")] = config.Display_Contrast; response->setLength(); request->send(response); @@ -105,7 +112,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) return; } - if (!(root.containsKey("curPin"))) { + if (!(root.containsKey("curPin") || root.containsKey("display"))) { retMsg[F("message")] = F("Values are missing!"); retMsg[F("code")] = WebApiError::GenericValueMissing; response->setLength(); @@ -123,7 +130,19 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) } CONFIG_T& config = Configuration.get(); + bool performRestart = root[F("curPin")][F("name")].as() != config.Dev_PinMapping; + strlcpy(config.Dev_PinMapping, root[F("curPin")][F("name")].as().c_str(), sizeof(config.Dev_PinMapping)); + config.Display_ShowLogo = root[F("display")][F("show_logo")].as(); + config.Display_PowerSafe = root[F("display")][F("power_safe")].as(); + config.Display_ScreenSaver = root[F("display")][F("screensaver")].as(); + config.Display_Contrast = root[F("display")][F("contrast")].as(); + + Display.showLogo = config.Display_ShowLogo; + Display.enablePowerSafe = config.Display_PowerSafe; + Display.enableScreensaver = config.Display_ScreenSaver; + Display.contrast = config.Display_Contrast; + Configuration.write(); retMsg[F("type")] = F("success"); @@ -133,8 +152,10 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) response->setLength(); request->send(response); - yield(); - delay(1000); - yield(); - ESP.restart(); + if (performRestart) { + yield(); + delay(1000); + yield(); + ESP.restart(); + } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2535e000..a68ac0ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ void setup() MessageOutput.print(F("migrated... ")); Configuration.migrate(); } + CONFIG_T& config = Configuration.get(); MessageOutput.println(F("done")); // Load PinMapping @@ -100,11 +101,14 @@ void setup() pin.display_clk, pin.display_cs, pin.display_reset); + Display.showLogo = config.Display_ShowLogo; + Display.enablePowerSafe = config.Display_PowerSafe; + Display.enableScreensaver = config.Display_ScreenSaver; + Display.contrast = config.Display_Contrast; MessageOutput.println(F("done")); // Check for default DTU serial MessageOutput.print(F("Check for default DTU serial... ")); - CONFIG_T& config = Configuration.get(); if (config.Dtu_Serial == DTU_SERIAL) { MessageOutput.print(F("generate serial based on ESP chip id: ")); uint64_t dtuId = Utils::generateDtuSerial(); From e0712ed7bc27efef25fb3f883e0f6e1c4f949b36 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 19 Jan 2023 23:25:30 +0100 Subject: [PATCH 11/25] webapi: Added frontend for display settings --- webapp/src/locales/de.json | 5 ++ webapp/src/locales/en.json | 5 ++ webapp/src/locales/fr.json | 5 ++ webapp/src/types/DeviceConfig.ts | 8 ++++ webapp/src/views/DeviceAdminView.vue | 69 ++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 19 deletions(-) diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index bd411cd6..24c0b8d5 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -475,6 +475,11 @@ "SelectedProfile": "Ausgewähltes Profil:", "DefaultProfile": "(Standard Einstellungen)", "ProfileHint": "Ihr Gerät reagiert möglicherweise nicht mehr, wenn Sie ein inkompatibles Profil wählen. In diesem Fall müssen Sie eine Löschung über das serielle Interface durchführen.", + "Display": "Display", + "PowerSafe": "Power Safe aktivieren:", + "Screensaver": "Screensaver aktivieren:", + "ShowLogo": "Logo Anzeigen:", + "Contrast": "Kontrast ({contrast}):", "Save": "@:dtuadmin.Save" }, "pininfo": { diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 58212c84..2e82b3f5 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -475,6 +475,11 @@ "SelectedProfile": "Selected profile:", "DefaultProfile": "(Default settings)", "ProfileHint": "Your device may stop responding if you select an incompatible profile. In this case, you must perform a deletion via the serial interface.", + "Display": "Display", + "PowerSafe": "Enable Power Safe:", + "Screensaver": "Enable Screensaver:", + "ShowLogo": "Show Logo:", + "Contrast": "Contrast ({contrast}):", "Save": "@:dtuadmin.Save" }, "pininfo": { diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 774c1b9b..d0d10c04 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -475,6 +475,11 @@ "SelectedProfile": "Selected profile:", "DefaultProfile": "(Default settings)", "ProfileHint": "Your device may stop responding if you select an incompatible profile. In this case, you must perform a deletion via the serial interface.", + "Display": "Display", + "PowerSafe": "Enable Power Safe:", + "Screensaver": "Enable Screensaver:", + "ShowLogo": "Show Logo:", + "Contrast": "Contrast ({contrast}):", "Save": "@:dtuadmin.Save" }, "pininfo": { diff --git a/webapp/src/types/DeviceConfig.ts b/webapp/src/types/DeviceConfig.ts index 51b967b7..99ce70c2 100644 --- a/webapp/src/types/DeviceConfig.ts +++ b/webapp/src/types/DeviceConfig.ts @@ -1,5 +1,13 @@ import type { Device } from "./PinMapping"; +export interface Display { + show_logo: boolean; + power_safe: boolean; + screensaver: boolean; + contrast: number; +} + export interface DeviceConfig { curPin: Device; + display: Display; } \ No newline at end of file diff --git a/webapp/src/views/DeviceAdminView.vue b/webapp/src/views/DeviceAdminView.vue index cc6606a8..b1369404 100644 --- a/webapp/src/views/DeviceAdminView.vue +++ b/webapp/src/views/DeviceAdminView.vue @@ -4,21 +4,22 @@ {{ alertMessage }} - -