105 lines
3.0 KiB
Python
105 lines
3.0 KiB
Python
import atexit
|
|
from time import perf_counter
|
|
try:
|
|
import RPi.GPIO as GPIO
|
|
GPIO.setmode(GPIO.BCM)
|
|
rpi = True
|
|
except:
|
|
rpi = False
|
|
class GPIO():
|
|
LOW = 0
|
|
HIGH = 1
|
|
|
|
|
|
class Actuator():
|
|
def __init__(self, *args, **kwargs):
|
|
self.wattage = kwargs.pop('wattage')
|
|
self.total_seconds_on = 0
|
|
self.logging = False
|
|
self.started_at = 0
|
|
|
|
def log_on(self):
|
|
if self.logging:
|
|
return
|
|
self.started_at = perf_counter()
|
|
self.logging = True
|
|
|
|
def elapsed(self):
|
|
return perf_counter() - self.started_at
|
|
|
|
def log_off(self):
|
|
if not self.logging:
|
|
return
|
|
self.total_seconds_on += self.elapsed()
|
|
self.logging = False
|
|
|
|
def s_to_hr(self, s):
|
|
return s / 60 / 60
|
|
|
|
def consumption(self):
|
|
total_time = self.total_seconds_on
|
|
if self.logging:
|
|
# If we are on, count this time too
|
|
total_time += self.elapsed()
|
|
return self.s_to_hr(total_time) * self.wattage
|
|
|
|
class GPIOPin(Actuator):
|
|
def __init__(self, *args, **kwargs):
|
|
self.pin = kwargs.pop('pin')
|
|
self.initial = kwargs.pop('initial')
|
|
self.onstate = kwargs.pop('onstate')
|
|
self.offstate = kwargs.pop('offstate')
|
|
GPIO.setup(self.pin, GPIO.OUT, initial=self.initial)
|
|
atexit.register(self.deinit)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def deinit(self):
|
|
# Be sure everything is off at exit
|
|
print('Cleaning before exit')
|
|
GPIO.output(self.pin, self.initial)
|
|
GPIO.cleanup()
|
|
|
|
def enable(self, enable=True):
|
|
GPIO.output(self.pin, self.onstate) if enable else self.disable()
|
|
if enable:
|
|
self.log_on()
|
|
else:
|
|
self.log_off()
|
|
|
|
def disable(self):
|
|
GPIO.output(self.pin, self.offstate)
|
|
self.log_off()
|
|
|
|
class MockPIN(Actuator):
|
|
def __init__(self, *args, **kwargs):
|
|
self.pin = kwargs.pop('pin')
|
|
self.initial = kwargs.pop('initial')
|
|
self.onstate = kwargs.pop('onstate')
|
|
self.offstate = kwargs.pop('offstate')
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def enable(self, enable=True):
|
|
if enable:
|
|
self.log_on()
|
|
else:
|
|
self.log_off()
|
|
# print('FAKE ENABLE') if enable else self.disable()
|
|
|
|
def disable(self):
|
|
self.log_off()
|
|
# print('FAKE DISABLE')
|
|
|
|
def PIN(*args, **kwargs):
|
|
return (GPIOPin if rpi else MockPIN)(*args, **kwargs)
|
|
|
|
actuators = {
|
|
'heater': PIN(pin=22, initial=GPIO.HIGH, onstate=GPIO.LOW, offstate=GPIO.HIGH,
|
|
wattage=100),
|
|
'fan': PIN(pin=27, initial=GPIO.HIGH, onstate=GPIO.LOW, offstate=GPIO.HIGH,
|
|
wattage=12*0.4),
|
|
'humidifier': PIN(pin=17, initial=GPIO.HIGH, onstate=GPIO.LOW, offstate=GPIO.HIGH,
|
|
wattage=25),
|
|
'heater2': PIN(pin=17, initial=GPIO.HIGH, onstate=GPIO.LOW, offstate=GPIO.HIGH,
|
|
wattage=2000),
|
|
}
|