diff --git a/Scripts/Common.py b/Scripts/Common.py index 5340f21..2ea0d41 100644 --- a/Scripts/Common.py +++ b/Scripts/Common.py @@ -22,21 +22,58 @@ CONFIG_UPDATE_AVAILABLE = True NO_CONFIG_UPDATE = False +# ------[_]-------- <------------| +# | | 25 | +# |...............| <------ | +# | | | | +# | | | | +# | | | | +# | | | 125 +# | | | | +# | | 70 | +# | | | | +# | | | | +# | | | | +# |...............| <------ | +# | | | | +# | | 30 | +# | | | | +# ----------------- <------------| + TANK_HEIGHT = 125 # Example tank height TOP_EMPTY_DISTANCE = 25 -BOTTOM_FULL_DISTANCE = 65 -ONE_THIRD_LEVEL = TANK_HEIGHT // 3 +BOTTOM_FULL_DISTANCE = 30 + +MAX_WATER_LEVEL = TANK_HEIGHT - TOP_EMPTY_DISTANCE +TWO_THIRD_LEVEL = MAX_WATER_LEVEL // 3 * 2 # Two-thirds full level CHECK_INTERVAL_SECONDS = 1 MAX_PRE_NIGHT_FILL_TIME = 600 +NIGHT_12AM = 0 +NIGHT_1AM = 1 +NIGHT_2AM = 2 +NIGHT_3AM = 3 +NIGHT_4AM = 4 +NIGHT_5AM = 5 +MORNING_6AM = 6 MORNING_7AM = 7 MORNING_8AM = 8 +MORNING_9AM = 9 +MORNING_10AM = 10 +MORNING_11AM = 11 +NOON_12PM = 12 +AFTERNOON_1PM = 13 +AFTERNOON_2PM = 14 +AFTERNOON_3PM = 15 +AFTERNOON_4PM = 16 AFTERNOON_5PM = 17 +EVENING_6PM = 18 EVENING_7PM = 19 EVENING_8PM = 20 -NIGHT_10PM = 22 NIGHT_9PM = 21 +NIGHT_10PM = 22 +NIGHT_11PM = 23 VALVE1_DEFAULT_DURATION = 1 # in minutes diff --git a/Scripts/Main.py b/Scripts/Main.py index 2914c63..76e2aed 100644 --- a/Scripts/Main.py +++ b/Scripts/Main.py @@ -84,8 +84,9 @@ def main(): try: lastCheckTime = time.time() preNightFillActive = False - preNightFillStart = None + preNightFillStartTime = None while True: + print("Main loop iteration...") currentTime = time.time() now = datetime.now() @@ -154,7 +155,6 @@ def main(): distance = readDistance(gpio, ULTRASONIC_TRIG, ULTRASONIC_ECHO) print(f"Distance: {distance} cm") waterLevel = TANK_HEIGHT - distance - rtDb = readRtDb() motorStatus = rtDb.get("motorStatus", "OFF") if configUpdateAvailable: @@ -166,20 +166,18 @@ def main(): gpio.output(MOTOR_PIN, False) print("Config update: Motor OFF") else: - # Automatic logic - motorStatus = "OFF" if isNightTime(): # Check if it's night time between 10 PM and 7 AM print("Night time: Automatic motor control disabled. Only manual control available!") preNightFillActive = False else: - if now.hour == NIGHT_9PM and waterLevel < ONE_THIRD_LEVEL and not preNightFillActive: - print("Pre-night: Water < 1/3, filling tank...") + if now.hour == NIGHT_9PM and ifWaterLevelBelowTwoThird(waterLevel) and not preNightFillActive: + print(f"Pre-night: Water < 2/3, filling tank for {MAX_PRE_NIGHT_FILL_TIME} seconds...") gpio.output(MOTOR_PIN, True) motorStatus = "ON" preNightFillActive = True - preNightFillStart = currentTime - elif preNightFillActive: - if waterLevel >= TANK_HEIGHT or (preNightFillStart is not None and currentTime - preNightFillStart > MAX_PRE_NIGHT_FILL_TIME): + preNightFillStartTime = currentTime + elif preNightFillActive and (preNightFillStartTime is not None): + if ifWaterLevelAboveMax(waterLevel) or ((currentTime - preNightFillStartTime) > MAX_PRE_NIGHT_FILL_TIME): gpio.output(MOTOR_PIN, False) motorStatus = "OFF" print("Tank filled before night.") @@ -188,11 +186,11 @@ def main(): gpio.output(MOTOR_PIN, True) motorStatus = "ON" print("Pre-night filling in progress...") - elif distance < TOP_EMPTY_DISTANCE: # Assuming sensor is at the top. Small distance means full. + elif ifWaterLevelAboveMax(waterLevel): # Assuming sensor is at the top. Small distance means full. gpio.output(MOTOR_PIN, False) motorStatus = "OFF" print("Tank full: Motor OFF") - elif distance > (TANK_HEIGHT - BOTTOM_FULL_DISTANCE): # Large distance means empty + elif ifWaterLevelBelowMin(waterLevel): # Large distance means empty gpio.output(MOTOR_PIN, True) motorStatus = "ON" print("Tank empty: Motor ON") diff --git a/Scripts/Utility.py b/Scripts/Utility.py index aa4657e..3084b9e 100644 --- a/Scripts/Utility.py +++ b/Scripts/Utility.py @@ -1,6 +1,6 @@ import json import os -from Common import RT_DB_FILE +from Common import * def readRtDb(): try: @@ -23,3 +23,37 @@ def writeRtDb(motorStatus=None, tankLevel=None, configUpdateAvailable=None): json.dump(db, f) except Exception as e: print(f"Error writing to {RT_DB_FILE}: {e}") + + +def ifWaterLevelBelowTwoThird(waterLevel): + # Allow a margin of +/- 5 cm around TWO_THIRD_LEVEL for consistency (hysteresis) + margin = 5 + if waterLevel < (TWO_THIRD_LEVEL - margin): + return True + elif waterLevel > (TWO_THIRD_LEVEL + margin): + return False + else: + return False + + +def ifWaterLevelAboveMax(waterLevel): + # Allow a margin of +/- 5 cm around MAX_WATER_LEVEL for consistency (hysteresis) + margin = 5 + if waterLevel > (MAX_WATER_LEVEL + margin): + return True + elif waterLevel < (MAX_WATER_LEVEL - margin): + return False + else: + return False + + +def ifWaterLevelBelowMin(waterLevel): + # Allow a margin of +/- 5 cm around BOTTOM_FULL_DISTANCE for consistency (hysteresis) + margin = 5 + minLevel = TANK_HEIGHT - BOTTOM_FULL_DISTANCE + if waterLevel < (minLevel - margin): + return True + elif waterLevel > (minLevel + margin): + return False + else: + return False diff --git a/config.yaml b/config.yaml index 5e5cde6..9f7a604 100644 --- a/config.yaml +++ b/config.yaml @@ -1,2 +1,2 @@ -appVersion: 1.2.1.1004 +appVersion: 1.2.2.1005