Going to see if namespaces help structuring the code.
This commit is contained in:
parent
6b49d62257
commit
3f8eb8b2b8
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -13,7 +13,7 @@ Measurements::Measurements(
|
|||
_storageSize = storageSize;
|
||||
_significantChange = significantChange;
|
||||
_minimumPublishTime = minimumPublishTime;
|
||||
_mqtt = DoughMQTT::Instance();
|
||||
_mqtt = Dough::MQTT::Instance();
|
||||
}
|
||||
|
||||
void Measurements::setup()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <Arduino.h>
|
||||
#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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef DOUGH_MQTT_H
|
||||
#define DOUGH_MQTT_H
|
||||
|
||||
#include <MQTT.h>
|
||||
#include <MQTTClient.h>
|
||||
#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
|
|
@ -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
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef DOUGH_MQTT_H
|
||||
#define DOUGH_MQTT_H
|
||||
|
||||
#include <MQTT.h>
|
||||
#include <MQTTClient.h>
|
||||
#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
|
15
src/main.cpp
15
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");
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue