diff --git a/README.md b/README.md index ca73c982..bc7f57e6 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smar It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries. [![version](https://img.shields.io/badge/version-1.13.4-brightgreen.svg)](CHANGELOG.md) -[![branch](https://img.shields.io/badge/branch-dev-orange.svg)](https://github.com/xoseperez/espurna/tree/dev/) +[![branch](https://img.shields.io/badge/branch-alexa-orange.svg)](https://github.com/xoseperez/espurna/tree/alexa/) [![license](https://img.shields.io/github/license/xoseperez/espurna.svg)](LICENSE) -[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna) +[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=alexa)](https://travis-ci.org/xoseperez/espurna) [![codacy](https://api.codacy.com/project/badge/Grade/c9496e25cf07434cba786b462cb15f49)](https://www.codacy.com/app/xoseperez/espurna/dashboard) [![downloads](https://img.shields.io/github/downloads/xoseperez/espurna/total.svg)](https://github.com/xoseperez/espurna/releases)
diff --git a/code/espurna/alexa.ino b/code/espurna/alexa.ino index 84e5ea2e..0388c3eb 100644 --- a/code/espurna/alexa.ino +++ b/code/espurna/alexa.ino @@ -36,6 +36,34 @@ void _alexaConfigure() { alexa.enable(wifiConnected() && alexaEnabled()); } +bool _alexaBodyCallback(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { + return alexa.process(request->client(), request->method() == HTTP_GET, request->url(), String((char *)data)); +} + +bool _alexaRequestCallback(AsyncWebServerRequest *request) { + String body = (request->hasParam("body", true)) ? request->getParam("body", true)->value() : String(); + return alexa.process(request->client(), request->method() == HTTP_GET, request->url(), body); +} + +#if BROKER_SUPPORT +void _alexaBrokerCallback(const char * topic, unsigned char id, const char * payload) { + + unsigned char value = atoi(payload); + + if (strcmp(MQTT_TOPIC_CHANNEL, topic) == 0) { + alexa.setState(id+1, value > 0, value); + } + + if (strcmp(MQTT_TOPIC_RELAY, topic) == 0) { + #if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT + if (id > 0) return; + #endif + alexa.setState(id, value, value > 0 ? 255 : 0); + } + +} +#endif // BROKER_SUPPORT + // ----------------------------------------------------------------------------- bool alexaEnabled() { @@ -47,8 +75,9 @@ void alexaSetup() { // Backwards compatibility moveSetting("fauxmoEnabled", "alexaEnabled"); - // Load & cache settings - _alexaConfigure(); + // Basic fauxmoESP configuration + alexa.createServer(false); + alexa.setPort(80); // Uses hostname as base name for all devices // TODO: use custom switch name when available @@ -79,6 +108,9 @@ void alexaSetup() { #endif + // Load & cache settings + _alexaConfigure(); + // Websockets #if WEB_SUPPORT wsOnSendRegister(_alexaWebSocketOnSend); @@ -102,8 +134,13 @@ void alexaSetup() { }); // Register main callbacks - espurnaRegisterLoop(alexaLoop); + webBodyRegister(_alexaBodyCallback); + webRequestRegister(_alexaRequestCallback); + #if BROKER_SUPPORT + brokerRegister(_alexaBrokerCallback); + #endif espurnaRegisterReload(_alexaConfigure); + espurnaRegisterLoop(alexaLoop); } diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index ecc80efa..6ceb1cf8 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -167,7 +167,9 @@ void nice_delay(unsigned long ms); #define AsyncWebSocket void #define AwsEventType void * #endif +typedef std::function web_body_callback_f; typedef std::function web_request_callback_f; +void webBodyRegister(web_body_callback_f callback); void webRequestRegister(web_request_callback_f callback); // ----------------------------------------------------------------------------- diff --git a/code/espurna/web.ino b/code/espurna/web.ino index 13470bc2..30c10a78 100644 --- a/code/espurna/web.ino +++ b/code/espurna/web.ino @@ -46,6 +46,7 @@ std::vector * _webConfigBuffer; bool _webConfigSuccess = false; std::vector _web_request_callbacks; +std::vector _web_body_callbacks; // ----------------------------------------------------------------------------- // HOOKS @@ -343,6 +344,17 @@ void _onRequest(AsyncWebServerRequest *request){ } +void _onBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { + + // Send request to subscribers + for (unsigned char i = 0; i < _web_body_callbacks.size(); i++) { + bool response = (_web_body_callbacks[i])(request, data, len, index, total); + if (response) return; + } + +} + + // ----------------------------------------------------------------------------- bool webAuthenticate(AsyncWebServerRequest *request) { @@ -362,6 +374,10 @@ AsyncWebServer * webServer() { return _server; } +void webBodyRegister(web_body_callback_f callback) { + _web_body_callbacks.push_back(callback); +} + void webRequestRegister(web_request_callback_f callback) { _web_request_callbacks.push_back(callback); } @@ -412,7 +428,9 @@ void webSetup() { }); #endif + // Handle other requests, including 404 + _server->onRequestBody(_onBody); _server->onNotFound(_onRequest); // Run server