|
@ -11,13 +11,13 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com> |
|
|
#include <fauxmoESP.h>
|
|
|
#include <fauxmoESP.h>
|
|
|
fauxmoESP alexa; |
|
|
fauxmoESP alexa; |
|
|
|
|
|
|
|
|
struct AlexaDevChange { |
|
|
|
|
|
AlexaDevChange(unsigned char device_id, bool state) : device_id(device_id), state(state) {}; |
|
|
|
|
|
unsigned char device_id = 0; |
|
|
|
|
|
bool state = false; |
|
|
|
|
|
}; |
|
|
|
|
|
#include <queue>
|
|
|
#include <queue>
|
|
|
static std::queue<AlexaDevChange> _alexa_dev_changes; |
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
unsigned char device_id; |
|
|
|
|
|
bool state; |
|
|
|
|
|
unsigned char value; |
|
|
|
|
|
} alexa_queue_element_t; |
|
|
|
|
|
static std::queue<alexa_queue_element_t> _alexa_queue; |
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
// -----------------------------------------------------------------------------
|
|
|
// ALEXA
|
|
|
// ALEXA
|
|
@ -29,15 +29,19 @@ bool _alexaWebSocketOnReceive(const char * key, JsonVariant& value) { |
|
|
|
|
|
|
|
|
void _alexaWebSocketOnSend(JsonObject& root) { |
|
|
void _alexaWebSocketOnSend(JsonObject& root) { |
|
|
root["alexaVisible"] = 1; |
|
|
root["alexaVisible"] = 1; |
|
|
root["alexaEnabled"] = getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1; |
|
|
|
|
|
|
|
|
root["alexaEnabled"] = alexaEnabled(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void _alexaConfigure() { |
|
|
void _alexaConfigure() { |
|
|
alexa.enable(getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1); |
|
|
|
|
|
|
|
|
alexa.enable(wifiConnected() && alexaEnabled()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
bool alexaEnabled() { |
|
|
|
|
|
return (getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void alexaSetup() { |
|
|
void alexaSetup() { |
|
|
|
|
|
|
|
|
// Backwards compatibility
|
|
|
// Backwards compatibility
|
|
@ -46,32 +50,56 @@ void alexaSetup() { |
|
|
// Load & cache settings
|
|
|
// Load & cache settings
|
|
|
_alexaConfigure(); |
|
|
_alexaConfigure(); |
|
|
|
|
|
|
|
|
#if WEB_SUPPORT
|
|
|
|
|
|
|
|
|
// Uses hostname as base name for all devices
|
|
|
|
|
|
// TODO: use custom switch name when available
|
|
|
|
|
|
String hostname = getSetting("hostname"); |
|
|
|
|
|
|
|
|
|
|
|
// Lights
|
|
|
|
|
|
#if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT
|
|
|
|
|
|
|
|
|
|
|
|
// Global switch
|
|
|
|
|
|
alexa.addDevice(hostname.c_str()); |
|
|
|
|
|
|
|
|
|
|
|
// For each channel
|
|
|
|
|
|
for (unsigned char i = 1; i <= lightChannels(); i++) { |
|
|
|
|
|
alexa.addDevice((hostname + " " + i).c_str()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Relays
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int relays = relayCount(); |
|
|
|
|
|
if (relays == 1) { |
|
|
|
|
|
alexa.addDevice(hostname.c_str()); |
|
|
|
|
|
} else { |
|
|
|
|
|
for (unsigned int i=1; i<=relays; i++) { |
|
|
|
|
|
alexa.addDevice((hostname + " " + i).c_str()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Websockets
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// Websockets
|
|
|
|
|
|
#if WEB_SUPPORT
|
|
|
wsOnSendRegister(_alexaWebSocketOnSend); |
|
|
wsOnSendRegister(_alexaWebSocketOnSend); |
|
|
wsOnAfterParseRegister(_alexaConfigure); |
|
|
wsOnAfterParseRegister(_alexaConfigure); |
|
|
wsOnReceiveRegister(_alexaWebSocketOnReceive); |
|
|
wsOnReceiveRegister(_alexaWebSocketOnReceive); |
|
|
|
|
|
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
unsigned int relays = relayCount(); |
|
|
|
|
|
String hostname = getSetting("hostname"); |
|
|
|
|
|
if (relays == 1) { |
|
|
|
|
|
alexa.addDevice(hostname.c_str()); |
|
|
|
|
|
} else { |
|
|
|
|
|
for (unsigned int i=0; i<relays; i++) { |
|
|
|
|
|
alexa.addDevice((hostname + "_" + i).c_str()); |
|
|
|
|
|
|
|
|
// Register wifi callback
|
|
|
|
|
|
wifiRegister([](justwifi_messages_t code, char * parameter) { |
|
|
|
|
|
if ((MESSAGE_CONNECTED == code) || (MESSAGE_DISCONNECTED == code)) { |
|
|
|
|
|
_alexaConfigure(); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
alexa.onSetState([&](unsigned char device_id, const char * name, bool state) { |
|
|
|
|
|
AlexaDevChange change(device_id, state); |
|
|
|
|
|
_alexa_dev_changes.push(change); |
|
|
|
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
alexa.onGetState([](unsigned char device_id, const char * name) { |
|
|
|
|
|
return relayStatus(device_id); |
|
|
|
|
|
|
|
|
// Callback
|
|
|
|
|
|
alexa.onSetState([&](unsigned char device_id, const char * name, bool state, unsigned char value) { |
|
|
|
|
|
alexa_queue_element_t element; |
|
|
|
|
|
element.device_id = device_id; |
|
|
|
|
|
element.state = state; |
|
|
|
|
|
element.value = value; |
|
|
|
|
|
_alexa_queue.push(element); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Register loop
|
|
|
// Register loop
|
|
@ -83,11 +111,24 @@ void alexaLoop() { |
|
|
|
|
|
|
|
|
alexa.handle(); |
|
|
alexa.handle(); |
|
|
|
|
|
|
|
|
while (!_alexa_dev_changes.empty()) { |
|
|
|
|
|
AlexaDevChange& change = _alexa_dev_changes.front(); |
|
|
|
|
|
DEBUG_MSG_P(PSTR("[ALEXA] Device #%u state: %s\n"), change.device_id, change.state ? "ON" : "OFF"); |
|
|
|
|
|
relayStatus(change.device_id, change.state); |
|
|
|
|
|
_alexa_dev_changes.pop(); |
|
|
|
|
|
|
|
|
while (!_alexa_queue.empty()) { |
|
|
|
|
|
|
|
|
|
|
|
alexa_queue_element_t element = _alexa_queue.front(); |
|
|
|
|
|
DEBUG_MSG_P(PSTR("[ALEXA] Device #%u state: %s value: %d\n"), element.device_id, element.state ? "ON" : "OFF", element.value); |
|
|
|
|
|
|
|
|
|
|
|
#if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT
|
|
|
|
|
|
if (0 == element.device_id) { |
|
|
|
|
|
relayStatus(0, element.state); |
|
|
|
|
|
} else { |
|
|
|
|
|
lightState(element.device_id - 1, element.state); |
|
|
|
|
|
lightChannel(element.device_id - 1, element.value); |
|
|
|
|
|
lightUpdate(true, true); |
|
|
|
|
|
} |
|
|
|
|
|
#else
|
|
|
|
|
|
relayStatus(element.device_id, element.state); |
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
_alexa_queue.pop(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|