all repos — iot-project @ 0627d8a0865451db9600af9ebcb04e083c391149

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