backend_iot/db.py (view raw)
1from peewee import Model, IntegerField, DateTimeField, DoesNotExist, FloatField, BooleanField
2from playhouse.sqliteq import SqliteQueueDatabase
3from playhouse.shortcuts import model_to_dict
4from backend_iot.common import current_latitude, current_longitude
5from backend_iot.api import get_aqi_owm
6from datetime import datetime, timedelta
7
8db = SqliteQueueDatabase("records.db")
9api_interval = timedelta(minutes=3)
10lat_threshold = 0.03
11lon_threshold = 0.03
12
13class BaseModel(Model):
14 class Meta:
15 database = db
16
17class Record(BaseModel):
18 timestamp = DateTimeField(default=datetime.now)
19 latitude = FloatField(default=0)
20 longitude = FloatField(default=0)
21 aqi = IntegerField(default=0)
22 t_in = FloatField(default=0)
23 t_out = FloatField(default=0)
24 t_setpoint = FloatField(default=0)
25 fan_speed = IntegerField(default=0)
26 power = BooleanField(default=False)
27 auto = BooleanField(default=False)
28 co_in = FloatField(default=0)
29 co_out = FloatField(default=0)
30 no2_in = FloatField(default=0)
31 pm10_out = FloatField(default=0)
32 airflow = IntegerField(default=0)
33 aq_in = IntegerField(default=0)
34
35class AQI(BaseModel):
36 timestamp = DateTimeField(default=datetime.now)
37 value = IntegerField()
38
39def set_aqi(value: int):
40 try:
41 AQI.delete().execute()
42 except DoesNotExist:
43 pass
44 return AQI.create(value=value)
45
46def get_aqi_from_cache(latitude, longitude):
47 try:
48 temp = AQI.select().order_by(AQI.timestamp.desc()).get()
49 except DoesNotExist:
50 return None
51
52 if temp.latitude - latitude > lat_threshold:
53 return None
54
55 if temp.longitude - longitude > lon_threshold:
56 return None
57
58 delta = datetime.now() - temp.timestamp
59 if delta > api_interval:
60 return None
61
62 return temp
63
64def get_aqi(latitude, longitude):
65 aqi = get_aqi_from_cache(latitude, longitude)
66
67 if aqi is not None:
68 return aqi.value
69
70 return get_aqi_owm(latitude, longitude)
71
72db.connect()
73db.create_tables([Record, AQI])
74
75def get_latest_record():
76 try:
77 return Record.select().order_by(Record.timestamp.desc()).get()
78 except DoesNotExist:
79 return add_record()
80
81def add_record(**info):
82 return Record.create(**info)
83
84def update_record(record):
85 record["latitude"] = current_latitude
86 record["longitude"] = current_longitude
87 record["timestamp"] = datetime.now()
88 record["aqi"] = get_aqi(current_latitude, current_longitude)
89 return record
90
91def record_to_dict(record):
92 temp = model_to_dict(record)
93 del temp["id"]
94 return temp
95
96def handle_new_data(form):
97 latest = record_to_dict(get_latest_record())
98
99 for key in form.keys():
100 if key not in latest.keys():
101 continue
102 if key == "fan_speed" and latest["auto"]:
103 continue
104 latest[key] = form[key]
105
106 new_record = update_record(latest)
107 add_record(**new_record)
108 return new_record