Compare commits

..

No commits in common. "master" and "v2.2" have entirely different histories.
master ... v2.2

6 changed files with 14 additions and 87 deletions

View file

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

View file

@ -5,34 +5,30 @@ 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_climate(delay_sec: int = 60): async def log_temperature():
# 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,co2\n") f.write("timestamp,temperature,humidity\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(delay_sec) await asyncio.sleep(60)
async def display_time(): async def display_time():

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) -> dict | None: def get_last_read(self):
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) -> dict | None: def read(self):
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

@ -1,48 +0,0 @@
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 ( from actions import (
climate_sensor, climate_sensor,
display_time, display_time,
log_temperature,
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,6 +20,7 @@ logging.getLogger().setLevel(logging.INFO)
# Start services # Start services
asyncio.create_task(log_temperature())
queue = ActionQueue(matrix_display.show_current_time) queue = ActionQueue(matrix_display.show_current_time)
app = FastAPI() app = FastAPI()
@ -61,7 +62,7 @@ async def turn_off():
@app.post("/temperature") @app.post("/temperature")
async def temperature(): async def temperature():
measurements = climate_sensor.read() measurements = climate_sensor.get_last_read()
if measurements is None: if measurements is None:
return {"message": "Failed to read temperature"} return {"message": "Failed to read temperature"}
@ -74,7 +75,7 @@ async def temperature():
@app.post("/humidity") @app.post("/humidity")
async def humidity(): async def humidity():
measurements = climate_sensor.read() measurements = climate_sensor.get_last_read()
if measurements is None: if measurements is None:
return {"message": "Failed to read humidity"} return {"message": "Failed to read humidity"}
@ -85,30 +86,6 @@ 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

3
start.sh Normal file
View file

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