try to smooth sensor values

master
Nicolò Balzarotti 2023-02-21 22:47:49 +01:00
parent 9c32bb4c4c
commit f11fa59dcc
1 changed files with 29 additions and 5 deletions

View File

@ -1,6 +1,7 @@
from time import perf_counter from time import perf_counter
from datetime import datetime, timedelta from datetime import datetime, timedelta
from collections import deque from collections import deque
from statistics import mean
from itertools import islice from itertools import islice
import re import re
from os.path import exists from os.path import exists
@ -27,19 +28,38 @@ except:
from random import random from random import random
from time import sleep from time import sleep
# How many seconds to use
WINDOW_SIZE_S = 5
class Sensor(): class Sensor():
def __init__(self, autocorr=0.7): 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.prevval = random() * 100
self.auto = autocorr self.auto = autocorr
self.measure = None self.measure = None
def read(self): def read(self):
sleep(0.5) sleep(0.5)
return (perf_counter(), return self.store(
int((random() * (1-self.auto) + self.prevval * self.auto) * 100) / 100) 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): class GPIOState(Sensor):
def __init__(self, pin, transform=lambda x: 1-x): def __init__(self, pin, transform=lambda x: 1-x):
super().__init__()
self.measure = 'Switch' self.measure = 'Switch'
self.pin = pin self.pin = pin
@ -53,10 +73,11 @@ class GPIOState(Sensor):
self.value = 0 self.value = 0
self.time = perf_counter() self.time = perf_counter()
return (self.time, self.transform(self.value)) return self.store(self.time, self.transform(self.value))
class Temperature1W(Sensor): class Temperature1W(Sensor):
def __init__(self, address): def __init__(self, address):
super().__init__()
self.measure = 'Temperature' self.measure = 'Temperature'
self.address = address self.address = address
@ -76,7 +97,8 @@ class Temperature1W(Sensor):
if content[0].strip()[-3:] != "YES": if content[0].strip()[-3:] != "YES":
print("INVALID CHECKSUM") print("INVALID CHECKSUM")
return (time, None) 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: if enable_sht:
i2c = board.I2C() # uses board.SCL and board.SDA i2c = board.I2C() # uses board.SCL and board.SDA
@ -87,6 +109,7 @@ if enable_sht:
class SHT40(Sensor): class SHT40(Sensor):
def __init__(self, what, every=60): def __init__(self, what, every=60):
super().__init__()
if what not in ("Temperature", "Humidity"): if what not in ("Temperature", "Humidity"):
print("ERROR: invalid sensor value: ", what) print("ERROR: invalid sensor value: ", what)
return return
@ -127,7 +150,8 @@ class SHT40(Sensor):
if reset: if reset:
self.reset_mode() self.reset_mode()
self.last_heat = perf_counter() 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(): class Sensors():
def __init__(self, history=2621440): def __init__(self, history=2621440):