More shuffling of functionality, getting things to match with my standards for 'clean code'.

This commit is contained in:
Maurice Makaay 2020-07-18 14:55:41 +02:00
parent 7f5f60a6ac
commit 09f3be6dcb
19 changed files with 158 additions and 135 deletions

View File

@ -12,21 +12,25 @@ namespace Dough
ui(onoffButtonInterruptCallback, setupButtonInterruptCallback), ui(onoffButtonInterruptCallback, setupButtonInterruptCallback),
wifi(), wifi(),
mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback), mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback),
temperatureSensor( sensorControllerPlugin(&mqtt, &ui),
&mqtt, "temperature", TemperatureSensor::Instance(),
TEMPERATURE_AVERAGE_STORAGE,
TEMPERATURE_MEASURE_INTERVAL, sensorOnMeasureCallback,
MINIMUM_PUBLISH_INTERVAL, sensorOnPublishCallback),
humiditySensor(
&mqtt, "humidity", HumiditySensor::Instance(),
HUMIDITY_AVERAGE_STORAGE,
HUMIDITY_MEASURE_INTERVAL, sensorOnMeasureCallback,
MINIMUM_PUBLISH_INTERVAL, sensorOnPublishCallback),
distanceSensor( distanceSensor(
&mqtt, "distance", DistanceSensor::Instance(), &sensorControllerPlugin,
&mqtt, "distance", distanceSensorX,
DISTANCE_AVERAGE_STORAGE, DISTANCE_AVERAGE_STORAGE,
DISTANCE_MEASURE_INTERVAL, sensorOnMeasureCallback, DISTANCE_MEASURE_INTERVAL,
MINIMUM_PUBLISH_INTERVAL, sensorOnPublishCallback), MINIMUM_PUBLISH_INTERVAL),
temperatureSensor(
&sensorControllerPlugin,
&mqtt, "temperature", temperatureSensorX,
TEMPERATURE_AVERAGE_STORAGE,
TEMPERATURE_MEASURE_INTERVAL,
MINIMUM_PUBLISH_INTERVAL),
humiditySensor(
&sensorControllerPlugin,
&mqtt, "humidity", humiditySensorX,
HUMIDITY_AVERAGE_STORAGE,
HUMIDITY_MEASURE_INTERVAL,
MINIMUM_PUBLISH_INTERVAL),
_logger("APP") {} _logger("APP") {}
void App::setup() void App::setup()
@ -41,17 +45,19 @@ namespace Dough
void App::measure() void App::measure()
{ {
if (config.isOk()) if (!config.isOk())
{ {
// Get measurements from the sensors. Suspend the user interface return;
// interrupts in the meanwhile, to not disturb the timing-sensitive
// sensor readings.
ui.suspend();
temperatureSensor.loop();
humiditySensor.loop();
distanceSensor.loop();
ui.resume();
} }
// Get measurements from the sensors. Suspend the user interface
// interrupts in the meanwhile, to not disturb the timing-sensitive
// sensor readings.
ui.suspend();
temperatureSensor.loop();
humiditySensor.loop();
distanceSensor.loop();
ui.resume();
} }
void App::clearHistory() void App::clearHistory()

View File

@ -5,10 +5,11 @@
#include "UI/UI.h" #include "UI/UI.h"
#include "App/Configuration.h" #include "App/Configuration.h"
#include "App/callbacks.h" #include "App/callbacks.h"
#include "Data/SensorController.h" #include "Sensors/SensorController.h"
#include "Sensors/TemperatureSensor.h" #include "App/SensorControllerPlugin.h"
#include "Sensors/HumiditySensor.h" #include "Sensors/HighLevel/TemperatureSensor.h"
#include "Sensors/DistanceSensor.h" #include "Sensors/HighLevel/HumiditySensor.h"
#include "Sensors/HighLevel/DistanceSensor.h"
#include "config.h" #include "config.h"
namespace Dough namespace Dough
@ -21,9 +22,13 @@ namespace Dough
UI ui; UI ui;
WiFi wifi; WiFi wifi;
MQTT mqtt; MQTT mqtt;
SensorController temperatureSensor; SensorControllerPlugin sensorControllerPlugin;
SensorController humiditySensor; DistanceSensor distanceSensorX;
SensorController distanceSensor; SensorController distanceSensor;
TemperatureSensor temperatureSensorX;
SensorController temperatureSensor;
HumiditySensor humiditySensorX;
SensorController humiditySensor;
void setup(); void setup();
void measure(); void measure();

View File

@ -0,0 +1,22 @@
#include "App/SensorControllerPlugin.h"
namespace Dough
{
SensorControllerPlugin::SensorControllerPlugin(MQTT *mqtt, UI *ui) : _mqtt(mqtt), _ui(ui)
{
}
void SensorControllerPlugin::doPublish(SensorController *controller) {
Serial.println(">>>>>>>>>> YO PLUGIN HERE! <<<<<<<<<<<");
}
void SensorControllerPlugin::beforeMeasure(SensorController *controller)
{
_ui->notifySensorActivity();
}
void SensorControllerPlugin::beforePublish(SensorController *controller)
{
_ui->notifyNetworkActivity();
}
}

View File

@ -0,0 +1,28 @@
#ifndef DOUGH_SENSORCONTROLLER_PLUGINS_H
#define DOUGH_SENSORCONTROLLER_PLUGINS_H
#include <Arduino.h>
#include "UI/Logger.h"
#include "Sensors/SensorController.h"
#include "Network/MQTT.h"
#include "UI/UI.h"
namespace Dough
{
// This class is a plugin for the Dough::SensorController. It takes care
// of notifying events via the device UI and publishing data via the MQTT broker.
class SensorControllerPlugin : public SensorControllerPluginBase
{
public:
SensorControllerPlugin(MQTT *mqtt, UI *ui);
virtual void beforeMeasure(SensorController *controller);
virtual void beforePublish(SensorController *controller);
virtual void doPublish(SensorController *controller);
private:
MQTT *_mqtt;
UI *_ui;
};
} // namespace Dough
#endif

View File

@ -37,16 +37,6 @@ void setupButtonInterruptCallback()
Dough::App::Instance()->ui.setupButton.handleButtonState(); Dough::App::Instance()->ui.setupButton.handleButtonState();
} }
void sensorOnMeasureCallback()
{
Dough::App::Instance()->ui.notifySensorActivity();
}
void sensorOnPublishCallback()
{
Dough::App::Instance()->ui.notifyNetworkActivity();
}
// This callback is called when the TC4 timer from the UI code hits an overflow // This callback is called when the TC4 timer from the UI code hits an overflow
// interrupt. It is defined outside the Dough namespace, because TC4_Handler is // interrupt. It is defined outside the Dough namespace, because TC4_Handler is
// a hard-coded root namespace function name. // a hard-coded root namespace function name.

View File

@ -4,6 +4,7 @@
#include "Network/MQTT.h" #include "Network/MQTT.h"
#include "UI/Logger.h" #include "UI/Logger.h"
#include "App/App.h" #include "App/App.h"
#include "Sensors/SensorController.h"
// This header file defines various callback functions that // This header file defines various callback functions that
// live in the global namespace. All callbacks are bundled here // live in the global namespace. All callbacks are bundled here
@ -17,8 +18,4 @@ void mqttOnMessageCallback(String &topic, String &payload);
void onoffButtonInterruptCallback(); void onoffButtonInterruptCallback();
void setupButtonInterruptCallback(); void setupButtonInterruptCallback();
// Callbacks from the Dough::SensorController module.
void sensorOnMeasureCallback();
void sensorOnPublishCallback();
#endif #endif

View File

@ -5,12 +5,10 @@ namespace Dough
MQTT::MQTT( MQTT::MQTT(
WiFi *wifi, WiFi *wifi,
MQTTConnectHandler onConnect, MQTTConnectHandler onConnect,
MQTTMessageHandler onMessage) : _logger("MQTT") MQTTMessageHandler onMessage) : _logger("MQTT"),
{ _wifi(wifi),
_wifi = wifi; _onConnect(onConnect),
_onConnect = onConnect; _onMessage(onMessage) {}
_onMessage = onMessage;
}
void MQTT::setup() void MQTT::setup()
{ {
@ -42,12 +40,12 @@ namespace Dough
} }
_logger.log("s", "Connection to broker successful"); _logger.log("s", "Connection to broker successful");
// Incoming messages will be passed on to the _onMessage() function.
_mqttClient.onMessage(_onMessage); _mqttClient.onMessage(_onMessage);
if (_onConnect != nullptr) // Call the _onConnect() function to notify the system that the connection
{ // to the MQTT broker was setup successfully.
_onConnect(this); _onConnect(this);
}
return true; return true;
} }
@ -93,4 +91,4 @@ namespace Dough
publish(key, "null"); publish(key, "null");
} }
} }
} } // namespace Dough

