From 90ce2a8e37b0c4e48f3b7e40fcaf19f6c4a46fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Fri, 19 Jan 2018 23:00:29 +0100 Subject: [PATCH] Local broker --- code/espurna/broker.ino | 32 ++++++++++++++++++++++++++++++++ code/espurna/config/arduino.h | 1 + code/espurna/config/general.h | 8 ++++++++ code/espurna/config/prototypes.h | 5 +++++ code/espurna/light.ino | 23 ++++++++++++++++++++++- code/espurna/ntp.ino | 10 ++++++++++ code/espurna/relay.ino | 5 +++++ code/espurna/sensor.ino | 4 ++++ code/espurna/utils.ino | 8 +++++++- 9 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 code/espurna/broker.ino diff --git a/code/espurna/broker.ino b/code/espurna/broker.ino new file mode 100644 index 00000000..f7b31421 --- /dev/null +++ b/code/espurna/broker.ino @@ -0,0 +1,32 @@ +/* + +BROKER MODULE + +Copyright (C) 2017-2018 by Xose PĂ©rez + +*/ + +#if BROKER_SUPPORT + +#include + +std::vector _broker_callbacks; + +// ----------------------------------------------------------------------------- + +void brokerRegister(void (*callback)(const char *, unsigned char, const char *)) { + _broker_callbacks.push_back(callback); +} + +void brokerPublish(const char * topic, unsigned char id, const char * message) { + DEBUG_MSG_P(PSTR("[BROKER] Message %s[%u] => %s\n"), topic, id, message); + for (unsigned char i=0; i<_broker_callbacks.size(); i++) { + (_broker_callbacks[i])(topic, id, message); + } +} + +void brokerPublish(const char * topic, const char * message) { + brokerPublish(topic, 0, message); +} + +#endif // BROKER_SUPPORT diff --git a/code/espurna/config/arduino.h b/code/espurna/config/arduino.h index d2b70ddc..4cdc35d2 100644 --- a/code/espurna/config/arduino.h +++ b/code/espurna/config/arduino.h @@ -76,6 +76,7 @@ //#define LLMNR_SUPPORT 1 // Only with Arduino Core 2.4.0 //#define MDNS_SERVER_SUPPORT 0 //#define MDNS_CLIENT_SUPPORT 1 +//#define BROKER_SUPPORT 0 //#define MQTT_SUPPORT 0 //#define NETBIOS_SUPPORT 1 // Only with Arduino Core 2.4.0 //#define NOFUSS_SUPPORT 1 diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 83f37b18..8ea8f37c 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -570,6 +570,14 @@ PROGMEM const char* const custom_reset_string[] = { #define MQTT_SETTER "/set" #endif +// ----------------------------------------------------------------------------- +// BROKER +// ----------------------------------------------------------------------------- + +#ifndef BROKER_SUPPORT +#define BROKER_SUPPORT 1 // The broker is a poor-man's pubsub manager +#endif + // ----------------------------------------------------------------------------- // SETTINGS // ----------------------------------------------------------------------------- diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index 3ddaf53e..15df02f1 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -47,6 +47,11 @@ typedef std::function mqtt_callb void mqttRegister(mqtt_callback_f callback); String mqttTopicKey(char * topic); +// ----------------------------------------------------------------------------- +// Broker +// ----------------------------------------------------------------------------- +void brokerRegister(void (*)(const char *, unsigned char, const char *)); + // ----------------------------------------------------------------------------- // Settings // ----------------------------------------------------------------------------- diff --git a/code/espurna/light.ino b/code/espurna/light.ino index eb05913b..67e84fa7 100644 --- a/code/espurna/light.ino +++ b/code/espurna/light.ino @@ -571,7 +571,7 @@ void lightMQTT() { // Channels for (unsigned int i=0; i < _light_channel.size(); i++) { - snprintf_P(buffer, sizeof(buffer), PSTR("%d"), _light_channel[i].value); + itoa(_light_channel[i].value, buffer, 10); mqttSend(MQTT_TOPIC_CHANNEL, i, buffer); } @@ -588,6 +588,22 @@ void lightMQTTGroup() { #endif +// ----------------------------------------------------------------------------- +// Broker +// ----------------------------------------------------------------------------- + +#if BROKER_SUPPORT + +void lightBroker() { + char buffer[10]; + for (unsigned int i=0; i < _light_channel.size(); i++) { + itoa(_light_channel[i].value, buffer, 10); + brokerPublish(MQTT_TOPIC_CHANNEL, i, buffer); + } +} + +#endif + // ----------------------------------------------------------------------------- // API // ----------------------------------------------------------------------------- @@ -610,6 +626,11 @@ void lightUpdate(bool save, bool forward, bool group_forward) { _light_steps_left = _light_use_transitions ? LIGHT_TRANSITION_STEPS : 1; _light_transition_ticker.attach_ms(LIGHT_TRANSITION_STEP, _lightProviderUpdate); + // Report channels to local broker + #if BROKER_SUPPORT + lightBroker(); + #endif + // Report color & brightness to MQTT broker #if MQTT_SUPPORT if (forward) lightMQTT(); diff --git a/code/espurna/ntp.ino b/code/espurna/ntp.ino index d027b0ff..321d88d9 100644 --- a/code/espurna/ntp.ino +++ b/code/espurna/ntp.ino @@ -95,7 +95,17 @@ void ntpSetup() { } void ntpLoop() { + now(); + + #if BROKER_SUPPORT + static unsigned char last_minute = 60; + if (ntpSynced() && (minute() != last_minute)) { + last_minute = minute(); + brokerPublish(MQTT_TOPIC_DATETIME, ntpDateTime().c_str()); + } + #endif + } #endif // NTP_SUPPORT diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index 0a500b62..8c2b30e5 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -762,6 +762,11 @@ void relayLoop(void) { // Call the provider to perform the action _relayProviderStatus(id, status); + // Send to Broker + #if BROKER_SUPPORT + brokerPublish(MQTT_TOPIC_RELAY, id, status ? "1" : "0"); + #endif + // Send MQTT #if MQTT_SUPPORT relayMQTT(id); diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index fd617a2c..824b0bba 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -692,6 +692,10 @@ void sensorLoop() { _magnitudes[i].reported = filtered; dtostrf(filtered, 1-sizeof(buffer), decimals, buffer); + #if BROKER_SUPPORT + brokerPublish(_magnitudeTopic(magnitude.type).c_str(), magnitude.local, buffer); + #endif + #if MQTT_SUPPORT if (SENSOR_USE_INDEX || (_counts[magnitude.type] > 1)) { diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index 3e9c3294..a345d989 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -271,6 +271,9 @@ void info() { #if ALEXA_SUPPORT DEBUG_MSG_P(PSTR(" ALEXA")); #endif + #if BROKER_SUPPORT + DEBUG_MSG_P(PSTR(" BROKER")); + #endif #if DEBUG_SERIAL_SUPPORT DEBUG_MSG_P(PSTR(" DEBUG_SERIAL")); #endif @@ -296,7 +299,10 @@ void info() { DEBUG_MSG_P(PSTR(" LLMNR")); #endif #if MDNS_SERVER_SUPPORT - DEBUG_MSG_P(PSTR(" MDNS")); + DEBUG_MSG_P(PSTR(" MDNS_SERVER")); + #endif + #if MDNS_CLIENT_SUPPORT + DEBUG_MSG_P(PSTR(" MDNS_CLIENT")); #endif #if NETBIOS_SUPPORT DEBUG_MSG_P(PSTR(" NETBIOS"));