171 lines
5.0 KiB
C++
171 lines
5.0 KiB
C++
#include "App/App.h"
|
|
|
|
namespace Dough
|
|
{
|
|
App *App::Instance()
|
|
{
|
|
static App *_instance = new App();
|
|
return _instance;
|
|
}
|
|
|
|
App::App() : config(),
|
|
ui(onoffButtonInterruptCallback, setupButtonInterruptCallback),
|
|
wifi(),
|
|
mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback),
|
|
statePlugin(&ui, &mqtt),
|
|
state(&statePlugin),
|
|
sensorControllerPlugin(&mqtt, &ui),
|
|
distanceSensor(),
|
|
distanceController(
|
|
&distanceSensor, &sensorControllerPlugin,
|
|
DISTANCE_AVERAGE_STORAGE, DISTANCE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
|
|
temperatureController(
|
|
new TemperatureSensor(), &sensorControllerPlugin,
|
|
TEMPERATURE_AVERAGE_STORAGE, TEMPERATURE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
|
|
humidityController(
|
|
new HumiditySensor(), &sensorControllerPlugin,
|
|
HUMIDITY_AVERAGE_STORAGE, HUMIDITY_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
|
|
_logger("APP")
|
|
{
|
|
ui.onoffButton.onPress(handleOnoffButtonPress);
|
|
ui.setupButton.onPress(handleSetupButtonPress);
|
|
}
|
|
|
|
void App::setup()
|
|
{
|
|
Dough::Logger::setup();
|
|
state.setup();
|
|
ui.setup();
|
|
wifi.setup();
|
|
mqtt.setup();
|
|
temperatureController.setup();
|
|
humidityController.setup();
|
|
distanceController.setup();
|
|
}
|
|
|
|
void App::loop()
|
|
{
|
|
if (!_setupNetworking())
|
|
{
|
|
return;
|
|
}
|
|
|
|
ui.processButtonEvents();
|
|
mqtt.procesIncomingsMessages();
|
|
|
|
switch (state.get())
|
|
{
|
|
case CONFIGURING:
|
|
_doConfigure();
|
|
break;
|
|
case MEASURING:
|
|
_doMeasure();
|
|
break;
|
|
case CALIBRATING:
|
|
_doCalibrate();
|
|
break;
|
|
case PAUSED:
|
|
temperatureController.clearHistory();
|
|
humidityController.clearHistory();
|
|
distanceController.clearHistory();
|
|
break;
|
|
default:
|
|
// NOOP
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool App::_setupNetworking()
|
|
{
|
|
if (!wifi.isConnected())
|
|
{
|
|
state.setWiFiConnected(false);
|
|
state.setWiFiConnected(wifi.connect());
|
|
return false;
|
|
}
|
|
if (!mqtt.isConnected())
|
|
{
|
|
state.setMQTTConnected(false);
|
|
state.setMQTTConnected(mqtt.connect());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void App::_doConfigure()
|
|
{
|
|
if (config.isOk())
|
|
{
|
|
state.startMeasurements();
|
|
}
|
|
}
|
|
|
|
void App::_doMeasure()
|
|
{
|
|
if (config.isOk())
|
|
{
|
|
if (temperatureController.loop())
|
|
distanceSensor.setTemperature(temperatureController.getLast().value);
|
|
if (humidityController.loop())
|
|
distanceSensor.setHumidity(humidityController.getLast().value);
|
|
if (distanceController.loop())
|
|
mqtt.publish("height", config.getContainerHeight() - distanceController.getLast().value);
|
|
}
|
|
else
|
|
{
|
|
state.startConfiguration();
|
|
}
|
|
}
|
|
|
|
void App::_doCalibrate()
|
|
{
|
|
int count = 0;
|
|
int runningTotal = 0;
|
|
unsigned int firstValue = 0;
|
|
unsigned int precision = distanceController.getPrecision();
|
|
|
|
for (;;)
|
|
{
|
|
// Read a sensor value. When this fails, then restart the calibration.
|
|
auto m = distanceController.readSensor();
|
|
if (!m.ok)
|
|
{
|
|
_logger.log("s", "Sensor reading failed, restarting calibration");
|
|
return;
|
|
}
|
|
_logger.log("sisis", "Calibration reading ", count, ": ", m.value, "mm");
|
|
|
|
count++;
|
|
runningTotal += m.value;
|
|
|
|
// If this is the first value that is read, then use that one to compare
|
|
// the upcoming measurements against.
|
|
if (count == 1)
|
|
{
|
|
firstValue = m.value;
|
|
}
|
|
// Otherwise, check if the new value is within the precision range of the
|
|
// distance sensor.
|
|
else if (abs(firstValue - m.value) > precision)
|
|
{
|
|
_logger.log("s", "New reading exceeds sensor precision, restarting calibration");
|
|
return;
|
|
}
|
|
|
|
// After reading 10 values in a row that are within the sensor precision,
|
|
// then we have a winner.
|
|
if (count == 10)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
_logger.log("sis", "Calibration completed, container height: ", firstValue, "mm");
|
|
unsigned int container_height = int(runningTotal / 10);
|
|
config.setContainerHeight(container_height);
|
|
mqtt.publish("container_height", container_height, true);
|
|
|
|
state.pauseDevice();
|
|
state.startMeasurements();
|
|
}
|
|
} // namespace Dough
|