From 3f8eb8b2b8b8c1e53a36357911f28da124e9db76 Mon Sep 17 00:00:00 2001 From: Maurice Makaay Date: Sun, 12 Jul 2020 01:52:08 +0200 Subject: [PATCH] Going to see if namespaces help structuring the code. --- src/Data/DataController.cpp | 6 +- src/Data/DataController.h | 6 +- src/Data/Measurements.cpp | 2 +- src/Data/Measurements.h | 4 +- src/Network/DoughMQTT.cpp | 133 ---------------------------------- src/Network/DoughMQTT.h | 46 ------------ src/Network/MQTT.cpp | 138 ++++++++++++++++++++++++++++++++++++ src/Network/MQTT.h | 50 +++++++++++++ src/main.cpp | 15 ++-- src/main.h | 2 +- 10 files changed, 206 insertions(+), 196 deletions(-) delete mode 100644 src/Network/DoughMQTT.cpp delete mode 100644 src/Network/DoughMQTT.h create mode 100644 src/Network/MQTT.cpp create mode 100644 src/Network/MQTT.h diff --git a/src/Data/DataController.cpp b/src/Data/DataController.cpp index d06eed7..942cdcb 100644 --- a/src/Data/DataController.cpp +++ b/src/Data/DataController.cpp @@ -36,7 +36,7 @@ DataController::DataController() : _temperatureMeasurements( _logger("DATA") { _ui = DoughUI::Instance(); - _mqtt = DoughMQTT::Instance(); + _mqtt = Dough::MQTT::Instance(); } // ---------------------------------------------------------------------- @@ -48,7 +48,7 @@ void DataController::setup() _containerHeight = 0.00; _containerHeightSet = false; - DoughMQTT *mqtt = DoughMQTT::Instance(); + Dough::MQTT *mqtt = Dough::MQTT::Instance(); mqtt->onConnect(DataController::handleMqttConnect); mqtt->onMessage(DataController::handleMqttMessage); @@ -57,7 +57,7 @@ void DataController::setup() _distanceMeasurements.setup(); } -void DataController::handleMqttConnect(DoughMQTT *mqtt) +void DataController::handleMqttConnect(Dough::MQTT *mqtt) { mqtt->subscribe("container_height"); } diff --git a/src/Data/DataController.h b/src/Data/DataController.h index a2cb18e..fbae401 100644 --- a/src/Data/DataController.h +++ b/src/Data/DataController.h @@ -33,7 +33,7 @@ #include "Sensors/HumiditySensor.h" #include "Sensors/DistanceSensor.h" #include "Network/DoughWiFi.h" -#include "Network/DoughMQTT.h" +#include "Network/MQTT.h" #include "UI/DoughUI.h" #include "UI/DoughLogger.h" @@ -58,14 +58,14 @@ public: void clearHistory(); void setContainerHeight(int height); bool isConfigured(); - static void handleMqttConnect(DoughMQTT *mqtt); + static void handleMqttConnect(Dough::MQTT *mqtt); static void handleMqttMessage(String &key, String &value); private: DataController(); static DataController *_instance; DoughUI *_ui; - DoughMQTT *_mqtt; + Dough::MQTT *_mqtt; Measurements _temperatureMeasurements; Measurements _humidityMeasurements; Measurements _distanceMeasurements; diff --git a/src/Data/Measurements.cpp b/src/Data/Measurements.cpp index 9166c13..eb3a4c9 100644 --- a/src/Data/Measurements.cpp +++ b/src/Data/Measurements.cpp @@ -13,7 +13,7 @@ Measurements::Measurements( _storageSize = storageSize; _significantChange = significantChange; _minimumPublishTime = minimumPublishTime; - _mqtt = DoughMQTT::Instance(); + _mqtt = Dough::MQTT::Instance(); } void Measurements::setup() diff --git a/src/Data/Measurements.h b/src/Data/Measurements.h index cab4561..d2d611d 100644 --- a/src/Data/Measurements.h +++ b/src/Data/Measurements.h @@ -4,7 +4,7 @@ #include #include "Sensors/SensorBase.h" #include "Data/Measurement.h" -#include "Network/DoughMQTT.h" +#include "Network/MQTT.h" /** * This class is used to store measurements for a sensor and to keep @@ -43,7 +43,7 @@ public: void clearHistory(); private: - DoughMQTT *_mqtt; + Dough::MQTT *_mqtt; const char *_mqttKey; char *_mqttAverageKey; SensorBase *_sensor; diff --git a/src/Network/DoughMQTT.cpp b/src/Network/DoughMQTT.cpp deleted file mode 100644 index ec425e1..0000000 --- a/src/Network/DoughMQTT.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "DoughMQTT.h" - -// ---------------------------------------------------------------------- -// Constructor -// ---------------------------------------------------------------------- - -DoughMQTT *DoughMQTT::_instance = nullptr; - -DoughMQTT *DoughMQTT::Instance() -{ - if (DoughMQTT::_instance == nullptr) - { - DoughMQTT::_instance = new DoughMQTT(); - } - return DoughMQTT::_instance; -} - -DoughMQTT::DoughMQTT() : _logger("MQTT") {} - -// ---------------------------------------------------------------------- -// Setup -// ---------------------------------------------------------------------- - -void DoughMQTT::setup() -{ - DoughWiFi *network = DoughWiFi::Instance(); - -#ifdef MQTT_DEVICE_ID - _mqttDeviceId = MQTT_DEVICE_ID; -#else - _mqttDeviceId = network->getMacAddress(); -#endif - _logger.log("ss", "Device ID = ", _mqttDeviceId); - - _mqttClient.begin(MQTT_BROKER, MQTT_PORT, network->client); -} - -void DoughMQTT::onConnect(DoughMQTTConnectHandler callback) -{ - _onConnect = callback; -} - -void DoughMQTT::onMessage(MQTTClientCallbackSimple callback) -{ - _onMessage = callback; -} - -// ---------------------------------------------------------------------- -// Loop -// ---------------------------------------------------------------------- - -bool DoughMQTT::isConnected() -{ - return _mqttClient.connected(); -} - -bool DoughMQTT::connect() -{ - _logger.log("sssi", "Broker = ", MQTT_BROKER, ":", MQTT_PORT); - _mqttClient.connect(_mqttDeviceId, MQTT_USERNAME, MQTT_PASSWORD); - - // Check if the connection to the broker was successful. - if (!_mqttClient.connected()) - { - _logger.log("s", "ERROR - Connection to broker failed"); - return false; - } - - _mqttClient.onMessage(DoughMQTT::handleMessage); - - if (_onConnect != nullptr) - { - _onConnect(this); - } - - return true; -} - -void DoughMQTT::procesIncomingsMessages() -{ - _mqttClient.loop(); -} - -void DoughMQTT::handleMessage(String &topic, String &payload) -{ - DoughMQTT::Instance()->_logger.log("sSsS", "<<< ", topic, " = ", payload); - - DoughMQTT *mqtt = DoughMQTT::Instance(); - if (mqtt->_onMessage != nullptr) - { - int pos = topic.lastIndexOf('/'); - if (pos != -1) - { - topic.remove(0, pos + 1); - mqtt->_onMessage(topic, payload); - } - } -} - -void DoughMQTT::subscribe(const char *key) -{ - char topic[200]; - snprintf(topic, sizeof(topic) / sizeof(topic[0]), "%s/%s/%s", MQTT_TOPIC_PREFIX, _mqttDeviceId, key); - _logger.log("ss", "Subscribe to ", topic); - _mqttClient.subscribe(topic); -} - -void DoughMQTT::publish(const char *key, const char *payload) -{ - char topic[200]; - snprintf(topic, sizeof(topic) / sizeof(topic[0]), "%s/%s/%s", MQTT_TOPIC_PREFIX, _mqttDeviceId, key); - _logger.log("ssss", ">>> ", topic, " = ", payload); - _mqttClient.publish(topic, payload); -} - -void DoughMQTT::publish(const char *key, int payload) -{ - char buf[16]; - snprintf(buf, 16, "%d", payload); - publish(key, buf); -} - -void DoughMQTT::publish(const char *key, Measurement measurement) -{ - if (measurement.ok) - { - publish(key, measurement.value); - } - else - { - publish(key, "null"); - } -} \ No newline at end of file diff --git a/src/Network/DoughMQTT.h b/src/Network/DoughMQTT.h deleted file mode 100644 index 0d12edc..0000000 --- a/src/Network/DoughMQTT.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef DOUGH_MQTT_H -#define DOUGH_MQTT_H - -#include -#include -#include "Network/DoughWiFi.h" -#include "Data/Measurement.h" -#include "UI/DoughLogger.h" -#include "config.h" - -/** - * This class encapsulates the connection to the MQTT broker. - * MQTT is used to publish measurements and to store configuration data. - */ -class DoughMQTT; - -typedef void (*DoughMQTTConnectHandler)(DoughMQTT *mqtt); -typedef void (*DoughMQTTMessageHandler)(String &key, String &value); - -class DoughMQTT -{ -public: - static DoughMQTT *Instance(); - void setup(); - void onConnect(DoughMQTTConnectHandler callback); - void onMessage(DoughMQTTMessageHandler callback); - bool isConnected(); - bool connect(); - void subscribe(const char *key); - void procesIncomingsMessages(); - void publish(const char *key, const char *payload); - void publish(const char *key, int payload); - void publish(const char *key, Measurement measurement); - -private: - DoughMQTT(); - static DoughMQTT *_instance; - MQTTClient _mqttClient; - DoughLogger _logger; - DoughMQTTConnectHandler _onConnect = nullptr; - MQTTClientCallbackSimple _onMessage = nullptr; - static void handleMessage(String &topic, String &payload); - char *_mqttDeviceId; -}; - -#endif diff --git a/src/Network/MQTT.cpp b/src/Network/MQTT.cpp new file mode 100644 index 0000000..2b3e8a0 --- /dev/null +++ b/src/Network/MQTT.cpp @@ -0,0 +1,138 @@ +#include "MQTT.h" + +namespace Dough +{ + + // ---------------------------------------------------------------------- + // Constructor + // ---------------------------------------------------------------------- + + MQTT *MQTT::_instance = nullptr; + + MQTT *MQTT::Instance() + { + if (MQTT::_instance == nullptr) + { + MQTT::_instance = new MQTT(); + } + return MQTT::_instance; + } + + MQTT::MQTT() : _logger("MQTT") {} + + // ---------------------------------------------------------------------- + // Setup + // ---------------------------------------------------------------------- + + void MQTT::setup() + { + DoughWiFi *network = DoughWiFi::Instance(); + +#ifdef MQTT_DEVICE_ID + _mqttDeviceId = MQTT_DEVICE_ID; +#else + _mqttDeviceId = network->getMacAddress(); +#endif + _logger.log("ss", "Device ID = ", _mqttDeviceId); + + _mqttClient.begin(MQTT_BROKER, MQTT_PORT, network->client); + } + + void MQTT::onConnect(MQTTConnectHandler callback) + { + _onConnect = callback; + } + + void MQTT::onMessage(MQTTClientCallbackSimple callback) + { + _onMessage = callback; + } + + // ---------------------------------------------------------------------- + // Loop + // ---------------------------------------------------------------------- + + bool MQTT::isConnected() + { + return _mqttClient.connected(); + } + + bool MQTT::connect() + { + _logger.log("sssi", "Broker = ", MQTT_BROKER, ":", MQTT_PORT); + _mqttClient.connect(_mqttDeviceId, MQTT_USERNAME, MQTT_PASSWORD); + + // Check if the connection to the broker was successful. + if (!_mqttClient.connected()) + { + _logger.log("s", "ERROR - Connection to broker failed"); + return false; + } + + _mqttClient.onMessage(MQTT::handleMessage); + + if (_onConnect != nullptr) + { + _onConnect(this); + } + + return true; + } + + void MQTT::procesIncomingsMessages() + { + _mqttClient.loop(); + } + + void MQTT::handleMessage(String &topic, String &payload) + { + MQTT::Instance()->_logger.log("sSsS", "<<< ", topic, " = ", payload); + + MQTT *mqtt = MQTT::Instance(); + if (mqtt->_onMessage != nullptr) + { + int pos = topic.lastIndexOf('/'); + if (pos != -1) + { + topic.remove(0, pos + 1); + mqtt->_onMessage(topic, payload); + } + } + } + + void MQTT::subscribe(const char *key) + { + char topic[200]; + snprintf(topic, sizeof(topic) / sizeof(topic[0]), "%s/%s/%s", MQTT_TOPIC_PREFIX, _mqttDeviceId, key); + _logger.log("ss", "Subscribe to ", topic); + _mqttClient.subscribe(topic); + } + + void MQTT::publish(const char *key, const char *payload) + { + char topic[200]; + snprintf(topic, sizeof(topic) / sizeof(topic[0]), "%s/%s/%s", MQTT_TOPIC_PREFIX, _mqttDeviceId, key); + _logger.log("ssss", ">>> ", topic, " = ", payload); + _mqttClient.publish(topic, payload); + } + + void MQTT::publish(const char *key, int payload) + { + char buf[16]; + snprintf(buf, 16, "%d", payload); + publish(key, buf); + } + + void MQTT::publish(const char *key, Measurement measurement) + { + if (measurement.ok) + { + publish(key, measurement.value); + } + else + { + publish(key, "null"); + } + } + +} // namespace Dough \ No newline at end of file diff --git a/src/Network/MQTT.h b/src/Network/MQTT.h new file mode 100644 index 0000000..f382119 --- /dev/null +++ b/src/Network/MQTT.h @@ -0,0 +1,50 @@ +#ifndef DOUGH_MQTT_H +#define DOUGH_MQTT_H + +#include +#include +#include "Network/DoughWiFi.h" +#include "Data/Measurement.h" +#include "UI/DoughLogger.h" +#include "config.h" + +namespace Dough +{ + /** + * This class encapsulates the connection to the MQTT broker. + * MQTT is used to publish measurements and to store configuration data. + */ + class MQTT; + + typedef void (*MQTTConnectHandler)(MQTT *mqtt); + typedef void (*MQTTMessageHandler)(String &key, String &value); + + class MQTT + { + public: + static MQTT *Instance(); + void setup(); + void onConnect(MQTTConnectHandler callback); + void onMessage(MQTTMessageHandler callback); + bool isConnected(); + bool connect(); + void subscribe(const char *key); + void procesIncomingsMessages(); + void publish(const char *key, const char *payload); + void publish(const char *key, int payload); + void publish(const char *key, Measurement measurement); + + private: + MQTT(); + static MQTT *_instance; + MQTTClient _mqttClient; + DoughLogger _logger; + MQTTConnectHandler _onConnect = nullptr; + MQTTClientCallbackSimple _onMessage = nullptr; + static void handleMessage(String &topic, String &payload); + char *_mqttDeviceId; + }; + +} // namespace Dough + +#endif diff --git a/src/main.cpp b/src/main.cpp index 34f784a..3f07a56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "main.h" +// TODO: move code to Dough namespace // TODO: move config to a separate class // TODO: see if I can give each sensor its own built-in loop schedule for sampling, the DoughData class might be overkill in the latest setup. // TOOD: implement the calibration logic @@ -15,7 +16,7 @@ void setup() HumiditySensor::Instance()->setup(); DistanceSensor::Instance()->setup(); DoughWiFi::Instance()->setup(); - DoughMQTT::Instance()->setup(); + Dough::MQTT::Instance()->setup(); DataController::Instance()->setup(); auto ui = DoughUI::Instance(); ui->setup(); @@ -28,7 +29,7 @@ void loop() { auto ui = DoughUI::Instance(); auto data = DataController::Instance(); - auto mqtt = DoughMQTT::Instance(); + auto mqtt = Dough::MQTT::Instance(); ui->processButtonEvents(); @@ -73,7 +74,7 @@ bool setupNetworkConnection() auto ui = DoughUI::Instance(); auto network = DoughWiFi::Instance(); - auto mqtt = DoughMQTT::Instance(); + auto mqtt = Dough::MQTT::Instance(); if (!network->isConnected()) { @@ -149,7 +150,7 @@ void setStateToConfiguring() ui->led1.on(); ui->led2.blink()->fast(); ui->led3.off(); - DoughMQTT::Instance()->publish("state", "configuring"); + Dough::MQTT::Instance()->publish("state", "configuring"); } void setStateToMeasuring() @@ -160,7 +161,7 @@ void setStateToMeasuring() ui->led1.on(); ui->led2.on(); ui->led3.on(); - DoughMQTT::Instance()->publish("state", "measuring"); + Dough::MQTT::Instance()->publish("state", "measuring"); } void setStateToPaused() @@ -171,7 +172,7 @@ void setStateToPaused() ui->led1.on(); ui->led2.on(); ui->led3.pulse(); - DoughMQTT::Instance()->publish("state", "paused"); + Dough::MQTT::Instance()->publish("state", "paused"); } void setStateToCalibrating() @@ -182,5 +183,5 @@ void setStateToCalibrating() ui->led1.on(); ui->led2.blink()->slow(); ui->led3.off(); - DoughMQTT::Instance()->publish("state", "calibrating"); + Dough::MQTT::Instance()->publish("state", "calibrating"); } diff --git a/src/main.h b/src/main.h index 314890c..6aa5527 100644 --- a/src/main.h +++ b/src/main.h @@ -6,7 +6,7 @@ #include "Sensors/HumiditySensor.h" #include "Sensors/DistanceSensor.h" #include "Network/DoughWiFi.h" -#include "Network/DoughMQTT.h" +#include "Network/MQTT.h" #include "Data/DataController.h" #include "UI/DoughButton.h" #include "UI/DoughUI.h"