From 2ff50169b92565fe9d64030a344e608323dc8786 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 21 Jan 2020 18:17:40 +0300 Subject: [PATCH 1/4] Static configuration for LED and Buttons - use similar to relay & wifi, configuration through helper methods that use indexed defines - clock cycles for led delay polling - button mode defaults --- code/espurna/button.h | 41 +++++ code/espurna/button.ino | 207 ++++++++++------------- code/espurna/button_config.h | 172 +++++++++++++++++++ code/espurna/config/defaults.h | 61 ++++--- code/espurna/config/deprecated.h | 6 + code/espurna/config/hardware.h | 2 + code/espurna/config/types.h | 8 +- code/espurna/espurna.ino | 2 + code/espurna/led.h | 45 +++++ code/espurna/led.ino | 276 +++++++++++++++++-------------- code/espurna/led_config.h | 59 +++++++ code/espurna/relay.ino | 1 + 12 files changed, 609 insertions(+), 271 deletions(-) create mode 100644 code/espurna/button.h create mode 100644 code/espurna/button_config.h create mode 100644 code/espurna/led.h create mode 100644 code/espurna/led_config.h diff --git a/code/espurna/button.h b/code/espurna/button.h new file mode 100644 index 00000000..c1bb8850 --- /dev/null +++ b/code/espurna/button.h @@ -0,0 +1,41 @@ +/* + +BUTTON MODULE + +Copyright (C) 2016-2019 by Xose Pérez + +*/ + +#pragma once + +#include + +struct button_t { + + // TODO: dblclick and debounce delays - right now a global setting, independent of ID + static unsigned long DebounceDelay; + static unsigned long DblclickDelay; + + // Use built-in indexed definitions to configure DebounceEvent + button_t(unsigned char index); + + // Provide custom DebounceEvent parameters instead + button_t(unsigned char pin, unsigned char mode, unsigned long actions, unsigned char relayID); + + bool state(); + + std::unique_ptr event; + unsigned long actions; + unsigned char relayID; +}; + +bool buttonState(unsigned char id); +unsigned char buttonAction(unsigned char id, unsigned char event); + +void buttonMQTT(unsigned char id, uint8_t event); +void buttonEvent(unsigned char id, unsigned char event); + +unsigned char buttonAdd(unsigned char pin, unsigned char mode, unsigned long actions, unsigned char relayID = RELAY_NONE); + +unsigned char buttonCount(); +void buttonSetup(); diff --git a/code/espurna/button.ino b/code/espurna/button.ino index 39580717..e45b5e11 100644 --- a/code/espurna/button.ino +++ b/code/espurna/button.ino @@ -6,32 +6,49 @@ Copyright (C) 2016-2019 by Xose Pérez */ -// ----------------------------------------------------------------------------- -// BUTTON -// ----------------------------------------------------------------------------- - #if BUTTON_SUPPORT #include +#include #include #include "system.h" #include "relay.h" #include "light.h" -typedef struct { - DebounceEvent * button; - unsigned long actions; - unsigned int relayID; -} button_t; +#include "button.h" +#include "button_config.h" + +// ----------------------------------------------------------------------------- + +// TODO: dblclick and debounce delays - right now a global setting, independent of ID +unsigned long button_t::DebounceDelay = BUTTON_DEBOUNCE_DELAY; +unsigned long button_t::DblclickDelay = BUTTON_DBLCLICK_DELAY; + +button_t::button_t(unsigned char pin, unsigned char mode, unsigned long actions, unsigned char relayID) : + event(new DebounceEvent(pin, mode, DebounceDelay, DblclickDelay)), + actions(actions), + relayID(relayID) +{} + +button_t::button_t(unsigned char index) : + button_t(_buttonPin(index), _buttonMode(index), _buttonConstructActions(index), _buttonRelay(index)) +{} + +bool button_t::state() { + return event->pressed(); +} std::vector _buttons; +unsigned char buttonCount() { + return _buttons.size(); +} + #if MQTT_SUPPORT void buttonMQTT(unsigned char id, uint8_t event) { - if (id >= _buttons.size()) return; - char payload[2]; + char payload[4] = {0}; itoa(event, payload, 10); mqttSend(MQTT_TOPIC_BUTTON, id, payload, false, false); // 1st bool = force, 2nd = retain } @@ -40,12 +57,8 @@ void buttonMQTT(unsigned char id, uint8_t event) { #if WEB_SUPPORT -unsigned char _buttonCount() { - return _buttons.size(); -} - void _buttonWebSocketOnVisible(JsonObject& root) { - if (_buttonCount() > 0) { + if (buttonCount() > 0) { root["btnVisible"] = 1; } } @@ -56,62 +69,23 @@ bool _buttonWebSocketOnKeyCheck(const char * key, JsonVariant& value) { #endif -int buttonFromRelay(unsigned int relayID) { - for (unsigned int i=0; i < _buttons.size(); i++) { - if (_buttons[i].relayID == relayID) return i; - } - return -1; -} - bool buttonState(unsigned char id) { if (id >= _buttons.size()) return false; - return _buttons[id].button->pressed(); + return _buttons[id].state(); } unsigned char buttonAction(unsigned char id, unsigned char event) { if (id >= _buttons.size()) return BUTTON_MODE_NONE; - unsigned long actions = _buttons[id].actions; - if (event == BUTTON_EVENT_PRESSED) return (actions) & 0x0F; - if (event == BUTTON_EVENT_CLICK) return (actions >> 4) & 0x0F; - if (event == BUTTON_EVENT_DBLCLICK) return (actions >> 8) & 0x0F; - if (event == BUTTON_EVENT_LNGCLICK) return (actions >> 12) & 0x0F; - if (event == BUTTON_EVENT_LNGLNGCLICK) return (actions >> 16) & 0x0F; - if (event == BUTTON_EVENT_TRIPLECLICK) return (actions >> 20) & 0x0F; - return BUTTON_MODE_NONE; + return _buttonDecodeEventAction(_buttons[id].actions, event); } -unsigned long buttonStore(unsigned long pressed, unsigned long click, unsigned long dblclick, unsigned long lngclick, unsigned long lnglngclick, unsigned long tripleclick) { - unsigned int value; - value = pressed; - value += click << 4; - value += dblclick << 8; - value += lngclick << 12; - value += lnglngclick << 16; - value += tripleclick << 20; - return value; -} - -uint8_t mapEvent(uint8_t event, uint8_t count, uint16_t length) { - if (event == EVENT_PRESSED) return BUTTON_EVENT_PRESSED; - if (event == EVENT_CHANGED) return BUTTON_EVENT_CLICK; - if (event == EVENT_RELEASED) { - if (1 == count) { - if (length > BUTTON_LNGLNGCLICK_DELAY) return BUTTON_EVENT_LNGLNGCLICK; - if (length > BUTTON_LNGCLICK_DELAY) return BUTTON_EVENT_LNGCLICK; - return BUTTON_EVENT_CLICK; - } - if (2 == count) return BUTTON_EVENT_DBLCLICK; - if (3 == count) return BUTTON_EVENT_TRIPLECLICK; - } - return BUTTON_EVENT_NONE; -} - -void buttonEvent(unsigned int id, unsigned char event) { +void buttonEvent(unsigned char id, unsigned char event) { DEBUG_MSG_P(PSTR("[BUTTON] Button #%u event %u\n"), id, event); if (event == 0) return; - unsigned char action = buttonAction(id, event); + auto& button = _buttons[id]; + unsigned char action = _buttonDecodeEventAction(button.actions, event); #if MQTT_SUPPORT if (action != BUTTON_MODE_NONE || BUTTON_MQTT_SEND_ALL_EVENTS) { @@ -120,21 +94,15 @@ void buttonEvent(unsigned int id, unsigned char event) { #endif if (BUTTON_MODE_TOGGLE == action) { - if (_buttons[id].relayID > 0) { - relayToggle(_buttons[id].relayID - 1); - } + relayToggle(button.relayID); } if (BUTTON_MODE_ON == action) { - if (_buttons[id].relayID > 0) { - relayStatus(_buttons[id].relayID - 1, true); - } + relayStatus(button.relayID, true); } if (BUTTON_MODE_OFF == action) { - if (_buttons[id].relayID > 0) { - relayStatus(_buttons[id].relayID - 1, false); - } + relayStatus(button.relayID, false); } if (BUTTON_MODE_AP == action) { @@ -180,81 +148,74 @@ void buttonEvent(unsigned int id, unsigned char event) { } +unsigned char buttonAdd(unsigned char pin, unsigned char mode, unsigned long actions, unsigned char relayID) { + _buttons.emplace_back(pin, mode, actions, relayID); + return _buttons.size() - 1; +} + void buttonSetup() { + // Special hardware cases + #if defined(ITEAD_SONOFF_DUAL) - unsigned int actions = buttonStore(BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE); - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, 1}); - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, 2}); - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, BUTTON3_RELAY}); + buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(0)); + buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(1)); + buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(2)); #elif defined(FOXEL_LIGHTFOX_DUAL) - unsigned int actions = buttonStore(BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE); - unsigned int btn1Relay = getSetting({"btnRelay", 0}, BUTTON1_RELAY - 1) + 1; - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn1Relay}); - unsigned int btn2Relay = getSetting({"btnRelay", 1}, BUTTON2_RELAY - 1) + 1; - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn2Relay}); - unsigned int btn3Relay = getSetting({"btnRelay", 2}, BUTTON3_RELAY - 1) + 1; - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn3Relay}); - unsigned int btn4Relay = getSetting({"btnRelay", 3}, BUTTON4_RELAY - 1) + 1; - _buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn4Relay}); + const auto actions = _buttonConstructActions( + BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, + BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE + ); + + for (unsigned char id = 0; id < 4; ++id) { + buttonAdd( + GPIO_NONE, BUTTON_PUSHBUTTON, + actions, getSetting({"btnRelay", id}, _buttonRelay(id)) + ); + } + + // Generic GPIO input handlers #else - unsigned long btnDelay = getSetting("btnDelay", BUTTON_DBLCLICK_DELAY); - UNUSED(btnDelay); + size_t buttons = 0; #if BUTTON1_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON1_PRESS, BUTTON1_CLICK, BUTTON1_DBLCLICK, BUTTON1_LNGCLICK, BUTTON1_LNGLNGCLICK, BUTTON1_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON1_PIN, BUTTON1_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON1_RELAY}); - } + ++buttons; #endif #if BUTTON2_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON2_PRESS, BUTTON2_CLICK, BUTTON2_DBLCLICK, BUTTON2_LNGCLICK, BUTTON2_LNGLNGCLICK, BUTTON2_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON2_PIN, BUTTON2_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON2_RELAY}); - } + ++buttons; #endif #if BUTTON3_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON3_PRESS, BUTTON3_CLICK, BUTTON3_DBLCLICK, BUTTON3_LNGCLICK, BUTTON3_LNGLNGCLICK, BUTTON3_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON3_PIN, BUTTON3_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON3_RELAY}); - } + ++buttons; #endif #if BUTTON4_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON4_PRESS, BUTTON4_CLICK, BUTTON4_DBLCLICK, BUTTON4_LNGCLICK, BUTTON4_LNGLNGCLICK, BUTTON4_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON4_PIN, BUTTON4_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON4_RELAY}); - } + ++buttons; #endif #if BUTTON5_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON5_PRESS, BUTTON5_CLICK, BUTTON5_DBLCLICK, BUTTON5_LNGCLICK, BUTTON5_LNGLNGCLICK, BUTTON5_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON5_PIN, BUTTON5_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON5_RELAY}); - } + ++buttons; #endif #if BUTTON6_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON6_PRESS, BUTTON6_CLICK, BUTTON6_DBLCLICK, BUTTON6_LNGCLICK, BUTTON6_LNGLNGCLICK, BUTTON6_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON6_PIN, BUTTON6_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON6_RELAY}); - } + ++buttons; #endif #if BUTTON7_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON7_PRESS, BUTTON7_CLICK, BUTTON7_DBLCLICK, BUTTON7_LNGCLICK, BUTTON7_LNGLNGCLICK, BUTTON7_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON7_PIN, BUTTON7_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON7_RELAY}); - } + ++buttons; #endif #if BUTTON8_PIN != GPIO_NONE - { - unsigned int actions = buttonStore(BUTTON8_PRESS, BUTTON8_CLICK, BUTTON8_DBLCLICK, BUTTON8_LNGCLICK, BUTTON8_LNGLNGCLICK, BUTTON8_TRIPLECLICK); - _buttons.push_back({new DebounceEvent(BUTTON8_PIN, BUTTON8_MODE, BUTTON_DEBOUNCE_DELAY, btnDelay), actions, BUTTON8_RELAY}); - } + ++buttons; #endif + // TODO: load based on index + button_t::DebounceDelay = getSetting("btnDebounce", BUTTON_DEBOUNCE_DELAY); + button_t::DblclickDelay = getSetting("btnDelay", BUTTON_DBLCLICK_DELAY); + + for (unsigned char id = 0; id < buttons; ++id) { + _buttons.emplace_back(id); + } + #endif DEBUG_MSG_P(PSTR("[BUTTON] Number of buttons: %u\n"), _buttons.size()); @@ -338,12 +299,14 @@ void buttonLoop() { #else - for (unsigned int i=0; i < _buttons.size(); i++) { - if (unsigned char event = _buttons[i].button->loop()) { - unsigned char count = _buttons[i].button->getEventCount(); - unsigned long length = _buttons[i].button->getEventLength(); - unsigned char mapped = mapEvent(event, count, length); - buttonEvent(i, mapped); + for (size_t id = 0; id < _buttons.size(); ++id) { + auto& button = _buttons[id]; + if (auto event = button.event->loop()) { + buttonEvent(id, _buttonMapEvent( + event, + button.event->getEventCount(), + button.event->getEventLength() + )); } } diff --git a/code/espurna/button_config.h b/code/espurna/button_config.h new file mode 100644 index 00000000..9228a923 --- /dev/null +++ b/code/espurna/button_config.h @@ -0,0 +1,172 @@ +/* + +BUTTON MODULE + +*/ + +#pragma once + +constexpr const unsigned char _buttonPin(unsigned char index) { + return ( + (index == 0) ? BUTTON1_PIN : + (index == 1) ? BUTTON2_PIN : + (index == 2) ? BUTTON3_PIN : + (index == 3) ? BUTTON4_PIN : + (index == 4) ? BUTTON5_PIN : + (index == 5) ? BUTTON6_PIN : + (index == 6) ? BUTTON7_PIN : + (index == 7) ? BUTTON8_PIN : GPIO_NONE + ); +} + +constexpr const unsigned char _buttonMode(unsigned char index) { + return ( + (index == 0) ? BUTTON1_MODE : + (index == 1) ? BUTTON2_MODE : + (index == 2) ? BUTTON3_MODE : + (index == 3) ? BUTTON4_MODE : + (index == 4) ? BUTTON5_MODE : + (index == 5) ? BUTTON6_MODE : + (index == 6) ? BUTTON7_MODE : + (index == 7) ? BUTTON8_MODE : (BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH) + ); +} + +constexpr const unsigned char _buttonPress(unsigned char index) { + return ( + (index == 0) ? BUTTON1_PRESS : + (index == 1) ? BUTTON2_PRESS : + (index == 2) ? BUTTON3_PRESS : + (index == 3) ? BUTTON4_PRESS : + (index == 4) ? BUTTON5_PRESS : + (index == 5) ? BUTTON6_PRESS : + (index == 6) ? BUTTON7_PRESS : + (index == 7) ? BUTTON8_PRESS : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonClick(unsigned char index) { + return ( + (index == 0) ? BUTTON1_CLICK : + (index == 1) ? BUTTON2_CLICK : + (index == 2) ? BUTTON3_CLICK : + (index == 3) ? BUTTON4_CLICK : + (index == 4) ? BUTTON5_CLICK : + (index == 5) ? BUTTON6_CLICK : + (index == 6) ? BUTTON7_CLICK : + (index == 7) ? BUTTON8_CLICK : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonDoubleClick(unsigned char index) { + return ( + (index == 0) ? BUTTON1_DBLCLICK : + (index == 1) ? BUTTON2_DBLCLICK : + (index == 2) ? BUTTON3_DBLCLICK : + (index == 3) ? BUTTON4_DBLCLICK : + (index == 4) ? BUTTON5_DBLCLICK : + (index == 5) ? BUTTON6_DBLCLICK : + (index == 6) ? BUTTON7_DBLCLICK : + (index == 7) ? BUTTON8_DBLCLICK : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonTripleClick(unsigned char index) { + return ( + (index == 0) ? BUTTON1_TRIPLECLICK : + (index == 1) ? BUTTON2_TRIPLECLICK : + (index == 2) ? BUTTON3_TRIPLECLICK : + (index == 3) ? BUTTON4_TRIPLECLICK : + (index == 4) ? BUTTON5_TRIPLECLICK : + (index == 5) ? BUTTON6_TRIPLECLICK : + (index == 6) ? BUTTON7_TRIPLECLICK : + (index == 7) ? BUTTON8_TRIPLECLICK : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonLongClick(unsigned char index) { + return ( + (index == 0) ? BUTTON1_LNGCLICK : + (index == 1) ? BUTTON2_LNGCLICK : + (index == 2) ? BUTTON3_LNGCLICK : + (index == 3) ? BUTTON4_LNGCLICK : + (index == 4) ? BUTTON5_LNGCLICK : + (index == 5) ? BUTTON6_LNGCLICK : + (index == 6) ? BUTTON7_LNGCLICK : + (index == 7) ? BUTTON8_LNGCLICK : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonLongLongClick(unsigned char index) { + return ( + (index == 0) ? BUTTON1_LNGLNGCLICK : + (index == 1) ? BUTTON2_LNGLNGCLICK : + (index == 2) ? BUTTON3_LNGLNGCLICK : + (index == 3) ? BUTTON4_LNGLNGCLICK : + (index == 4) ? BUTTON5_LNGLNGCLICK : + (index == 5) ? BUTTON6_LNGLNGCLICK : + (index == 6) ? BUTTON7_LNGLNGCLICK : + (index == 7) ? BUTTON8_LNGLNGCLICK : BUTTON_MODE_NONE + ); +} + +constexpr const unsigned char _buttonRelay(unsigned char index) { + return ( + (index == 0) ? (BUTTON1_RELAY - 1) : + (index == 1) ? (BUTTON2_RELAY - 1) : + (index == 2) ? (BUTTON3_RELAY - 1) : + (index == 3) ? (BUTTON4_RELAY - 1) : + (index == 4) ? (BUTTON5_RELAY - 1) : + (index == 5) ? (BUTTON6_RELAY - 1) : + (index == 6) ? (BUTTON7_RELAY - 1) : + (index == 7) ? (BUTTON8_RELAY - 1) : RELAY_NONE + ); +} + +constexpr const unsigned char _buttonDecodeEventAction(unsigned long actions, unsigned char event) { + return ( + (event == BUTTON_EVENT_PRESSED) ? ((actions) & 0x0F) : + (event == BUTTON_EVENT_CLICK) ? ((actions >> 4) & 0x0F) : + (event == BUTTON_EVENT_DBLCLICK) ? ((actions >> 8) & 0x0F) : + (event == BUTTON_EVENT_LNGCLICK) ? ((actions >> 12) & 0x0F) : + (event == BUTTON_EVENT_LNGLNGCLICK) ? ((actions >> 16) & 0x0F) : + (event == BUTTON_EVENT_TRIPLECLICK) ? ((actions >> 20) & 0x0F) : BUTTON_MODE_NONE + ); +} + +constexpr const uint8_t _buttonMapReleased(uint8_t count, uint8_t length) { + return ( + (1 == count) ? ( + (length > BUTTON_LNGLNGCLICK_DELAY) ? BUTTON_EVENT_LNGLNGCLICK : + (length > BUTTON_LNGCLICK_DELAY) ? BUTTON_EVENT_LNGCLICK : BUTTON_EVENT_CLICK + ) : + (2 == count) ? BUTTON_EVENT_DBLCLICK : + (3 == count) ? BUTTON_EVENT_TRIPLECLICK : + BUTTON_EVENT_NONE + ); +} + +constexpr const uint8_t _buttonMapEvent(uint8_t event, uint8_t count, uint16_t length) { + return ( + (event == EVENT_PRESSED) ? BUTTON_EVENT_PRESSED : + (event == EVENT_CHANGED) ? BUTTON_EVENT_CLICK : + (event == EVENT_RELEASED) ? _buttonMapReleased(count, length) : + BUTTON_EVENT_NONE + ); +} + +constexpr uint32_t _buttonConstructActions(unsigned long pressed, unsigned long click, unsigned long dblclick, unsigned long lngclick, unsigned long lnglngclick, unsigned long tripleclick) { + return ( + (tripleclick << 20) | + (lnglngclick << 16) | + (lngclick << 12) | + (dblclick << 8) | + (click << 4) | + pressed + ); +} + +constexpr uint32_t _buttonConstructActions(unsigned char id) { + return _buttonConstructActions(_buttonPress(id), _buttonClick(id), _buttonDoubleClick(id), _buttonLongClick(id), _buttonLongLongClick(id), _buttonTripleClick(id)); +} + diff --git a/code/espurna/config/defaults.h b/code/espurna/config/defaults.h index eb7dc30f..71dbf0d5 100644 --- a/code/espurna/config/defaults.h +++ b/code/espurna/config/defaults.h @@ -1,9 +1,3 @@ -// ----------------------------------------------------------------------------- -// Hardware default values -// ----------------------------------------------------------------------------- - -#define GPIO_NONE 0x99 - // ----------------------------------------------------------------------------- // Buttons // ----------------------------------------------------------------------------- @@ -33,6 +27,31 @@ #define BUTTON8_PIN GPIO_NONE #endif +#ifndef BUTTON1_MODE +#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON2_MODE +#define BUTTON2_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON3_MODE +#define BUTTON3_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON4_MODE +#define BUTTON4_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON5_MODE +#define BUTTON5_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON6_MODE +#define BUTTON6_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON7_MODE +#define BUTTON7_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif +#ifndef BUTTON8_MODE +#define BUTTON8_MODE BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH +#endif + #ifndef BUTTON1_PRESS #define BUTTON1_PRESS BUTTON_MODE_NONE #endif @@ -184,28 +203,28 @@ #endif #ifndef BUTTON1_RELAY -#define BUTTON1_RELAY 0 +#define BUTTON1_RELAY RELAY_NONE #endif #ifndef BUTTON2_RELAY -#define BUTTON2_RELAY 0 +#define BUTTON2_RELAY RELAY_NONE #endif #ifndef BUTTON3_RELAY -#define BUTTON3_RELAY 0 +#define BUTTON3_RELAY RELAY_NONE #endif #ifndef BUTTON4_RELAY -#define BUTTON4_RELAY 0 +#define BUTTON4_RELAY RELAY_NONE #endif #ifndef BUTTON5_RELAY -#define BUTTON5_RELAY 0 +#define BUTTON5_RELAY RELAY_NONE #endif #ifndef BUTTON6_RELAY -#define BUTTON6_RELAY 0 +#define BUTTON6_RELAY RELAY_NONE #endif #ifndef BUTTON7_RELAY -#define BUTTON7_RELAY 0 +#define BUTTON7_RELAY RELAY_NONE #endif #ifndef BUTTON8_RELAY -#define BUTTON8_RELAY 0 +#define BUTTON8_RELAY RELAY_NONE #endif // ----------------------------------------------------------------------------- @@ -510,25 +529,25 @@ #define LED1_MODE LED_MODE_WIFI #endif #ifndef LED2_MODE -#define LED2_MODE LED_MODE_MQTT +#define LED2_MODE LED_MODE_MANUAL #endif #ifndef LED3_MODE -#define LED3_MODE LED_MODE_MQTT +#define LED3_MODE LED_MODE_MANUAL #endif #ifndef LED4_MODE -#define LED4_MODE LED_MODE_MQTT +#define LED4_MODE LED_MODE_MANUAL #endif #ifndef LED5_MODE -#define LED5_MODE LED_MODE_MQTT +#define LED5_MODE LED_MODE_MANUAL #endif #ifndef LED6_MODE -#define LED6_MODE LED_MODE_MQTT +#define LED6_MODE LED_MODE_MANUAL #endif #ifndef LED7_MODE -#define LED7_MODE LED_MODE_MQTT +#define LED7_MODE LED_MODE_MANUAL #endif #ifndef LED8_MODE -#define LED8_MODE LED_MODE_MQTT +#define LED8_MODE LED_MODE_MANUAL #endif #ifndef LED1_RELAY diff --git a/code/espurna/config/deprecated.h b/code/espurna/config/deprecated.h index c5817822..05b1f770 100644 --- a/code/espurna/config/deprecated.h +++ b/code/espurna/config/deprecated.h @@ -47,3 +47,9 @@ #if MQTT_SUPPORT && MQTT_LIBRARY == MQTT_LIBRARY_ASYNCMQTT_CLIENT && ASYNC_TCP_SSL_ENABLED #warning "Current implementation of AsyncMqttClient with axTLS is no longer supported. Consider switching to the SECURE_CLIENT configuration with MQTT_LIBRARY_ARDUINOMQTT or MQTT_LIBRARY_PUBSUBCLIENT. See: https://github.com/xoseperez/espurna/issues/1465" #endif + +// 1.14.2 renames MQTT to MANUAL +#undef LED_MODE_MQTT +#ifdef LED_MODE_MQTT +#warning LED_MODE_MQTT is deprecated! Please use LED_MODE_MANUAL instead +#endif diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 4eed2af3..1d560ae2 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -550,6 +550,8 @@ #define DEBUG_SERIAL_SUPPORT 0 // Buttons + #define BUTTON1_RELAY 1 + #define BUTTON2_RELAY 2 #define BUTTON3_RELAY 1 // LEDs diff --git a/code/espurna/config/types.h b/code/espurna/config/types.h index ffee81c9..071aadd2 100644 --- a/code/espurna/config/types.h +++ b/code/espurna/config/types.h @@ -153,7 +153,7 @@ // LED //------------------------------------------------------------------------------ -#define LED_MODE_MQTT 0 // LED will be managed from MQTT (OFF by default) +#define LED_MODE_MANUAL 0 // LED will be managed manually (OFF by default) #define LED_MODE_WIFI 1 // LED will blink according to the WIFI status #define LED_MODE_FOLLOW 2 // LED will follow state of linked relay (check RELAY#_LED) #define LED_MODE_FOLLOW_INVERSE 3 // LED will follow the opposite state of linked relay (check RELAY#_LED) @@ -377,3 +377,9 @@ #define SECURE_CLIENT_CHECK_FINGERPRINT 1 // legacy fingerprint validation #define SECURE_CLIENT_CHECK_CA 2 // set trust anchor from PROGMEM CA certificate +// ----------------------------------------------------------------------------- +// Hardware default values +// ----------------------------------------------------------------------------- + +#define GPIO_NONE 0x99 +#define RELAY_NONE 0x99 diff --git a/code/espurna/espurna.ino b/code/espurna/espurna.ino index 1424ead0..642c28be 100644 --- a/code/espurna/espurna.ino +++ b/code/espurna/espurna.ino @@ -23,7 +23,9 @@ along with this program. If not, see . #include "board.h" #include "broker.h" +#include "button.h" #include "debug.h" +#include "led.h" #include "relay.h" #include "settings.h" #include "system.h" diff --git a/code/espurna/led.h b/code/espurna/led.h new file mode 100644 index 00000000..1c3bfadd --- /dev/null +++ b/code/espurna/led.h @@ -0,0 +1,45 @@ +/* + +LED MODULE + +Copyright (C) 2016-2019 by Xose Pérez + +*/ + +#pragma once + +struct led_t { + led_t(); + led_t(unsigned char id); + + bool status(); + bool status(bool new_status); + + bool toggle(); + + unsigned char pin; + bool inverse; + unsigned char mode; + unsigned char relayID; +}; + +struct led_delay_t { + led_delay_t(unsigned long on_ms, unsigned long off_ms); + const unsigned long on; + const unsigned long off; +}; + +enum class LedMode { + NetworkAutoconfig, + NetworkConnected, + NetworkConnectedInverse, + NetworkConfig, + NetworkConfigInverse, + NetworkIdle, + None +}; + +const led_delay_t& _ledGetDelay(LedMode mode); +void ledUpdate(bool do_update); +void ledSetup(); + diff --git a/code/espurna/led.ino b/code/espurna/led.ino index b04894a5..217314b1 100644 --- a/code/espurna/led.ino +++ b/code/espurna/led.ino @@ -6,72 +6,98 @@ Copyright (C) 2016-2019 by Xose Pérez */ -// ----------------------------------------------------------------------------- -// LED -// ----------------------------------------------------------------------------- - #if LED_SUPPORT -#include "relay.h" #include "broker.h" +#include "relay.h" -typedef struct { - unsigned char pin; - bool reverse; - unsigned char mode; - unsigned char relay; -} led_t; - -std::vector _leds; -bool _led_update = false; // For relay-based modes - -// ----------------------------------------------------------------------------- - -bool _ledStatus(unsigned char id) { - if (id >= _ledCount()) return false; - bool status = digitalRead(_leds[id].pin); - return _leds[id].reverse ? !status : status; +#include "led.h" +#include "led_config.h" + +// LED helper class + +led_t::led_t() : + pin(GPIO_NONE), + inverse(false), + mode(LED_MODE_MANUAL), + relayID(0) +{} + +led_t::led_t(unsigned char id) : + pin(_ledPin(id)), + inverse(_ledInverse(id)), + mode(_ledMode(id)), + relayID(_ledRelay(id)) +{ + if (pin != GPIO_NONE) { + pinMode(pin, OUTPUT); + } } -bool _ledStatus(unsigned char id, bool status) { - if (id >=_ledCount()) return false; - digitalWrite(_leds[id].pin, _leds[id].reverse ? !status : status); - return status; +bool led_t::status() { + bool result = digitalRead(pin); + return inverse ? !result : result; } -bool _ledToggle(unsigned char id) { - if (id >= _ledCount()) return false; - return _ledStatus(id, !_ledStatus(id)); +bool led_t::status(bool new_status) { + digitalWrite(pin, inverse ? !new_status : new_status); + return new_status; } -unsigned char _ledMode(unsigned char id) { - if (id >= _ledCount()) return false; - return _leds[id].mode; +bool led_t::toggle() { + return status(!status()); } -void _ledMode(unsigned char id, unsigned char mode) { - if (id >= _ledCount()) return; - _leds[id].mode = mode; -} +led_delay_t::led_delay_t(unsigned long on_ms, unsigned long off_ms) : + on(microsecondsToClockCycles(on_ms * 1000)), + off(microsecondsToClockCycles(off_ms * 1000)) +{} + +// For relay-based modes +bool _led_update = false; + +// For network-based modes, cycle ON & OFF (time in milliseconds) +// XXX: internals convert these to clock cycles, delay cannot be longer than 25000 / 50000 ms +const led_delay_t _ledDelays[] { + {100, 100}, // Autoconfig + {100, 4900}, // Connected + {4900, 100}, // Connected (inverse) + {100, 900}, // Config / AP + {900, 100}, // Config / AP (inverse) + {500, 500} // Idle +}; + +std::vector _leds; -unsigned char _ledRelay(unsigned char id) { - if (id >= _ledCount()) return false; - return _leds[id].relay; +// ----------------------------------------------------------------------------- + +unsigned char _ledCount() { + return _leds.size(); } -void _ledRelay(unsigned char id, unsigned char relay) { - if (id >= _ledCount()) return; - _leds[id].relay = relay; +const led_delay_t& _ledModeToDelay(LedMode mode) { + static_assert( + (sizeof(_ledDelays) / sizeof(_ledDelays[0])) <= static_cast(LedMode::None), + "LedMode mapping out-of-bounds" + ); + return _ledDelays[static_cast(mode)]; } -void _ledBlink(unsigned char id, unsigned long delayOff, unsigned long delayOn) { - if (id >= _ledCount()) return; - static unsigned long next = millis(); - if (next < millis()) { - next += (_ledToggle(id) ? delayOn : delayOff); +void _ledBlink(led_t& led, const led_delay_t& delays) { + static auto clock_last = ESP.getCycleCount(); + static auto delay_for = delays.on; + + const auto clock_current = ESP.getCycleCount(); + if (clock_current - clock_last >= delay_for) { + delay_for = led.toggle() ? delays.on : delays.off; + clock_last = clock_current; } } +inline void _ledBlink(led_t& led, const LedMode mode) { + _ledBlink(led, _ledModeToDelay(mode)); +} + #if WEB_SUPPORT bool _ledWebSocketOnKeyCheck(const char * key, JsonVariant& value) { @@ -85,12 +111,12 @@ void _ledWebSocketOnVisible(JsonObject& root) { } void _ledWebSocketOnConnected(JsonObject& root) { - if (_ledCount() == 0) return; + if (!_ledCount()) return; JsonArray& leds = root.createNestedArray("ledConfig"); - for (byte i=0; i<_ledCount(); i++) { + for (unsigned char id = 0; id < _ledCount(); ++id) { JsonObject& led = leds.createNestedObject(); - led["mode"] = getSetting({"ledMode", i}, _ledMode(i)); - led["relay"] = getSetting({"ledRelay", i}, _ledRelay(i)); + led["mode"] = getSetting({"ledMode", id}, _leds[id].mode); + led["relay"] = getSetting({"ledRelay", id}, _leds[id].relayID); } } @@ -118,28 +144,28 @@ void _ledMQTTCallback(unsigned int type, const char * topic, const char * payloa if (type == MQTT_MESSAGE_EVENT) { - // Match topic - String t = mqttMagnitude((char *) topic); - if (!t.startsWith(MQTT_TOPIC_LED)) return; + // Only want `led/+/` + const String magnitude = mqttMagnitude((char *) topic); + if (!magnitude.startsWith(MQTT_TOPIC_LED)) return; - // Get led ID - unsigned int ledID = t.substring(strlen(MQTT_TOPIC_LED)+1).toInt(); + // Get led ID from after the slash when t is `led/` + unsigned int ledID = magnitude.substring(strlen(MQTT_TOPIC_LED) + 1).toInt(); if (ledID >= _ledCount()) { DEBUG_MSG_P(PSTR("[LED] Wrong ledID (%d)\n"), ledID); return; } // Check if LED is managed - if (_ledMode(ledID) != LED_MODE_MQTT) return; + if (_leds[ledID].mode != LED_MODE_MANUAL) return; - // get value + // Get value based on relays payload logic (0 / off, 1 / on, 2 / toggle) const auto value = relayParsePayload(payload); - // Action to perform + // Action to perform is also based on relay constants ... TODO generic enum? if (value == RelayStatus::TOGGLE) { - _ledToggle(ledID); + _leds[ledID].toggle(); } else { - _ledStatus(ledID, (value == RelayStatus::ON)); + _leds[ledID].status(value == RelayStatus::ON); } } @@ -147,56 +173,53 @@ void _ledMQTTCallback(unsigned int type, const char * topic, const char * payloa } #endif -unsigned char _ledCount() { - return _leds.size(); -} - void _ledConfigure() { - for (unsigned char i=0; i < _leds.size(); i++) { - _ledMode(i, getSetting({"ledMode", i}, _ledMode(i))); - _ledRelay(i, getSetting({"ledRelay", i}, _ledRelay(i))); + for (unsigned char id = 0; id < _leds.size(); ++id) { + _leds[id].mode = getSetting({"ledMode", id}, _ledMode(id)); + _leds[id].relayID = getSetting({"ledRelay", id}, _ledRelay(id)); } _led_update = true; } // ----------------------------------------------------------------------------- -void ledUpdate(bool value) { - _led_update = value; +void ledUpdate(bool do_update) { + _led_update = do_update; } void ledSetup() { + size_t leds = 0; + #if LED1_PIN != GPIO_NONE - _leds.push_back((led_t) { LED1_PIN, LED1_PIN_INVERSE, LED1_MODE, LED1_RELAY - 1 }); + ++leds; #endif #if LED2_PIN != GPIO_NONE - _leds.push_back((led_t) { LED2_PIN, LED2_PIN_INVERSE, LED2_MODE, LED2_RELAY - 1 }); + ++leds; #endif #if LED3_PIN != GPIO_NONE - _leds.push_back((led_t) { LED3_PIN, LED3_PIN_INVERSE, LED3_MODE, LED3_RELAY - 1 }); + ++leds; #endif #if LED4_PIN != GPIO_NONE - _leds.push_back((led_t) { LED4_PIN, LED4_PIN_INVERSE, LED4_MODE, LED4_RELAY - 1 }); + ++leds; #endif #if LED5_PIN != GPIO_NONE - _leds.push_back((led_t) { LED5_PIN, LED5_PIN_INVERSE, LED5_MODE, LED5_RELAY - 1 }); + ++leds; #endif #if LED6_PIN != GPIO_NONE - _leds.push_back((led_t) { LED6_PIN, LED6_PIN_INVERSE, LED6_MODE, LED6_RELAY - 1 }); + ++leds; #endif #if LED7_PIN != GPIO_NONE - _leds.push_back((led_t) { LED7_PIN, LED7_PIN_INVERSE, LED7_MODE, LED7_RELAY - 1 }); + ++leds; #endif #if LED8_PIN != GPIO_NONE - _leds.push_back((led_t) { LED8_PIN, LED8_PIN_INVERSE, LED8_MODE, LED8_RELAY - 1 }); + ++leds; #endif - for (unsigned char i=0; i < _leds.size(); i++) { - if (!hasSetting({"ledMode", i})) setSetting({"ledMode", i}, _leds[i].mode); - if (!hasSetting({"ledRelay", i})) setSetting({"ledRelay", i}, _leds[i].relay); - pinMode(_leds[i].pin, OUTPUT); - _ledStatus(i, false); + _leds.reserve(leds); + + for (unsigned char id=0; id < leds; ++id) { + _leds.emplace_back(id); } _ledConfigure(); @@ -223,69 +246,68 @@ void ledSetup() { espurnaRegisterLoop(ledLoop); espurnaRegisterReload(_ledConfigure); - } void ledLoop() { - uint8_t wifi_state = wifiState(); + const auto wifi_state = wifiState(); - for (unsigned char i=0; i<_leds.size(); i++) { + for (auto& led : _leds) { - if (_ledMode(i) == LED_MODE_WIFI) { + if (led.mode == LED_MODE_WIFI) { - if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) { - _ledBlink(i, 100, 100); + if ((wifi_state & WIFI_STATE_WPS) || (wifi_state & WIFI_STATE_SMARTCONFIG)) { + _ledBlink(led, LedMode::NetworkAutoconfig); } else if (wifi_state & WIFI_STATE_STA) { - _ledBlink(i, 4900, 100); + _ledBlink(led, LedMode::NetworkConnected); } else if (wifi_state & WIFI_STATE_AP) { - _ledBlink(i, 900, 100); + _ledBlink(led, LedMode::NetworkConfig); } else { - _ledBlink(i, 500, 500); + _ledBlink(led, LedMode::NetworkIdle); } } - if (_ledMode(i) == LED_MODE_FINDME_WIFI) { + if (led.mode == LED_MODE_FINDME_WIFI) { - if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) { - _ledBlink(i, 100, 100); + if ((wifi_state & WIFI_STATE_WPS) || (wifi_state & WIFI_STATE_SMARTCONFIG)) { + _ledBlink(led, LedMode::NetworkAutoconfig); } else if (wifi_state & WIFI_STATE_STA) { - if (relayStatus(_leds[i].relay)) { - _ledBlink(i, 4900, 100); + if (relayStatus(led.relayID)) { + _ledBlink(led, LedMode::NetworkConnected); } else { - _ledBlink(i, 100, 4900); + _ledBlink(led, LedMode::NetworkConnectedInverse); } } else if (wifi_state & WIFI_STATE_AP) { - if (relayStatus(_leds[i].relay)) { - _ledBlink(i, 900, 100); + if (relayStatus(led.relayID)) { + _ledBlink(led, LedMode::NetworkConfig); } else { - _ledBlink(i, 100, 900); + _ledBlink(led, LedMode::NetworkConfigInverse); } } else { - _ledBlink(i, 500, 500); + _ledBlink(led, LedMode::NetworkIdle); } } - if (_ledMode(i) == LED_MODE_RELAY_WIFI) { + if (led.mode == LED_MODE_RELAY_WIFI) { - if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) { - _ledBlink(i, 100, 100); + if ((wifi_state & WIFI_STATE_WPS) || (wifi_state & WIFI_STATE_SMARTCONFIG)) { + _ledBlink(led, LedMode::NetworkAutoconfig); } else if (wifi_state & WIFI_STATE_STA) { - if (relayStatus(_leds[i].relay)) { - _ledBlink(i, 100, 4900); + if (relayStatus(led.relayID)) { + _ledBlink(led, LedMode::NetworkConnected); } else { - _ledBlink(i, 4900, 100); + _ledBlink(led, LedMode::NetworkConnectedInverse); } } else if (wifi_state & WIFI_STATE_AP) { - if (relayStatus(_leds[i].relay)) { - _ledBlink(i, 100, 900); + if (relayStatus(led.relayID)) { + _ledBlink(led, LedMode::NetworkConfig); } else { - _ledBlink(i, 900, 100); + _ledBlink(led, LedMode::NetworkConfigInverse); } } else { - _ledBlink(i, 500, 500); + _ledBlink(led, LedMode::NetworkIdle); } } @@ -293,42 +315,42 @@ void ledLoop() { // Relay-based modes, update only if relays have been updated if (!_led_update) continue; - if (_ledMode(i) == LED_MODE_FOLLOW) { - _ledStatus(i, relayStatus(_leds[i].relay)); + if (led.mode == LED_MODE_FOLLOW) { + led.status(relayStatus(led.relayID)); } - if (_ledMode(i) == LED_MODE_FOLLOW_INVERSE) { - _ledStatus(i, !relayStatus(_leds[i].relay)); + if (led.mode == LED_MODE_FOLLOW_INVERSE) { + led.status(!relayStatus(led.relayID)); } - if (_ledMode(i) == LED_MODE_FINDME) { + if (led.mode == LED_MODE_FINDME) { bool status = true; - for (unsigned char k=0; k= _relays.size()) return false; if (!_relayStatusLock(id, status)) { From 2e891e3129133ea5025547d730682c1c4c162c26 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 21 Jan 2020 21:49:58 +0300 Subject: [PATCH 2/4] Debug: use lowercase enum for mode (following isocpp guidelines) --- code/espurna/config/general.h | 3 ++- code/espurna/debug.h | 6 +++--- code/espurna/debug.ino | 18 +++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 837c4490..f6f76fcd 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -33,7 +33,8 @@ //------------------------------------------------------------------------------ #ifndef DEBUG_LOG_MODE -#define DEBUG_LOG_MODE DebugLogMode::ENABLED +#define DEBUG_LOG_MODE DebugLogMode::Enabled // Set global logger mode. One of: + // ::Enabled, ::Disabled or ::SkipBoot #endif // Serial debug log diff --git a/code/espurna/debug.h b/code/espurna/debug.h index 9f742411..f4de095f 100644 --- a/code/espurna/debug.h +++ b/code/espurna/debug.h @@ -16,9 +16,9 @@ class PrintRaw; class PrintHex; enum class DebugLogMode : int { - DISABLED = 0, - ENABLED = 1, - SKIP_BOOT = 2 + Disabled = 0, + Enabled = 1, + SkipBoot = 2 }; bool debugLogBuffer(); diff --git a/code/espurna/debug.ino b/code/espurna/debug.ino index cb528b3a..f6a38dc6 100644 --- a/code/espurna/debug.ino +++ b/code/espurna/debug.ino @@ -281,12 +281,12 @@ void debugSetup() { String _debugLogModeSerialize(DebugLogMode value) { switch (value) { - case DebugLogMode::DISABLED: + case DebugLogMode::Disabled: return "0"; - case DebugLogMode::SKIP_BOOT: + case DebugLogMode::SkipBoot: return "2"; default: - case DebugLogMode::ENABLED: + case DebugLogMode::Enabled: return "1"; } } @@ -294,12 +294,12 @@ String _debugLogModeSerialize(DebugLogMode value) { DebugLogMode _debugLogModeDeserialize(const String& value) { switch (value.toInt()) { case 0: - return DebugLogMode::DISABLED; + return DebugLogMode::Disabled; case 2: - return DebugLogMode::SKIP_BOOT; + return DebugLogMode::SkipBoot; case 1: default: - return DebugLogMode::ENABLED; + return DebugLogMode::Enabled; } } @@ -311,15 +311,15 @@ void debugConfigureBoot() { const auto mode = getSetting("dbgLogMode", DEBUG_LOG_MODE); switch (mode) { - case DebugLogMode::SKIP_BOOT: + case DebugLogMode::SkipBoot: schedule_function([]() { _debug_enabled = true; }); // fall through - case DebugLogMode::DISABLED: + case DebugLogMode::Disabled: _debug_enabled = false; break; - case DebugLogMode::ENABLED: + case DebugLogMode::Enabled: _debug_enabled = true; break; } From d1df9d5587a41ad76c71d186fb4faf1a329b780d Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 21 Jan 2020 18:15:40 +0300 Subject: [PATCH 3/4] Add timelib header in utils --- code/espurna/utils.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index 5f6037d4..34e1efe5 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -6,11 +6,13 @@ Copyright (C) 2017-2019 by Xose Pérez */ -#include "utils.h" -#include "libs/HeapStats.h" +#include #include -#include +#include + +#include "utils.h" +#include "libs/HeapStats.h" void setDefaultHostname() { if (strlen(HOSTNAME) > 0) { From 712bd8a5e1e2d68dafbd5785da625021873724bc Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Wed, 22 Jan 2020 01:56:59 +0300 Subject: [PATCH 4/4] Buttons: small optimization for vector --- code/espurna/button.ino | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/espurna/button.ino b/code/espurna/button.ino index e45b5e11..3bb70e79 100644 --- a/code/espurna/button.ino +++ b/code/espurna/button.ino @@ -159,12 +159,16 @@ void buttonSetup() { #if defined(ITEAD_SONOFF_DUAL) + _buttons.reserve(3); + buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(0)); buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(1)); buttonAdd(GPIO_NONE, BUTTON_PUSHBUTTON, 0, _buttonRelay(2)); #elif defined(FOXEL_LIGHTFOX_DUAL) + _buttons.reserve(4); + const auto actions = _buttonConstructActions( BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE @@ -208,6 +212,8 @@ void buttonSetup() { ++buttons; #endif + _buttons.reserve(buttons); + // TODO: load based on index button_t::DebounceDelay = getSetting("btnDebounce", BUTTON_DEBOUNCE_DELAY); button_t::DblclickDelay = getSetting("btnDelay", BUTTON_DBLCLICK_DELAY);