Compare commits

..

17 commits
v2.2 ... master

6 changed files with 87 additions and 14 deletions

View file

@ -4,4 +4,5 @@ fastapi
uvicorn
fastapi-cors
Adafruit_DHT
requests
requests
mh_z19

View file

@ -5,30 +5,34 @@ from config import climate_log_file, dht22_pin
from handler.dht22_climate import Dht22Climate
from handler.matrix_display import MatrixDisplay
from handler.mhz19_co2 import Mhz19Co2
climate_sensor = Dht22Climate(dht22_pin)
co2_sensor = Mhz19Co2()
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 not os.path.isfile(climate_log_file):
with open(climate_log_file, "w") as f:
f.write("timestamp,temperature,humidity\n")
f.write("timestamp,temperature,humidity,co2\n")
while True:
measurements = climate_sensor.read()
co2_density = co2_sensor.read()
if measurements is not None:
with open(climate_log_file, "a") as f:
f.write(
"{},{},{}\n".format(
"{},{},{},{}\n".format(
datetime.now().isoformat(),
measurements["temperature"],
measurements["humidity"],
co2_density,
)
)
await asyncio.sleep(60)
await asyncio.sleep(delay_sec)
async def display_time():

View file

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

48
src/handler/mhz19_co2.py Normal file
View file

@ -0,0 +1,48 @@
import serial
class Mhz19Co2:
def __init__(self):
self.last_read = None
self.serial_port = "/dev/serial0"
self.baud_rate = 9600
self.byte_size = 8
self.parity = "N"
self.stop_bits = 1
self.timeout = None
def get_last_read(self) -> int | None:
if self.last_read is None:
return self.read()
return self.last_read
def read(self) -> int | None:
ser = None
try:
ser = serial.Serial(
port=self.serial_port,
baudrate=self.baud_rate,
bytesize=self.byte_size,
parity=self.parity,
stopbits=self.stop_bits,
timeout=self.timeout,
)
# send "Read CO2" command
command_data = bytes([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
ser.write(command_data)
# read "Return Value (CO2 concentration)"
data = ser.read(9)
concentration = data[2] * 256 + data[3]
except Exception as e:
print(f"Error reading data: {e}")
finally:
if ser:
ser.close()
ser = None
self.last_read = concentration
return concentration

View file

@ -8,9 +8,9 @@ from fastapi.middleware.cors import CORSMiddleware
from actions import (
climate_sensor,
display_time,
log_temperature,
matrix_display,
display_pattern,
co2_sensor,
)
from config import climate_log_file
from handler.action_queue import ActionQueue
@ -20,7 +20,6 @@ logging.getLogger().setLevel(logging.INFO)
# Start services
asyncio.create_task(log_temperature())
queue = ActionQueue(matrix_display.show_current_time)
app = FastAPI()
@ -62,7 +61,7 @@ async def turn_off():
@app.post("/temperature")
async def temperature():
measurements = climate_sensor.get_last_read()
measurements = climate_sensor.read()
if measurements is None:
return {"message": "Failed to read temperature"}
@ -75,7 +74,7 @@ async def temperature():
@app.post("/humidity")
async def humidity():
measurements = climate_sensor.get_last_read()
measurements = climate_sensor.read()
if measurements is None:
return {"message": "Failed to read humidity"}
@ -86,6 +85,30 @@ async def humidity():
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")
async def history():
day_entry_count = 24 * 60

View file

@ -1,3 +0,0 @@
cd /home/pi/matrix-clock/src
uvicorn main:app --reload --host 0.0.0.0