Implemented co2 sensor and silent climate endpoint

This commit is contained in:
Maximilian Giller 2024-08-10 00:57:37 +02:00
parent 9715339c43
commit aff797bcb5
4 changed files with 52 additions and 23 deletions

View file

@ -5,30 +5,34 @@ from config import climate_log_file, dht22_pin
from handler.dht22_climate import Dht22Climate from handler.dht22_climate import Dht22Climate
from handler.matrix_display import MatrixDisplay from handler.matrix_display import MatrixDisplay
from handler.mhz19_co2 import Mhz19Co2
climate_sensor = Dht22Climate(dht22_pin) climate_sensor = Dht22Climate(dht22_pin)
co2_sensor = Mhz19Co2()
matrix_display = MatrixDisplay() matrix_display = MatrixDisplay()
async def log_temperature(): async def log_climate(delay_sec: int = 60):
# If file does not exist, create it and write header # If file does not exist, create it and write header
if not os.path.isfile(climate_log_file): if not os.path.isfile(climate_log_file):
with open(climate_log_file, "w") as f: with open(climate_log_file, "w") as f:
f.write("timestamp,temperature,humidity\n") f.write("timestamp,temperature,humidity,co2\n")
while True: while True:
measurements = climate_sensor.read() measurements = climate_sensor.read()
co2_density = co2_sensor.read()
if measurements is not None: if measurements is not None:
with open(climate_log_file, "a") as f: with open(climate_log_file, "a") as f:
f.write( f.write(
"{},{},{}\n".format( "{},{},{},{}\n".format(
datetime.now().isoformat(), datetime.now().isoformat(),
measurements["temperature"], measurements["temperature"],
measurements["humidity"], measurements["humidity"],
co2_density,
) )
) )
await asyncio.sleep(60) await asyncio.sleep(delay_sec)
async def display_time(): async def display_time():
@ -41,11 +45,11 @@ async def display_time():
async def display_pattern(*args, **kwargs): async def display_pattern(*args, **kwargs):
old_contrast = matrix_display.contrast old_contrast = matrix_display.contrast
if "contrast" in kwargs.keys(): if "contrast" in kwargs:
matrix_display.set_contrast(int(kwargs["contrast"])) matrix_display.set_contrast(int(kwargs["contrast"]))
try: try:
while True: while True:
await matrix_display.pattern(*args, **kwargs) await matrix_display.pattern(*args, **kwargs)
except: except:
if "contrast" in kwargs.keys(): if "contrast" in kwargs:
matrix_display.set_contrast(old_contrast) matrix_display.set_contrast(old_contrast)

View file

@ -8,12 +8,12 @@ class Dht22Climate:
self.pin = pin self.pin = pin
self.last_read = None self.last_read = None
def get_last_read(self): def get_last_read(self) -> dict | None:
if self.last_read is None: if self.last_read is None:
return self.read() return self.read()
return self.last_read return self.last_read
def read(self): def read(self) -> dict | None:
humidity, temperature = Adafruit_DHT.read_retry(self.sensor, self.pin) humidity, temperature = Adafruit_DHT.read_retry(self.sensor, self.pin)
if humidity is not None and temperature is not None: if humidity is not None and temperature is not None:
self.last_read = {"temperature": temperature, "humidity": humidity} self.last_read = {"temperature": temperature, "humidity": humidity}

View file

@ -12,12 +12,12 @@ class Mhz19Co2:
self.stop_bits = 1 self.stop_bits = 1
self.timeout = None self.timeout = None
def get_last_read(self): def get_last_read(self) -> int | None:
if self.last_read is None: if self.last_read is None:
return self.read() return self.read()
return self.last_read return self.last_read
def read(self): def read(self) -> int | None:
ser = None ser = None
try: try:
ser = serial.Serial( ser = serial.Serial(
@ -45,15 +45,15 @@ class Mhz19Co2:
# show CO2 concentration # show CO2 concentration
concentration = data[2] * 256 + data[3] concentration = data[2] * 256 + data[3]
print(f"=== send data ===") # print(f"=== send data ===")
print(f"send: {command_data}") # print(f"send: {command_data}")
print(f"=== read data ===") # print(f"=== read data ===")
print(f"data: {data}") # print(f"data: {data}")
print(f"data[2] {data[2]}") # print(f"data[2] {data[2]}")
print(f"data[3] {data[3]}") # print(f"data[3] {data[3]}")
print(f"CO2 Concentration {concentration} ppm") # print(f"CO2 Concentration {concentration} ppm")
print(f"=== === ===") # print(f"=== === ===")
print(f"") # print(f"")
except Exception as e: except Exception as e:
print(f"Error reading data: {e}") print(f"Error reading data: {e}")

View file

@ -8,9 +8,10 @@ from fastapi.middleware.cors import CORSMiddleware
from actions import ( from actions import (
climate_sensor, climate_sensor,
display_time, display_time,
log_temperature, log_climate,
matrix_display, matrix_display,
display_pattern, display_pattern,
co2_sensor,
) )
from config import climate_log_file from config import climate_log_file
from handler.action_queue import ActionQueue from handler.action_queue import ActionQueue
@ -20,7 +21,7 @@ logging.getLogger().setLevel(logging.INFO)
# Start services # Start services
asyncio.create_task(log_temperature()) # asyncio.create_task(log_climate())
queue = ActionQueue(matrix_display.show_current_time) queue = ActionQueue(matrix_display.show_current_time)
app = FastAPI() app = FastAPI()
@ -62,7 +63,7 @@ async def turn_off():
@app.post("/temperature") @app.post("/temperature")
async def temperature(): async def temperature():
measurements = climate_sensor.get_last_read() measurements = climate_sensor.read()
if measurements is None: if measurements is None:
return {"message": "Failed to read temperature"} return {"message": "Failed to read temperature"}
@ -75,7 +76,7 @@ async def temperature():
@app.post("/humidity") @app.post("/humidity")
async def humidity(): async def humidity():
measurements = climate_sensor.get_last_read() measurements = climate_sensor.read()
if measurements is None: if measurements is None:
return {"message": "Failed to read humidity"} return {"message": "Failed to read humidity"}
@ -86,6 +87,30 @@ async def humidity():
return measurements return measurements
@app.post("/co2")
async def co2():
co2 = co2_sensor.read()
if co2 is None:
return {"message": "Failed to read co2"}
await queue.add_action_to_queue(matrix_display.show_text, f"{co2}ppm")
return {"co2": co2}
@app.post("/climate")
async def climate():
measurements = climate_sensor.read()
if measurements is None:
return {"message": "Failed to read humidy and temperature"}
co2 = co2_sensor.read()
if co2 is None:
return {"message": "Failed to read co2"}
return {"co2": co2, **measurements}
@app.post("/history") @app.post("/history")
async def history(): async def history():
day_entry_count = 24 * 60 day_entry_count = 24 * 60