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 fastapi import FastAPI, Depends, Query
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
from requests import session
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from db import get_session
|
from db import get_session
|
||||||
from models.measurement import IndoorMeasurementCreateRequest, MeasurementListResponse, OutdoorMeasurementCreateRequest, \
|
from models.measurement import IndoorMeasurementCreateRequest, MeasurementListResponse, OutdoorMeasurementCreateRequest, \
|
||||||
MeasurementResolution
|
MeasurementResolution, RecordResponse
|
||||||
from models.station import StationCreateRequest, StationCreateResponse, Station, StationListResponse, \
|
from models.station import StationCreateRequest, StationCreateResponse, Station, StationListResponse, \
|
||||||
StationUpdateResponse, StationUpdateRequest
|
StationUpdateResponse, StationUpdateRequest
|
||||||
from services import stationService, measurementService
|
from services import stationService, measurementService
|
||||||
@ -59,3 +61,7 @@ async def get_measurements(
|
|||||||
limit: int | None = None,
|
limit: int | None = None,
|
||||||
session: Session = Depends(get_session)):
|
session: Session = Depends(get_session)):
|
||||||
return measurementService.get_measurements(session, station_ids, indoor, from_timestamp, to_timestamp, limit, resolution)
|
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
|
indoor: bool
|
||||||
|
|
||||||
class MeasurementListResponse(SQLModel):
|
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 datetime import datetime
|
||||||
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func, Select, Integer
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
|
|
||||||
from models.measurement import IndoorMeasurement, IndoorMeasurementCreateRequest, OutdoorMeasurementCreateRequest, \
|
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 models.station import Station, StationCreateRequest, StationListResponse
|
||||||
from services import stationService
|
from services import stationService
|
||||||
from coolname import generate_slug
|
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.add(OutdoorMeasurement.model_validate(measurement))
|
||||||
session.commit()
|
session.commit()
|
||||||
from typing import Type, Union
|
from typing import Type, Union, List
|
||||||
|
|
||||||
|
|
||||||
def period_format(resolution: MeasurementResolution) -> str:
|
def period_format(resolution: MeasurementResolution) -> str:
|
||||||
@ -208,4 +209,92 @@ def get_measurements(session: Session, station_ids: list[int] | None, indoor: bo
|
|||||||
stations=[
|
stations=[
|
||||||
*[StationMeasurementResponse(station=outdoor_result.station, measurements=outdoor_result.measurements, indoor=False) for outdoor_result in outdoor_results],
|
*[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