diff --git a/sensors.py b/sensors.py index 641846d..1fb6b96 100644 --- a/sensors.py +++ b/sensors.py @@ -1,6 +1,7 @@ from time import perf_counter from datetime import datetime, timedelta from collections import deque +from statistics import mean from itertools import islice import re from os.path import exists @@ -27,19 +28,38 @@ except: from random import random from time import sleep +# How many seconds to use +WINDOW_SIZE_S = 5 + class Sensor(): def __init__(self, autocorr=0.7): + # We won't sample at more than 10Hz, so this is safe + self.history = deque([], int(WINDOW_SIZE_S * 10)) + + ## This is just for debugging self.prevval = random() * 100 self.auto = autocorr self.measure = None def read(self): sleep(0.5) - return (perf_counter(), - int((random() * (1-self.auto) + self.prevval * self.auto) * 100) / 100) + return self.store( + perf_counter(), + int((random() * (1-self.auto) + self.prevval * self.auto) * 100) / 100) + + def smooth(self): + # TODO: Implement *correctly* this (take into account the time) + m = mean([el[1] for el in self.history]) + return (self.history[-1][0], m) + + def store(self, value, time): + self.history.append((value, time)) + return self.smooth() + class GPIOState(Sensor): def __init__(self, pin, transform=lambda x: 1-x): + super().__init__() self.measure = 'Switch' self.pin = pin @@ -53,10 +73,11 @@ class GPIOState(Sensor): self.value = 0 self.time = perf_counter() - return (self.time, self.transform(self.value)) + return self.store(self.time, self.transform(self.value)) class Temperature1W(Sensor): def __init__(self, address): + super().__init__() self.measure = 'Temperature' self.address = address @@ -76,7 +97,8 @@ class Temperature1W(Sensor): if content[0].strip()[-3:] != "YES": print("INVALID CHECKSUM") return (time, None) - return (time, int(re.search("t=([0-9]+)", content[1]).group(1)) / 1000.0) + return self.store( + time, int(re.search("t=([0-9]+)", content[1]).group(1)) / 1000.0) if enable_sht: i2c = board.I2C() # uses board.SCL and board.SDA @@ -87,6 +109,7 @@ if enable_sht: class SHT40(Sensor): def __init__(self, what, every=60): + super().__init__() if what not in ("Temperature", "Humidity"): print("ERROR: invalid sensor value: ", what) return @@ -127,7 +150,8 @@ class SHT40(Sensor): if reset: self.reset_mode() self.last_heat = perf_counter() - return (time, temperature if self.measure == 'Temperature' else relative_humidity) + return self.store( + time, temperature if self.measure == 'Temperature' else relative_humidity) class Sensors(): def __init__(self, history=2621440):