From 75d9f34be6dbe96c3bbbaaf7190513c28aaba71b Mon Sep 17 00:00:00 2001 From: qubeck Date: Mon, 15 Jan 2018 13:56:00 +0100 Subject: [PATCH 1/2] Introduced alexa device separation via explicit mapping to prevent a race condition on fast changes (e.g. on alexa group state change) --- code/espurna/alexa.ino | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/code/espurna/alexa.ino b/code/espurna/alexa.ino index 35b1ba88..15accce0 100644 --- a/code/espurna/alexa.ino +++ b/code/espurna/alexa.ino @@ -9,16 +9,17 @@ Copyright (C) 2016-2018 by Xose Pérez #if ALEXA_SUPPORT #include - +#include fauxmoESP alexa; // ----------------------------------------------------------------------------- // ALEXA // ----------------------------------------------------------------------------- - -bool _alexa_change = false; -unsigned int _alexa_device_id = 0; -bool _alexa_state = false; +struct alexa_dev { + bool _alexa_change = false; + bool _alexa_state = false; +}; +std::map alexa_devices; void _alexaWebSocketOnSend(JsonObject& root) { root["alexaVisible"] = 1; @@ -57,10 +58,9 @@ void alexaSetup() { } } - alexa.onSetState([relays](unsigned char device_id, const char * name, bool state) { - _alexa_change = true; - _alexa_device_id = device_id; - _alexa_state = state; + alexa.onSetState([&](unsigned char device_id, const char * name, bool state) { + alexa_devices[device_id]._alexa_change = true; + alexa_devices[device_id]._alexa_state = state; }); alexa.onGetState([relays](unsigned char device_id, const char * name) { @@ -73,10 +73,12 @@ void alexaLoop() { alexa.handle(); - if (_alexa_change) { - DEBUG_MSG_P(PSTR("[ALEXA] Device #%d state: %s\n"), _alexa_device_id, _alexa_state ? "ON" : "OFF"); - _alexa_change = false; - relayStatus(_alexa_device_id, _alexa_state); + for (std::map::iterator it=alexa_devices.begin(); it!=alexa_devices.end(); ++it) { + if (it->second._alexa_change) { + DEBUG_MSG_P(PSTR("[ALEXA] Device #%d state: %s\n"), it->first, it->second._alexa_state ? "ON" : "OFF"); + it->second._alexa_change = false; + relayStatus(it->first, it->second._alexa_state); + } } } From 0f948e0498a74e51b80905b4e047bce52060467f Mon Sep 17 00:00:00 2001 From: qubeck Date: Mon, 15 Jan 2018 16:09:30 +0100 Subject: [PATCH 2/2] changed alexa change propagation to a queue based impl. to be more efficient --- code/espurna/alexa.ino | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/code/espurna/alexa.ino b/code/espurna/alexa.ino index 15accce0..a7991bac 100644 --- a/code/espurna/alexa.ino +++ b/code/espurna/alexa.ino @@ -9,17 +9,18 @@ Copyright (C) 2016-2018 by Xose Pérez #if ALEXA_SUPPORT #include -#include +#include fauxmoESP alexa; // ----------------------------------------------------------------------------- // ALEXA // ----------------------------------------------------------------------------- -struct alexa_dev { - bool _alexa_change = false; - bool _alexa_state = false; +struct AlexaDevChange { + AlexaDevChange(unsigned char device_id, bool state) : device_id(device_id), state(state) {}; + unsigned char device_id = 0; + bool state = false; }; -std::map alexa_devices; +static std::queue _alexa_dev_changes; void _alexaWebSocketOnSend(JsonObject& root) { root["alexaVisible"] = 1; @@ -59,8 +60,8 @@ void alexaSetup() { } alexa.onSetState([&](unsigned char device_id, const char * name, bool state) { - alexa_devices[device_id]._alexa_change = true; - alexa_devices[device_id]._alexa_state = state; + AlexaDevChange change(device_id, state); + _alexa_dev_changes.push(change); }); alexa.onGetState([relays](unsigned char device_id, const char * name) { @@ -73,14 +74,12 @@ void alexaLoop() { alexa.handle(); - for (std::map::iterator it=alexa_devices.begin(); it!=alexa_devices.end(); ++it) { - if (it->second._alexa_change) { - DEBUG_MSG_P(PSTR("[ALEXA] Device #%d state: %s\n"), it->first, it->second._alexa_state ? "ON" : "OFF"); - it->second._alexa_change = false; - relayStatus(it->first, it->second._alexa_state); - } + while (!_alexa_dev_changes.empty()) { + AlexaDevChange& change = _alexa_dev_changes.front(); + DEBUG_MSG_P(PSTR("[ALEXA] Device #%d state: %s\n"), change.device_id, change.state ? "ON" : "OFF"); + relayStatus(change.device_id, change.state); + _alexa_dev_changes.pop(); } - } #endif