From 007a8027c720df8a76fe3dd4c6f70f0da8b0163e Mon Sep 17 00:00:00 2001 From: sickprodigy Date: Wed, 5 Nov 2025 13:13:27 -0500 Subject: [PATCH] Add ACController class for managing AC unit operation with safety timers --- Scripts/air_conditioning.py | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Scripts/air_conditioning.py diff --git a/Scripts/air_conditioning.py b/Scripts/air_conditioning.py new file mode 100644 index 0000000..afcb9e9 --- /dev/null +++ b/Scripts/air_conditioning.py @@ -0,0 +1,68 @@ +from machine import Pin +import time + +class ACController: + """Control AC unit via opto-coupler relay.""" + def __init__(self, relay_pin=15, min_run_time=300, min_off_time=180): + """ + relay_pin: GPIO pin connected to opto-coupler input + min_run_time: Minimum seconds AC must run before turning off (prevent short cycling) + min_off_time: Minimum seconds AC must be off before turning on (compressor protection) + """ + self.relay = Pin(relay_pin, Pin.OUT) + self.relay.off() # Start with AC off (relay normally open) + + self.min_run_time = min_run_time + self.min_off_time = min_off_time + + self.is_on = False + self.last_state_change = time.ticks_ms() + + def turn_on(self): + """Turn AC on if minimum off time has elapsed.""" + if self.is_on: + return True # Already on + + now = time.ticks_ms() + time_since_change = time.ticks_diff(now, self.last_state_change) / 1000 + + if time_since_change < self.min_off_time: + remaining = int(self.min_off_time - time_since_change) + print(f"AC cooldown: {remaining}s remaining before can turn on") + return False + + self.relay.on() + self.is_on = True + self.last_state_change = now + print("AC turned ON") + return True + + def turn_off(self): + """Turn AC off if minimum run time has elapsed.""" + if not self.is_on: + return True # Already off + + now = time.ticks_ms() + time_since_change = time.ticks_diff(now, self.last_state_change) / 1000 + + if time_since_change < self.min_run_time: + remaining = int(self.min_run_time - time_since_change) + print(f"AC minimum runtime: {remaining}s remaining before can turn off") + return False + + self.relay.off() + self.is_on = False + self.last_state_change = now + print("AC turned OFF") + return True + + def get_state(self): + """Return current AC state.""" + return self.is_on + + def force_off(self): + """Emergency shut off (bypasses timers).""" + self.relay.off() + self.is_on = False + self.last_state_change = time.ticks_ms() + print("AC FORCE OFF") \ No newline at end of file