mirror of
https://github.com/NotAShelf/air-quality-monitor.git
synced 2024-11-26 15:16:49 +00:00
python cleanup
remove unaccessed imports
This commit is contained in:
parent
7a978853a8
commit
047447dce1
3 changed files with 96 additions and 88 deletions
|
@ -1,45 +0,0 @@
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
import serial
|
|
||||||
import redis
|
|
||||||
import aqi
|
|
||||||
|
|
||||||
redis_client = redis.StrictRedis(host=os.environ.get('REDIS_HOST'), port=6379, db=0)
|
|
||||||
|
|
||||||
|
|
||||||
class AirQualityMonitor():
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.ser = serial.Serial(os.environ.get('SERIAL_DEVICE','/dev/ttyUSB0'))
|
|
||||||
|
|
||||||
def get_measurement(self):
|
|
||||||
self.data = []
|
|
||||||
for index in range(0,10):
|
|
||||||
datum = self.ser.read()
|
|
||||||
self.data.append(datum)
|
|
||||||
self.pmtwo = int.from_bytes(b''.join(self.data[2:4]), byteorder='little') / 10
|
|
||||||
self.pmten = int.from_bytes(b''.join(self.data[4:6]), byteorder='little') / 10
|
|
||||||
myaqi = aqi.to_aqi([(aqi.POLLUTANT_PM25, str(self.pmtwo)),
|
|
||||||
(aqi.POLLUTANT_PM10, str(self.pmten))])
|
|
||||||
self.aqi = float(myaqi)
|
|
||||||
|
|
||||||
self.meas = {
|
|
||||||
"timestamp": datetime.datetime.now(),
|
|
||||||
"pm2.5": self.pmtwo,
|
|
||||||
"pm10": self.pmten,
|
|
||||||
"aqi": self.aqi,
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
'time': int(time.time()),
|
|
||||||
'measurement': self.meas
|
|
||||||
}
|
|
||||||
|
|
||||||
def save_measurement_to_redis(self):
|
|
||||||
"""Saves measurement to redis db"""
|
|
||||||
redis_client.lpush('measurements', json.dumps(self.get_measurement(), default=str))
|
|
||||||
|
|
||||||
def get_last_n_measurements(self):
|
|
||||||
"""Returns the last n measurements in the list"""
|
|
||||||
return [json.loads(x) for x in redis_client.lrange('measurements', 0, -1)]
|
|
89
src/app.py
89
src/app.py
|
@ -1,87 +1,90 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from flask import Flask, request, jsonify, render_template
|
|
||||||
from AirQualityMonitor import AirQualityMonitor
|
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
|
||||||
import redis
|
|
||||||
import atexit
|
import atexit
|
||||||
|
|
||||||
|
from flask import Flask, jsonify, render_template
|
||||||
|
from monitor import AirQualityMonitor
|
||||||
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from flask_cors import CORS, cross_origin
|
from flask_cors import CORS, cross_origin
|
||||||
|
|
||||||
|
# initialize Flask and CORS
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
cors = CORS(app)
|
cors = CORS(app)
|
||||||
app.config['CORS_HEADERS'] = 'Content-Type'
|
app.config["CORS_HEADERS"] = "Content-Type"
|
||||||
aqm = AirQualityMonitor()
|
|
||||||
|
|
||||||
|
# initialize AirQualityMonitor and scheduler
|
||||||
|
aqm = AirQualityMonitor()
|
||||||
scheduler = BackgroundScheduler()
|
scheduler = BackgroundScheduler()
|
||||||
scheduler.add_job(func=aqm.save_measurement_to_redis, trigger="interval", seconds=60)
|
scheduler.add_job(func=aqm.save_measurement_to_redis, trigger="interval", seconds=60)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
atexit.register(lambda: scheduler.shutdown())
|
|
||||||
|
|
||||||
def pretty_timestamps(measurement):
|
def pretty_timestamps(measurement):
|
||||||
timestamps = []
|
"""Convert timestamps to a more readable format."""
|
||||||
for x in measurement:
|
return [x["measurement"]["timestamp"].split(".")[0] for x in measurement]
|
||||||
timestamp = x['measurement']['timestamp']
|
|
||||||
timestamps += [timestamp.split('.')[0]]
|
|
||||||
return timestamps
|
|
||||||
|
|
||||||
def reconfigure_data(measurement):
|
def reconfigure_data(measurement):
|
||||||
"""Reconfigures data for chart.js"""
|
"""Reconfigures data for chart.js"""
|
||||||
current = int(time.time())
|
measurement = measurement[:30][::-1]
|
||||||
measurement = measurement[:30]
|
|
||||||
measurement.reverse()
|
|
||||||
return {
|
return {
|
||||||
'labels': pretty_timestamps(measurement),
|
"labels": pretty_timestamps(measurement),
|
||||||
'aqi': {
|
"aqi": {
|
||||||
'label': 'aqi',
|
"label": "aqi",
|
||||||
'data': [x['measurement']['aqi'] for x in measurement],
|
"data": [x["measurement"]["aqi"] for x in measurement],
|
||||||
'backgroundColor': '#181d27',
|
"backgroundColor": "#181d27",
|
||||||
'borderColor': '#181d27',
|
"borderColor": "#181d27",
|
||||||
'borderWidth': 3,
|
"borderWidth": 3,
|
||||||
},
|
},
|
||||||
'pm10': {
|
"pm10": {
|
||||||
'label': 'pm10',
|
"label": "pm10",
|
||||||
'data': [x['measurement']['pm10'] for x in measurement],
|
"data": [x["measurement"]["pm10"] for x in measurement],
|
||||||
'backgroundColor': '#cc0000',
|
"backgroundColor": "#cc0000",
|
||||||
'borderColor': '#cc0000',
|
"borderColor": "#cc0000",
|
||||||
'borderWidth': 3,
|
"borderWidth": 3,
|
||||||
},
|
},
|
||||||
'pm2': {
|
"pm2": {
|
||||||
'label': 'pm2.5',
|
"label": "pm2.5",
|
||||||
'data': [x['measurement']['pm2.5'] for x in measurement],
|
"data": [x["measurement"]["pm2.5"] for x in measurement],
|
||||||
'backgroundColor': '#42C0FB',
|
"backgroundColor": "#42C0FB",
|
||||||
'borderColor': '#42C0FB',
|
"borderColor": "#42C0FB",
|
||||||
'borderWidth': 3,
|
"borderWidth": 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
"""Index page for the application"""
|
"""Index page for the application"""
|
||||||
context = {
|
context = {
|
||||||
'historical': reconfigure_data(aqm.get_last_n_measurements()),
|
"historical": reconfigure_data(aqm.get_last_n_measurements()),
|
||||||
}
|
}
|
||||||
return render_template('index.html', context=context)
|
return render_template("index.html", context=context)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/')
|
@app.route("/api/")
|
||||||
@cross_origin()
|
@cross_origin()
|
||||||
|
|
||||||
def api():
|
def api():
|
||||||
"""Returns historical data from the sensor"""
|
"""Returns historical data from the sensor"""
|
||||||
context = {
|
context = {
|
||||||
'historical': reconfigure_data(aqm.get_last_n_measurements()),
|
"historical": reconfigure_data(aqm.get_last_n_measurements()),
|
||||||
}
|
}
|
||||||
return jsonify(context)
|
return jsonify(context)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/now/')
|
@app.route("/api/now/")
|
||||||
def api_now():
|
def api_now():
|
||||||
"""Returns latest data from the sensor"""
|
"""Returns latest data from the sensor"""
|
||||||
context = {
|
context = {
|
||||||
'current': aqm.get_measurement(),
|
"current": aqm.get_measurement(),
|
||||||
}
|
}
|
||||||
return jsonify(context)
|
return jsonify(context)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(debug=True, use_reloader=False, host='0.0.0.0', port=int(os.environ.get('PORT', '8000')))
|
app.run(
|
||||||
|
debug=True,
|
||||||
|
use_reloader=False,
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=int(os.environ.get("PORT", "8000")),
|
||||||
|
)
|
||||||
|
|
50
src/monitor.py
Normal file
50
src/monitor.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
import serial
|
||||||
|
import redis
|
||||||
|
import aqi
|
||||||
|
|
||||||
|
|
||||||
|
REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
|
||||||
|
REDIS_PORT = int(os.environ.get("REDIS_PORT", 6379))
|
||||||
|
REDIS_DB = int(os.environ.get("REDIS_DB", 0))
|
||||||
|
redis_client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)
|
||||||
|
|
||||||
|
|
||||||
|
class AirQualityMonitor:
|
||||||
|
SERIAL_DEVICE = os.environ.get("SERIAL_DEVICE", "/dev/ttyUSB0")
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.ser = serial.Serial(self.SERIAL_DEVICE)
|
||||||
|
|
||||||
|
def get_measurement(self):
|
||||||
|
"""Fetches a measurement from the sensor and returns it."""
|
||||||
|
data = [self.ser.read() for _ in range(10)]
|
||||||
|
pmtwo = int.from_bytes(b"".join(data[2:4]), byteorder="little") / 10
|
||||||
|
pmten = int.from_bytes(b"".join(data[4:6]), byteorder="little") / 10
|
||||||
|
aqi_value = aqi.to_aqi(
|
||||||
|
[
|
||||||
|
(aqi.POLLUTANT_PM25, str(pmtwo)),
|
||||||
|
(aqi.POLLUTANT_PM10, str(pmten)),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
measurement = {
|
||||||
|
"timestamp": datetime.datetime.now(),
|
||||||
|
"pm2.5": pmtwo,
|
||||||
|
"pm10": pmten,
|
||||||
|
"aqi": float(aqi_value),
|
||||||
|
}
|
||||||
|
return {"time": int(time.time()), "measurement": measurement}
|
||||||
|
|
||||||
|
def save_measurement_to_redis(self):
|
||||||
|
"""Saves measurement to redis db"""
|
||||||
|
redis_client.lpush(
|
||||||
|
"measurements", json.dumps(self.get_measurement(), default=str)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_last_n_measurements(self):
|
||||||
|
"""Returns the last n measurements in the list"""
|
||||||
|
return [json.loads(x) for x in redis_client.lrange("measurements", 0, -1)]
|
Loading…
Reference in a new issue