module models
¶
The database models involved
- class app.models.ATM41DataRaw(**kwargs)[source]¶
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- atmospheric_pressure: Mapped[Decimal]¶
atmospheric pressure in kPa
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- lightning_average_distance: Mapped[Decimal]¶
distance of lightning strikes in km
- lightning_strike_count: Mapped[Decimal]¶
number of lightning strikes
- maximum_wind_speed: Mapped[Decimal]¶
maximum wind speed in m/s (gusts)
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- precipitation_sum: Mapped[Decimal]¶
precipitation sum in mm
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- sensor: Mapped[Sensor]¶
The sensor the data was measured with
- sensor_id: Mapped[str]¶
id of the sensor e.g.
DEC1234
- sensor_temperature_internal: Mapped[Decimal]¶
internal temperature of the sensor in °C
- solar_radiation: Mapped[Decimal]¶
solar radiation in W/m2
- u_wind: Mapped[Decimal]¶
u wind component in m/s
- v_wind: Mapped[Decimal]¶
v wind component in m/s
- vapor_pressure: Mapped[Decimal]¶
vapor pressure in kPa
- wind_direction: Mapped[Decimal]¶
wind direction in °
- wind_speed: Mapped[Decimal]¶
wind speed in m/s
- x_orientation_angle: Mapped[Decimal]¶
x-tilt angle of the sensor in °
- y_orientation_angle: Mapped[Decimal]¶
y-tilt angle of the sensor in °
- class app.models.BLGDataRaw(**kwargs)[source]¶
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- black_globe_temperature: Mapped[Decimal]¶
black globe temperature in °C
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- sensor: Mapped[Sensor]¶
The sensor the data was measured with
- sensor_id: Mapped[str]¶
id of the sensor e.g.
DEC1234
- thermistor_resistance: Mapped[Decimal]¶
thermistor resistance in Ohms
- voltage_ratio: Mapped[Decimal]¶
voltage ratio of the sensor
- class app.models.BiometData(**kwargs)[source]¶
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_qc_persistence_check: Mapped[bool]¶
- air_temperature_qc_range_check: Mapped[bool]¶
- air_temperature_qc_spike_dip_check: Mapped[bool]¶
- atmospheric_pressure: Mapped[Decimal]¶
atmospheric pressure in kPa
- atmospheric_pressure_qc_persistence_check: Mapped[bool]¶
- atmospheric_pressure_qc_range_check: Mapped[bool]¶
- atmospheric_pressure_qc_spike_dip_check: Mapped[bool]¶
- atmospheric_pressure_reduced: Mapped[Decimal]¶
atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- black_globe_temperature: Mapped[Decimal]¶
black globe temperature in °C
- black_globe_temperature_qc_persistence_check: Mapped[bool]¶
- black_globe_temperature_qc_range_check: Mapped[bool]¶
- black_globe_temperature_qc_spike_dip_check: Mapped[bool]¶
- blg_battery_voltage: Mapped[Decimal]¶
battery voltage of the black globe sensor in Volts
- blg_sensor: Mapped[Sensor | None]¶
The black globe sensor the data was measured with
- blg_sensor_id: Mapped[str | None]¶
id of the BLG sensor these measurements were taken with
- blg_time_offset: Mapped[Decimal]¶
time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- deployments: Mapped[list[SensorDeployment]]¶
list of deployments that were involved in the measurement of this data
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- lightning_average_distance: Mapped[Decimal]¶
distance of lightning strikes in km
- lightning_average_distance_qc_persistence_check: Mapped[bool]¶
- lightning_average_distance_qc_range_check: Mapped[bool]¶
- lightning_strike_count: Mapped[Decimal]¶
number of lightning strikes
- lightning_strike_count_qc_persistence_check: Mapped[bool]¶
- lightning_strike_count_qc_range_check: Mapped[bool]¶
- maximum_wind_speed: Mapped[Decimal]¶
maximum wind speed in m/s (gusts)
- maximum_wind_speed_qc_persistence_check: Mapped[bool]¶
- maximum_wind_speed_qc_range_check: Mapped[bool]¶
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- mrt: Mapped[Decimal]¶
mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- pet: Mapped[Decimal]¶
physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_category: Mapped[HeatStressCategories]¶
physiological equivalent temperature category derived from
PET_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- precipitation_sum: Mapped[Decimal]¶
precipitation sum in mm
- precipitation_sum_qc_persistence_check: Mapped[bool]¶
- precipitation_sum_qc_range_check: Mapped[bool]¶
- precipitation_sum_qc_spike_dip_check: Mapped[bool]¶
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- qc_flagged: Mapped[bool]¶
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_qc_persistence_check: Mapped[bool]¶
- relative_humidity_qc_range_check: Mapped[bool]¶
- relative_humidity_qc_spike_dip_check: Mapped[bool]¶
- sensor: Mapped[Sensor]¶
The sensor the data was measured with
- sensor_id: Mapped[str]¶
id of the ATM41 sensor these measurements were taken with
- sensor_temperature_internal: Mapped[Decimal]¶
internal temperature of the sensor in °C
- solar_radiation: Mapped[Decimal]¶
solar radiation in W/m2
- solar_radiation_qc_persistence_check: Mapped[bool]¶
- solar_radiation_qc_range_check: Mapped[bool]¶
- solar_radiation_qc_spike_dip_check: Mapped[bool]¶
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- thermistor_resistance: Mapped[Decimal]¶
thermistor resistance in Ohms
- u_wind: Mapped[Decimal]¶
u wind component in m/s
- u_wind_qc_persistence_check: Mapped[bool]¶
- u_wind_qc_range_check: Mapped[bool]¶
- u_wind_qc_spike_dip_check: Mapped[bool]¶
- utci: Mapped[Decimal]¶
universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_category: Mapped[HeatStressCategories]¶
universal thermal climate index category derived from
UTCI_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- v_wind: Mapped[Decimal]¶
v wind component in m/s
- v_wind_qc_persistence_check: Mapped[bool]¶
- v_wind_qc_range_check: Mapped[bool]¶
- v_wind_qc_spike_dip_check: Mapped[bool]¶
- vapor_pressure: Mapped[Decimal]¶
vapor pressure in kPa
- voltage_ratio: Mapped[Decimal]¶
voltage ratio of the sensor
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wind_direction: Mapped[Decimal]¶
wind direction in °
- wind_direction_qc_persistence_check: Mapped[bool]¶
- wind_direction_qc_range_check: Mapped[bool]¶
- wind_speed: Mapped[Decimal]¶
wind speed in m/s
- wind_speed_qc_persistence_check: Mapped[bool]¶
- wind_speed_qc_range_check: Mapped[bool]¶
- wind_speed_qc_spike_dip_check: Mapped[bool]¶
- x_orientation_angle: Mapped[Decimal]¶
x-tilt angle of the sensor in °
- x_orientation_angle_qc_range_check: Mapped[bool]¶
- x_orientation_angle_qc_spike_dip_check: Mapped[bool]¶
- y_orientation_angle: Mapped[Decimal]¶
y-tilt angle of the sensor in °
- y_orientation_angle_qc_range_check: Mapped[bool]¶
- y_orientation_angle_qc_spike_dip_check: Mapped[bool]¶
- class app.models.BiometDataDaily(**kwargs)[source]¶
This is not an actual table, but a materialized view. We simply trick sqlalchemy into thinking this was a table. Querying a materialized view does not differ from querying a proper table.
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_max: Mapped[Decimal]¶
maximum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_min: Mapped[Decimal]¶
minimum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_max: Mapped[Decimal]¶
maximum of air temperature in °C
- air_temperature_min: Mapped[Decimal]¶
minimum of air temperature in °C
- atmospheric_pressure: Mapped[Decimal]¶
atmospheric pressure in kPa
- atmospheric_pressure_max: Mapped[Decimal]¶
maximum of atmospheric pressure in kPa
- atmospheric_pressure_min: Mapped[Decimal]¶
minimum of atmospheric pressure in kPa
- atmospheric_pressure_reduced: Mapped[Decimal]¶
atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- atmospheric_pressure_reduced_max: Mapped[Decimal]¶
maximum of atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- atmospheric_pressure_reduced_min: Mapped[Decimal]¶
minimum of atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- battery_voltage_max: Mapped[Decimal]¶
maximum of The battery voltage of the sensor in Volts
- battery_voltage_min: Mapped[Decimal]¶
minimum of The battery voltage of the sensor in Volts
- black_globe_temperature: Mapped[Decimal]¶
black globe temperature in °C
- black_globe_temperature_max: Mapped[Decimal]¶
maximum of black globe temperature in °C
- black_globe_temperature_min: Mapped[Decimal]¶
minimum of black globe temperature in °C
- blg_battery_voltage: Mapped[Decimal]¶
battery voltage of the black globe sensor in Volts
- blg_battery_voltage_max: Mapped[Decimal]¶
maximum of battery voltage of the black globe sensor in Volts
- blg_battery_voltage_min: Mapped[Decimal]¶
minimum of battery voltage of the black globe sensor in Volts
- blg_time_offset: Mapped[Decimal]¶
time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- blg_time_offset_max: Mapped[Decimal]¶
maximum of time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- blg_time_offset_min: Mapped[Decimal]¶
minimum of time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- creation_sql: str = " WITH data_bounds AS (\n SELECT\n station_id,\n MIN(measured_at) AS start_time,\n MAX(measured_at) AS end_time\n FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n GROUP BY station_id\n ), filling_time_series AS (\n SELECT generate_series(\n DATE_TRUNC('hour', (\n SELECT MIN(measured_at) FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end)\n ),\n DATE_TRUNC('hour', (\n SELECT MAX(measured_at) FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end) + '1 hour'::INTERVAL\n ),\n '1 hour'::INTERVAL\n ) AS measured_at\n ),\n stations_subset AS (\n -- TODO: this could be faster if check the station table by station_type\n SELECT DISTINCT station_id FROM biomet_data\n ),\n time_station_combinations AS (\n SELECT\n measured_at,\n stations_subset.station_id,\n start_time,\n end_time\n FROM filling_time_series\n CROSS JOIN stations_subset\n JOIN data_bounds\n ON data_bounds.station_id = stations_subset.station_id\n WHERE filling_time_series.measured_at >= data_bounds.start_time\n AND filling_time_series.measured_at <= data_bounds.end_time\n ), all_data AS(\n (\n SELECT\n measured_at AS ma,\n station_id,\n NULL AS absolute_humidity,\n NULL AS air_temperature,\n NULL AS atmospheric_pressure,\n NULL AS atmospheric_pressure_reduced,\n NULL AS battery_voltage,\n NULL AS black_globe_temperature,\n NULL AS blg_battery_voltage,\n NULL AS blg_time_offset,\n NULL AS dew_point,\n NULL AS heat_index,\n NULL AS lightning_average_distance,\n NULL AS lightning_strike_count,\n NULL AS maximum_wind_speed,\n NULL AS mrt,\n NULL AS pet,\n NULL AS pet_category,\n NULL AS precipitation_sum,\n NULL AS protocol_version,\n NULL AS relative_humidity,\n NULL AS sensor_temperature_internal,\n NULL AS solar_radiation,\n NULL AS specific_humidity,\n NULL AS thermistor_resistance,\n NULL AS u_wind,\n NULL AS utci,\n NULL AS utci_category,\n NULL AS v_wind,\n NULL AS vapor_pressure,\n NULL AS voltage_ratio,\n NULL AS wet_bulb_temperature,\n NULL AS wind_direction,\n NULL AS wind_speed,\n NULL AS x_orientation_angle,\n NULL AS y_orientation_angle\n FROM time_station_combinations\n )\n UNION ALL\n (\n SELECT\n measured_at AS ma,\n station_id,\n absolute_humidity,\n air_temperature,\n atmospheric_pressure,\n atmospheric_pressure_reduced,\n battery_voltage,\n black_globe_temperature,\n blg_battery_voltage,\n blg_time_offset,\n dew_point,\n heat_index,\n lightning_average_distance,\n lightning_strike_count,\n maximum_wind_speed,\n mrt,\n pet,\n pet_category,\n precipitation_sum,\n protocol_version,\n relative_humidity,\n sensor_temperature_internal,\n solar_radiation,\n specific_humidity,\n thermistor_resistance,\n u_wind,\n utci,\n utci_category,\n v_wind,\n vapor_pressure,\n voltage_ratio,\n wet_bulb_temperature,\n wind_direction,\n wind_speed,\n x_orientation_angle,\n y_orientation_angle\n FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n )\n ) SELECT\n (time_bucket('1day', ma, 'CET') + '1 hour'::INTERVAL)::DATE AS measured_at,\n station_id,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(air_temperature)\n ELSE NULL\n END AS air_temperature,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN max(air_temperature)\n ELSE NULL\n END AS air_temperature_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN min(air_temperature)\n ELSE NULL\n END AS air_temperature_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(atmospheric_pressure)\n ELSE NULL\n END AS atmospheric_pressure,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN max(atmospheric_pressure)\n ELSE NULL\n END AS atmospheric_pressure_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN min(atmospheric_pressure)\n ELSE NULL\n END AS atmospheric_pressure_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure_reduced IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(atmospheric_pressure_reduced)\n ELSE NULL\n END AS atmospheric_pressure_reduced,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure_reduced IS NOT NULL) / 288.0\n ) > 0.7 THEN max(atmospheric_pressure_reduced)\n ELSE NULL\n END AS atmospheric_pressure_reduced_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE atmospheric_pressure_reduced IS NOT NULL) / 288.0\n ) > 0.7 THEN min(atmospheric_pressure_reduced)\n ELSE NULL\n END AS atmospheric_pressure_reduced_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(battery_voltage)\n ELSE NULL\n END AS battery_voltage,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN max(battery_voltage)\n ELSE NULL\n END AS battery_voltage_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN min(battery_voltage)\n ELSE NULL\n END AS battery_voltage_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE black_globe_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(black_globe_temperature)\n ELSE NULL\n END AS black_globe_temperature,\n CASE\n WHEN (count(*) FILTER (\n WHERE black_globe_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN max(black_globe_temperature)\n ELSE NULL\n END AS black_globe_temperature_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE black_globe_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN min(black_globe_temperature)\n ELSE NULL\n END AS black_globe_temperature_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(blg_battery_voltage)\n ELSE NULL\n END AS blg_battery_voltage,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN max(blg_battery_voltage)\n ELSE NULL\n END AS blg_battery_voltage_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN min(blg_battery_voltage)\n ELSE NULL\n END AS blg_battery_voltage_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_time_offset IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(blg_time_offset)\n ELSE NULL\n END AS blg_time_offset,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_time_offset IS NOT NULL) / 288.0\n ) > 0.7 THEN max(blg_time_offset)\n ELSE NULL\n END AS blg_time_offset_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE blg_time_offset IS NOT NULL) / 288.0\n ) > 0.7 THEN min(blg_time_offset)\n ELSE NULL\n END AS blg_time_offset_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(dew_point)\n ELSE NULL\n END AS dew_point,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN max(dew_point)\n ELSE NULL\n END AS dew_point_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN min(dew_point)\n ELSE NULL\n END AS dew_point_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(heat_index)\n ELSE NULL\n END AS heat_index,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN max(heat_index)\n ELSE NULL\n END AS heat_index_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN min(heat_index)\n ELSE NULL\n END AS heat_index_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE lightning_average_distance IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0)\n ELSE NULL\n END AS lightning_average_distance,\n CASE\n WHEN (count(*) FILTER (\n WHERE lightning_average_distance IS NOT NULL) / 288.0\n ) > 0.7 THEN max(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0)\n ELSE NULL\n END AS lightning_average_distance_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE lightning_average_distance IS NOT NULL) / 288.0\n ) > 0.7 THEN min(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0)\n ELSE NULL\n END AS lightning_average_distance_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE lightning_strike_count IS NOT NULL) / 288.0\n ) > 0.7 THEN sum(lightning_strike_count)\n ELSE NULL\n END AS lightning_strike_count,\n CASE\n WHEN (count(*) FILTER (\n WHERE maximum_wind_speed IS NOT NULL) / 288.0\n ) > 0.7 THEN max(maximum_wind_speed)\n ELSE NULL\n END AS maximum_wind_speed,\n CASE\n WHEN (count(*) FILTER (\n WHERE mrt IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(mrt)\n ELSE NULL\n END AS mrt,\n CASE\n WHEN (count(*) FILTER (\n WHERE mrt IS NOT NULL) / 288.0\n ) > 0.7 THEN max(mrt)\n ELSE NULL\n END AS mrt_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE mrt IS NOT NULL) / 288.0\n ) > 0.7 THEN min(mrt)\n ELSE NULL\n END AS mrt_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE pet IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(pet)\n ELSE NULL\n END AS pet,\n CASE\n WHEN (count(*) FILTER (\n WHERE pet_category IS NOT NULL) / 288.0\n ) > 0.7 THEN mode() WITHIN GROUP (ORDER BY pet_category ASC)\n ELSE NULL\n END AS pet_category,\n CASE\n WHEN (count(*) FILTER (\n WHERE pet IS NOT NULL) / 288.0\n ) > 0.7 THEN max(pet)\n ELSE NULL\n END AS pet_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE pet IS NOT NULL) / 288.0\n ) > 0.7 THEN min(pet)\n ELSE NULL\n END AS pet_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE precipitation_sum IS NOT NULL) / 288.0\n ) > 0.7 THEN sum(precipitation_sum)\n ELSE NULL\n END AS precipitation_sum,\n CASE\n WHEN (count(*) FILTER (\n WHERE protocol_version IS NOT NULL) / 288.0\n ) > 0.7 THEN mode() WITHIN GROUP (ORDER BY protocol_version ASC)\n ELSE NULL\n END AS protocol_version,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(relative_humidity)\n ELSE NULL\n END AS relative_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(relative_humidity)\n ELSE NULL\n END AS relative_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(relative_humidity)\n ELSE NULL\n END AS relative_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE sensor_temperature_internal IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(sensor_temperature_internal)\n ELSE NULL\n END AS sensor_temperature_internal,\n CASE\n WHEN (count(*) FILTER (\n WHERE sensor_temperature_internal IS NOT NULL) / 288.0\n ) > 0.7 THEN max(sensor_temperature_internal)\n ELSE NULL\n END AS sensor_temperature_internal_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE sensor_temperature_internal IS NOT NULL) / 288.0\n ) > 0.7 THEN min(sensor_temperature_internal)\n ELSE NULL\n END AS sensor_temperature_internal_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE solar_radiation IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(solar_radiation)\n ELSE NULL\n END AS solar_radiation,\n CASE\n WHEN (count(*) FILTER (\n WHERE solar_radiation IS NOT NULL) / 288.0\n ) > 0.7 THEN max(solar_radiation)\n ELSE NULL\n END AS solar_radiation_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE solar_radiation IS NOT NULL) / 288.0\n ) > 0.7 THEN min(solar_radiation)\n ELSE NULL\n END AS solar_radiation_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(specific_humidity)\n ELSE NULL\n END AS specific_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(specific_humidity)\n ELSE NULL\n END AS specific_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(specific_humidity)\n ELSE NULL\n END AS specific_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE thermistor_resistance IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(thermistor_resistance)\n ELSE NULL\n END AS thermistor_resistance,\n CASE\n WHEN (count(*) FILTER (\n WHERE thermistor_resistance IS NOT NULL) / 288.0\n ) > 0.7 THEN max(thermistor_resistance)\n ELSE NULL\n END AS thermistor_resistance_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE thermistor_resistance IS NOT NULL) / 288.0\n ) > 0.7 THEN min(thermistor_resistance)\n ELSE NULL\n END AS thermistor_resistance_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE u_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(u_wind)\n ELSE NULL\n END AS u_wind,\n CASE\n WHEN (count(*) FILTER (\n WHERE u_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN max(u_wind)\n ELSE NULL\n END AS u_wind_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE u_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN min(u_wind)\n ELSE NULL\n END AS u_wind_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE utci IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(utci)\n ELSE NULL\n END AS utci,\n CASE\n WHEN (count(*) FILTER (\n WHERE utci_category IS NOT NULL) / 288.0\n ) > 0.7 THEN mode() WITHIN GROUP (ORDER BY utci_category ASC)\n ELSE NULL\n END AS utci_category,\n CASE\n WHEN (count(*) FILTER (\n WHERE utci IS NOT NULL) / 288.0\n ) > 0.7 THEN max(utci)\n ELSE NULL\n END AS utci_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE utci IS NOT NULL) / 288.0\n ) > 0.7 THEN min(utci)\n ELSE NULL\n END AS utci_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE v_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(v_wind)\n ELSE NULL\n END AS v_wind,\n CASE\n WHEN (count(*) FILTER (\n WHERE v_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN max(v_wind)\n ELSE NULL\n END AS v_wind_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE v_wind IS NOT NULL) / 288.0\n ) > 0.7 THEN min(v_wind)\n ELSE NULL\n END AS v_wind_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE vapor_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(vapor_pressure)\n ELSE NULL\n END AS vapor_pressure,\n CASE\n WHEN (count(*) FILTER (\n WHERE vapor_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN max(vapor_pressure)\n ELSE NULL\n END AS vapor_pressure_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE vapor_pressure IS NOT NULL) / 288.0\n ) > 0.7 THEN min(vapor_pressure)\n ELSE NULL\n END AS vapor_pressure_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE voltage_ratio IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(voltage_ratio)\n ELSE NULL\n END AS voltage_ratio,\n CASE\n WHEN (count(*) FILTER (\n WHERE voltage_ratio IS NOT NULL) / 288.0\n ) > 0.7 THEN max(voltage_ratio)\n ELSE NULL\n END AS voltage_ratio_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE voltage_ratio IS NOT NULL) / 288.0\n ) > 0.7 THEN min(voltage_ratio)\n ELSE NULL\n END AS voltage_ratio_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN max(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN min(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE wind_direction IS NOT NULL) / 288.0\n ) > 0.7 THEN avg_angle(wind_direction)\n ELSE NULL\n END AS wind_direction,\n CASE\n WHEN (count(*) FILTER (\n WHERE wind_speed IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(wind_speed)\n ELSE NULL\n END AS wind_speed,\n CASE\n WHEN (count(*) FILTER (\n WHERE wind_speed IS NOT NULL) / 288.0\n ) > 0.7 THEN max(wind_speed)\n ELSE NULL\n END AS wind_speed_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE wind_speed IS NOT NULL) / 288.0\n ) > 0.7 THEN min(wind_speed)\n ELSE NULL\n END AS wind_speed_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE x_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(x_orientation_angle)\n ELSE NULL\n END AS x_orientation_angle,\n CASE\n WHEN (count(*) FILTER (\n WHERE x_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN max(x_orientation_angle)\n ELSE NULL\n END AS x_orientation_angle_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE x_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN min(x_orientation_angle)\n ELSE NULL\n END AS x_orientation_angle_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE y_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(y_orientation_angle)\n ELSE NULL\n END AS y_orientation_angle,\n CASE\n WHEN (count(*) FILTER (\n WHERE y_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN max(y_orientation_angle)\n ELSE NULL\n END AS y_orientation_angle_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE y_orientation_angle IS NOT NULL) / 288.0\n ) > 0.7 THEN min(y_orientation_angle)\n ELSE NULL\n END AS y_orientation_angle_min\n FROM all_data\n GROUP BY measured_at, station_id\n ORDER BY measured_at, station_id\n "¶
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_max: Mapped[Decimal]¶
maximum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_min: Mapped[Decimal]¶
minimum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_max: Mapped[Decimal]¶
maximum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_min: Mapped[Decimal]¶
minimum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- lightning_average_distance: Mapped[Decimal]¶
distance of lightning strikes in km
- lightning_average_distance_max: Mapped[Decimal]¶
maximum of distance of lightning strikes in km
- lightning_average_distance_min: Mapped[Decimal]¶
minimum of distance of lightning strikes in km
- lightning_strike_count: Mapped[Decimal]¶
number of lightning strikes
- maximum_wind_speed: Mapped[Decimal]¶
maximum wind speed in m/s (gusts)
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- mrt: Mapped[Decimal]¶
mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- mrt_max: Mapped[Decimal]¶
maximum of mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- mrt_min: Mapped[Decimal]¶
minimum of mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- pet: Mapped[Decimal]¶
physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_category: Mapped[HeatStressCategories]¶
physiological equivalent temperature category derived from
PET_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- pet_max: Mapped[Decimal]¶
maximum of physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_min: Mapped[Decimal]¶
minimum of physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- precipitation_sum: Mapped[Decimal]¶
precipitation sum in mm
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_max: Mapped[Decimal]¶
maximum of relative humidity in %
- relative_humidity_min: Mapped[Decimal]¶
minimum of relative humidity in %
- sensor_temperature_internal: Mapped[Decimal]¶
internal temperature of the sensor in °C
- sensor_temperature_internal_max: Mapped[Decimal]¶
maximum of internal temperature of the sensor in °C
- sensor_temperature_internal_min: Mapped[Decimal]¶
minimum of internal temperature of the sensor in °C
- solar_radiation: Mapped[Decimal]¶
solar radiation in W/m2
- solar_radiation_max: Mapped[Decimal]¶
maximum of solar radiation in W/m2
- solar_radiation_min: Mapped[Decimal]¶
minimum of solar radiation in W/m2
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_max: Mapped[Decimal]¶
maximum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_min: Mapped[Decimal]¶
minimum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- thermistor_resistance: Mapped[Decimal]¶
thermistor resistance in Ohms
- thermistor_resistance_max: Mapped[Decimal]¶
maximum of thermistor resistance in Ohms
- thermistor_resistance_min: Mapped[Decimal]¶
minimum of thermistor resistance in Ohms
- u_wind: Mapped[Decimal]¶
u wind component in m/s
- u_wind_max: Mapped[Decimal]¶
maximum of u wind component in m/s
- u_wind_min: Mapped[Decimal]¶
minimum of u wind component in m/s
- utci: Mapped[Decimal]¶
universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_category: Mapped[HeatStressCategories]¶
universal thermal climate index category derived from
UTCI_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- utci_max: Mapped[Decimal]¶
maximum of universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_min: Mapped[Decimal]¶
minimum of universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- v_wind: Mapped[Decimal]¶
v wind component in m/s
- v_wind_max: Mapped[Decimal]¶
maximum of v wind component in m/s
- v_wind_min: Mapped[Decimal]¶
minimum of v wind component in m/s
- vapor_pressure: Mapped[Decimal]¶
vapor pressure in kPa
- vapor_pressure_max: Mapped[Decimal]¶
maximum of vapor pressure in kPa
- vapor_pressure_min: Mapped[Decimal]¶
minimum of vapor pressure in kPa
- voltage_ratio: Mapped[Decimal]¶
voltage ratio of the sensor
- voltage_ratio_max: Mapped[Decimal]¶
maximum of voltage ratio of the sensor
- voltage_ratio_min: Mapped[Decimal]¶
minimum of voltage ratio of the sensor
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_max: Mapped[Decimal]¶
maximum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_min: Mapped[Decimal]¶
minimum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wind_direction: Mapped[Decimal]¶
wind direction in °
- wind_speed: Mapped[Decimal]¶
wind speed in m/s
- wind_speed_max: Mapped[Decimal]¶
maximum of wind speed in m/s
- wind_speed_min: Mapped[Decimal]¶
minimum of wind speed in m/s
- x_orientation_angle: Mapped[Decimal]¶
x-tilt angle of the sensor in °
- x_orientation_angle_max: Mapped[Decimal]¶
maximum of x-tilt angle of the sensor in °
- x_orientation_angle_min: Mapped[Decimal]¶
minimum of x-tilt angle of the sensor in °
- y_orientation_angle: Mapped[Decimal]¶
y-tilt angle of the sensor in °
- y_orientation_angle_max: Mapped[Decimal]¶
maximum of y-tilt angle of the sensor in °
- y_orientation_angle_min: Mapped[Decimal]¶
minimum of y-tilt angle of the sensor in °
- class app.models.BiometDataHourly(**kwargs)[source]¶
This is not an actual table, but a materialized view. We simply trick sqlalchemy into thinking this was a table. Querying a materialized view does not differ from querying a proper table.
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_max: Mapped[Decimal]¶
maximum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_min: Mapped[Decimal]¶
minimum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_max: Mapped[Decimal]¶
maximum of air temperature in °C
- air_temperature_min: Mapped[Decimal]¶
minimum of air temperature in °C
- atmospheric_pressure: Mapped[Decimal]¶
atmospheric pressure in kPa
- atmospheric_pressure_max: Mapped[Decimal]¶
maximum of atmospheric pressure in kPa
- atmospheric_pressure_min: Mapped[Decimal]¶
minimum of atmospheric pressure in kPa
- atmospheric_pressure_reduced: Mapped[Decimal]¶
atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- atmospheric_pressure_reduced_max: Mapped[Decimal]¶
maximum of atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- atmospheric_pressure_reduced_min: Mapped[Decimal]¶
minimum of atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- battery_voltage_max: Mapped[Decimal]¶
maximum of The battery voltage of the sensor in Volts
- battery_voltage_min: Mapped[Decimal]¶
minimum of The battery voltage of the sensor in Volts
- black_globe_temperature: Mapped[Decimal]¶
black globe temperature in °C
- black_globe_temperature_max: Mapped[Decimal]¶
maximum of black globe temperature in °C
- black_globe_temperature_min: Mapped[Decimal]¶
minimum of black globe temperature in °C
- blg_battery_voltage: Mapped[Decimal]¶
battery voltage of the black globe sensor in Volts
- blg_battery_voltage_max: Mapped[Decimal]¶
maximum of battery voltage of the black globe sensor in Volts
- blg_battery_voltage_min: Mapped[Decimal]¶
minimum of battery voltage of the black globe sensor in Volts
- blg_time_offset: Mapped[Decimal]¶
time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- blg_time_offset_max: Mapped[Decimal]¶
maximum of time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- blg_time_offset_min: Mapped[Decimal]¶
minimum of time offset of the Blackglobe sensor to the corresponding ATM41 sensor in seconds
- creation_sql: str = " WITH data_bounds AS (\n SELECT\n station_id,\n MIN(measured_at) AS start_time,\n MAX(measured_at) AS end_time\n FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n GROUP BY station_id\n ), filling_time_series AS (\n SELECT generate_series(\n DATE_TRUNC('hour', (\n SELECT MIN(measured_at) FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end)\n ),\n DATE_TRUNC('hour', (\n SELECT MAX(measured_at) FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end) + '1 hour'::INTERVAL\n ),\n '1 hour'::INTERVAL\n ) AS measured_at\n ),\n stations_subset AS (\n -- TODO: this could be faster if check the station table by station_type\n SELECT DISTINCT station_id FROM biomet_data\n ),\n time_station_combinations AS (\n SELECT\n measured_at,\n stations_subset.station_id,\n start_time,\n end_time\n FROM filling_time_series\n CROSS JOIN stations_subset\n JOIN data_bounds\n ON data_bounds.station_id = stations_subset.station_id\n WHERE filling_time_series.measured_at >= data_bounds.start_time\n AND filling_time_series.measured_at <= data_bounds.end_time\n ), all_data AS(\n (\n SELECT\n measured_at AS ma,\n station_id,\n NULL AS absolute_humidity,\n NULL AS air_temperature,\n NULL AS atmospheric_pressure,\n NULL AS atmospheric_pressure_reduced,\n NULL AS battery_voltage,\n NULL AS black_globe_temperature,\n NULL AS blg_battery_voltage,\n NULL AS blg_time_offset,\n NULL AS dew_point,\n NULL AS heat_index,\n NULL AS lightning_average_distance,\n NULL AS lightning_strike_count,\n NULL AS maximum_wind_speed,\n NULL AS mrt,\n NULL AS pet,\n NULL AS pet_category,\n NULL AS precipitation_sum,\n NULL AS protocol_version,\n NULL AS relative_humidity,\n NULL AS sensor_temperature_internal,\n NULL AS solar_radiation,\n NULL AS specific_humidity,\n NULL AS thermistor_resistance,\n NULL AS u_wind,\n NULL AS utci,\n NULL AS utci_category,\n NULL AS v_wind,\n NULL AS vapor_pressure,\n NULL AS voltage_ratio,\n NULL AS wet_bulb_temperature,\n NULL AS wind_direction,\n NULL AS wind_speed,\n NULL AS x_orientation_angle,\n NULL AS y_orientation_angle\n FROM time_station_combinations\n )\n UNION ALL\n (\n SELECT\n measured_at AS ma,\n station_id,\n absolute_humidity,\n air_temperature,\n atmospheric_pressure,\n atmospheric_pressure_reduced,\n battery_voltage,\n black_globe_temperature,\n blg_battery_voltage,\n blg_time_offset,\n dew_point,\n heat_index,\n lightning_average_distance,\n lightning_strike_count,\n maximum_wind_speed,\n mrt,\n pet,\n pet_category,\n precipitation_sum,\n protocol_version,\n relative_humidity,\n sensor_temperature_internal,\n solar_radiation,\n specific_humidity,\n thermistor_resistance,\n u_wind,\n utci,\n utci_category,\n v_wind,\n vapor_pressure,\n voltage_ratio,\n wet_bulb_temperature,\n wind_direction,\n wind_speed,\n x_orientation_angle,\n y_orientation_angle\n FROM biomet_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n )\n ) SELECT\n time_bucket('1 hour', ma) + '1 hour'::INTERVAL AS measured_at,\n station_id,\n avg(absolute_humidity) AS absolute_humidity,\n max(absolute_humidity) AS absolute_humidity_max,\n min(absolute_humidity) AS absolute_humidity_min,\n avg(air_temperature) AS air_temperature,\n max(air_temperature) AS air_temperature_max,\n min(air_temperature) AS air_temperature_min,\n avg(atmospheric_pressure) AS atmospheric_pressure,\n max(atmospheric_pressure) AS atmospheric_pressure_max,\n min(atmospheric_pressure) AS atmospheric_pressure_min,\n avg(atmospheric_pressure_reduced) AS atmospheric_pressure_reduced,\n max(atmospheric_pressure_reduced) AS atmospheric_pressure_reduced_max,\n min(atmospheric_pressure_reduced) AS atmospheric_pressure_reduced_min,\n avg(battery_voltage) AS battery_voltage,\n max(battery_voltage) AS battery_voltage_max,\n min(battery_voltage) AS battery_voltage_min,\n avg(black_globe_temperature) AS black_globe_temperature,\n max(black_globe_temperature) AS black_globe_temperature_max,\n min(black_globe_temperature) AS black_globe_temperature_min,\n avg(blg_battery_voltage) AS blg_battery_voltage,\n max(blg_battery_voltage) AS blg_battery_voltage_max,\n min(blg_battery_voltage) AS blg_battery_voltage_min,\n avg(blg_time_offset) AS blg_time_offset,\n max(blg_time_offset) AS blg_time_offset_max,\n min(blg_time_offset) AS blg_time_offset_min,\n avg(dew_point) AS dew_point,\n max(dew_point) AS dew_point_max,\n min(dew_point) AS dew_point_min,\n avg(heat_index) AS heat_index,\n max(heat_index) AS heat_index_max,\n min(heat_index) AS heat_index_min,\n avg(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0) AS lightning_average_distance,\n max(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0) AS lightning_average_distance_max,\n min(lightning_average_distance) FILTER (WHERE lightning_average_distance > 0.0) AS lightning_average_distance_min,\n sum(lightning_strike_count) AS lightning_strike_count,\n max(maximum_wind_speed) AS maximum_wind_speed,\n avg(mrt) AS mrt,\n max(mrt) AS mrt_max,\n min(mrt) AS mrt_min,\n avg(pet) AS pet,\n mode() WITHIN GROUP (ORDER BY pet_category ASC) AS pet_category,\n max(pet) AS pet_max,\n min(pet) AS pet_min,\n sum(precipitation_sum) AS precipitation_sum,\n mode() WITHIN GROUP (ORDER BY protocol_version ASC) AS protocol_version,\n avg(relative_humidity) AS relative_humidity,\n max(relative_humidity) AS relative_humidity_max,\n min(relative_humidity) AS relative_humidity_min,\n avg(sensor_temperature_internal) AS sensor_temperature_internal,\n max(sensor_temperature_internal) AS sensor_temperature_internal_max,\n min(sensor_temperature_internal) AS sensor_temperature_internal_min,\n avg(solar_radiation) AS solar_radiation,\n max(solar_radiation) AS solar_radiation_max,\n min(solar_radiation) AS solar_radiation_min,\n avg(specific_humidity) AS specific_humidity,\n max(specific_humidity) AS specific_humidity_max,\n min(specific_humidity) AS specific_humidity_min,\n avg(thermistor_resistance) AS thermistor_resistance,\n max(thermistor_resistance) AS thermistor_resistance_max,\n min(thermistor_resistance) AS thermistor_resistance_min,\n avg(u_wind) AS u_wind,\n max(u_wind) AS u_wind_max,\n min(u_wind) AS u_wind_min,\n avg(utci) AS utci,\n mode() WITHIN GROUP (ORDER BY utci_category ASC) AS utci_category,\n max(utci) AS utci_max,\n min(utci) AS utci_min,\n avg(v_wind) AS v_wind,\n max(v_wind) AS v_wind_max,\n min(v_wind) AS v_wind_min,\n avg(vapor_pressure) AS vapor_pressure,\n max(vapor_pressure) AS vapor_pressure_max,\n min(vapor_pressure) AS vapor_pressure_min,\n avg(voltage_ratio) AS voltage_ratio,\n max(voltage_ratio) AS voltage_ratio_max,\n min(voltage_ratio) AS voltage_ratio_min,\n avg(wet_bulb_temperature) AS wet_bulb_temperature,\n max(wet_bulb_temperature) AS wet_bulb_temperature_max,\n min(wet_bulb_temperature) AS wet_bulb_temperature_min,\n avg_angle(wind_direction) AS wind_direction,\n avg(wind_speed) AS wind_speed,\n max(wind_speed) AS wind_speed_max,\n min(wind_speed) AS wind_speed_min,\n avg(x_orientation_angle) AS x_orientation_angle,\n max(x_orientation_angle) AS x_orientation_angle_max,\n min(x_orientation_angle) AS x_orientation_angle_min,\n avg(y_orientation_angle) AS y_orientation_angle,\n max(y_orientation_angle) AS y_orientation_angle_max,\n min(y_orientation_angle) AS y_orientation_angle_min\n FROM all_data\n GROUP BY measured_at, station_id\n ORDER BY measured_at, station_id\n "¶
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_max: Mapped[Decimal]¶
maximum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_min: Mapped[Decimal]¶
minimum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_max: Mapped[Decimal]¶
maximum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_min: Mapped[Decimal]¶
minimum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- lightning_average_distance: Mapped[Decimal]¶
distance of lightning strikes in km
- lightning_average_distance_max: Mapped[Decimal]¶
maximum of distance of lightning strikes in km
- lightning_average_distance_min: Mapped[Decimal]¶
minimum of distance of lightning strikes in km
- lightning_strike_count: Mapped[Decimal]¶
number of lightning strikes
- maximum_wind_speed: Mapped[Decimal]¶
maximum wind speed in m/s (gusts)
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- mrt: Mapped[Decimal]¶
mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- mrt_max: Mapped[Decimal]¶
maximum of mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- mrt_min: Mapped[Decimal]¶
minimum of mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- pet: Mapped[Decimal]¶
physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_category: Mapped[HeatStressCategories]¶
physiological equivalent temperature category derived from
PET_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- pet_max: Mapped[Decimal]¶
maximum of physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_min: Mapped[Decimal]¶
minimum of physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- precipitation_sum: Mapped[Decimal]¶
precipitation sum in mm
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_max: Mapped[Decimal]¶
maximum of relative humidity in %
- relative_humidity_min: Mapped[Decimal]¶
minimum of relative humidity in %
- sensor_temperature_internal: Mapped[Decimal]¶
internal temperature of the sensor in °C
- sensor_temperature_internal_max: Mapped[Decimal]¶
maximum of internal temperature of the sensor in °C
- sensor_temperature_internal_min: Mapped[Decimal]¶
minimum of internal temperature of the sensor in °C
- solar_radiation: Mapped[Decimal]¶
solar radiation in W/m2
- solar_radiation_max: Mapped[Decimal]¶
maximum of solar radiation in W/m2
- solar_radiation_min: Mapped[Decimal]¶
minimum of solar radiation in W/m2
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_max: Mapped[Decimal]¶
maximum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_min: Mapped[Decimal]¶
minimum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- thermistor_resistance: Mapped[Decimal]¶
thermistor resistance in Ohms
- thermistor_resistance_max: Mapped[Decimal]¶
maximum of thermistor resistance in Ohms
- thermistor_resistance_min: Mapped[Decimal]¶
minimum of thermistor resistance in Ohms
- u_wind: Mapped[Decimal]¶
u wind component in m/s
- u_wind_max: Mapped[Decimal]¶
maximum of u wind component in m/s
- u_wind_min: Mapped[Decimal]¶
minimum of u wind component in m/s
- utci: Mapped[Decimal]¶
universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_category: Mapped[HeatStressCategories]¶
universal thermal climate index category derived from
UTCI_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- utci_max: Mapped[Decimal]¶
maximum of universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_min: Mapped[Decimal]¶
minimum of universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- v_wind: Mapped[Decimal]¶
v wind component in m/s
- v_wind_max: Mapped[Decimal]¶
maximum of v wind component in m/s
- v_wind_min: Mapped[Decimal]¶
minimum of v wind component in m/s
- vapor_pressure: Mapped[Decimal]¶
vapor pressure in kPa
- vapor_pressure_max: Mapped[Decimal]¶
maximum of vapor pressure in kPa
- vapor_pressure_min: Mapped[Decimal]¶
minimum of vapor pressure in kPa
- voltage_ratio: Mapped[Decimal]¶
voltage ratio of the sensor
- voltage_ratio_max: Mapped[Decimal]¶
maximum of voltage ratio of the sensor
- voltage_ratio_min: Mapped[Decimal]¶
minimum of voltage ratio of the sensor
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_max: Mapped[Decimal]¶
maximum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_min: Mapped[Decimal]¶
minimum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wind_direction: Mapped[Decimal]¶
wind direction in °
- wind_speed: Mapped[Decimal]¶
wind speed in m/s
- wind_speed_max: Mapped[Decimal]¶
maximum of wind speed in m/s
- wind_speed_min: Mapped[Decimal]¶
minimum of wind speed in m/s
- x_orientation_angle: Mapped[Decimal]¶
x-tilt angle of the sensor in °
- x_orientation_angle_max: Mapped[Decimal]¶
maximum of x-tilt angle of the sensor in °
- x_orientation_angle_min: Mapped[Decimal]¶
minimum of x-tilt angle of the sensor in °
- y_orientation_angle: Mapped[Decimal]¶
y-tilt angle of the sensor in °
- y_orientation_angle_max: Mapped[Decimal]¶
maximum of y-tilt angle of the sensor in °
- y_orientation_angle_min: Mapped[Decimal]¶
minimum of y-tilt angle of the sensor in °
- class app.models.BuddyCheckQc(**kwargs)[source]¶
The quality control flags returned by the buddy check for a station.
- air_temperature_qc_buddy_check: Mapped[bool]¶
quality control for the air temperature using a buddy check
- air_temperature_qc_isolated_check: Mapped[bool]¶
quality control for the air temperature using an isolation check
- atmospheric_pressure_qc_buddy_check: Mapped[bool]¶
quality control for the atmospheric pressure using a buddy check
- atmospheric_pressure_qc_isolated_check: Mapped[bool]¶
quality control for the atmospheric pressure using an isolation check
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- qc_score: Mapped[Decimal]¶
Quality control score of the data. This is calculated by weighting the different QC checks according to their severity
- relative_humidity_qc_buddy_check: Mapped[bool]¶
quality control for the relative humidity using a buddy check
- relative_humidity_qc_isolated_check: Mapped[bool]¶
quality control for the relative humidity using an isolation check
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- class app.models.HeatStressCategories(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Enum for the different heat stress categories as defined by PET or UTCI.
- extreme_cold_stress = 'extreme cold stress'¶
- extreme_heat_stress = 'extreme heat stress'¶
- moderate_cold_stress = 'moderate cold stress'¶
- moderate_heat_stress = 'moderate heat stress'¶
- no_thermal_stress = 'no thermal stress'¶
- slight_cold_stress = 'slight cold stress'¶
- slight_heat_stress = 'slight heat stress'¶
- strong_cold_stress = 'strong cold stress'¶
- strong_heat_stress = 'strong heat stress'¶
- unknown = 'unknown'¶
- very_strong_cold_stress = 'very strong cold stress'¶
- very_strong_heat_stress = 'very strong heat stress'¶
- class app.models.LatestData(**kwargs)[source]¶
This is not an actual table, but a materialized view. We simply trick sqlalchemy into thinking this was a table. Querying a materialized view does not differ from querying a proper table.
The query for creating this materialized view is saved above.
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_qc_buddy_check: Mapped[bool]¶
quality control for the air temperature using a buddy check
- air_temperature_qc_isolated_check: Mapped[bool]¶
quality control for the air temperature using an isolation check
- air_temperature_qc_persistence_check: Mapped[bool]¶
- air_temperature_qc_range_check: Mapped[bool]¶
- air_temperature_qc_spike_dip_check: Mapped[bool]¶
- altitude: Mapped[float]¶
altitude of the station in m a.s.l.
- atmospheric_pressure: Mapped[Decimal]¶
atmospheric pressure in kPa
- atmospheric_pressure_qc_buddy_check: Mapped[bool]¶
quality control for the atmospheric pressure using a buddy check
- atmospheric_pressure_qc_isolated_check: Mapped[bool]¶
quality control for the atmospheric pressure using an isolation check
- atmospheric_pressure_qc_persistence_check: Mapped[bool]¶
- atmospheric_pressure_qc_range_check: Mapped[bool]¶
- atmospheric_pressure_qc_spike_dip_check: Mapped[bool]¶
- atmospheric_pressure_reduced: Mapped[Decimal]¶
atmospheric pressure reduced to sea level in hPa calculated using
app.tasks.reduce_pressure()
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- black_globe_temperature: Mapped[Decimal]¶
black globe temperature in °C
- black_globe_temperature_qc_persistence_check: Mapped[bool]¶
- black_globe_temperature_qc_range_check: Mapped[bool]¶
- black_globe_temperature_qc_spike_dip_check: Mapped[bool]¶
- creation_sql: str = " CREATE MATERIALIZED VIEW IF NOT EXISTS latest_data AS\n (\n SELECT DISTINCT ON (station_id)\n biomet_data.station_id,\n long_name,\n latitude,\n longitude,\n altitude,\n district,\n lcz,\n station_type,\n biomet_data.measured_at,\n air_temperature,\n relative_humidity,\n dew_point,\n absolute_humidity,\n specific_humidity,\n heat_index,\n wet_bulb_temperature,\n atmospheric_pressure,\n atmospheric_pressure_reduced,\n lightning_average_distance,\n lightning_strike_count,\n mrt,\n pet,\n pet_category,\n precipitation_sum,\n solar_radiation,\n utci,\n utci_category,\n vapor_pressure,\n wind_direction,\n wind_speed,\n maximum_wind_speed,\n u_wind,\n v_wind,\n sensor_temperature_internal,\n x_orientation_angle,\n y_orientation_angle,\n black_globe_temperature,\n thermistor_resistance,\n voltage_ratio,\n air_temperature_qc_range_check,\n air_temperature_qc_persistence_check,\n air_temperature_qc_spike_dip_check,\n relative_humidity_qc_range_check,\n relative_humidity_qc_persistence_check,\n relative_humidity_qc_spike_dip_check,\n atmospheric_pressure_qc_range_check,\n atmospheric_pressure_qc_persistence_check,\n atmospheric_pressure_qc_spike_dip_check,\n wind_speed_qc_range_check,\n wind_speed_qc_persistence_check,\n wind_speed_qc_spike_dip_check,\n wind_direction_qc_range_check,\n wind_direction_qc_persistence_check,\n u_wind_qc_range_check,\n u_wind_qc_persistence_check,\n u_wind_qc_spike_dip_check,\n v_wind_qc_range_check,\n v_wind_qc_persistence_check,\n v_wind_qc_spike_dip_check,\n maximum_wind_speed_qc_range_check,\n maximum_wind_speed_qc_persistence_check,\n precipitation_sum_qc_range_check,\n precipitation_sum_qc_persistence_check,\n precipitation_sum_qc_spike_dip_check,\n solar_radiation_qc_range_check,\n solar_radiation_qc_persistence_check,\n solar_radiation_qc_spike_dip_check,\n lightning_average_distance_qc_range_check,\n lightning_average_distance_qc_persistence_check,\n lightning_strike_count_qc_range_check,\n lightning_strike_count_qc_persistence_check,\n x_orientation_angle_qc_range_check,\n x_orientation_angle_qc_spike_dip_check,\n y_orientation_angle_qc_range_check,\n y_orientation_angle_qc_spike_dip_check,\n black_globe_temperature_qc_range_check,\n black_globe_temperature_qc_persistence_check,\n black_globe_temperature_qc_spike_dip_check,\n qc_flagged,\n air_temperature_qc_isolated_check,\n air_temperature_qc_buddy_check,\n relative_humidity_qc_isolated_check,\n relative_humidity_qc_buddy_check,\n atmospheric_pressure_qc_isolated_check,\n atmospheric_pressure_qc_buddy_check,\n qc_score,\n battery_voltage,\n protocol_version\n FROM biomet_data\n INNER JOIN station ON biomet_data.station_id = station.station_id\n LEFT OUTER JOIN buddy_check_qc ON (\n biomet_data.station_id = buddy_check_qc.station_id AND\n biomet_data.measured_at = buddy_check_qc.measured_at\n )\n ORDER BY biomet_data.station_id, biomet_data.measured_at DESC\n )\n UNION ALL\n (\n SELECT DISTINCT ON (station_id)\n temp_rh_data.station_id,\n long_name,\n latitude,\n longitude,\n altitude,\n district,\n lcz,\n station_type,\n temp_rh_data.measured_at,\n air_temperature,\n relative_humidity,\n dew_point,\n absolute_humidity,\n specific_humidity,\n heat_index,\n wet_bulb_temperature,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n air_temperature_qc_range_check,\n air_temperature_qc_persistence_check,\n air_temperature_qc_spike_dip_check,\n relative_humidity_qc_range_check,\n relative_humidity_qc_persistence_check,\n relative_humidity_qc_spike_dip_check,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n NULL,\n qc_flagged,\n air_temperature_qc_isolated_check,\n air_temperature_qc_buddy_check,\n relative_humidity_qc_isolated_check,\n relative_humidity_qc_buddy_check,\n NULL,\n NULL,\n qc_score,\n battery_voltage,\n protocol_version\n FROM temp_rh_data\n INNER JOIN station ON temp_rh_data.station_id = station.station_id\n LEFT OUTER JOIN buddy_check_qc ON (\n temp_rh_data.station_id = buddy_check_qc.station_id AND\n temp_rh_data.measured_at = buddy_check_qc.measured_at\n )\n WHERE station.station_type <> 'double'\n ORDER BY temp_rh_data.station_id, temp_rh_data.measured_at DESC\n )\n "¶
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- district: Mapped[str]¶
name of the district the station is located in
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- latitude: Mapped[float]¶
latitude of the station in decimal degrees
- lcz: Mapped[str]¶
local climate zone of the station
- lightning_average_distance: Mapped[Decimal]¶
distance of lightning strikes in km
- lightning_average_distance_qc_persistence_check: Mapped[bool]¶
- lightning_average_distance_qc_range_check: Mapped[bool]¶
- lightning_strike_count: Mapped[Decimal]¶
number of lightning strikes
- lightning_strike_count_qc_persistence_check: Mapped[bool]¶
- lightning_strike_count_qc_range_check: Mapped[bool]¶
- long_name: Mapped[str]¶
long name of the station e.g.
Nordmarkt
- longitude: Mapped[float]¶
longitude of the station in decimal degrees
- maximum_wind_speed: Mapped[Decimal]¶
maximum wind speed in m/s (gusts)
- maximum_wind_speed_qc_persistence_check: Mapped[bool]¶
- maximum_wind_speed_qc_range_check: Mapped[bool]¶
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- mrt: Mapped[Decimal]¶
mean radiant temperature in °C calculated using
thermal_comfort.mean_radiant_temp()
- pet: Mapped[Decimal]¶
physiological equivalent temperature in °C calculated using
thermal_comfort.pet_static()
- pet_category: Mapped[HeatStressCategories]¶
physiological equivalent temperature category derived from
PET_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- precipitation_sum: Mapped[Decimal]¶
precipitation sum in mm
- precipitation_sum_qc_persistence_check: Mapped[bool]¶
- precipitation_sum_qc_range_check: Mapped[bool]¶
- precipitation_sum_qc_spike_dip_check: Mapped[bool]¶
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- qc_flagged: Mapped[bool]¶
- qc_score: Mapped[Decimal]¶
Quality control score of the data. This is calculated by weighting the different QC checks according to their severity
- async classmethod refresh(*, concurrently=True, **kwargs) None [source]¶
override the base refresh since this is actually a materialized view.
- Return type:
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_qc_buddy_check: Mapped[bool]¶
quality control for the relative humidity using a buddy check
- relative_humidity_qc_isolated_check: Mapped[bool]¶
quality control for the relative humidity using an isolation check
- relative_humidity_qc_persistence_check: Mapped[bool]¶
- relative_humidity_qc_range_check: Mapped[bool]¶
- relative_humidity_qc_spike_dip_check: Mapped[bool]¶
- sensor_temperature_internal: Mapped[Decimal]¶
internal temperature of the sensor in °C
- solar_radiation: Mapped[Decimal]¶
solar radiation in W/m2
- solar_radiation_qc_persistence_check: Mapped[bool]¶
- solar_radiation_qc_range_check: Mapped[bool]¶
- solar_radiation_qc_spike_dip_check: Mapped[bool]¶
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station e.g.
DOBNOM
- station_type: Mapped[StationType]¶
type of the station e.g.
temprh
- thermistor_resistance: Mapped[Decimal]¶
thermistor resistance in Ohms
- u_wind: Mapped[Decimal]¶
u wind component in m/s
- u_wind_qc_persistence_check: Mapped[bool]¶
- u_wind_qc_range_check: Mapped[bool]¶
- u_wind_qc_spike_dip_check: Mapped[bool]¶
- utci: Mapped[Decimal]¶
universal thermal climate index in °C calculated using
thermal_comfort.utci_approx()
- utci_category: Mapped[HeatStressCategories]¶
universal thermal climate index category derived from
UTCI_STRESS_CATEGORIES
and applied usingapp.tasks.category_mapping()
- v_wind: Mapped[Decimal]¶
v wind component in m/s
- v_wind_qc_persistence_check: Mapped[bool]¶
- v_wind_qc_range_check: Mapped[bool]¶
- v_wind_qc_spike_dip_check: Mapped[bool]¶
- vapor_pressure: Mapped[Decimal]¶
vapor pressure in kPa
- voltage_ratio: Mapped[Decimal]¶
voltage ratio of the sensor
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wind_direction: Mapped[Decimal]¶
wind direction in °
- wind_direction_qc_persistence_check: Mapped[bool]¶
- wind_direction_qc_range_check: Mapped[bool]¶
- wind_speed: Mapped[Decimal]¶
wind speed in m/s
- wind_speed_qc_persistence_check: Mapped[bool]¶
- wind_speed_qc_range_check: Mapped[bool]¶
- wind_speed_qc_spike_dip_check: Mapped[bool]¶
- x_orientation_angle: Mapped[Decimal]¶
x-tilt angle of the sensor in °
- x_orientation_angle_qc_range_check: Mapped[bool]¶
- x_orientation_angle_qc_spike_dip_check: Mapped[bool]¶
- y_orientation_angle: Mapped[Decimal]¶
y-tilt angle of the sensor in °
- y_orientation_angle_qc_range_check: Mapped[bool]¶
- y_orientation_angle_qc_spike_dip_check: Mapped[bool]¶
- class app.models.MaterializedView(**kwargs) None [source]¶
Baseclass for a materialized view. The view is faked as a table, so that sqlalchemy can handle it like a table and so we can incrementally refresh it.
- creation_sql: str¶
- is_continuous_aggregate = False¶
- async classmethod refresh(*, concurrently=True, window_start=None, window_end=None) None [source]¶
Refresh the materialized view.
This takes into account whether the view is a continuous aggregate or a vanilla postgres materialized view. This needs to be done outside of a transaction.
- Parameters:
concurrently (
bool
) – Whether to refresh the view concurrently. Refreshing concurrently is slower, however no exclusive lock is acquired. This way reads to the view can still be performed. This only applies to vanilla postgres materialized views. (default:True
)window_start (
datetime
|None
) – The start of the window that will be refreshed. This only applies to continuous aggregates. This is not inclusive. (default:None
)window_end (
datetime
|None
) – The end of the window that will be refreshed. This only applies to continuous aggregates. This is inclusive. (default:None
)
- Return type:
- station_id: Mapped[str] = <sqlalchemy.orm.properties.MappedColumn object>¶
- class app.models.SHT35DataRaw(**kwargs)[source]¶
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- sensor: Mapped[Sensor]¶
The sensor the data was measured with
- sensor_id: Mapped[str]¶
id of the sensor e.g.
DEC1234
- class app.models.Sensor(**kwargs)[source]¶
Pool of sensors that can be installed at a station
- current_station: Mapped[Station | None]¶
the station the sensor is currently deployed at
- deployments: Mapped[list[SensorDeployment]]¶
list of all deployments of the sensor
- device_id: Mapped[int]¶
device id of the sensor e.g.
1234567890
- former_stations: Mapped[list[Station]]¶
list of stations the sensor was previously deployed at
- relhum_calib_offset: Mapped[Decimal]¶
relative humidity calibration offset in %. This is the offset that is applied to the relative humidity value before it is stored in the database
- sensor_id: Mapped[str]¶
id of the sensor e.g.
DEC1234
- sensor_type: Mapped[SensorType]¶
type of the sensor e.g.
biomet
- temp_calib_offset: Mapped[Decimal]¶
temperature calibration offset in °C. This is the offset that is applied to the temperature value before it is stored in the database
- class app.models.SensorDeployment(**kwargs)[source]¶
Deployment of a sensor at a station
- deployment_id: Mapped[int]¶
- sensor: Mapped[Sensor]¶
- sensor_id: Mapped[str]¶
- setup_date: Mapped[datetime]¶
- station: Mapped[Station]¶
- station_id: Mapped[str]¶
- teardown_date: Mapped[datetime | None]¶
- class app.models.SensorType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Enum differentiating between the different types of sensors:
atm41
: ATM41 sensor with many parametersblg
: BLG sensor with black globe temperaturesht35
: SHT35 sensor with temperature and relative humidity
- atm41 = 'atm41'¶
- blg = 'blg'¶
- sht35 = 'sht35'¶
- class app.models.Station(**kwargs)[source]¶
Representation of a station which has a physical location and sensor(s) attached to it.
- active_deployments: Mapped[list[SensorDeployment]]¶
list of deployments that are currently active at the station
- active_sensors: Mapped[list[Sensor]]¶
list of sensors that are currently deployed at the station
- altitude: Mapped[float]¶
altitude of the station in m a.s.l.
- artificial_heat_sources: Mapped[str]¶
artificial heat sources at the station
- blg_sensor_distance_from_mounting_structure: Mapped[Decimal | None]¶
the distance of the black globe sensor of the station from the mounting structure
- blg_sensor_height_agl: Mapped[Decimal | None]¶
the mounting height of the black globe sensor of the station
- blg_sensor_orientation: Mapped[Decimal | None]¶
the orientation (-angle) of the arm of the black globe sensor of the station from the mounting structure
- city: Mapped[str]¶
name of the city the station is located in
- comment: Mapped[str | None]¶
a text describing the station
- country: Mapped[str]¶
name of the country the station is located in
- deployments: Mapped[list[SensorDeployment]]¶
list of all deployments at the station
- district: Mapped[str]¶
name of the district the station is located in
- dominant_land_use: Mapped[str | None]¶
dominant land use at the station
- former_deployments: Mapped[list[SensorDeployment]]¶
list of deployments that were previously active at the station
- former_sensors: Mapped[list[Sensor]]¶
list of sensors that were previously deployed at the station
- latitude: Mapped[float]¶
latitude of the station in decimal degrees
- lcz: Mapped[str | None]¶
local climate zone of the station
- leuchtennummer: Mapped[int]¶
the number of the streetlight the sensor is mounted to
- long_name: Mapped[str]¶
long name of the station e.g.
Nordmarkt
- longitude: Mapped[float]¶
longitude of the station in decimal degrees
- mounting_structure_diameter: Mapped[Decimal | None]¶
the diameter of the mounting structure at the mounting height
- mounting_structure_height_agl: Mapped[Decimal | None]¶
the total height of the mounting structure above ground level
- mounting_structure_light_extension_offset: Mapped[Decimal | None]¶
when mounted to a lantern post, the overhang of the lantern
- mounting_structure_material: Mapped[str | None]¶
The material the structure the sensor is mounted to is made of e.g. metal, wood, …
- mounting_type: Mapped[str | None]¶
the structure the sensor is mounted to e.g. black mast, building, …
- number: Mapped[str | None]¶
if possible, the number of the closest building
- orographic_setting: Mapped[str | None]¶
orographic setting of the station e.g. flat, hilly, …
- plz: Mapped[int]¶
postal code of the station
- proximity_to_building: Mapped[Decimal | None]¶
the distance to the closest building in m
- proximity_to_parking: Mapped[Decimal | None]¶
the distance to the closest parking lot in m
- proximity_to_tree: Mapped[Decimal | None]¶
the distance to the closest tree in m
- sensor_distance_from_mounting_structure: Mapped[Decimal | None]¶
the distance of the main component of the station (ATM41 or SHT35) from the mounting structure
- sensor_height_agl: Mapped[Decimal | None]¶
the mounting height of the main component of the station (ATM41 or SHT35)
- sensor_orientation: Mapped[Decimal | None]¶
the orientation (-angle) of the arm of the main component of the station (ATM41 or SHT35) from the mounting structure
- station_id: Mapped[str]¶
id of the station e.g.
DOBNOM
- station_type: Mapped[StationType]¶
type of the station e.g.
temprh
- street: Mapped[str]¶
name of the street the station is located at
- surrounding_land_cover_description: Mapped[str | None]¶
a text describing the surrounding land cover
- svf: Mapped[Decimal]¶
- urban_atlas_class_name: Mapped[str | None]¶
urban atlas class name of the station
- urban_atlas_class_nr: Mapped[int | None]¶
urban atlas class number of the station
- class app.models.StationType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Enum differentiating between the different types of stations:
temprh
: station with a SHT35 sensorbiomet
: station with an ATM41 and a BLG sensordouble
: station with an ATM41, SHT35, and a BLG sensor
- biomet = 'biomet'¶
- double = 'double'¶
- temprh = 'temprh'¶
- class app.models.TempRHData(**kwargs)[source]¶
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_qc_persistence_check: Mapped[bool]¶
- air_temperature_qc_range_check: Mapped[bool]¶
- air_temperature_qc_spike_dip_check: Mapped[bool]¶
- air_temperature_raw: Mapped[Decimal]¶
raw air temperature in °C with no calibration applied
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- deployment: Mapped[SensorDeployment]¶
the deployment that made the measurement of this data
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- qc_flagged: Mapped[bool]¶
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_qc_persistence_check: Mapped[bool]¶
- relative_humidity_qc_range_check: Mapped[bool]¶
- relative_humidity_qc_spike_dip_check: Mapped[bool]¶
- relative_humidity_raw: Mapped[Decimal]¶
raw relative humidity in % with no calibration applied
- sensor: Mapped[Sensor]¶
The sensor the data was measured with
- sensor_id: Mapped[str]¶
id of the SHT35 sensor these measurements were taken with
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- class app.models.TempRHDataDaily(**kwargs)[source]¶
This is not an actual table, but a materialized view. We simply trick sqlalchemy into thinking this was a table. Querying a materialized view does not differ from querying a proper table.
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_max: Mapped[Decimal]¶
maximum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_min: Mapped[Decimal]¶
minimum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_max: Mapped[Decimal]¶
maximum of air temperature in °C
- air_temperature_min: Mapped[Decimal]¶
minimum of air temperature in °C
- air_temperature_raw: Mapped[Decimal]¶
raw air temperature in °C with no calibration applied
- air_temperature_raw_max: Mapped[Decimal]¶
maximum of raw air temperature in °C with no calibration applied
- air_temperature_raw_min: Mapped[Decimal]¶
minimum of raw air temperature in °C with no calibration applied
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- battery_voltage_max: Mapped[Decimal]¶
maximum of The battery voltage of the sensor in Volts
- battery_voltage_min: Mapped[Decimal]¶
minimum of The battery voltage of the sensor in Volts
- creation_sql: str = " WITH data_bounds AS (\n SELECT\n station_id,\n MIN(measured_at) AS start_time,\n MAX(measured_at) AS end_time\n FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n GROUP BY station_id\n ), filling_time_series AS (\n SELECT generate_series(\n DATE_TRUNC('hour', (\n SELECT MIN(measured_at) FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end)\n ),\n DATE_TRUNC('hour', (\n SELECT MAX(measured_at) FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end) + '1 hour'::INTERVAL\n ),\n '1 hour'::INTERVAL\n ) AS measured_at\n ),\n stations_subset AS (\n -- TODO: this could be faster if check the station table by station_type\n SELECT DISTINCT station_id FROM temp_rh_data\n ),\n time_station_combinations AS (\n SELECT\n measured_at,\n stations_subset.station_id,\n start_time,\n end_time\n FROM filling_time_series\n CROSS JOIN stations_subset\n JOIN data_bounds\n ON data_bounds.station_id = stations_subset.station_id\n WHERE filling_time_series.measured_at >= data_bounds.start_time\n AND filling_time_series.measured_at <= data_bounds.end_time\n ), all_data AS(\n (\n SELECT\n measured_at AS ma,\n station_id,\n NULL AS absolute_humidity,\n NULL AS air_temperature,\n NULL AS air_temperature_raw,\n NULL AS battery_voltage,\n NULL AS dew_point,\n NULL AS heat_index,\n NULL AS protocol_version,\n NULL AS relative_humidity,\n NULL AS relative_humidity_raw,\n NULL AS specific_humidity,\n NULL AS wet_bulb_temperature\n FROM time_station_combinations\n )\n UNION ALL\n (\n SELECT\n measured_at AS ma,\n station_id,\n absolute_humidity,\n air_temperature,\n air_temperature_raw,\n battery_voltage,\n dew_point,\n heat_index,\n protocol_version,\n relative_humidity,\n relative_humidity_raw,\n specific_humidity,\n wet_bulb_temperature\n FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n )\n ) SELECT\n (time_bucket('1day', ma, 'CET') + '1 hour'::INTERVAL)::DATE AS measured_at,\n station_id,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE absolute_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(absolute_humidity)\n ELSE NULL\n END AS absolute_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(air_temperature)\n ELSE NULL\n END AS air_temperature,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN max(air_temperature)\n ELSE NULL\n END AS air_temperature_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN min(air_temperature)\n ELSE NULL\n END AS air_temperature_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(air_temperature_raw)\n ELSE NULL\n END AS air_temperature_raw,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN max(air_temperature_raw)\n ELSE NULL\n END AS air_temperature_raw_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE air_temperature_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN min(air_temperature_raw)\n ELSE NULL\n END AS air_temperature_raw_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(battery_voltage)\n ELSE NULL\n END AS battery_voltage,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN max(battery_voltage)\n ELSE NULL\n END AS battery_voltage_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE battery_voltage IS NOT NULL) / 288.0\n ) > 0.7 THEN min(battery_voltage)\n ELSE NULL\n END AS battery_voltage_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(dew_point)\n ELSE NULL\n END AS dew_point,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN max(dew_point)\n ELSE NULL\n END AS dew_point_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE dew_point IS NOT NULL) / 288.0\n ) > 0.7 THEN min(dew_point)\n ELSE NULL\n END AS dew_point_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(heat_index)\n ELSE NULL\n END AS heat_index,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN max(heat_index)\n ELSE NULL\n END AS heat_index_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE heat_index IS NOT NULL) / 288.0\n ) > 0.7 THEN min(heat_index)\n ELSE NULL\n END AS heat_index_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE protocol_version IS NOT NULL) / 288.0\n ) > 0.7 THEN mode() WITHIN GROUP (ORDER BY protocol_version ASC)\n ELSE NULL\n END AS protocol_version,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(relative_humidity)\n ELSE NULL\n END AS relative_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(relative_humidity)\n ELSE NULL\n END AS relative_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(relative_humidity)\n ELSE NULL\n END AS relative_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(relative_humidity_raw)\n ELSE NULL\n END AS relative_humidity_raw,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN max(relative_humidity_raw)\n ELSE NULL\n END AS relative_humidity_raw_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE relative_humidity_raw IS NOT NULL) / 288.0\n ) > 0.7 THEN min(relative_humidity_raw)\n ELSE NULL\n END AS relative_humidity_raw_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(specific_humidity)\n ELSE NULL\n END AS specific_humidity,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN max(specific_humidity)\n ELSE NULL\n END AS specific_humidity_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE specific_humidity IS NOT NULL) / 288.0\n ) > 0.7 THEN min(specific_humidity)\n ELSE NULL\n END AS specific_humidity_min,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN avg(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN max(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature_max,\n CASE\n WHEN (count(*) FILTER (\n WHERE wet_bulb_temperature IS NOT NULL) / 288.0\n ) > 0.7 THEN min(wet_bulb_temperature)\n ELSE NULL\n END AS wet_bulb_temperature_min\n FROM all_data\n GROUP BY measured_at, station_id\n ORDER BY measured_at, station_id\n "¶
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_max: Mapped[Decimal]¶
maximum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_min: Mapped[Decimal]¶
minimum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_max: Mapped[Decimal]¶
maximum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_min: Mapped[Decimal]¶
minimum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_max: Mapped[Decimal]¶
maximum of relative humidity in %
- relative_humidity_min: Mapped[Decimal]¶
minimum of relative humidity in %
- relative_humidity_raw: Mapped[Decimal]¶
raw relative humidity in % with no calibration applied
- relative_humidity_raw_max: Mapped[Decimal]¶
maximum of raw relative humidity in % with no calibration applied
- relative_humidity_raw_min: Mapped[Decimal]¶
minimum of raw relative humidity in % with no calibration applied
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_max: Mapped[Decimal]¶
maximum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_min: Mapped[Decimal]¶
minimum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_max: Mapped[Decimal]¶
maximum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_min: Mapped[Decimal]¶
minimum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- class app.models.TempRHDataHourly(**kwargs)[source]¶
This is not an actual table, but a materialized view. We simply trick sqlalchemy into thinking this was a table. Querying a materialized view does not differ from querying a proper table.
- absolute_humidity: Mapped[Decimal]¶
absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_max: Mapped[Decimal]¶
maximum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- absolute_humidity_min: Mapped[Decimal]¶
minimum of absolute humidity in g/m3 calculated using
thermal_comfort.absolute_humidity()
- air_temperature: Mapped[Decimal]¶
air temperature in °C
- air_temperature_max: Mapped[Decimal]¶
maximum of air temperature in °C
- air_temperature_min: Mapped[Decimal]¶
minimum of air temperature in °C
- air_temperature_raw: Mapped[Decimal]¶
raw air temperature in °C with no calibration applied
- air_temperature_raw_max: Mapped[Decimal]¶
maximum of raw air temperature in °C with no calibration applied
- air_temperature_raw_min: Mapped[Decimal]¶
minimum of raw air temperature in °C with no calibration applied
- battery_voltage: Mapped[Decimal]¶
The battery voltage of the sensor in Volts
- battery_voltage_max: Mapped[Decimal]¶
maximum of The battery voltage of the sensor in Volts
- battery_voltage_min: Mapped[Decimal]¶
minimum of The battery voltage of the sensor in Volts
- creation_sql: str = " WITH data_bounds AS (\n SELECT\n station_id,\n MIN(measured_at) AS start_time,\n MAX(measured_at) AS end_time\n FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n GROUP BY station_id\n ), filling_time_series AS (\n SELECT generate_series(\n DATE_TRUNC('hour', (\n SELECT MIN(measured_at) FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end)\n ),\n DATE_TRUNC('hour', (\n SELECT MAX(measured_at) FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end) + '1 hour'::INTERVAL\n ),\n '1 hour'::INTERVAL\n ) AS measured_at\n ),\n stations_subset AS (\n -- TODO: this could be faster if check the station table by station_type\n SELECT DISTINCT station_id FROM temp_rh_data\n ),\n time_station_combinations AS (\n SELECT\n measured_at,\n stations_subset.station_id,\n start_time,\n end_time\n FROM filling_time_series\n CROSS JOIN stations_subset\n JOIN data_bounds\n ON data_bounds.station_id = stations_subset.station_id\n WHERE filling_time_series.measured_at >= data_bounds.start_time\n AND filling_time_series.measured_at <= data_bounds.end_time\n ), all_data AS(\n (\n SELECT\n measured_at AS ma,\n station_id,\n NULL AS absolute_humidity,\n NULL AS air_temperature,\n NULL AS air_temperature_raw,\n NULL AS battery_voltage,\n NULL AS dew_point,\n NULL AS heat_index,\n NULL AS protocol_version,\n NULL AS relative_humidity,\n NULL AS relative_humidity_raw,\n NULL AS specific_humidity,\n NULL AS wet_bulb_temperature\n FROM time_station_combinations\n )\n UNION ALL\n (\n SELECT\n measured_at AS ma,\n station_id,\n absolute_humidity,\n air_temperature,\n air_temperature_raw,\n battery_voltage,\n dew_point,\n heat_index,\n protocol_version,\n relative_humidity,\n relative_humidity_raw,\n specific_humidity,\n wet_bulb_temperature\n FROM temp_rh_data\n WHERE measured_at BETWEEN :window_start AND :window_end\n )\n ) SELECT\n time_bucket('1 hour', ma) + '1 hour'::INTERVAL AS measured_at,\n station_id,\n avg(absolute_humidity) AS absolute_humidity,\n max(absolute_humidity) AS absolute_humidity_max,\n min(absolute_humidity) AS absolute_humidity_min,\n avg(air_temperature) AS air_temperature,\n max(air_temperature) AS air_temperature_max,\n min(air_temperature) AS air_temperature_min,\n avg(air_temperature_raw) AS air_temperature_raw,\n max(air_temperature_raw) AS air_temperature_raw_max,\n min(air_temperature_raw) AS air_temperature_raw_min,\n avg(battery_voltage) AS battery_voltage,\n max(battery_voltage) AS battery_voltage_max,\n min(battery_voltage) AS battery_voltage_min,\n avg(dew_point) AS dew_point,\n max(dew_point) AS dew_point_max,\n min(dew_point) AS dew_point_min,\n avg(heat_index) AS heat_index,\n max(heat_index) AS heat_index_max,\n min(heat_index) AS heat_index_min,\n mode() WITHIN GROUP (ORDER BY protocol_version ASC) AS protocol_version,\n avg(relative_humidity) AS relative_humidity,\n max(relative_humidity) AS relative_humidity_max,\n min(relative_humidity) AS relative_humidity_min,\n avg(relative_humidity_raw) AS relative_humidity_raw,\n max(relative_humidity_raw) AS relative_humidity_raw_max,\n min(relative_humidity_raw) AS relative_humidity_raw_min,\n avg(specific_humidity) AS specific_humidity,\n max(specific_humidity) AS specific_humidity_max,\n min(specific_humidity) AS specific_humidity_min,\n avg(wet_bulb_temperature) AS wet_bulb_temperature,\n max(wet_bulb_temperature) AS wet_bulb_temperature_max,\n min(wet_bulb_temperature) AS wet_bulb_temperature_min\n FROM all_data\n GROUP BY measured_at, station_id\n ORDER BY measured_at, station_id\n "¶
- dew_point: Mapped[Decimal]¶
dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_max: Mapped[Decimal]¶
maximum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- dew_point_min: Mapped[Decimal]¶
minimum of dew point temperature in °C calculated using
thermal_comfort.dew_point()
- heat_index: Mapped[Decimal]¶
heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_max: Mapped[Decimal]¶
maximum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- heat_index_min: Mapped[Decimal]¶
minimum of heat index in °C calculated using
thermal_comfort.heat_index_extended()
- measured_at: Mapped[datetime]¶
The exact time the value was measured in UTC
- protocol_version: Mapped[int]¶
The protocol version the data was sent with
- relative_humidity: Mapped[Decimal]¶
relative humidity in %
- relative_humidity_max: Mapped[Decimal]¶
maximum of relative humidity in %
- relative_humidity_min: Mapped[Decimal]¶
minimum of relative humidity in %
- relative_humidity_raw: Mapped[Decimal]¶
raw relative humidity in % with no calibration applied
- relative_humidity_raw_max: Mapped[Decimal]¶
maximum of raw relative humidity in % with no calibration applied
- relative_humidity_raw_min: Mapped[Decimal]¶
minimum of raw relative humidity in % with no calibration applied
- specific_humidity: Mapped[Decimal]¶
specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_max: Mapped[Decimal]¶
maximum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- specific_humidity_min: Mapped[Decimal]¶
minimum of specific humidity in g/kg calculated using
thermal_comfort.specific_humidity()
- station: Mapped[Station]¶
The station the data was measured at
- station_id: Mapped[str]¶
id of the station these measurements were taken at
- wet_bulb_temperature: Mapped[Decimal]¶
wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_max: Mapped[Decimal]¶
maximum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- wet_bulb_temperature_min: Mapped[Decimal]¶
minimum of wet bulb temperature in °C calculated using
thermal_comfort.wet_bulb_temp()
- app.models.create_hypertable(target, connection, **kwargs) None [source]¶
Create a timescaledb hypertable for the given table if it doesn’t exist.
- Parameters:
target (
Table
) – The table to create a hypertable forconnection (
Connection
) – The database connection to usekwargs (
Any
) – Additional keyword arguments (which are ignored)
- Return type: