PlantCtrl/esp32/src/PlantCtrl.cpp

164 lines
4.9 KiB
C++
Raw Normal View History

2020-09-07 18:18:46 +02:00
/**
* @file PlantCtrl.cpp
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-05-27
*
* @copyright Copyright (c) 2020
*
*/
#include "PlantCtrl.h"
#include "ControllerConfiguration.h"
2021-07-01 21:19:51 +02:00
#include "TimeUtils.h"
2021-07-09 21:50:51 +02:00
#include "MathUtils.h"
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
2020-09-07 18:18:46 +02:00
Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSettings_t *setting)
{
2020-10-14 20:07:56 +02:00
this->mPinSensor = pinSensor;
this->mPinPump = pinPump;
2020-10-16 16:22:48 +02:00
this->mPlant = plant;
this->mSetting = setting;
2020-12-20 17:00:44 +01:00
this->mPlantId = plantId;
2020-10-16 18:25:02 +02:00
}
void Plant::init(void)
{
2020-10-23 16:20:34 +02:00
/* Initialize Home Settings validator */
this->mSetting->pSensorDry->setDefaultValue(DEACTIVATED_PLANT);
2021-07-09 21:50:51 +02:00
this->mSetting->pSensorDry->setValidator([](double candidate) {
return (((candidate >= 0.0) && (candidate <= 100.0)) || equalish(candidate,DEACTIVATED_PLANT));
2020-10-16 16:22:48 +02:00
});
this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00
this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 23));
2020-10-16 16:22:48 +02:00
});
this->mSetting->pPumpAllowedHourRangeEnd->setDefaultValue(20); // stop pumps at 20:00
this->mSetting->pPumpAllowedHourRangeEnd->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 23));
2020-10-16 16:22:48 +02:00
});
2020-10-16 18:25:02 +02:00
this->mSetting->pPumpOnlyWhenLowLight->setDefaultValue(true);
this->mSetting->pPumpCooldownInHours->setDefaultValue(20); // minutes
this->mSetting->pPumpCooldownInHours->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 1024));
2020-10-16 16:22:48 +02:00
});
2020-10-23 16:20:34 +02:00
/* Initialize Hardware */
Serial.println("Set GPIO mode " + String(mPinPump) + "=" + String(OUTPUT));
Serial.flush();
2020-10-23 16:20:34 +02:00
pinMode(this->mPinPump, OUTPUT);
Serial.println("Set GPIO mode " + String(mPinSensor) + "=" + String(ANALOG));
Serial.flush();
2020-10-23 16:20:34 +02:00
pinMode(this->mPinSensor, ANALOG);
Serial.println("Set GPIO " + String(mPinPump) + "=" + String(LOW));
Serial.flush();
digitalWrite(this->mPinPump, LOW);
2020-10-23 16:20:34 +02:00
}
void Plant::clearMoisture(void){
this->moistureRaw.clear();
}
void Plant::addSenseValue(void)
{
int raw = analogRead(this->mPinSensor);
if(raw < MOIST_SENSOR_MAX_ADC && raw > MOIST_SENSOR_MIN_ADC){
this->moistureRaw.add(raw);
}
2020-10-23 16:20:34 +02:00
}
void Plant::postMQTTconnection(void)
{
2020-10-23 16:20:34 +02:00
const String OFF = String("OFF");
this->mConnected = true;
2020-10-23 16:20:34 +02:00
this->mPlant->setProperty("switch").send(OFF);
2021-07-09 21:50:51 +02:00
long raw = getCurrentMoisture();
double pct = 100 - mapf(raw, MOIST_SENSOR_MIN_ADC, MOIST_SENSOR_MAX_ADC, 0, 100);
if (equalish(raw, MISSING_SENSOR))
{
pct = 0;
}
if (pct < 0)
{
pct = 0;
}
if (pct > 100)
{
pct = 100;
}
this->mPlant->setProperty("moist").send(String(round(pct*10)/10));
this->mPlant->setProperty("moistraw").send(String(raw));
2020-10-23 16:20:34 +02:00
}
void Plant::deactivatePump(void)
{
2021-05-26 21:46:33 +02:00
int plantId = this->mPlantId;
Serial << "deactivating pump " << plantId << endl;
2020-10-23 16:20:34 +02:00
digitalWrite(this->mPinPump, LOW);
if (this->mConnected)
{
2020-10-23 16:20:34 +02:00
const String OFF = String("OFF");
this->mPlant->setProperty("switch").send(OFF);
}
2020-09-07 18:18:46 +02:00
}
void Plant::publishState(String state) {
if (this->mConnected)
{
this->mPlant->setProperty("state").send(state);
}
}
void Plant::activatePump(void)
{
2021-05-26 21:46:33 +02:00
int plantId = this->mPlantId;
Serial << "activating pump " << plantId << endl;
2020-10-23 16:20:34 +02:00
digitalWrite(this->mPinPump, HIGH);
if (this->mConnected)
{
2020-10-23 16:20:34 +02:00
const String OFF = String("ON");
this->mPlant->setProperty("switch").send(OFF);
2021-07-01 21:19:51 +02:00
this->mPlant->setProperty("lastPump").send(String(getCurrentTime()));
2020-10-23 16:20:34 +02:00
}
}
2021-07-09 22:51:50 +02:00
bool Plant::switchHandler(const HomieRange& range, const String& value) {
if (range.isRange) {
return false; // only one switch is present
}
if ((value.equals("ON")) || (value.equals("On")) || (value.equals("on")) || (value.equals("true"))) {
this->activatePump();
return true;
} else if ((value.equals("OFF")) || (value.equals("Off")) || (value.equals("off")) || (value.equals("false")) ) {
this->deactivatePump();
return true;
} else {
return false;
}
}
void Plant::setSwitchHandler(HomieInternals::PropertyInputHandler f) {
this->mPump.settable(f);
}
void Plant::advertise(void)
{
2020-10-23 16:20:34 +02:00
// Advertise topics
2021-07-09 22:51:50 +02:00
mPump = this->mPlant->advertise("switch").setName("Pump").setDatatype("boolean");
2021-07-01 21:19:51 +02:00
this->mPlant->advertise("lastPump").setName("lastPump").setDatatype("number").setUnit("unixtime");
this->mPlant->advertise("moist").setName("Percent").setDatatype("number").setUnit("%");
this->mPlant->advertise("moistraw").setName("adc").setDatatype("number").setUnit("3.3/4096V");
this->mPlant->advertise("state").setName("state").setDatatype("string");
2020-10-23 16:20:34 +02:00
}