ADD: Measurement Records
This commit is contained in:
parent
ed0d2897ce
commit
3483a7008c
8
main.py
8
main.py
@ -4,12 +4,14 @@ from typing import List
|
||||
|
||||
from fastapi import FastAPI, Depends, Query
|
||||
from enum import Enum
|
||||
|
||||
from requests import session
|
||||
from sqlmodel import Session
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from db import get_session
|
||||
from models.measurement import IndoorMeasurementCreateRequest, MeasurementListResponse, OutdoorMeasurementCreateRequest, \
|
||||
MeasurementResolution
|
||||
MeasurementResolution, RecordResponse
|
||||
from models.station import StationCreateRequest, StationCreateResponse, Station, StationListResponse, \
|
||||
StationUpdateResponse, StationUpdateRequest
|
||||
from services import stationService, measurementService
|
||||
@ -59,3 +61,7 @@ async def get_measurements(
|
||||
limit: int | None = None,
|
||||
session: Session = Depends(get_session)):
|
||||
return measurementService.get_measurements(session, station_ids, indoor, from_timestamp, to_timestamp, limit, resolution)
|
||||
|
||||
@app.get('/measurements/records', response_model=RecordResponse, status_code=200)
|
||||
async def get_records(station_ids: list[int] | None = Query(default=None), from_timestamp: datetime | None = None, session: Session = Depends(get_session)):
|
||||
return RecordResponse.model_validate(measurementService.get_measurement_records(session, station_ids, from_timestamp))
|
||||
@ -58,4 +58,21 @@ class StationMeasurementResponse(SQLModel):
|
||||
indoor: bool
|
||||
|
||||
class MeasurementListResponse(SQLModel):
|
||||
stations: list[StationMeasurementResponse]
|
||||
stations: list[StationMeasurementResponse]
|
||||
|
||||
class MeasurementRecordItem(SQLModel):
|
||||
recordValue: float
|
||||
timestamp: datetime
|
||||
station: StationListResponse
|
||||
|
||||
class MeasurementRecord(SQLModel):
|
||||
min_value: MeasurementRecordItem
|
||||
max_value: MeasurementRecordItem
|
||||
|
||||
class RecordResponse(SQLModel):
|
||||
inner_temperature_record: MeasurementRecord
|
||||
outer_temperature_record: MeasurementRecord
|
||||
inner_humidity_record: MeasurementRecord
|
||||
outer_humidity_record: MeasurementRecord
|
||||
pressure_record: MeasurementRecord
|
||||
night_temperature_record: MeasurementRecord
|
||||
@ -1,10 +1,11 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy import func, Select, Integer
|
||||
from sqlmodel import Session, select
|
||||
|
||||
from models.measurement import IndoorMeasurement, IndoorMeasurementCreateRequest, OutdoorMeasurementCreateRequest, \
|
||||
OutdoorMeasurement, MeasurementListResponse, StationMeasurementResponse, MeasurementResponse, MeasurementResolution
|
||||
OutdoorMeasurement, MeasurementListResponse, StationMeasurementResponse, MeasurementResponse, MeasurementResolution, \
|
||||
MeasurementRecord, RecordResponse, MeasurementRecordItem
|
||||
from models.station import Station, StationCreateRequest, StationListResponse
|
||||
from services import stationService
|
||||
from coolname import generate_slug
|
||||
@ -48,7 +49,7 @@ def push_outdoor_measurement(session: Session, raw_measurement: OutdoorMeasureme
|
||||
|
||||
session.add(OutdoorMeasurement.model_validate(measurement))
|
||||
session.commit()
|
||||
from typing import Type, Union
|
||||
from typing import Type, Union, List
|
||||
|
||||
|
||||
def period_format(resolution: MeasurementResolution) -> str:
|
||||
@ -208,4 +209,92 @@ def get_measurements(session: Session, station_ids: list[int] | None, indoor: bo
|
||||
stations=[
|
||||
*[StationMeasurementResponse(station=outdoor_result.station, measurements=outdoor_result.measurements, indoor=False) for outdoor_result in outdoor_results],
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
def get_measurement_record(
|
||||
session: Session,
|
||||
model: Type[IndoorMeasurement | OutdoorMeasurement],
|
||||
field: str,
|
||||
station_ids: list[int] | None,
|
||||
from_timestamp: datetime | None,
|
||||
order: str,
|
||||
night_only: bool = False,
|
||||
) -> MeasurementRecordItem | None:
|
||||
column = getattr(model, field)
|
||||
statement = select(model)
|
||||
|
||||
if station_ids is not None:
|
||||
statement = statement.where(model.station_id.in_(station_ids))
|
||||
|
||||
if from_timestamp is not None:
|
||||
to_timestamp = datetime.now()
|
||||
statement = statement.where(model.timestamp >= from_timestamp)
|
||||
statement = statement.where(model.timestamp <= to_timestamp)
|
||||
|
||||
if night_only:
|
||||
hour = func.cast(func.strftime("%H", model.timestamp), Integer)
|
||||
statement = statement.where((hour >= 22) | (hour < 6))
|
||||
|
||||
statement = statement.where(column.is_not(None))
|
||||
statement = statement.order_by(column.desc() if order == 'max' else column.asc())
|
||||
statement = statement.limit(1)
|
||||
|
||||
result = session.exec(statement).first()
|
||||
if result is None:
|
||||
return None
|
||||
|
||||
station = session.get(Station, result.station_id)
|
||||
return MeasurementRecordItem(
|
||||
recordValue=getattr(result, field),
|
||||
timestamp=result.timestamp,
|
||||
station=StationListResponse.model_validate(station),
|
||||
)
|
||||
|
||||
def get_inner_temperature_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None, order: str) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, IndoorMeasurement, "temperature", station_ids, from_timestamp, order)
|
||||
|
||||
def get_outer_temperature_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None, order: str) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, OutdoorMeasurement, "temperature", station_ids, from_timestamp, order)
|
||||
|
||||
def get_inner_humidity_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None, order: str) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, IndoorMeasurement, "humidity", station_ids, from_timestamp, order)
|
||||
|
||||
def get_outer_humidity_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None, order: str) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, OutdoorMeasurement, "humidity", station_ids, from_timestamp, order)
|
||||
|
||||
def get_pressure_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None, order: str) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, OutdoorMeasurement, "pressure", station_ids, from_timestamp, order)
|
||||
|
||||
def get_warmest_night_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, OutdoorMeasurement, "temperature", station_ids, from_timestamp, "max", night_only=True)
|
||||
|
||||
def get_coldest_night_record(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None) -> MeasurementRecordItem | None:
|
||||
return get_measurement_record(session, OutdoorMeasurement, "temperature", station_ids, from_timestamp, "min", night_only=True)
|
||||
|
||||
def get_measurement_records(session: Session, station_ids: list[int] | None, from_timestamp: datetime | None):
|
||||
return RecordResponse(
|
||||
inner_temperature_record = MeasurementRecord(
|
||||
max_value=get_inner_temperature_record(session, station_ids, from_timestamp, order='max'),
|
||||
min_value=get_inner_temperature_record(session, station_ids, from_timestamp, order='min')
|
||||
),
|
||||
outer_temperature_record = MeasurementRecord(
|
||||
max_value=get_outer_temperature_record(session, station_ids, from_timestamp, order='max'),
|
||||
min_value=get_outer_temperature_record(session, station_ids, from_timestamp, order='min')
|
||||
),
|
||||
inner_humidity_record = MeasurementRecord(
|
||||
max_value=get_inner_humidity_record(session, station_ids, from_timestamp, order='max'),
|
||||
min_value=get_inner_humidity_record(session, station_ids, from_timestamp, order='min')
|
||||
),
|
||||
outer_humidity_record = MeasurementRecord(
|
||||
max_value=get_outer_humidity_record(session, station_ids, from_timestamp, order='max'),
|
||||
min_value=get_outer_humidity_record(session, station_ids, from_timestamp, order='min')
|
||||
),
|
||||
pressure_record = MeasurementRecord(
|
||||
max_value=get_pressure_record(session, station_ids, from_timestamp, order='max'),
|
||||
min_value=get_pressure_record(session, station_ids, from_timestamp, order='min')
|
||||
),
|
||||
night_temperature_record = MeasurementRecord(
|
||||
max_value=get_warmest_night_record(session, None, from_timestamp),
|
||||
min_value=get_coldest_night_record(session, None, from_timestamp),
|
||||
)
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user