mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-23 13:56:10 +02:00
fix wakeup issue, once wifi was lost during night the communication didn't start in the morning
reenabled FlashStringHelper because of lacking RAM complete rewrite of monochrome display class, thx to @dAjaY85 -> displays are now configurable in setup
This commit is contained in:
parent
76b5818f48
commit
2b3f252bbf
17 changed files with 385 additions and 483 deletions
2
.github/workflows/compile_development.yml
vendored
2
.github/workflows/compile_development.yml
vendored
|
@ -47,7 +47,7 @@ jobs:
|
|||
run: python convert.py
|
||||
|
||||
- name: Run PlatformIO
|
||||
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp8266-sh1106 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 --environment esp32-wroom32-sh1106
|
||||
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp32-wroom32-release
|
||||
|
||||
- name: Rename Binary files
|
||||
id: rename-binary-files
|
||||
|
|
2
.github/workflows/compile_release.yml
vendored
2
.github/workflows/compile_release.yml
vendored
|
@ -51,7 +51,7 @@ jobs:
|
|||
run: python convert.py
|
||||
|
||||
- name: Run PlatformIO
|
||||
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp8266-sh1106 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 --environment esp32-wroom32-sh1106
|
||||
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp32-wroom32-release
|
||||
|
||||
- name: Rename Binary files
|
||||
id: rename-binary-files
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
(starting from release version `0.5.66`)
|
||||
|
||||
## 0.5.75
|
||||
* fix wakeup issue, once wifi was lost during night the communication didn't start in the morning
|
||||
* reenabled FlashStringHelper because of lacking RAM
|
||||
* complete rewrite of monochrome display class, thx to @dAjaY85 -> displays are now configurable in setup
|
||||
|
||||
## 0.5.74
|
||||
* improved payload handling (retransmit all fragments on CRC error)
|
||||
* improved `isAvailable`, checkes all record structs, inverter becomes available more early because version is check first
|
||||
|
|
20
src/app.cpp
20
src/app.cpp
|
@ -64,9 +64,8 @@ void app::setup() {
|
|||
mApi.setup(this, mSys, mWeb.getWebSrvPtr(), mConfig);
|
||||
|
||||
// Plugins
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) || defined(ENA_SH1106)
|
||||
mMonoDisplay.setup(&mConfig->plugin.display, mSys, &mTimestamp);
|
||||
#endif
|
||||
if(mConfig->plugin.display.type != 0)
|
||||
mMonoDisplay.setup(&mConfig->plugin.display, mSys, &mTimestamp, 0xff, mVersion);
|
||||
|
||||
mPubSerial.setup(mConfig, mSys, &mTimestamp);
|
||||
|
||||
|
@ -133,6 +132,7 @@ void app::onWifi(bool gotIp) {
|
|||
mInnerLoopCb = std::bind(&app::loopStandard, this);
|
||||
mSendTickerId = every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval, "tSend");
|
||||
mMqttReconnect = true;
|
||||
mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers!
|
||||
once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2");
|
||||
}
|
||||
else {
|
||||
|
@ -146,27 +146,27 @@ void app::regularTickers(void) {
|
|||
DPRINTLN(DBG_DEBUG, F("regularTickers"));
|
||||
everySec(std::bind(&WebType::tickSecond, &mWeb), "webSc");
|
||||
// Plugins
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) || defined(ENA_SH1106)
|
||||
if(mConfig->plugin.display.type != 0)
|
||||
everySec(std::bind(&MonoDisplayType::tickerSecond, &mMonoDisplay), "disp");
|
||||
#endif
|
||||
every(std::bind(&PubSerialType::tick, &mPubSerial), mConfig->serial.interval, "uart");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::tickNtpUpdate(void) {
|
||||
uint32_t nxtTrig = 5; // default: check again in 5 sec
|
||||
if (mWifi.getNtpTime(&nxtTrig)) {
|
||||
if (mWifi.getNtpTime()) {
|
||||
if (mMqttReconnect && mMqttEnabled) {
|
||||
mMqtt.connect();
|
||||
everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS");
|
||||
everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM");
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight
|
||||
if(mConfig->mqtt.rstYieldMidNight)
|
||||
onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "midNi");
|
||||
if(mConfig->mqtt.rstYieldMidNight) {
|
||||
uint32_t midTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight
|
||||
onceAt(std::bind(&app::tickMidnight, this), midTrig, "midNi");
|
||||
}
|
||||
mMqttReconnect = false;
|
||||
}
|
||||
|
||||
nxtTrig = 43200;
|
||||
nxtTrig = 43200; // check again in 12h
|
||||
|
||||
if((mSunrise == 0) && (mConfig->sun.lat) && (mConfig->sun.lon)) {
|
||||
mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600;
|
||||
|
|
14
src/app.h
14
src/app.h
|
@ -46,10 +46,8 @@ typedef PubMqtt<HmSystemType> PubMqttType;
|
|||
typedef PubSerial<HmSystemType> PubSerialType;
|
||||
|
||||
// PLUGINS
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) || defined(ENA_SH1106)
|
||||
#include "plugins/MonochromeDisplay/MonochromeDisplay.h"
|
||||
typedef MonochromeDisplay<HmSystemType> MonoDisplayType;
|
||||
#endif
|
||||
#include "plugins/MonochromeDisplay/MonochromeDisplay.h"
|
||||
typedef MonochromeDisplay<HmSystemType> MonoDisplayType;
|
||||
|
||||
|
||||
class app : public IApp, public ah::Scheduler {
|
||||
|
@ -180,10 +178,8 @@ class app : public IApp, public ah::Scheduler {
|
|||
|
||||
void setTimestamp(uint32_t newTime) {
|
||||
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
|
||||
if(0 == newTime) {
|
||||
uint32_t tmp;
|
||||
mWifi.getNtpTime(&tmp);
|
||||
}
|
||||
if(0 == newTime)
|
||||
mWifi.getNtpTime();
|
||||
else
|
||||
Scheduler::setTimestamp(newTime);
|
||||
}
|
||||
|
@ -269,9 +265,7 @@ class app : public IApp, public ah::Scheduler {
|
|||
uint32_t mSunrise, mSunset;
|
||||
|
||||
// plugins
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) || defined(ENA_SH1106)
|
||||
MonoDisplayType mMonoDisplay;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /*__APP_H__*/
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
#define DEF_CE_PIN 2
|
||||
#define DEF_IRQ_PIN 0
|
||||
#endif
|
||||
#define DEF_LED0_PIN 255 // off
|
||||
#define DEF_LED1_PIN 255 // off
|
||||
|
||||
// default NRF24 power, possible values (0 - 3)
|
||||
#define DEF_AMPLIFIERPOWER 1
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* More info:
|
||||
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout
|
||||
* */
|
||||
#define DEF_PIN_OFF 255
|
||||
|
||||
|
||||
#define PROT_MASK_INDEX 0x0001
|
||||
|
@ -117,10 +118,15 @@ typedef struct {
|
|||
} cfgInst_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
bool pwrSaveAtIvOffline;
|
||||
uint32_t wakeUp;
|
||||
uint32_t sleepAt;
|
||||
bool logoEn;
|
||||
bool pxShift;
|
||||
uint16_t wakeUp;
|
||||
uint16_t sleepAt;
|
||||
uint8_t contrast;
|
||||
uint8_t pin0;
|
||||
uint8_t pin1;
|
||||
} display_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -216,14 +222,15 @@ class settings {
|
|||
DeserializationError err = deserializeJson(root, fp);
|
||||
if(!err && (root.size() > 0)) {
|
||||
mCfg.valid = true;
|
||||
jsonWifi(root["wifi"]);
|
||||
jsonNrf(root["nrf"]);
|
||||
jsonNtp(root["ntp"]);
|
||||
jsonSun(root["sun"]);
|
||||
jsonSerial(root["serial"]);
|
||||
jsonMqtt(root["mqtt"]);
|
||||
jsonLed(root["led"]);
|
||||
jsonInst(root["inst"]);
|
||||
jsonWifi(root[F("wifi")]);
|
||||
jsonNrf(root[F("nrf")]);
|
||||
jsonNtp(root[F("ntp")]);
|
||||
jsonSun(root[F("sun")]);
|
||||
jsonSerial(root[F("serial")]);
|
||||
jsonMqtt(root[F("mqtt")]);
|
||||
jsonLed(root[F("led")]);
|
||||
jsonPlugin(root[F("plugin")]);
|
||||
jsonInst(root[F("inst")]);
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
|
@ -252,6 +259,7 @@ class settings {
|
|||
jsonSerial(root.createNestedObject(F("serial")), true);
|
||||
jsonMqtt(root.createNestedObject(F("mqtt")), true);
|
||||
jsonLed(root.createNestedObject(F("led")), true);
|
||||
jsonPlugin(root.createNestedObject(F("plugin")), true);
|
||||
jsonInst(root.createNestedObject(F("inst")), true);
|
||||
|
||||
if(0 == serializeJson(root, fp)) {
|
||||
|
@ -323,13 +331,17 @@ class settings {
|
|||
mCfg.mqtt.rstValsNotAvail = false;
|
||||
mCfg.mqtt.rstValsCommStop = false;
|
||||
|
||||
mCfg.led.led0 = DEF_LED0_PIN;
|
||||
mCfg.led.led1 = DEF_LED1_PIN;
|
||||
mCfg.led.led0 = DEF_PIN_OFF;
|
||||
mCfg.led.led1 = DEF_PIN_OFF;
|
||||
|
||||
memset(&mCfg.inst, 0, sizeof(cfgInst_t));
|
||||
|
||||
mCfg.plugin.display.pwrSaveAtIvOffline = false;
|
||||
mCfg.plugin.display.contrast = 60;
|
||||
mCfg.plugin.display.logoEn = true;
|
||||
mCfg.plugin.display.pxShift = true;
|
||||
mCfg.plugin.display.pin0 = DEF_PIN_OFF; // SCL
|
||||
mCfg.plugin.display.pin1 = DEF_PIN_OFF; // SDA
|
||||
}
|
||||
|
||||
void jsonWifi(JsonObject obj, bool set = false) {
|
||||
|
@ -452,6 +464,32 @@ class settings {
|
|||
}
|
||||
}
|
||||
|
||||
void jsonPlugin(JsonObject obj, bool set = false) {
|
||||
if(set) {
|
||||
JsonObject disp = obj.createNestedObject("disp");
|
||||
disp[F("type")] = mCfg.plugin.display.type;
|
||||
disp[F("pwrSafe")] = (bool)mCfg.plugin.display.pwrSaveAtIvOffline;
|
||||
disp[F("logo")] = (bool)mCfg.plugin.display.logoEn;
|
||||
disp[F("pxShift")] = (bool)mCfg.plugin.display.pxShift;
|
||||
disp[F("wake")] = mCfg.plugin.display.wakeUp;
|
||||
disp[F("sleep")] = mCfg.plugin.display.sleepAt;
|
||||
disp[F("contrast")] = mCfg.plugin.display.contrast;
|
||||
disp[F("pin0")] = mCfg.plugin.display.pin0;
|
||||
disp[F("pin1")] = mCfg.plugin.display.pin1;
|
||||
} else {
|
||||
JsonObject disp = obj["disp"];
|
||||
mCfg.plugin.display.type = disp[F("type")];
|
||||
mCfg.plugin.display.pwrSaveAtIvOffline = (bool) disp[F("pwrSafe")];
|
||||
mCfg.plugin.display.logoEn = (bool) disp[F("logo")];
|
||||
mCfg.plugin.display.pxShift = (bool) disp[F("pxShift")];
|
||||
mCfg.plugin.display.wakeUp = disp[F("wake")];
|
||||
mCfg.plugin.display.sleepAt = disp[F("sleep")];
|
||||
mCfg.plugin.display.contrast = disp[F("contrast")];
|
||||
mCfg.plugin.display.pin0 = disp[F("pin0")];
|
||||
mCfg.plugin.display.pin1 = disp[F("pin1")];
|
||||
}
|
||||
}
|
||||
|
||||
void jsonInst(JsonObject obj, bool set = false) {
|
||||
if(set)
|
||||
obj[F("en")] = (bool)mCfg.inst.enabled;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 74
|
||||
#define VERSION_PATCH 75
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -315,6 +315,22 @@ class Inverter {
|
|||
return true;
|
||||
}
|
||||
|
||||
REC_TYP getChannelFieldValue(uint8_t channel, uint8_t fieldId, record_t<> *rec) {
|
||||
uint8_t pos = 0;
|
||||
if(NULL != rec) {
|
||||
for(; pos < rec->length; pos++) {
|
||||
if((rec->assign[pos].ch == channel) && (rec->assign[pos].fieldId == fieldId))
|
||||
break;
|
||||
}
|
||||
if(pos >= rec->length)
|
||||
return 0;
|
||||
|
||||
return rec->record[pos];
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
REC_TYP getValue(uint8_t pos, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getValue"));
|
||||
if(NULL == rec)
|
||||
|
|
|
@ -38,6 +38,8 @@ lib_deps =
|
|||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
;esp8266/DNSServer
|
||||
;esp8266/EEPROM
|
||||
;esp8266/ESP8266WiFi
|
||||
|
@ -89,60 +91,6 @@ monitor_filters =
|
|||
time ; Add timestamp with milliseconds for each new line
|
||||
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
[env:esp8266-nokia5110]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 80000000L
|
||||
build_flags = -D RELEASE -DU8X8_NO_HW_I2C -DENA_NOKIA
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp8266-ssd1306]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 80000000L
|
||||
build_flags = -D RELEASE -DENA_SSD1306
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp8266-sh1106]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 80000000L
|
||||
build_flags = -D RELEASE -DENA_SH1106
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp32-wroom32-release]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
|
@ -163,59 +111,3 @@ monitor_filters =
|
|||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
[env:esp32-wroom32-nokia5110]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
build_flags = -D RELEASE -std=gnu++14 -DU8X8_NO_HW_I2C -DENA_NOKIA
|
||||
build_unflags = -std=gnu++11
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp32-wroom32-ssd1306]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
build_flags = -D RELEASE -std=gnu++14 -DENA_SSD1306
|
||||
build_unflags = -std=gnu++11
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/ThingPulse/esp8266-oled-ssd1306.git
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp32-wroom32-sh1106]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
build_flags = -D RELEASE -std=gnu++14 -DENA_SH1106
|
||||
build_unflags = -std=gnu++11
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
https://github.com/bertmelis/espMqttClient#v1.3.3
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/ThingPulse/esp8266-oled-ssd1306.git
|
||||
https://github.com/JChristensen/Timezone
|
||||
olikraus/U8g2
|
|
@ -1,46 +1,41 @@
|
|||
#ifndef __MONOCHROME_DISPLAY__
|
||||
#define __MONOCHROME_DISPLAY__
|
||||
|
||||
/* esp8266 : SCL = 5, SDA = 4 */
|
||||
/* ewsp32 : SCL = 22, SDA = 21 */
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) || defined(ENA_SH1106)
|
||||
#include <U8g2lib.h>
|
||||
#ifdef ENA_NOKIA
|
||||
#define DISP_PROGMEM U8X8_PROGMEM
|
||||
#else // ENA_SSD1306 || ENA_SH1106
|
||||
#define DISP_PROGMEM PROGMEM
|
||||
#endif
|
||||
|
||||
#include <Timezone.h>
|
||||
|
||||
#include "../../utils/helper.h"
|
||||
#include "../../hm/hmSystem.h"
|
||||
|
||||
#define DISP_DEFAULT_TIMEOUT 60 // in seconds
|
||||
|
||||
|
||||
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 // ................
|
||||
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[] DISP_PROGMEM = {
|
||||
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};
|
||||
B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000
|
||||
};
|
||||
|
||||
|
||||
static TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
|
||||
static TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Tim
|
||||
|
@ -48,31 +43,41 @@ static TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central Eu
|
|||
template<class HMSYSTEM>
|
||||
class MonochromeDisplay {
|
||||
public:
|
||||
#ifdef ENA_NOKIA
|
||||
MonochromeDisplay() : mDisplay(U8G2_R0, 5, 4, 16), mCE(CEST, CET) {
|
||||
mNewPayload = false;
|
||||
mExtra = 0;
|
||||
}
|
||||
#else // ENA_SSD1306 || ENA_SH1106
|
||||
MonochromeDisplay() : mDisplay(U8G2_R0, SCL, SDA, U8X8_PIN_NONE), mCE(CEST, CET) {
|
||||
mNewPayload = false;
|
||||
mExtra = 0;
|
||||
}
|
||||
#endif
|
||||
uint8_t dispContrast = 60;
|
||||
|
||||
void setup(display_t *cfg, HMSYSTEM *sys, uint32_t *utcTs) {
|
||||
MonochromeDisplay() : mCE(CEST, CET) {}
|
||||
|
||||
void setup(display_t *cfg, HMSYSTEM *sys, uint32_t *utcTs, uint8_t disp_reset, const char *version) {
|
||||
mCfg = cfg;
|
||||
mSys = sys;
|
||||
mUtcTs = utcTs;
|
||||
memset( mToday, 0, sizeof(float)*MAX_NUM_INVERTERS );
|
||||
memset( mTotal, 0, sizeof(float)*MAX_NUM_INVERTERS );
|
||||
mLastHour = 25;
|
||||
mDisplay.begin();
|
||||
ShowInfoText("booting...");
|
||||
mNewPayload = false;
|
||||
mLoopCnt = 0;
|
||||
|
||||
mTimeout = DISP_DEFAULT_TIMEOUT; // power off timeout (after inverters go offline)
|
||||
if(mCfg->type) {
|
||||
switch(mCfg->type) {
|
||||
case 1:
|
||||
mDisplay = new U8G2_PCD8544_84X48_F_4W_HW_SPI(U8G2_R0, mCfg->pin0, mCfg->pin1, disp_reset);
|
||||
break;
|
||||
case 2:
|
||||
mDisplay = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, disp_reset, mCfg->pin0, mCfg->pin1);
|
||||
break;
|
||||
case 3:
|
||||
mDisplay = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, disp_reset, mCfg->pin0, mCfg->pin1);
|
||||
break;
|
||||
}
|
||||
mDisplay->begin();
|
||||
|
||||
void loop(void) {
|
||||
mIsLarge = ((mDisplay->getWidth() > 120) && (mDisplay->getHeight() > 60));
|
||||
calcLineHeights();
|
||||
|
||||
mDisplay->clearBuffer();
|
||||
mDisplay->setContrast(mCfg->contrast);
|
||||
printText("Ahoy!", 0, 35);
|
||||
printText(version, 3, 46);
|
||||
mDisplay->sendBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void payloadEventListener(uint8_t cmd) {
|
||||
|
@ -80,244 +85,136 @@ class MonochromeDisplay {
|
|||
}
|
||||
|
||||
void tickerSecond() {
|
||||
static int cnt=1;
|
||||
if(mNewPayload || !(cnt % 10)) {
|
||||
cnt=1;
|
||||
if(mCfg->pwrSaveAtIvOffline) {
|
||||
if(mTimeout != 0)
|
||||
mTimeout--;
|
||||
}
|
||||
if(mNewPayload || ((++mLoopCnt % 10) == 0)) {
|
||||
mNewPayload = false;
|
||||
mLoopCnt = 0;
|
||||
DataScreen();
|
||||
}
|
||||
else
|
||||
cnt++;
|
||||
}
|
||||
|
||||
private:
|
||||
void ShowInfoText(const char *txt) {
|
||||
/* u8g2_font_open_iconic_embedded_2x_t 'D' + 'G' + 'J' */
|
||||
mDisplay.clear();
|
||||
mDisplay.firstPage();
|
||||
do {
|
||||
const char *e;
|
||||
const char *p = txt;
|
||||
int y=10;
|
||||
mDisplay.setFont(u8g2_font_5x8_tr);
|
||||
while(1) {
|
||||
for(e=p+1; (*e && (*e != '\n')); e++);
|
||||
size_t len=e-p;
|
||||
mDisplay.setCursor(2,y);
|
||||
String res=((String)p).substring(0,len);
|
||||
mDisplay.print(res);
|
||||
if ( !*e )
|
||||
break;
|
||||
p=e+1;
|
||||
y+=12;
|
||||
}
|
||||
mDisplay.sendBuffer();
|
||||
} while( mDisplay.nextPage() );
|
||||
void DataScreen() {
|
||||
if (mCfg->type == 0)
|
||||
return;
|
||||
if(*mUtcTs == 0)
|
||||
return;
|
||||
|
||||
float totalPower = 0;
|
||||
float totalYieldDay = 0;
|
||||
float totalYieldTotal = 0;
|
||||
|
||||
bool isprod = false;
|
||||
|
||||
Inverter<> *iv;
|
||||
record_t<> *rec;
|
||||
for (uint8_t i = 0; i < mSys->getNumInverters(); i++) {
|
||||
iv = mSys->getInverterByPos(i);
|
||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
if (iv == NULL)
|
||||
continue;
|
||||
|
||||
if (iv->isProducing(*mUtcTs))
|
||||
isprod = true;
|
||||
|
||||
totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec);
|
||||
totalYieldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec);
|
||||
totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec);
|
||||
}
|
||||
|
||||
void DataScreen(void) {
|
||||
String timeStr = ah::getDateTimeStr(mCE.toLocal(*mUtcTs)).substring(2, 16);
|
||||
int hr = timeStr.substring(9,2).toInt();
|
||||
IPAddress ip = WiFi.localIP();
|
||||
float totalYield = 0.0, totalYieldToday = 0.0, totalActual = 0.0;
|
||||
char fmtText[32];
|
||||
int ucnt=0, num_inv=0;
|
||||
unsigned int pow_i[ MAX_NUM_INVERTERS ];
|
||||
mDisplay->clearBuffer();
|
||||
|
||||
memset( pow_i, 0, sizeof(unsigned int)* MAX_NUM_INVERTERS );
|
||||
if ( hr < mLastHour ) // next day ? reset today-values
|
||||
memset( mToday, 0, sizeof(float)*MAX_NUM_INVERTERS );
|
||||
mLastHour = hr;
|
||||
// Logos
|
||||
// pxMovement +x (0 - 6 px)
|
||||
uint8_t ex = (_mExtra % 7);
|
||||
if (isprod) {
|
||||
mDisplay->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow);
|
||||
if (mCfg->logoEn)
|
||||
mDisplay->drawXBMP(mDisplay->getWidth() - 24 + ex, 2, 16, 16, bmp_logo);
|
||||
}
|
||||
|
||||
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
||||
if (NULL != iv) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos;
|
||||
uint8_t list[] = {FLD_PAC, FLD_YT, FLD_YD};
|
||||
|
||||
for (uint8_t fld = 0; fld < 3; fld++) {
|
||||
pos = iv->getPosByChFld(CH0, list[fld],rec);
|
||||
int isprod = iv->isProducing(*mUtcTs);
|
||||
|
||||
if(fld == 1)
|
||||
{
|
||||
if ( isprod )
|
||||
mTotal[num_inv] = iv->getValue(pos,rec);
|
||||
totalYield += mTotal[num_inv];
|
||||
}
|
||||
if(fld == 2)
|
||||
{
|
||||
if ( isprod )
|
||||
mToday[num_inv] = iv->getValue(pos,rec);
|
||||
totalYieldToday += mToday[num_inv];
|
||||
}
|
||||
if((fld == 0) && isprod )
|
||||
{
|
||||
pow_i[num_inv] = iv->getValue(pos,rec);
|
||||
totalActual += iv->getValue(pos,rec);
|
||||
ucnt++;
|
||||
}
|
||||
}
|
||||
num_inv++;
|
||||
}
|
||||
}
|
||||
/* u8g2_font_open_iconic_embedded_2x_t 'D' + 'G' + 'J' */
|
||||
mDisplay.clear();
|
||||
mDisplay.firstPage();
|
||||
do {
|
||||
#ifdef ENA_NOKIA
|
||||
if(ucnt) {
|
||||
//=====> Actual Production
|
||||
mDisplay.drawXBMP(10,1,8,17,bmp_arrow);
|
||||
mDisplay.setFont(u8g2_font_logisoso16_tr);
|
||||
mDisplay.setCursor(25,17);
|
||||
if (totalActual>999){
|
||||
sprintf(fmtText,"%2.1f",(totalActual/1000));
|
||||
mDisplay.print(String(fmtText)+F(" kW"));
|
||||
if ((totalPower > 0) && isprod) {
|
||||
mTimeout = DISP_DEFAULT_TIMEOUT;
|
||||
mDisplay->setPowerSave(false);
|
||||
mDisplay->setContrast(mCfg->contrast);
|
||||
if (totalPower > 999)
|
||||
snprintf(_fmtText, sizeof(_fmtText), "%2.1f kW", (totalPower / 1000));
|
||||
else
|
||||
snprintf(_fmtText, sizeof(_fmtText), "%3.0f W", totalPower);
|
||||
printText(_fmtText, 0, 20);
|
||||
} else {
|
||||
sprintf(fmtText,"%3.0f",totalActual);
|
||||
mDisplay.print(String(fmtText)+F(" W"));
|
||||
}
|
||||
//<=======================
|
||||
}
|
||||
else
|
||||
{
|
||||
//=====> Offline
|
||||
mDisplay.setFont(u8g2_font_logisoso16_tr );
|
||||
mDisplay.setCursor(10,17);
|
||||
mDisplay.print(String(F("offline")));
|
||||
//<=======================
|
||||
|
||||
}
|
||||
mDisplay.drawHLine(2,20,78);
|
||||
mDisplay.setFont(u8g2_font_5x8_tr);
|
||||
mDisplay.setCursor(5,29);
|
||||
if (( num_inv < 2 ) || !(mExtra%2))
|
||||
{
|
||||
sprintf(fmtText,"%4.0f",totalYieldToday);
|
||||
mDisplay.print(F("today ")+String(fmtText)+F(" Wh"));
|
||||
mDisplay.setCursor(5,37);
|
||||
sprintf(fmtText,"%.1f",totalYield);
|
||||
mDisplay.print(F("total ")+String(fmtText)+F(" kWh"));
|
||||
}
|
||||
else
|
||||
{
|
||||
int id1=(mExtra/2)%(num_inv-1);
|
||||
if( pow_i[id1] )
|
||||
mDisplay.print(F("#")+String(id1+1)+F(" ")+String(pow_i[id1])+F(" W"));
|
||||
else
|
||||
mDisplay.print(F("#")+String(id1+1)+F(" -----"));
|
||||
mDisplay.setCursor(5,37);
|
||||
if( pow_i[id1+1] )
|
||||
mDisplay.print(F("#")+String(id1+2)+F(" ")+String(pow_i[id1+1])+F(" W"));
|
||||
else
|
||||
mDisplay.print(F("#")+String(id1+2)+F(" -----"));
|
||||
}
|
||||
if ( !(mExtra%10) && ip ) {
|
||||
mDisplay.setCursor(5,47);
|
||||
mDisplay.print(ip.toString());
|
||||
}
|
||||
else {
|
||||
mDisplay.setCursor(5,47);
|
||||
mDisplay.print(timeStr);
|
||||
}
|
||||
#else // ENA_SSD1306
|
||||
mDisplay.setContrast(mCfg->contrast);
|
||||
// pxZittern in +x (0 - 8 px)
|
||||
int ex = 2*( mExtra % 5 );
|
||||
mDisplay.drawXBM(100+ex,2,16,16,bmp_logo);
|
||||
mDisplay.setFont(u8g2_font_ncenB08_tr);
|
||||
if(ucnt) {
|
||||
//=====> Actual Production
|
||||
mDisplay.setPowerSave(false);
|
||||
displaySleep=false;
|
||||
mDisplay.setFont(u8g2_font_logisoso18_tr);
|
||||
mDisplay.drawXBM(10+ex,2,8,17,bmp_arrow);
|
||||
mDisplay.setCursor(25+ex,20);
|
||||
if (totalActual>999){
|
||||
sprintf(fmtText,"%2.1f",(totalActual/1000));
|
||||
mDisplay.print(String(fmtText)+F(" kW"));
|
||||
} else {
|
||||
sprintf(fmtText,"%3.0f",totalActual);
|
||||
mDisplay.print(String(fmtText)+F(" W"));
|
||||
}
|
||||
//<=======================
|
||||
}
|
||||
else
|
||||
{
|
||||
//=====> Offline
|
||||
if(!displaySleep) {
|
||||
displaySleepTimer = millis();
|
||||
displaySleep=true;
|
||||
}
|
||||
mDisplay.setFont(u8g2_font_logisoso18_tr);
|
||||
mDisplay.setCursor(10+ex,20);
|
||||
mDisplay.print(String(F("offline")));
|
||||
printText("offline", 0, 25);
|
||||
if(mCfg->pwrSaveAtIvOffline) {
|
||||
if ((millis() - displaySleepTimer) > displaySleepDelay)
|
||||
mDisplay.setPowerSave(true);
|
||||
if(mTimeout == 0)
|
||||
mDisplay->setPowerSave(true);
|
||||
}
|
||||
//<=======================
|
||||
}
|
||||
mDisplay.drawLine(2+ex, 23, 123, 23);
|
||||
mDisplay.setFont(u8g2_font_ncenB10_tr);
|
||||
mDisplay.setCursor(2+ex,36);
|
||||
if (( num_inv < 2 ) || !(mExtra%2))
|
||||
{
|
||||
//=====> Today & Total Production
|
||||
sprintf(fmtText,"%5.0f",totalYieldToday);
|
||||
mDisplay.print(F("today: ")+String(fmtText)+F(" Wh"));
|
||||
mDisplay.setCursor(2+ex,50);
|
||||
sprintf(fmtText,"%.1f",totalYield);
|
||||
mDisplay.print(F("total: ")+String(fmtText)+F(" kWh"));
|
||||
//<=======================
|
||||
|
||||
snprintf(_fmtText, sizeof(_fmtText), "today: %4.0f Wh", totalYieldDay);
|
||||
printText(_fmtText, 1);
|
||||
|
||||
snprintf(_fmtText, sizeof(_fmtText), "total: %.1f kWh", totalYieldTotal);
|
||||
printText(_fmtText, 2);
|
||||
|
||||
IPAddress ip = WiFi.localIP();
|
||||
if (!(_mExtra % 10) && (ip)) {
|
||||
printText(ip.toString().c_str(), 3);
|
||||
} else {
|
||||
int id1=(mExtra/2)%(num_inv-1);
|
||||
if( pow_i[id1] )
|
||||
mDisplay.print(F("#")+String(id1+1)+F(" ")+String(pow_i[id1])+F(" W"));
|
||||
// Get current time
|
||||
if(mIsLarge)
|
||||
printText(ah::getDateTimeStr(mCE.toLocal(*mUtcTs)).c_str(), 3);
|
||||
else
|
||||
mDisplay.print(F("#")+String(id1+1)+F(" -----"));
|
||||
mDisplay.setCursor(5+ex,50);
|
||||
if( pow_i[id1+1] )
|
||||
mDisplay.print(F("#")+String(id1+2)+F(" ")+String(pow_i[id1+1])+F(" W"));
|
||||
else
|
||||
mDisplay.print(F("#")+String(id1+2)+F(" -----"));
|
||||
printText(ah::getTimeStr(mCE.toLocal(*mUtcTs)).c_str(), 3);
|
||||
}
|
||||
mDisplay.setFont(u8g2_font_5x8_tr);
|
||||
mDisplay.setCursor(5+ex,63);
|
||||
if ( !(mExtra%10) && ip )
|
||||
mDisplay.print(ip.toString());
|
||||
else
|
||||
mDisplay.print(timeStr);
|
||||
#endif
|
||||
mDisplay.sendBuffer();
|
||||
} while( mDisplay.nextPage() );
|
||||
delay(200);
|
||||
mExtra++;
|
||||
mDisplay->sendBuffer();
|
||||
|
||||
_mExtra++;
|
||||
}
|
||||
|
||||
void calcLineHeights() {
|
||||
uint8_t yOff = 0;
|
||||
for(uint8_t i = 0; i < 4; i++) {
|
||||
setFont(i);
|
||||
yOff += (mDisplay->getMaxCharHeight() + 1);
|
||||
mLineOffsets[i] = yOff;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setFont(uint8_t line) {
|
||||
switch (line) {
|
||||
case 0: mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB14_tr : u8g2_font_lubBI14_tr); break;
|
||||
case 3: mDisplay->setFont(u8g2_font_5x8_tr); break;
|
||||
default: mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB10_tr : u8g2_font_5x8_tr); break;
|
||||
}
|
||||
}
|
||||
|
||||
void printText(const char* text, uint8_t line, uint8_t dispX = 5) {
|
||||
if(!mIsLarge)
|
||||
dispX = 5;
|
||||
setFont(line);
|
||||
if(mCfg->pxShift)
|
||||
dispX += (_mExtra % 7); // add pixel movement
|
||||
mDisplay->drawStr(dispX, mLineOffsets[line], text);
|
||||
}
|
||||
|
||||
// private member variables
|
||||
#ifdef ENA_NOKIA
|
||||
U8G2_PCD8544_84X48_1_4W_HW_SPI mDisplay;
|
||||
#elif defined(ENA_SSD1306)
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C mDisplay;
|
||||
#elif defined(ENA_SH1106)
|
||||
U8G2_SH1106_128X64_NONAME_F_HW_I2C mDisplay;
|
||||
#endif
|
||||
int mExtra;
|
||||
U8G2* mDisplay;
|
||||
|
||||
uint8_t _mExtra;
|
||||
uint16_t mTimeout; // interval at which to power save (milliseconds)
|
||||
char _fmtText[32];
|
||||
|
||||
bool mNewPayload;
|
||||
float mTotal[ MAX_NUM_INVERTERS ];
|
||||
float mToday[ MAX_NUM_INVERTERS ];
|
||||
bool mIsLarge;
|
||||
uint8_t mLoopCnt;
|
||||
uint32_t *mUtcTs;
|
||||
int mLastHour;
|
||||
uint8_t mLineOffsets[5];
|
||||
display_t *mCfg;
|
||||
HMSYSTEM *mSys;
|
||||
Timezone mCE;
|
||||
bool displaySleep;
|
||||
uint32_t displaySleepTimer;
|
||||
const uint32_t displaySleepDelay= 60000;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /*__MONOCHROME_DISPLAY__*/
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#ifndef __DBG_H__
|
||||
#define __DBG_H__
|
||||
#if defined(F) //defined(ESP32) &&
|
||||
#if defined(F) && defined(ESP32)
|
||||
#undef F
|
||||
#define F(sl) (sl)
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "../appInterface.h"
|
||||
|
||||
#if defined(F) //defined(ESP32) &&
|
||||
#if defined(F) && defined(ESP32)
|
||||
#undef F
|
||||
#define F(sl) (sl)
|
||||
#endif
|
||||
|
@ -354,6 +354,16 @@ class RestApi {
|
|||
ah::ip2Char(mConfig->sys.ip.gateway, buf); obj[F("gateway")] = String(buf);
|
||||
}
|
||||
|
||||
void getDisplay(JsonObject obj) {
|
||||
obj[F("disp_type")] = (uint8_t)mConfig->plugin.display.type;
|
||||
obj[F("disp_pwr")] = (bool)mConfig->plugin.display.pwrSaveAtIvOffline;
|
||||
obj[F("logo_en")] = (bool)mConfig->plugin.display.logoEn;
|
||||
obj[F("px_shift")] = (bool)mConfig->plugin.display.pxShift;
|
||||
obj[F("contrast")] = (uint8_t)mConfig->plugin.display.contrast;
|
||||
obj[F("pinDisp0")] = mConfig->plugin.display.pin0;
|
||||
obj[F("pinDisp1")] = mConfig->plugin.display.pin1;
|
||||
}
|
||||
|
||||
void getMenu(JsonObject obj) {
|
||||
uint8_t i = 0;
|
||||
uint16_t mask = (mApp->getProtection()) ? mConfig->sys.protectionMask : 0;
|
||||
|
@ -461,6 +471,7 @@ class RestApi {
|
|||
getRadio(obj.createNestedObject(F("radio")));
|
||||
getSerial(obj.createNestedObject(F("serial")));
|
||||
getStaticIp(obj.createNestedObject(F("static_ip")));
|
||||
getDisplay(obj.createNestedObject(F("display")));
|
||||
}
|
||||
|
||||
void getNetworks(JsonObject obj) {
|
||||
|
|
|
@ -165,7 +165,7 @@
|
|||
<div class="s_content">
|
||||
<fieldset>
|
||||
<legend class="des">System Config</legend>
|
||||
<p class="des">Pinout (Wemos)</p>
|
||||
<p class="des">Pinout</p>
|
||||
<div id="pinout"></div>
|
||||
|
||||
<p class="des">Radio (NRF24L01+)</p>
|
||||
|
@ -181,6 +181,25 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
|
||||
<button type="button" class="s_collapsible">Display Config</button>
|
||||
<div class="s_content">
|
||||
<fieldset>
|
||||
<legend class="des">Display Config</legend>
|
||||
<div id="dispType"></div>
|
||||
<label for="logoEn">Show Logo</label>
|
||||
<input type="checkbox" class="cb" name="logoEn"/><br/>
|
||||
<label for="dispPwr">Turn off while inverters are offline</label>
|
||||
<input type="checkbox" class="cb" name="dispPwr"/><br/>
|
||||
<label for="dispPxSh">Enable pixel shifting</label>
|
||||
<input type="checkbox" class="cb" name="dispPxSh"/><br/>
|
||||
|
||||
<label for="dispCont">Contrast</label>
|
||||
<select name="dispCont" id="contrast"></select>
|
||||
<p class="des">Pinout</p>
|
||||
<div id="dispPins"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="reboot">Reboot device after successful save</label>
|
||||
<input type="checkbox" class="cb" name="reboot" checked />
|
||||
|
@ -221,6 +240,56 @@
|
|||
var highestId = 0;
|
||||
var maxInv = 0;
|
||||
|
||||
var esp8266pins = [
|
||||
[255, "off / default"],
|
||||
[0, "D3 (GPIO0)"],
|
||||
[1, "TX (GPIO1)"],
|
||||
[2, "D4 (GPIO2)"],
|
||||
[3, "RX (GPIO3)"],
|
||||
[4, "D2 (GPIO4, SDA)"],
|
||||
[5, "D1 (GPIO5, SCL)"],
|
||||
[6, "GPIO6"],
|
||||
[7, "GPIO7"],
|
||||
[8, "GPIO8"],
|
||||
[9, "GPIO9"],
|
||||
[10, "GPIO10"],
|
||||
[11, "GPIO11"],
|
||||
[12, "D6 (GPIO12)"],
|
||||
[13, "D7 (GPIO13)"],
|
||||
[14, "D5 (GPIO14)"],
|
||||
[15, "D8 (GPIO15)"],
|
||||
[16, "D0 (GPIO16 - no IRQ!)"]
|
||||
];
|
||||
var esp32pins = [
|
||||
[255, "off / default"],
|
||||
[0, "GPIO0"],
|
||||
[1, "TX (GPIO1)"],
|
||||
[2, "GPIO2 (LED)"],
|
||||
[3, "RX (GPIO3)"],
|
||||
[4, "GPIO4"],
|
||||
[5, "GPIO5"],
|
||||
[12, "GPIO12"],
|
||||
[13, "GPIO13"],
|
||||
[14, "GPIO14"],
|
||||
[15, "GPIO15"],
|
||||
[16, "GPIO16"],
|
||||
[17, "GPIO17"],
|
||||
[18, "GPIO18"],
|
||||
[19, "GPIO19"],
|
||||
[21, "GPIO21 (SDA)"],
|
||||
[22, "GPIO22 (SCL)"],
|
||||
[23, "GPIO23"],
|
||||
[25, "GPIO25"],
|
||||
[26, "GPIO26"],
|
||||
[27, "GPIO27"],
|
||||
[32, "GPIO32"],
|
||||
[33, "GPIO33"],
|
||||
[34, "GPIO34"],
|
||||
[35, "GPIO35"],
|
||||
[36, "VP (GPIO36)"],
|
||||
[39, "VN (GPIO39)"]
|
||||
];
|
||||
|
||||
const re = /11[2,4,6]1.*/;
|
||||
|
||||
document.getElementById("btnAdd").addEventListener("click", function() {
|
||||
|
@ -443,59 +512,7 @@
|
|||
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['led0', 'pinLed0'], ['led1', 'pinLed1']];
|
||||
for(p of pins) {
|
||||
e.appendChild(lbl(p[1], p[0].toUpperCase()));
|
||||
if("ESP8266" == type) {
|
||||
e.appendChild(sel(p[1], [
|
||||
[255, "off / default"],
|
||||
[0, "D3 (GPIO0)"],
|
||||
[1, "TX (GPIO1)"],
|
||||
[2, "D4 (GPIO2)"],
|
||||
[3, "RX (GPIO3)"],
|
||||
[4, "D2 (GPIO4)"],
|
||||
[5, "D1 (GPIO5)"],
|
||||
[6, "GPIO6"],
|
||||
[7, "GPIO7"],
|
||||
[8, "GPIO8"],
|
||||
[9, "GPIO9"],
|
||||
[10, "GPIO10"],
|
||||
[11, "GPIO11"],
|
||||
[12, "D6 (GPIO12)"],
|
||||
[13, "D7 (GPIO13)"],
|
||||
[14, "D5 (GPIO14)"],
|
||||
[15, "D8 (GPIO15)"],
|
||||
[16, "D0 (GPIO16 - no IRQ!)"]
|
||||
], obj[p[0]]));
|
||||
}
|
||||
else {
|
||||
e.appendChild(sel(p[1], [
|
||||
[255, "off / default"],
|
||||
[0, "GPIO0"],
|
||||
[1, "TX (GPIO1)"],
|
||||
[2, "GPIO2 (LED)"],
|
||||
[3, "RX (GPIO3)"],
|
||||
[4, "GPIO4"],
|
||||
[5, "GPIO5"],
|
||||
[12, "GPIO12"],
|
||||
[13, "GPIO13"],
|
||||
[14, "GPIO14"],
|
||||
[15, "GPIO15"],
|
||||
[16, "GPIO16"],
|
||||
[17, "GPIO17"],
|
||||
[18, "GPIO18"],
|
||||
[19, "GPIO19"],
|
||||
[21, "GPIO21"],
|
||||
[22, "GPIO22"],
|
||||
[23, "GPIO23"],
|
||||
[25, "GPIO25"],
|
||||
[26, "GPIO26"],
|
||||
[27, "GPIO27"],
|
||||
[32, "GPIO32"],
|
||||
[33, "GPIO33"],
|
||||
[34, "GPIO34"],
|
||||
[35, "GPIO35"],
|
||||
[36, "VP (GPIO36)"],
|
||||
[39, "VN (GPIO39)"]
|
||||
], obj[p[0]]));
|
||||
}
|
||||
e.appendChild(sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,6 +533,29 @@
|
|||
document.getElementsByName("serIntvl")[0].value = obj["interval"];
|
||||
}
|
||||
|
||||
function parseDisplay(obj, type) {
|
||||
for(var i of [["logoEn", "logo_en"], ["dispPwr", "disp_pwr"], ["dispPxSh", "px_shift"]])
|
||||
document.getElementsByName(i[0])[0].checked = obj[i[1]];
|
||||
|
||||
var e = document.getElementById("dispPins");
|
||||
pins = [['SCL / CS', 'pinDisp0'], ['SDA / DC', 'pinDisp1']];
|
||||
for(p of pins) {
|
||||
e.appendChild(lbl(p[1], p[0].toUpperCase()));
|
||||
e.appendChild(sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[1]]));
|
||||
}
|
||||
|
||||
var opts = [[0, "None"], [1, "Nokia5110"], [2, "SSD1306 0.96\""], [3, "SH1106 1.3\""]];
|
||||
document.getElementById("dispType").append(
|
||||
lbl("dispType", "Type"),
|
||||
sel("dispType", opts, obj["disp_type"])
|
||||
);
|
||||
|
||||
e = document.getElementById("contrast");
|
||||
for(var i = 30; i < 101; i += 2) {
|
||||
e.appendChild(opt(i, i, (i == obj["contrast"])));
|
||||
}
|
||||
}
|
||||
|
||||
function parse(root) {
|
||||
if(null != root) {
|
||||
parseMenu(root["menu"]);
|
||||
|
@ -529,6 +569,7 @@
|
|||
parsePinout(root["pinout"], root["system"]["esp_type"]);
|
||||
parseRadio(root["radio"]);
|
||||
parseSerial(root["serial"]);
|
||||
parseDisplay(root["display"], root["system"]["esp_type"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,7 +596,7 @@
|
|||
hiddenInput = document.getElementById("disclaimer")
|
||||
hiddenInput.value = sessionStorage.getItem("gDisclaimer");
|
||||
|
||||
getAjax("/api/setup", parse);
|
||||
getAjax("http://10.20.3.44/api/setup", parse);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -562,6 +562,17 @@ class Web {
|
|||
// Needed to log TX buffers to serial console
|
||||
mSys->Radio.mSerialDebug = mConfig->serial.debug;
|
||||
}
|
||||
|
||||
// display
|
||||
mConfig->plugin.display.pwrSaveAtIvOffline = (request->arg("dispPwr") == "on");
|
||||
mConfig->plugin.display.logoEn = (request->arg("logoEn") == "on");
|
||||
mConfig->plugin.display.pxShift = (request->arg("dispPxSh") == "on");
|
||||
mConfig->plugin.display.type = request->arg("dispType").toInt();
|
||||
mConfig->plugin.display.contrast = request->arg("dispCont").toInt();
|
||||
mConfig->plugin.display.pin0 = request->arg("pinDisp0").toInt();
|
||||
mConfig->plugin.display.pin1 = request->arg("pinDisp1").toInt();
|
||||
|
||||
|
||||
mApp->saveSettings();
|
||||
|
||||
if(request->arg("reboot") == "on")
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
// NTP CONFIG
|
||||
#define NTP_PACKET_SIZE 48
|
||||
#define NTP_RETRIES 5
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1) {}
|
||||
|
@ -26,7 +25,7 @@ void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb) {
|
|||
mStaConn = DISCONNECTED;
|
||||
mCnt = 0;
|
||||
mScanActive = false;
|
||||
mRetries = NTP_RETRIES;
|
||||
mLastNtpFailed = false;
|
||||
|
||||
#if defined(ESP8266)
|
||||
wifiConnectHandler = WiFi.onStationModeConnected(std::bind(&ahoywifi::onConnect, this, std::placeholders::_1));
|
||||
|
@ -149,26 +148,25 @@ void ahoywifi::setupStation(void) {
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ahoywifi::getNtpTime(uint32_t *nxtTrig) {
|
||||
if(0 != mRetries) {
|
||||
DPRINTLN(DBG_INFO, "try to getNtpTime");
|
||||
*nxtTrig = 43200; // check again in 12h (if NTP was successful)
|
||||
mRetries--;
|
||||
} else if(0 != *mUtcTimestamp) { // time is availabe, but NTP not
|
||||
*nxtTrig = 5; // check again 5s
|
||||
mRetries = NTP_RETRIES;
|
||||
bool ahoywifi::getNtpTime() {
|
||||
if(mLastNtpFailed && (0 != *mUtcTimestamp)) { // time is available, but NTP not maybe it was set by "sync with browser"
|
||||
mLastNtpFailed = false;
|
||||
return true; // true is necessary to enable all timers even if NTP was not reachable
|
||||
}
|
||||
|
||||
if(GOT_IP != mStaConn)
|
||||
if(GOT_IP != mStaConn) {
|
||||
mLastNtpFailed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
IPAddress timeServer;
|
||||
uint8_t buf[NTP_PACKET_SIZE];
|
||||
uint8_t retry = 0;
|
||||
|
||||
if (WiFi.hostByName(mConfig->ntp.addr, timeServer) != 1)
|
||||
if (WiFi.hostByName(mConfig->ntp.addr, timeServer) != 1) {
|
||||
mLastNtpFailed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
mUdp.begin(mConfig->ntp.port);
|
||||
sendNTPpacket(timeServer);
|
||||
|
@ -193,6 +191,7 @@ bool ahoywifi::getNtpTime(uint32_t *nxtTrig) {
|
|||
}
|
||||
|
||||
DPRINTLN(DBG_INFO, F("[NTP]: getNtpTime failed"));
|
||||
mLastNtpFailed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -275,10 +274,10 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) {
|
|||
if(mStaConn != CONNECTING) {
|
||||
mStaConn = DISCONNECTED;
|
||||
mCnt = 5; // try to reconnect in 5 sec
|
||||
mLastNtpFailed = false;
|
||||
setupWifi(); // reconnect with AP / Station setup
|
||||
mAppWifiCb(false);
|
||||
DPRINTLN(DBG_INFO, "[WiFi] Connection Lost");
|
||||
mRetries = NTP_RETRIES;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class ahoywifi {
|
|||
|
||||
void setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb);
|
||||
void tickWifiLoop(void);
|
||||
bool getNtpTime(uint32_t *nxtTrig);
|
||||
bool getNtpTime();
|
||||
void scanAvailNetworks(void);
|
||||
void getAvailNetworks(JsonObject obj);
|
||||
|
||||
|
@ -68,7 +68,7 @@ class ahoywifi {
|
|||
|
||||
uint8_t mLoopCnt;
|
||||
bool mScanActive;
|
||||
uint8_t mRetries;
|
||||
bool mLastNtpFailed;
|
||||
};
|
||||
|
||||
#endif /*__AHOYWIFI_H__*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue