Browse Source

Websocket callbacks

fastled
Xose Pérez 6 years ago
parent
commit
7b101f6791
8 changed files with 104 additions and 42 deletions
  1. +12
    -0
      code/espurna/alexa.ino
  2. +14
    -3
      code/espurna/analog.ino
  3. +3
    -3
      code/espurna/api.ino
  4. +11
    -4
      code/espurna/config/prototypes.h
  5. +14
    -3
      code/espurna/counter.ino
  6. +18
    -0
      code/espurna/influxdb.ino
  7. +5
    -5
      code/espurna/mqtt.ino
  8. +27
    -24
      code/espurna/ws.ino

+ 12
- 0
code/espurna/alexa.ino View File

@ -20,6 +20,13 @@ bool _alexa_change = false;
unsigned int _alexa_device_id = 0; unsigned int _alexa_device_id = 0;
bool _alexa_state = false; bool _alexa_state = false;
#if WEB_SUPPORT
void _alexaWSSend(JsonObject& root) {
root["alexaVisible"] = 1;
root["alexaEnabled"] = getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1;
}
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void alexaConfigure() { void alexaConfigure() {
@ -34,6 +41,11 @@ void alexaSetup() {
// Load & cache settings // Load & cache settings
alexaConfigure(); alexaConfigure();
#if WEB_SUPPORT
// Websockets
wsRegister(_alexaWSSend);
#endif
unsigned int relays = relayCount(); unsigned int relays = relayCount();
String hostname = getSetting("hostname"); String hostname = getSetting("hostname");
if (relays == 1) { if (relays == 1) {


+ 14
- 3
code/espurna/analog.ino View File

@ -12,6 +12,13 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
// ANALOG // ANALOG
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void _analogWSSend(JsonObject& root) {
root["analogVisible"] = 1;
root["analogValue"] = getAnalog();
}
// -----------------------------------------------------------------------------
unsigned int getAnalog() { unsigned int getAnalog() {
return analogRead(ANALOG_PIN); return analogRead(ANALOG_PIN);
} }
@ -21,9 +28,15 @@ void analogSetup() {
pinMode(ANALOG_PIN, INPUT); pinMode(ANALOG_PIN, INPUT);
#if WEB_SUPPORT #if WEB_SUPPORT
// Websocket register
wsRegister(_analogWSSend);
// API register
apiRegister(ANALOG_TOPIC, ANALOG_TOPIC, [](char * buffer, size_t len) { apiRegister(ANALOG_TOPIC, ANALOG_TOPIC, [](char * buffer, size_t len) {
snprintf_P(buffer, len, PSTR("%d"), getAnalog()); snprintf_P(buffer, len, PSTR("%d"), getAnalog());
}); });
#endif #endif
DEBUG_MSG_P(PSTR("[ANALOG] Monitoring analog values\n")); DEBUG_MSG_P(PSTR("[ANALOG] Monitoring analog values\n"));
@ -56,9 +69,7 @@ void analogLoop() {
// Update websocket clients // Update websocket clients
#if WEB_SUPPORT #if WEB_SUPPORT
char buffer[100];
snprintf_P(buffer, sizeof(buffer), PSTR("{\"analogVisible\": 1, \"analogValue\": %d}"), analog);
wsSend(buffer);
wsSend(_analogWSSend);
#endif #endif
} }


+ 3
- 3
code/espurna/api.ino View File

@ -16,8 +16,8 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
typedef struct { typedef struct {
char * url; char * url;
char * key; char * key;
apiGetCallbackFunction getFn = NULL;
apiPutCallbackFunction putFn = NULL;
api_get_callback_f getFn = NULL;
api_put_callback_f putFn = NULL;
} web_api_t; } web_api_t;
std::vector<web_api_t> _apis; std::vector<web_api_t> _apis;
@ -154,7 +154,7 @@ void _onRPC(AsyncWebServerRequest *request) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn) {
void apiRegister(const char * url, const char * key, api_get_callback_f getFn, api_put_callback_f putFn) {
// Store it // Store it
web_api_t api; web_api_t api;


+ 11
- 4
code/espurna/config/prototypes.h View File

@ -2,21 +2,28 @@
#include <NtpClientLib.h> #include <NtpClientLib.h>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <AsyncMqttClient.h> #include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#include <functional> #include <functional>
AsyncWebServer * webServer(); AsyncWebServer * webServer();
typedef std::function<void(char *, size_t)> apiGetCallbackFunction;
typedef std::function<void(const char *)> apiPutCallbackFunction;
void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn = NULL);
typedef std::function<void(char *, size_t)> api_get_callback_f;
typedef std::function<void(const char *)> api_put_callback_f;
void apiRegister(const char * url, const char * key, api_get_callback_f getFn, api_put_callback_f putFn = NULL);
void mqttRegister(void (*callback)(unsigned int, const char *, const char *));
typedef std::function<void(unsigned int, const char *, const char *)> mqtt_callback_f;
void mqttRegister(mqtt_callback_f callback);
String mqttSubtopic(char * topic); String mqttSubtopic(char * topic);
typedef std::function<void(JsonObject&)> ws_callback_f;
void wsRegister(ws_callback_f sender, ws_callback_f receiver = NULL);
void wsSend(ws_callback_f sender);
template<typename T> bool setSetting(const String& key, T value); template<typename T> bool setSetting(const String& key, T value);
template<typename T> bool setSetting(const String& key, unsigned int index, T value); template<typename T> bool setSetting(const String& key, unsigned int index, T value);
template<typename T> String getSetting(const String& key, T defaultValue); template<typename T> String getSetting(const String& key, T defaultValue);
template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue); template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue);
template<typename T> void domoticzSend(const char * key, T value); template<typename T> void domoticzSend(const char * key, T value);
template<typename T> void domoticzSend(const char * key, T nvalue, const char * svalue); template<typename T> void domoticzSend(const char * key, T nvalue, const char * svalue);


+ 14
- 3
code/espurna/counter.ino View File

@ -26,6 +26,13 @@ void ICACHE_RAM_ATTR _counterISR() {
} }
} }
#if WEB_SUPPORT
void _counterWSSend(JsonObject& root) {
root["counterVisible"] = 1;
root["counterValue"] = getCounter();
}
#endif
unsigned long getCounter() { unsigned long getCounter() {
return _counterValue; return _counterValue;
} }
@ -36,9 +43,15 @@ void counterSetup() {
attachInterrupt(COUNTER_PIN, _counterISR, COUNTER_INTERRUPT_MODE); attachInterrupt(COUNTER_PIN, _counterISR, COUNTER_INTERRUPT_MODE);
#if WEB_SUPPORT #if WEB_SUPPORT
// Websockets
wsRegister(_counterWSSend);
// API
apiRegister(COUNTER_TOPIC, COUNTER_TOPIC, [](char * buffer, size_t len) { apiRegister(COUNTER_TOPIC, COUNTER_TOPIC, [](char * buffer, size_t len) {
snprintf_P(buffer, len, PSTR("%d"), getCounter()); snprintf_P(buffer, len, PSTR("%d"), getCounter());
}); });
#endif #endif
DEBUG_MSG_P(PSTR("[COUNTER] Counter on GPIO %d\n"), COUNTER_PIN); DEBUG_MSG_P(PSTR("[COUNTER] Counter on GPIO %d\n"), COUNTER_PIN);
@ -62,9 +75,7 @@ void counterLoop() {
// Update websocket clients // Update websocket clients
#if WEB_SUPPORT #if WEB_SUPPORT
char buffer[100];
snprintf_P(buffer, sizeof(buffer), PSTR("{\"counterVisible\": 1, \"counterValue\": %d}"), _counterValue);
wsSend(buffer);
wsSend(_counterWSSend);
#endif #endif
// Do we have to report? // Do we have to report?


+ 18
- 0
code/espurna/influxdb.ino View File

@ -14,6 +14,21 @@ Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
bool _idb_enabled = false; bool _idb_enabled = false;
SyncClient _idb_client; SyncClient _idb_client;
// -----------------------------------------------------------------------------
#if WEB_SUPPORT
void _idbWSSend(JsonObject& root) {
root["idbVisible"] = 1;
root["idbHost"] = getSetting("idbHost");
root["idbPort"] = getSetting("idbPort", INFLUXDB_PORT).toInt();
root["idbDatabase"] = getSetting("idbDatabase");
root["idbUsername"] = getSetting("idbUsername");
root["idbPassword"] = getSetting("idbPassword");
}
#endif
// -----------------------------------------------------------------------------
template<typename T> bool idbSend(const char * topic, T payload) { template<typename T> bool idbSend(const char * topic, T payload) {
if (!_idb_enabled) return true; if (!_idb_enabled) return true;
@ -61,6 +76,9 @@ void idbConfigure() {
void idbSetup() { void idbSetup() {
idbConfigure(); idbConfigure();
#if WEB_SUPPORT
wsRegister(_idbWSSend);
#endif
} }
#endif #endif

+ 5
- 5
code/espurna/mqtt.ino View File

@ -44,7 +44,7 @@ char *_mqtt_will;
unsigned long _mqtt_connected_at = 0; unsigned long _mqtt_connected_at = 0;
#endif #endif
std::vector<void (*)(unsigned int, const char *, const char *)> _mqtt_callbacks;
std::vector<mqtt_callback_f> _mqtt_callbacks;
typedef struct { typedef struct {
char * topic; char * topic;
@ -192,7 +192,7 @@ void mqttUnsubscribeRaw(const char * topic) {
} }
} }
void mqttRegister(void (*callback)(unsigned int, const char *, const char *)) {
void mqttRegister(mqtt_callback_f callback) {
_mqtt_callbacks.push_back(callback); _mqtt_callbacks.push_back(callback);
} }
@ -241,7 +241,7 @@ void _mqttOnConnect() {
// Send connect event to subscribers // Send connect event to subscribers
for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) { for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) {
(*_mqtt_callbacks[i])(MQTT_CONNECT_EVENT, NULL, NULL);
(_mqtt_callbacks[i])(MQTT_CONNECT_EVENT, NULL, NULL);
} }
} }
@ -252,7 +252,7 @@ void _mqttOnDisconnect() {
// Send disconnect event to subscribers // Send disconnect event to subscribers
for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) { for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) {
(*_mqtt_callbacks[i])(MQTT_DISCONNECT_EVENT, NULL, NULL);
(_mqtt_callbacks[i])(MQTT_DISCONNECT_EVENT, NULL, NULL);
} }
} }
@ -274,7 +274,7 @@ void _mqttOnMessage(char* topic, char* payload, unsigned int len) {
// Send message event to subscribers // Send message event to subscribers
for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) { for (unsigned char i = 0; i < _mqtt_callbacks.size(); i++) {
(*_mqtt_callbacks[i])(MQTT_MESSAGE_EVENT, topic, message);
(_mqtt_callbacks[i])(MQTT_MESSAGE_EVENT, topic, message);
} }
} }


+ 27
- 24
code/espurna/ws.ino View File

@ -12,10 +12,15 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <Ticker.h> #include <Ticker.h>
#include <vector>
#include "ws.h" #include "ws.h"
AsyncWebSocket _ws("/ws"); AsyncWebSocket _ws("/ws");
Ticker _web_defer; Ticker _web_defer;
std::vector<ws_callback_f> _ws_sender_callbacks;
std::vector<ws_callback_f> _ws_receiver_callbacks;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Private methods // Private methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -558,20 +563,6 @@ void _wsStart(uint32_t client_id) {
#endif #endif
#if INFLUXDB_SUPPORT
root["idbVisible"] = 1;
root["idbHost"] = getSetting("idbHost");
root["idbPort"] = getSetting("idbPort", INFLUXDB_PORT).toInt();
root["idbDatabase"] = getSetting("idbDatabase");
root["idbUsername"] = getSetting("idbUsername");
root["idbPassword"] = getSetting("idbPassword");
#endif
#if ALEXA_SUPPORT
root["alexaVisible"] = 1;
root["alexaEnabled"] = getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1;
#endif
#if DS18B20_SUPPORT #if DS18B20_SUPPORT
root["dsVisible"] = 1; root["dsVisible"] = 1;
root["dsTmp"] = getDSTemperatureStr(); root["dsTmp"] = getDSTemperatureStr();
@ -589,16 +580,6 @@ void _wsStart(uint32_t client_id) {
root["rfDevice"] = getSetting("rfDevice", RF_DEVICE); root["rfDevice"] = getSetting("rfDevice", RF_DEVICE);
#endif #endif
#if ANALOG_SUPPORT
root["analogVisible"] = 1;
root["analogValue"] = getAnalog();
#endif
#if COUNTER_SUPPORT
root["counterVisible"] = 1;
root["counterValue"] = getCounter();
#endif
#if POWER_PROVIDER != POWER_PROVIDER_NONE #if POWER_PROVIDER != POWER_PROVIDER_NONE
root["pwrVisible"] = 1; root["pwrVisible"] = 1;
root["pwrCurrent"] = getCurrent(); root["pwrCurrent"] = getCurrent();
@ -664,6 +645,12 @@ void _wsStart(uint32_t client_id) {
network["dns"] = getSetting("dns" + String(i)); network["dns"] = getSetting("dns" + String(i));
} }
// Module setters
for (unsigned char i = 0; i < _ws_sender_callbacks.size(); i++) {
(_ws_sender_callbacks[i])(root);
}
} }
String output; String output;
@ -713,6 +700,22 @@ bool wsConnected() {
return (_ws.count() > 0); return (_ws.count() > 0);
} }
void wsRegister(ws_callback_f sender, ws_callback_f receiver) {
_ws_sender_callbacks.push_back(sender);
if (receiver) _ws_receiver_callbacks.push_back(receiver);
}
void wsSend(ws_callback_f sender) {
if (_ws.count() > 0) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
sender(root);
String output;
root.printTo(output);
wsSend((char *) output.c_str());
}
}
void wsSend(const char * payload) { void wsSend(const char * payload) {
if (_ws.count() > 0) { if (_ws.count() > 0) {
_ws.textAll(payload); _ws.textAll(payload);


Loading…
Cancel
Save