diff --git a/board/sym-lib-table b/board/sym-lib-table index e713e5d..b51ae06 100644 --- a/board/sym-lib-table +++ b/board/sym-lib-table @@ -1,4 +1,5 @@ -(sym_lib_table - (lib (name LP38690DT-3.3)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/LP38690DT-3.3.lib)(options "")(descr "")) - (lib (name ESP32-DEVKITC-32D)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/ESP32/ESP32-DEVKITC-32D.lib)(options "")(descr "")) -) +(sym_lib_table + (lib (name LP38690DT-3.3)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/LP38690DT-3.3.lib)(options "")(descr "")) + (lib (name ESP32-DEVKITC-32D)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/ESP32/ESP32-DEVKITC-32D.lib)(options "")(descr "")) + (lib (name PlantCtrlESP32-rescue)(type Legacy)(uri ${KIPRJMOD}/PlantCtrlESP32-rescue.lib)(options "")(descr "")) +) diff --git a/esp32/include/PlantCtrl.h b/esp32/include/PlantCtrl.h index a955797..55acb48 100644 --- a/esp32/include/PlantCtrl.h +++ b/esp32/include/PlantCtrl.h @@ -20,12 +20,12 @@ class Plant { private: RunningMedian moistureRaw = RunningMedian(5); HomieNode* mPlant = NULL; - -public: - //FIXME visibility int mPinSensor=0; /**< Pin of the moist sensor */ int mPinPump=0; /**< Pin of the pump */ PlantSettings_t* mSetting; + bool mConnected = false; + +public: /** * @brief Construct a new Plant object * @@ -37,29 +37,22 @@ public: HomieNode* plant, PlantSettings_t* setting); + void postMQTTconnection(void); + + void advertise(void); + /** - * @brief Add a value, to be measured + * @brief Measure a new analog moister value * - * @param analogValue */ - void addSenseValue(int analogValue); + void addSenseValue(void); - /** - * @brief Get the Sensor Pin of the analog measuring - * - * @return int - */ - int getSensorPin() { return mPinSensor; } - - /** - * @brief Get the Pump Pin object - * - * @return int - */ - int getPumpPin() { return mPinPump; } - int getSensorValue() { return moistureRaw.getMedian(); } + void deactivatePump(void); + + void activatePump(void); + /** * @brief Check if a plant is too dry and needs some water. * @@ -73,8 +66,17 @@ public: HomieInternals::SendingPromise& setProperty(const String& property) const { return mPlant->setProperty(property); } + bool switchHandler(const HomieRange& range, const String& value); void init(void); + + bool isInCooldown(long sinceLastActivation) { + return (this->mSetting->pPumpCooldownInHours->get() > sinceLastActivation / 3600); + } + + bool isAllowedOnlyAtLowLight(void) { + return this->mSetting->pPumpOnlyWhenLowLight->get(); + } }; #endif diff --git a/esp32/src/PlantCtrl.cpp b/esp32/src/PlantCtrl.cpp index e7cf64d..e07459d 100644 --- a/esp32/src/PlantCtrl.cpp +++ b/esp32/src/PlantCtrl.cpp @@ -20,6 +20,7 @@ Plant::Plant(int pinSensor, int pinPump,int plantId, HomieNode* plant, PlantSett } void Plant::init(void) { + /* Initialize Home Settings validator */ this->mSetting->pSensorDry->setDefaultValue(4095); this->mSetting->pSensorDry->setValidator([] (long candidate) { return (((candidate >= 0) && (candidate <= 4095) ) || candidate == DEACTIVATED_PLANT); @@ -37,9 +38,64 @@ void Plant::init(void) { this->mSetting->pPumpCooldownInHours->setValidator([] (long candidate) { return ((candidate >= 0) && (candidate <= 1024) ); }); - + + /* Initialize Hardware */ + pinMode(this->mPinPump, OUTPUT); + pinMode(this->mPinSensor, ANALOG); + digitalWrite(this->mPinPump, LOW); } -void Plant::addSenseValue(int analog) { - this->moistureRaw.add(analog); -} \ No newline at end of file +void Plant::addSenseValue(void) { + this->moistureRaw.add( analogRead(this->mPinSensor) ); +} + +void Plant::postMQTTconnection(void) { + const String OFF = String("OFF"); + this->mConnected=true; + this->mPlant->setProperty("switch").send(OFF); +} + +void Plant::deactivatePump(void) { + digitalWrite(this->mPinPump, LOW); + if (this->mConnected) { + const String OFF = String("OFF"); + this->mPlant->setProperty("switch").send(OFF); + } +} + +void Plant::activatePump(void) { + digitalWrite(this->mPinPump, HIGH); + if (this->mConnected) { + const String OFF = String("ON"); + this->mPlant->setProperty("switch").send(OFF); + } +} + +void Plant::advertise(void) { + // Advertise topics + this->mPlant->advertise("switch").setName("Pump 1") + .setDatatype("boolean"); + //FIXME add .settable(this->switchHandler) + this->mPlant->advertise("moist").setName("Percent") + .setDatatype("number") + .setUnit("%"); +} + + +/* FIXME +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; + } + } +} +*/ \ No newline at end of file diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 1319b3f..6b19fcc 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -144,7 +144,7 @@ void mode2MQTT(){ digitalWrite(OUTPUT_PUMP, LOW); for(int i=0; i < MAX_PLANTS; i++) { - digitalWrite(mPlants[i].mPinPump, LOW); + mPlants[i].deactivatePump(); } if (deepSleepTime.get()) { @@ -200,7 +200,7 @@ void mode2MQTT(){ if(lastPumpRunning != -1 && hasWater){ digitalWrite(OUTPUT_PUMP, HIGH); setLastActivationForPump(lastPumpRunning, getCurrentTime()); - digitalWrite(mPlants[lastPumpRunning].mPinPump, HIGH); + mPlants[lastPumpRunning].activatePump(); } if(lastPumpRunning == -1 || !hasWater){ if(getSolarVoltage() < SOLAR_CHARGE_MIN_VOLTAGE){ @@ -311,7 +311,7 @@ void readSensors() { /* wait before reading something */ for (int readCnt=0;readCnt < AMOUNT_SENOR_QUERYS; readCnt++) { for(int i=0; i < MAX_PLANTS; i++) { - mPlants[i].addSenseValue(analogRead(mPlants[i].getSensorPin())); + mPlants[i].addSenseValue(); } } @@ -354,7 +354,6 @@ void readSensors() { //Homie.getMqttClient().disconnect(); void onHomieEvent(const HomieEvent& event) { - const String OFF = String("OFF"); switch(event.type) { case HomieEventType::SENDING_STATISTICS: mode2MQTT(); @@ -370,15 +369,9 @@ void onHomieEvent(const HomieEvent& event) { mode2MQTT(); Homie.getLogger() << "MQTT 1" << endl; - - plant0.setProperty("switch").send(OFF); - plant1.setProperty("switch").send(OFF); - plant2.setProperty("switch").send(OFF); - plant3.setProperty("switch").send(OFF); - plant4.setProperty("switch").send(OFF); - plant5.setProperty("switch").send(OFF); - plant6.setProperty("switch").send(OFF); - + for(int i=0; i < MAX_PLANTS; i++) { + mPlants[i].postMQTTconnection(); + } break; case HomieEventType::READY_TO_SLEEP: Homie.getLogger() << "rtsleep" << endl; @@ -405,13 +398,13 @@ int determineNextPump(){ long lastActivation = getLastActivationForPump(i); long sinceLastActivation = getCurrentTime()-lastActivation; //this pump is in cooldown skip it and disable low power mode trigger for it - if(mPlants[i].mSetting->pPumpCooldownInHours->get() > sinceLastActivation / 3600){ + if(mPlants[i].isInCooldown(sinceLastActivation) ){ Serial.println("Skipping due to cooldown"); //setMoistureTrigger(i, DEACTIVATED_PLANT); //continue; } //skip as it is not low light - if(!isLowLight && mPlants[i].mSetting->pPumpOnlyWhenLowLight->get()){ + if(!isLowLight && mPlants[i].isAllowedOnlyAtLowLight()){ Serial.println("Skipping due to light"); continue; } @@ -425,45 +418,6 @@ int determineNextPump(){ return -1; } - -bool switchGeneralPumpHandler(const int pump, const HomieRange& range, const String& value) { - if (range.isRange) return false; // only one switch is present - switch (pump) - { -#if MAX_PLANTS >= 1 - case 0: -#endif -#if MAX_PLANTS >= 2 - case 1: -#endif - #if MAX_PLANTS >= 3 -#endif - case 2: -#if MAX_PLANTS >= 4 - case 3: -#endif -#if MAX_PLANTS >= 5 - case 4: -#endif -#if MAX_PLANTS >= 6 - case 5: -#endif - - if ((value.equals("ON")) || (value.equals("On")) || (value.equals("on")) || (value.equals("true"))) { - digitalWrite(mPlants[pump].getPumpPin(), HIGH); - return true; - } else if ((value.equals("OFF")) || (value.equals("Off")) || (value.equals("off")) || (value.equals("false")) ) { - digitalWrite(mPlants[pump].getPumpPin(), LOW); - return true; - } else { - return false; - } - break; - default: - return false; - } -} - /** * @brief Handle Mqtt commands to keep controller alive * @@ -484,43 +438,6 @@ bool aliveHandler(const HomieRange& range, const String& value) { return true; } -/** - * @brief Handle Mqtt commands for the pumpe, responsible for the first plant - * - * @param range multiple transmitted values (not used for this function) - * @param value single value - * @return true when the command was parsed and executed succuessfully - * @return false on errors when parsing the request - */ -bool switch1Handler(const HomieRange& range, const String& value) { - return switchGeneralPumpHandler(0, range, value); -} - - -/** - * @brief Handle Mqtt commands for the pumpe, responsible for the second plant - * - * @param range multiple transmitted values (not used for this function) - * @param value single value - * @return true when the command was parsed and executed succuessfully - * @return false on errors when parsing the request - */ -bool switch2Handler(const HomieRange& range, const String& value) { - return switchGeneralPumpHandler(1, range, value); -} - -/** - * @brief Handle Mqtt commands for the pumpe, responsible for the third plant - * - * @param range multiple transmitted values (not used for this function) - * @param value single value - * @return true when the command was parsed and executed succuessfully - * @return false on errors when parsing the request - */ -bool switch3Handler(const HomieRange& range, const String& value) { - return switchGeneralPumpHandler(2, range, value); -} - void homieLoop(){ } @@ -548,38 +465,9 @@ void systemInit(){ mConfigured = Homie.isConfigured(); if (mConfigured) { - // Advertise topics - plant1.advertise("switch").setName("Pump 1") - .setDatatype("boolean") - .settable(switch1Handler); - plant1.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant2.advertise("switch").setName("Pump 2") - .setDatatype("boolean") - .settable(switch2Handler); - plant2.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant3.advertise("switch").setName("Pump 3") - .setDatatype("boolean") - .settable(switch3Handler); - plant3.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant4.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant5.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant6.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - plant0.advertise("moist").setName("Percent") - .setDatatype("number") - .setUnit("%"); - + for(int i=0; i < MAX_PLANTS; i++) { + mPlants[i].advertise(); + } sensorTemp.advertise("control") .setName("Temperature") .setDatatype("number") @@ -707,13 +595,10 @@ void setup() { /* Intialize inputs and outputs */ pinMode(SENSOR_LIPO, ANALOG); pinMode(SENSOR_SOLAR, ANALOG); - for(int i=0; i < MAX_PLANTS; i++) { - pinMode(mPlants[i].getPumpPin(), OUTPUT); - pinMode(mPlants[i].getSensorPin(), ANALOG); - digitalWrite(mPlants[i].getPumpPin(), LOW); - } /* read button */ pinMode(BUTTON, INPUT); + + /* Power pins */ pinMode(OUTPUT_PUMP, OUTPUT); /* Disable Wifi and bluetooth */