21 ESP_LOGI(
"hempy",
"%s State: %s, Weight: %.2fkg (Average: %.1f, Increment: %.1f, Max: %.1f), Drain:%.1fkg (%.0fsec), Evaporation:%.1fkg (Dry: %.2fkg, Wet: %.2fkg)",
22 Name.c_str(),
to_text_state(
State), WeightSensor->state, AverageWeight, WateringIncrement->state, MaxWateringWeight->state, DrainTargetWeight->state, DrainWaitTime->state, EvaporationTargetWeight->state, DryWeight->state, WetWeight->state);
56 if (UpdateInProgress && !Force)
60 UpdateInProgress =
true;
61 bool BlockOverWritingState =
false;
63 if (
State != NewState)
73 WaterPump->turn_off();
74 if (
State != NewState)
79 WaterPump->turn_off();
80 if (
State != NewState)
82 if (WeightSensor->state >= MaxWateringWeight->state || WeightSensor->state >= WetWeight->state)
85 BlockOverWritingState =
true;
87 if (!ManualWateringDetected && DryWeight->state > 0 && WeightSensor->state > DryWeight->state && AverageWeight < WeightSensor->state)
89 ManualWateringDetected =
true;
90 ManualWateringStarted = millis();
92 if (ManualWateringDetected &&
CurrentTime - ManualWateringStarted >= ManualWateringTime->state * 1000)
94 ManualWateringDetected =
false;
95 if (!AverageReset && DryWeight->state > 0 && AverageWeight >= DryWeight->state)
98 BlockOverWritingState =
true;
103 if (WaterPump->state)
104 WaterPump->turn_off();
105 if (
State != NewState)
107 if (!AverageReset && ((StartWateringWeight->state > 0 && AverageWeight <= StartWateringWeight->state) || (EvaporationTargetWeight->state > 0 && DryWeight->state > 0 && AverageWeight <= DryWeight->state)))
110 BlockOverWritingState =
true;
114 if (
State != NewState)
117 StateWeight = WeightSensor->state;
123 WaterPump->turn_on();
125 if (WeightSensor->state >= MaxWateringWeight->state || (WeightSensor->state >= StateWeight + WateringIncrement->state && WeightSensor->state >= WetWeight->state))
129 BlockOverWritingState =
true;
131 else if ((
CurrentTime - PumpOnTimer) > MaxWateringTime->state * 1000)
133 ESP_LOGW(
"Hempy",
"%s Timeout, pump failed", Name.c_str());
135 BlockOverWritingState =
true;
139 if (WaterPump->state)
140 WaterPump->turn_off();
141 if (
State != NewState)
143 StateWeight = WeightSensor->state;
144 ESP_LOGW(
"Hempy",
"Stored drain start weight: %.2f", StateWeight);
146 if (
CurrentTime - StateTimer >= (DrainWaitTime->state * 1000))
148 DrainProgress += StateWeight - WeightSensor->state;
150 if (DrainProgress >= DrainTargetWeight->state || WeightSensor->state >= MaxWateringWeight->state)
152 WetWeight->publish_state(WeightSensor->state);
153 float CalculatedDryWeight = WeightSensor->state - EvaporationTargetWeight->state;
154 if (CalculatedDryWeight >= StartWateringWeight->state)
155 DryWeight->publish_state(CalculatedDryWeight);
157 DryWeight->publish_state(StartWateringWeight->state);
165 BlockOverWritingState =
true;
170 if (
State != NewState && !BlockOverWritingState)
174 UpdateInProgress =
false;
252 if (WetWeight->state > 0)
254 float NewDryWeight = WetWeight->state - EvaporationTarget;
255 if (StartWateringWeight->state < NewDryWeight)
256 DryWeight->publish_state(NewDryWeight);
258 DryWeight->publish_state(StartWateringWeight->state);
259 ESP_LOGI(
"hempy",
"%s Next watering weight: %.2f", Name.c_str(), DryWeight->state);
265 if (isnan(NewValue) || isinf(NewValue))
267 ESP_LOGE(
"hempy",
"Invalid sensor reading detected: %.2f, skipping it.", NewValue);
268 return AverageWeight;
274 for (
int i = 0; i < AverageQueueSize; ++i)
276 AverageReadings[i] = NewValue;
278 AverageTotal = AverageQueueSize * NewValue;
279 AverageReset =
false;
283 AverageTotal += NewValue - AverageReadings[AverageCurrent];
284 AverageReadings[AverageCurrent] = NewValue;
286 AverageCurrent = (AverageCurrent + 1) % AverageQueueSize;
290 return AverageTotal / AverageQueueSize;