View File

@ -31,8 +31,8 @@ namespace Dough
void publish(const char *key, Measurement measurement); void publish(const char *key, Measurement measurement);
private: private:
WiFi *_wifi;
Logger _logger; Logger _logger;
WiFi *_wifi;
MQTTClient _mqttClient; MQTTClient _mqttClient;
MQTTConnectHandler _onConnect; MQTTConnectHandler _onConnect;
MQTTClientCallbackSimple _onMessage; MQTTClientCallbackSimple _onMessage;

View File

@ -2,15 +2,8 @@
namespace Dough namespace Dough
{ {
DistanceSensor *DistanceSensor::Instance()
{
static DistanceSensor *_instance = new DistanceSensor();
return _instance;
}
DistanceSensor::DistanceSensor() : _logger("DISTANCE") DistanceSensor::DistanceSensor() : _logger("DISTANCE")
{ {
_logger.log("s", "INIT distance sensor object");// TODO
_hcsr04 = new SensorHCSR04(HCSR04_TRIG_PIN, HCSR04_ECHO_PIN); _hcsr04 = new SensorHCSR04(HCSR04_TRIG_PIN, HCSR04_ECHO_PIN);
} }

View File

@ -1,7 +1,7 @@
#ifndef DOUGH_DISTANCE_SENSOR_H #ifndef DOUGH_DISTANCE_SENSOR_H
#define DOUGH_DISTANCE_SENSOR_H #define DOUGH_DISTANCE_SENSOR_H
#include "Sensors/SensorBase.h" #include "Sensors/HighLevel/SensorBase.h"
#include "Sensors/LowLevel/SensorHCSR04.h" #include "Sensors/LowLevel/SensorHCSR04.h"
#include "UI/Logger.h" #include "UI/Logger.h"
#include "Data/Measurement.h" #include "Data/Measurement.h"
@ -13,7 +13,7 @@ namespace Dough
class DistanceSensor : public SensorBase class DistanceSensor : public SensorBase
{ {
public: public:
static DistanceSensor *Instance(); DistanceSensor();
void setTemperature(int temperature); void setTemperature(int temperature);
void setHumidity(int humidity); void setHumidity(int humidity);
virtual void setup(); virtual void setup();
@ -21,7 +21,6 @@ namespace Dough
virtual unsigned int getPrecision(); virtual unsigned int getPrecision();
private: private:
DistanceSensor();
Logger _logger; Logger _logger;
SensorHCSR04 *_hcsr04; SensorHCSR04 *_hcsr04;
}; };

View File

@ -2,12 +2,6 @@
namespace Dough namespace Dough
{ {
HumiditySensor *HumiditySensor::Instance()
{
static HumiditySensor *_instance = new HumiditySensor();
return _instance;
}
HumiditySensor::HumiditySensor() : _logger("HUMIDITY") {} HumiditySensor::HumiditySensor() : _logger("HUMIDITY") {}
void HumiditySensor::setup() void HumiditySensor::setup()
@ -26,7 +20,6 @@ namespace Dough
else else
{ {
_logger.log("sis", "Humidity = ", int(t), "%"); _logger.log("sis", "Humidity = ", int(t), "%");
DistanceSensor::Instance()->setHumidity(int(t));
return Measurement::Value(int(t)); return Measurement::Value(int(t));
} }
} }
@ -34,5 +27,5 @@ namespace Dough
unsigned int HumiditySensor::getPrecision() unsigned int HumiditySensor::getPrecision()
{ {
return 2; // prevent flapping when transitioning from value A to value B return 2; // prevent flapping when transitioning from value A to value B
} }
} } // namespace Dough

View File

@ -1,11 +1,10 @@
#ifndef DOUGH_HUMIDITY_SENSOR_H #ifndef DOUGH_HUMIDITY_SENSOR_H
#define DOUGH_HUMIDITY_SENSOR_H #define DOUGH_HUMIDITY_SENSOR_H
#include "Sensors/SensorBase.h" #include "Sensors/HighLevel/SensorBase.h"
#include "Sensors/LowLevel/SensorDHT11.h" #include "Sensors/LowLevel/SensorDHT11.h"
#include "UI/Logger.h" #include "UI/Logger.h"
#include "Data/Measurement.h" #include "Data/Measurement.h"
#include "Sensors/DistanceSensor.h"
#include "config.h" #include "config.h"
namespace Dough namespace Dough
@ -14,13 +13,12 @@ namespace Dough
class HumiditySensor : public SensorBase class HumiditySensor : public SensorBase
{ {
public: public:
static HumiditySensor *Instance(); HumiditySensor();
virtual void setup(); virtual void setup();
virtual Measurement read(); virtual Measurement read();
virtual unsigned int getPrecision(); virtual unsigned int getPrecision();
private: private:
HumiditySensor();
Logger _logger; Logger _logger;
}; };
} }

View File

@ -5,7 +5,7 @@
namespace Dough namespace Dough
{ {
// This interface is implemented by all sensors. // This interface is implemented by all high level sensors.
class SensorBase class SensorBase
{ {
public: public:

View File

@ -2,12 +2,6 @@
namespace Dough namespace Dough
{ {
TemperatureSensor *TemperatureSensor::Instance()
{
static TemperatureSensor *_instance = new TemperatureSensor();
return _instance;
}
TemperatureSensor::TemperatureSensor() : _logger("TEMPERATURE") {} TemperatureSensor::TemperatureSensor() : _logger("TEMPERATURE") {}
void TemperatureSensor::setup() void TemperatureSensor::setup()
@ -15,10 +9,6 @@ namespace Dough
SensorDHT11::Instance()->begin(); SensorDHT11::Instance()->begin();
} }
// ----------------------------------------------------------------------
// loop
// ----------------------------------------------------------------------
Measurement TemperatureSensor::read() Measurement TemperatureSensor::read()
{ {
float t = SensorDHT11::Instance()->readTemperature(); float t = SensorDHT11::Instance()->readTemperature();
@ -30,7 +20,6 @@ namespace Dough
else else
{ {
_logger.log("sis", "Temperature = ", int(t), "°C"); _logger.log("sis", "Temperature = ", int(t), "°C");
DistanceSensor::Instance()->setTemperature(int(t));
return Measurement::Value(int(t)); return Measurement::Value(int(t));
} }
} }

View File

@ -1,11 +1,10 @@
#ifndef DOUGH_TEMPERATURE_SENSOR_H #ifndef DOUGH_TEMPERATURE_SENSOR_H
#define DOUGH_TEMPERATURE_SENSOR_H #define DOUGH_TEMPERATURE_SENSOR_H
#include "Sensors/SensorBase.h" #include "Sensors/HighLevel/SensorBase.h"
#include "Sensors/LowLevel/SensorDHT11.h" #include "Sensors/LowLevel/SensorDHT11.h"
#include "UI/Logger.h" #include "UI/Logger.h"
#include "Data/Measurement.h" #include "Data/Measurement.h"
#include "Sensors/DistanceSensor.h"
#include "config.h" #include "config.h"
namespace Dough namespace Dough
@ -14,13 +13,12 @@ namespace Dough
class TemperatureSensor : public SensorBase class TemperatureSensor : public SensorBase
{ {
public: public:
static TemperatureSensor *Instance(); TemperatureSensor();
virtual void setup(); virtual void setup();
virtual Measurement read(); virtual Measurement read();
virtual unsigned int getPrecision(); virtual unsigned int getPrecision();
private: private:
TemperatureSensor();
Logger _logger; Logger _logger;
}; };
} }

View File

@ -1,31 +1,28 @@
#include "Data/SensorController.h" #include "Sensors/SensorController.h"
#include "UI/UI.h" #include "UI/UI.h"
namespace Dough namespace Dough
{ {
SensorController::SensorController( SensorController::SensorController(
SensorControllerPluginBase *plugin,
MQTT *mqtt, MQTT *mqtt,
const char *mqttKey, const char *mqttKey,
SensorBase *sensor, SensorBase &sensor,
unsigned int storageSize, unsigned int storageSize,
unsigned int minimumMeasureTime, unsigned int minimumMeasureTime,
SensorControllerCallback onMeasure, unsigned int minimumPublishTime) : _plugin(plugin),
unsigned int minimumPublishTime, _mqtt(mqtt),
SensorControllerCallback onPublish) _sensor(sensor)
{ {
_mqtt = mqtt;
_mqttKey = mqttKey; _mqttKey = mqttKey;
_sensor = sensor;
_storageSize = storageSize; _storageSize = storageSize;
_minimumMeasureTime = minimumMeasureTime; _minimumMeasureTime = minimumMeasureTime;
_onMeasure = onMeasure;
_minimumPublishTime = minimumPublishTime; _minimumPublishTime = minimumPublishTime;
_onPublish = onPublish;
} }
void SensorController::setup() void SensorController::setup()
{ {
_sensor->setup(); _sensor.setup();
// Format the key to use for publishing the average (i.e. "<mqttKey>/average"). // Format the key to use for publishing the average (i.e. "<mqttKey>/average").
auto lenAverageKey = strlen(_mqttKey) + 9; // +9 for the "/average\0" suffix auto lenAverageKey = strlen(_mqttKey) + 9; // +9 for the "/average\0" suffix
@ -45,12 +42,16 @@ namespace Dough
{ {
if (_mustMeasure()) if (_mustMeasure())
{ {
_onMeasure(); _plugin->beforeMeasure(this);
_measure(); _measure();
_plugin->afterMeasure(this);
} }
if (_mustPublish()) if (_mustPublish())
{ {
_onPublish(); _plugin->beforePublish(this);
Serial.println("CALLING doPublish() from plugin"); // DEBUG XXX
_plugin->doPublish(this);
_plugin->afterPublish(this);
_publish(); _publish();
} }
} }
@ -73,8 +74,8 @@ namespace Dough
void SensorController::_measure() void SensorController::_measure()
{ {
_lastMeasuredAt = millis(); _lastMeasuredAt = millis();
_store(_sensor->read()); _store(_sensor.read());
} }
bool SensorController::_mustPublish() bool SensorController::_mustPublish()
@ -102,7 +103,7 @@ namespace Dough
return _lastPublishedAt == 0 || delta >= (_minimumPublishTime * 1000); return _lastPublishedAt == 0 || delta >= (_minimumPublishTime * 1000);
} }
auto precision = _sensor->getPrecision(); auto precision = _sensor.getPrecision();
// When there is a significant change in the sensor value, then publish. // When there is a significant change in the sensor value, then publish.
if (abs(_lastPublished.value - lastMeasurement.value) >= precision) if (abs(_lastPublished.value - lastMeasurement.value) >= precision)
@ -197,4 +198,4 @@ namespace Dough
_storage[i]->clear(); _storage[i]->clear();
} }
} }
} } // namespace Dough

View File

@ -1,25 +1,40 @@
#ifndef DOUGH_MEASUREMENTS_H #ifndef DOUGH_SENSORCONTROLLER_H
#define DOUGH_MEASUREMENTS_H #define DOUGH_SENSORCONTROLLER_H
#include <Arduino.h> #include <Arduino.h>
#include "Sensors/SensorBase.h" #include "Sensors/HighLevel/SensorBase.h"
#include "Data/Measurement.h" #include "Data/Measurement.h"
#include "Network/MQTT.h" #include "Network/MQTT.h"
namespace Dough namespace Dough
{ {
typedef void (*SensorControllerCallback)();
// This class is used to store measurements for a sensor and to keep // This class is used to store measurements for a sensor and to keep
// track of running totals for handling average computations. // track of running totals for handling average computations.
// It also provides functionality to decide when to read a measurement // It also provides functionality to decide when to read a measurement
// from a sensor and when to publish measurements to MQTT (after significant // from a sensor and when to publish measurements (after significant
// changes occur or when the last publish was too long ago). // changes occur or when the last publish was too long ago).
class SensorController;
// This class can be derived from to create a plugin module for the
// Dough::SensorController. Methods from this interface will be called
// by the Dough::SensorController at appropriate times.
class SensorControllerPluginBase
{
public:
virtual void beforeMeasure(SensorController *controller) {};
virtual void afterMeasure(SensorController *controller) {};
virtual void beforePublish(SensorController *controller) {};
virtual void doPublish(SensorController *controller) {};
virtual void afterPublish(SensorController *controller) {};
};
class SensorController class SensorController
{ {
public: public:
// Create a new Measurements object. // Create a new Measurements object.
// //
// @param plugin
// The Dough::SensorControllerPluginBase to use.
// @param mqtt // @param mqtt
// The Dough::MQTT object, which is connected to the MQTT broker. // The Dough::MQTT object, which is connected to the MQTT broker.
// @param mqttKey // @param mqttKey
@ -35,7 +50,7 @@ namespace Dough
// from the sensor. // from the sensor.
// @param onMeasure // @param onMeasure
// A callback function that is called right before a measurement // A callback function that is called right before a measurement
// is taken. // is taken using the contained sensor object.
// @param minimumPublishTime // @param minimumPublishTime
// The number of seconds after which to forcibly publish measurements // The number of seconds after which to forcibly publish measurements
// to MQTT, even when no significant changes to measurements were seen. // to MQTT, even when no significant changes to measurements were seen.
@ -43,14 +58,13 @@ namespace Dough
// A callback function that is called right before a measurement // A callback function that is called right before a measurement
// is published. // is published.
SensorController( SensorController(
SensorControllerPluginBase *plugin,
MQTT *mqtt, MQTT *mqtt,
const char *mqttKey, const char *mqttKey,
SensorBase *sensor, SensorBase &sensor,
unsigned int storageSize, unsigned int storageSize,
unsigned int minimumMeasureTime, unsigned int minimumMeasureTime,
SensorControllerCallback onMeasure, unsigned int minimumPublishTime);
unsigned int minimumPublishTime,
SensorControllerCallback onPublish);
void setup(); void setup();
void loop(); void loop();
Measurement getLast(); Measurement getLast();
@ -58,22 +72,21 @@ namespace Dough
void clearHistory(); void clearHistory();
private: private:
SensorControllerPluginBase *_plugin;
MQTT *_mqtt; MQTT *_mqtt;
const char *_mqttKey; const char *_mqttKey;
char *_mqttAverageKey; char *_mqttAverageKey;
SensorBase *_sensor; SensorBase &_sensor;
Measurement **_storage; Measurement **_storage;
unsigned int _storageSize; unsigned int _storageSize;
int _averageSum = 0; int _averageSum = 0;
unsigned int _averageCount = 0; unsigned int _averageCount = 0;
unsigned int _index = 0; unsigned int _index = 0;
bool _mustMeasure(); bool _mustMeasure();
SensorControllerCallback _onMeasure;
void _measure(); void _measure();
unsigned int _minimumMeasureTime; unsigned int _minimumMeasureTime;
unsigned long _lastMeasuredAt = 0; unsigned long _lastMeasuredAt = 0;
bool _mustPublish(); bool _mustPublish();
SensorControllerCallback _onPublish ;
void _publish(); void _publish();
unsigned int _minimumPublishTime; unsigned int _minimumPublishTime;
unsigned long _lastPublishedAt = 0; unsigned long _lastPublishedAt = 0;
@ -82,6 +95,6 @@ namespace Dough
void _store(Measurement measurement); void _store(Measurement measurement);
unsigned int _next(); unsigned int _next();
}; };
} } // namespace Dough
#endif #endif

View File

@ -1,13 +1,6 @@
// The speed to use for the serial terminal logging. // The speed to use for the serial terminal logging.
#define LOG_BAUDRATE 9600 #define LOG_BAUDRATE 9600
// Define this one to wait for USB serial to come up.
// This can be useful during development, when you want all
// serial messages to appear in the serial monitor.
// Without this, some of the initial serial messages might
// be missing from the output.
//#define LOG_WAIT_SERIAL
// The digital pins to which the push buttons are connected. // The digital pins to which the push buttons are connected.
#define ONOFF_BUTTON_PIN 2 #define ONOFF_BUTTON_PIN 2
#define SETUP_BUTTON_PIN 3 #define SETUP_BUTTON_PIN 3

View File

@ -3,9 +3,9 @@
#include <Arduino.h> #include <Arduino.h>
#include "App/App.h" #include "App/App.h"
#include "Sensors/TemperatureSensor.h" #include "Sensors/HighLevel/TemperatureSensor.h"
#include "Sensors/HumiditySensor.h" #include "Sensors/HighLevel/HumiditySensor.h"
#include "Sensors/DistanceSensor.h" #include "Sensors/HighLevel/DistanceSensor.h"
#include "Network/WiFi.h" #include "Network/WiFi.h"
#include "Network/MQTT.h" #include "Network/MQTT.h"
#include "UI/Button.h" #include "UI/Button.h"