Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

147 lines
3.6 KiB

/*
ALEXA MODULE
Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
Module key prefix: alx
*/
#if ALEXA_SUPPORT
#include <fauxmoESP.h>
fauxmoESP alexa;
#include <queue>
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
// -----------------------------------------------------------------------------
#if WEB_SUPPORT
void _alexaWebSocketOnSend(JsonObject& root) {
root["alxVisible"] = 1;
root["alxEnabled"] = alexaEnabled();
}
#endif
void _alexaConfigure() {
alexa.enable(wifiConnected() && alexaEnabled());
}
bool _alexaKeyCheck(const char * key) {
return (strncmp(key, "alx", 3) == 0);
}
void _alexaBackwards() {
moveSetting("fauxmoEnabled", "alxEnabled"); // 1.9.0 - 2017-08-25
moveSetting("alexaEnabled", "alxEnabled"); // 1.14.0 - 2018-06-27
}
// -----------------------------------------------------------------------------
bool alexaEnabled() {
return (getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1);
}
void alexaSetup() {
// Check backwards compatibility
_alexaBackwards();
// Load & cache settings
_alexaConfigure();
// 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());
}
}
#endif
// 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);
});
// Websockets
#if WEB_SUPPORT
wsOnSendRegister(_alexaWebSocketOnSend);
#endif
// Register wifi callback
wifiRegister([](justwifi_messages_t code, char * parameter) {
if ((MESSAGE_CONNECTED == code) || (MESSAGE_DISCONNECTED == code)) {
_alexaConfigure();
}
});
// Settings
settingsRegisterKeyCheck(_alexaKeyCheck);
// Register main callbacks
espurnaRegisterLoop(alexaLoop);
espurnaRegisterReload(_alexaConfigure);
}
void alexaLoop() {
alexa.handle();
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();
}
}
#endif