187 lines
4.7 KiB
C++
187 lines
4.7 KiB
C++
#include "main.h"
|
|
|
|
// 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
|
|
// TODO: see what more stuff can be moved to the UI code. Maybe state to UI state translation ought to be there as well
|
|
// TODO: make significantChange part of sensor class?
|
|
|
|
DoughBoyState state = CONFIGURING;
|
|
auto logger = DoughLogger("MAIN");
|
|
|
|
void setup()
|
|
{
|
|
TemperatureSensor::Instance()->setup();
|
|
HumiditySensor::Instance()->setup();
|
|
DistanceSensor::Instance()->setup();
|
|
DoughWiFi::Instance()->setup();
|
|
DoughMQTT::Instance()->setup();
|
|
DataController::Instance()->setup();
|
|
auto ui = DoughUI::Instance();
|
|
ui->setup();
|
|
ui->onoffButton.onPress(handleOnoffButtonPress);
|
|
ui->setupButton.onPress(handleSetupButtonPress);
|
|
logger.log("s", "Initialization completed, starting device");
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
auto ui = DoughUI::Instance();
|
|
auto data = DataController::Instance();
|
|
auto mqtt = DoughMQTT::Instance();
|
|
|
|
ui->processButtonEvents();
|
|
|
|
if (!setupNetworkConnection())
|
|
{
|
|
return;
|
|
}
|
|
|
|
mqtt->procesIncomingsMessages();
|
|
|
|
if (state == CONFIGURING && data->isConfigured())
|
|
{
|
|
setStateToMeasuring();
|
|
}
|
|
else if (state == MEASURING && !data->isConfigured())
|
|
{
|
|
setStateToConfiguring();
|
|
}
|
|
else if (state == MEASURING)
|
|
{
|
|
DataController::Instance()->loop();
|
|
}
|
|
else if (state == CALIBRATING)
|
|
{
|
|
delay(3000);
|
|
setStateToPaused();
|
|
}
|
|
else if (state == PAUSED)
|
|
{
|
|
DataController::Instance()->clearHistory();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the device is connected to the WiFi network and the MQTT broker.
|
|
* If not, then try to setup the connection.
|
|
* Returns true if the connection was established, false otherwise.
|
|
*/
|
|
bool setupNetworkConnection()
|
|
{
|
|
static auto connectionState = CONNECTING_WIFI;
|
|
|
|
auto ui = DoughUI::Instance();
|
|
auto network = DoughWiFi::Instance();
|
|
auto mqtt = DoughMQTT::Instance();
|
|
|
|
if (!network->isConnected())
|
|
{
|
|
if (connectionState == CONNECTED)
|
|
{
|
|
logger.log("s", "ERROR - Connection to WiFi network lost! Reconnecting ...");
|
|
}
|
|
else
|
|
{
|
|
logger.log("s", "Connecting to the WiFi network ...");
|
|
}
|
|
connectionState = CONNECTING_WIFI;
|
|
ui->led1.blink()->slow();
|
|
ui->led2.off();
|
|
ui->led3.off();
|
|
network->connect();
|
|
}
|
|
if (network->isConnected() && !mqtt->isConnected())
|
|
{
|
|
if (connectionState == CONNECTED)
|
|
{
|
|
logger.log("s", "ERROR - Connection to the MQTT broker lost! Reconnecting ...");
|
|
}
|
|
else
|
|
{
|
|
logger.log("s", "Connecting to the MQTT broker ...");
|
|
}
|
|
connectionState = CONNECTING_MQTT;
|
|
ui->led1.blink()->fast();
|
|
ui->led2.off();
|
|
ui->led3.off();
|
|
mqtt->connect();
|
|
}
|
|
if (network->isConnected() && mqtt->isConnected())
|
|
{
|
|
if (connectionState != CONNECTED)
|
|
{
|
|
logger.log("s", "Connection to MQTT broker established");
|
|
ui->led1.on();
|
|
ui->led2.off();
|
|
ui->led3.off();
|
|
ui->clearButtonEvents();
|
|
connectionState = CONNECTED;
|
|
setStateToConfiguring();
|
|
}
|
|
}
|
|
|
|
return connectionState == CONNECTED;
|
|
}
|
|
|
|
void handleOnoffButtonPress()
|
|
{
|
|
if (state == MEASURING)
|
|
{
|
|
setStateToPaused();
|
|
}
|
|
else if (state == PAUSED)
|
|
{
|
|
setStateToMeasuring();
|
|
}
|
|
}
|
|
|
|
void handleSetupButtonPress()
|
|
{
|
|
setStateToCalibrating();
|
|
}
|
|
|
|
void setStateToConfiguring()
|
|
{
|
|
auto ui = DoughUI::Instance();
|
|
logger.log("s", "Waiting for configuration ...");
|
|
state = CONFIGURING;
|
|
ui->led1.on();
|
|
ui->led2.blink()->fast();
|
|
ui->led3.off();
|
|
DoughMQTT::Instance()->publish("state", "configuring");
|
|
}
|
|
|
|
void setStateToMeasuring()
|
|
{
|
|
auto ui = DoughUI::Instance();
|
|
logger.log("s", "Starting measurements");
|
|
state = MEASURING;
|
|
ui->led1.on();
|
|
ui->led2.on();
|
|
ui->led3.on();
|
|
DoughMQTT::Instance()->publish("state", "measuring");
|
|
}
|
|
|
|
void setStateToPaused()
|
|
{
|
|
auto ui = DoughUI::Instance();
|
|
logger.log("s", "Pausing measurements");
|
|
state = PAUSED;
|
|
ui->led1.on();
|
|
ui->led2.on();
|
|
ui->led3.pulse();
|
|
DoughMQTT::Instance()->publish("state", "paused");
|
|
}
|
|
|
|
void setStateToCalibrating()
|
|
{
|
|
auto ui = DoughUI::Instance();
|
|
logger.log("s", "Requested device calibration");
|
|
state = CALIBRATING;
|
|
ui->led1.on();
|
|
ui->led2.blink()->slow();
|
|
ui->led3.off();
|
|
DoughMQTT::Instance()->publish("state", "calibrating");
|
|
}
|