V 1.5.6 fix: tatsächliche Uhrzeit von Min/Max in der Statistikzeile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+25
-4
@@ -408,19 +408,26 @@ async def get_daily_aggregated_data(
|
|||||||
"""Gibt täglich aggregierte Wetterdaten zurück (Tagesmittel mit Min/Max-Temperaturen)"""
|
"""Gibt täglich aggregierte Wetterdaten zurück (Tagesmittel mit Min/Max-Temperaturen)"""
|
||||||
with conn.cursor() as cursor:
|
with conn.cursor() as cursor:
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
date_trunc('day', datetime) as datetime,
|
date_trunc('day', datetime) as datetime,
|
||||||
AVG(temperature)::float as temperature,
|
AVG(temperature)::float as temperature,
|
||||||
MIN(temperature)::float as min_temperature,
|
MIN(temperature)::float as min_temperature,
|
||||||
MAX(temperature)::float as max_temperature,
|
MAX(temperature)::float as max_temperature,
|
||||||
|
(array_agg(datetime ORDER BY temperature ASC NULLS LAST))[1] as min_temperature_time,
|
||||||
|
(array_agg(datetime ORDER BY temperature DESC NULLS LAST))[1] as max_temperature_time,
|
||||||
ROUND(AVG(humidity))::int as humidity,
|
ROUND(AVG(humidity))::int as humidity,
|
||||||
MIN(humidity)::int as min_humidity,
|
MIN(humidity)::int as min_humidity,
|
||||||
MAX(humidity)::int as max_humidity,
|
MAX(humidity)::int as max_humidity,
|
||||||
|
(array_agg(datetime ORDER BY humidity ASC NULLS LAST))[1] as min_humidity_time,
|
||||||
|
(array_agg(datetime ORDER BY humidity DESC NULLS LAST))[1] as max_humidity_time,
|
||||||
AVG(pressure)::float as pressure,
|
AVG(pressure)::float as pressure,
|
||||||
MIN(pressure)::float as min_pressure,
|
MIN(pressure)::float as min_pressure,
|
||||||
MAX(pressure)::float as max_pressure,
|
MAX(pressure)::float as max_pressure,
|
||||||
|
(array_agg(datetime ORDER BY pressure ASC NULLS LAST))[1] as min_pressure_time,
|
||||||
|
(array_agg(datetime ORDER BY pressure DESC NULLS LAST))[1] as max_pressure_time,
|
||||||
AVG(wind_speed * 1.60934)::float as wind_speed,
|
AVG(wind_speed * 1.60934)::float as wind_speed,
|
||||||
MAX(wind_gust * 1.60934)::float as wind_gust,
|
MAX(wind_gust * 1.60934)::float as wind_gust,
|
||||||
|
(array_agg(datetime ORDER BY wind_gust DESC NULLS LAST))[1] as max_wind_gust_time,
|
||||||
AVG(wind_dir)::float as wind_dir,
|
AVG(wind_dir)::float as wind_dir,
|
||||||
SUM(rain)::float as total_rain
|
SUM(rain)::float as total_rain
|
||||||
FROM weather_data
|
FROM weather_data
|
||||||
@@ -441,19 +448,26 @@ async def get_daily_with_minmax_data(
|
|||||||
"""Gibt täglich aggregierte Wetterdaten mit Min/Max-Temperaturen zurück"""
|
"""Gibt täglich aggregierte Wetterdaten mit Min/Max-Temperaturen zurück"""
|
||||||
with conn.cursor() as cursor:
|
with conn.cursor() as cursor:
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
date_trunc('day', datetime) as datetime,
|
date_trunc('day', datetime) as datetime,
|
||||||
AVG(temperature)::float as temperature,
|
AVG(temperature)::float as temperature,
|
||||||
MIN(temperature)::float as min_temperature,
|
MIN(temperature)::float as min_temperature,
|
||||||
MAX(temperature)::float as max_temperature,
|
MAX(temperature)::float as max_temperature,
|
||||||
|
(array_agg(datetime ORDER BY temperature ASC NULLS LAST))[1] as min_temperature_time,
|
||||||
|
(array_agg(datetime ORDER BY temperature DESC NULLS LAST))[1] as max_temperature_time,
|
||||||
ROUND(AVG(humidity))::int as humidity,
|
ROUND(AVG(humidity))::int as humidity,
|
||||||
MIN(humidity)::int as min_humidity,
|
MIN(humidity)::int as min_humidity,
|
||||||
MAX(humidity)::int as max_humidity,
|
MAX(humidity)::int as max_humidity,
|
||||||
|
(array_agg(datetime ORDER BY humidity ASC NULLS LAST))[1] as min_humidity_time,
|
||||||
|
(array_agg(datetime ORDER BY humidity DESC NULLS LAST))[1] as max_humidity_time,
|
||||||
AVG(pressure)::float as pressure,
|
AVG(pressure)::float as pressure,
|
||||||
MIN(pressure)::float as min_pressure,
|
MIN(pressure)::float as min_pressure,
|
||||||
MAX(pressure)::float as max_pressure,
|
MAX(pressure)::float as max_pressure,
|
||||||
|
(array_agg(datetime ORDER BY pressure ASC NULLS LAST))[1] as min_pressure_time,
|
||||||
|
(array_agg(datetime ORDER BY pressure DESC NULLS LAST))[1] as max_pressure_time,
|
||||||
AVG(wind_speed * 1.60934)::float as wind_speed,
|
AVG(wind_speed * 1.60934)::float as wind_speed,
|
||||||
MAX(wind_gust * 1.60934)::float as wind_gust,
|
MAX(wind_gust * 1.60934)::float as wind_gust,
|
||||||
|
(array_agg(datetime ORDER BY wind_gust DESC NULLS LAST))[1] as max_wind_gust_time,
|
||||||
AVG(wind_dir)::float as wind_dir,
|
AVG(wind_dir)::float as wind_dir,
|
||||||
SUM(rain)::float as total_rain
|
SUM(rain)::float as total_rain
|
||||||
FROM weather_data
|
FROM weather_data
|
||||||
@@ -462,7 +476,7 @@ async def get_daily_with_minmax_data(
|
|||||||
ORDER BY datetime ASC
|
ORDER BY datetime ASC
|
||||||
""", (days,))
|
""", (days,))
|
||||||
results = cursor.fetchall()
|
results = cursor.fetchall()
|
||||||
|
|
||||||
return [dict(row) for row in results]
|
return [dict(row) for row in results]
|
||||||
|
|
||||||
|
|
||||||
@@ -561,19 +575,26 @@ async def get_daily_aggregated_range(
|
|||||||
|
|
||||||
with conn.cursor() as cursor:
|
with conn.cursor() as cursor:
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
date_trunc('day', datetime) as datetime,
|
date_trunc('day', datetime) as datetime,
|
||||||
AVG(temperature)::float as temperature,
|
AVG(temperature)::float as temperature,
|
||||||
MIN(temperature)::float as min_temperature,
|
MIN(temperature)::float as min_temperature,
|
||||||
MAX(temperature)::float as max_temperature,
|
MAX(temperature)::float as max_temperature,
|
||||||
|
(array_agg(datetime ORDER BY temperature ASC NULLS LAST))[1] as min_temperature_time,
|
||||||
|
(array_agg(datetime ORDER BY temperature DESC NULLS LAST))[1] as max_temperature_time,
|
||||||
ROUND(AVG(humidity))::int as humidity,
|
ROUND(AVG(humidity))::int as humidity,
|
||||||
MIN(humidity)::int as min_humidity,
|
MIN(humidity)::int as min_humidity,
|
||||||
MAX(humidity)::int as max_humidity,
|
MAX(humidity)::int as max_humidity,
|
||||||
|
(array_agg(datetime ORDER BY humidity ASC NULLS LAST))[1] as min_humidity_time,
|
||||||
|
(array_agg(datetime ORDER BY humidity DESC NULLS LAST))[1] as max_humidity_time,
|
||||||
AVG(pressure)::float as pressure,
|
AVG(pressure)::float as pressure,
|
||||||
MIN(pressure)::float as min_pressure,
|
MIN(pressure)::float as min_pressure,
|
||||||
MAX(pressure)::float as max_pressure,
|
MAX(pressure)::float as max_pressure,
|
||||||
|
(array_agg(datetime ORDER BY pressure ASC NULLS LAST))[1] as min_pressure_time,
|
||||||
|
(array_agg(datetime ORDER BY pressure DESC NULLS LAST))[1] as max_pressure_time,
|
||||||
AVG(wind_speed * 1.60934)::float as wind_speed,
|
AVG(wind_speed * 1.60934)::float as wind_speed,
|
||||||
MAX(wind_gust * 1.60934)::float as wind_gust,
|
MAX(wind_gust * 1.60934)::float as wind_gust,
|
||||||
|
(array_agg(datetime ORDER BY wind_gust DESC NULLS LAST))[1] as max_wind_gust_time,
|
||||||
AVG(wind_dir)::float as wind_dir,
|
AVG(wind_dir)::float as wind_dir,
|
||||||
SUM(rain)::float as total_rain
|
SUM(rain)::float as total_rain
|
||||||
FROM weather_data
|
FROM weather_data
|
||||||
|
|||||||
@@ -808,54 +808,56 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zeitformat basierend auf Zeitraum
|
|
||||||
const isCustomRange = typeof timeRange === 'object' && timeRange.type === 'custom'
|
const isCustomRange = typeof timeRange === 'object' && timeRange.type === 'custom'
|
||||||
const customDays = isCustomRange ? (timeRange.days || 1) : 0
|
const customDays = isCustomRange ? (timeRange.days || 1) : 0
|
||||||
let timeFormat = 'dd.MM HH:mm'
|
const is24h = timeRange === '24h' || (isCustomRange && customDays < 7)
|
||||||
|
const timeFormat = is24h ? 'HH:mm' : 'dd.MM HH:mm'
|
||||||
if (isCustomRange) {
|
|
||||||
timeFormat = customDays < 7 ? 'HH:mm' : 'dd.MM HH:mm'
|
// Gibt die anzuzeigende Zeit zurück: bei aggregierten Daten das spezifische *_time-Feld,
|
||||||
} else {
|
// bei Rohdaten (24h) das datetime des Datenpunkts selbst.
|
||||||
timeFormat = timeRange === '24h' ? 'HH:mm' : 'dd.MM HH:mm'
|
const itemTime = (item, timeField) => {
|
||||||
|
if (!item) return null
|
||||||
|
const raw = item[timeField] ?? item.datetime
|
||||||
|
return format(new Date(raw), timeFormat, { locale: de })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperatur
|
// Temperatur
|
||||||
const minTempItem = periodData.reduce((min, item) =>
|
const minTempItem = periodData.reduce((min, item) =>
|
||||||
item.temperature != null && (min === null || item.temperature < min.temperature) ? item : min, null)
|
item.temperature != null && (min === null || item.temperature < min.temperature) ? item : min, null)
|
||||||
const maxTempItem = periodData.reduce((max, item) =>
|
const maxTempItem = periodData.reduce((max, item) =>
|
||||||
item.temperature != null && (max === null || item.temperature > max.temperature) ? item : max, null)
|
item.temperature != null && (max === null || item.temperature > max.temperature) ? item : max, null)
|
||||||
|
|
||||||
// Luftfeuchtigkeit
|
// Luftfeuchtigkeit
|
||||||
const minHumidityItem = periodData.reduce((min, item) =>
|
const minHumidityItem = periodData.reduce((min, item) =>
|
||||||
item.humidity != null && (min === null || item.humidity < min.humidity) ? item : min, null)
|
item.humidity != null && (min === null || item.humidity < min.humidity) ? item : min, null)
|
||||||
const maxHumidityItem = periodData.reduce((max, item) =>
|
const maxHumidityItem = periodData.reduce((max, item) =>
|
||||||
item.humidity != null && (max === null || item.humidity > max.humidity) ? item : max, null)
|
item.humidity != null && (max === null || item.humidity > max.humidity) ? item : max, null)
|
||||||
|
|
||||||
// Luftdruck
|
// Luftdruck
|
||||||
const minPressureItem = periodData.reduce((min, item) =>
|
const minPressureItem = periodData.reduce((min, item) =>
|
||||||
item.pressure != null && (min === null || item.pressure < min.pressure) ? item : min, null)
|
item.pressure != null && (min === null || item.pressure < min.pressure) ? item : min, null)
|
||||||
const maxPressureItem = periodData.reduce((max, item) =>
|
const maxPressureItem = periodData.reduce((max, item) =>
|
||||||
item.pressure != null && (max === null || item.pressure > max.pressure) ? item : max, null)
|
item.pressure != null && (max === null || item.pressure > max.pressure) ? item : max, null)
|
||||||
|
|
||||||
// Windgeschwindigkeit
|
// Wind
|
||||||
const maxWindGustItem = periodData.reduce((max, item) =>
|
const maxWindGustItem = periodData.reduce((max, item) =>
|
||||||
item.wind_gust != null && (max === null || item.wind_gust > max.wind_gust) ? item : max, null)
|
item.wind_gust != null && (max === null || item.wind_gust > max.wind_gust) ? item : max, null)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
minTemp: minTempItem?.temperature ?? null,
|
minTemp: minTempItem?.temperature ?? null,
|
||||||
maxTemp: maxTempItem?.temperature ?? null,
|
maxTemp: maxTempItem?.temperature ?? null,
|
||||||
minTempTime: minTempItem ? format(new Date(minTempItem.datetime), timeFormat, { locale: de }) : null,
|
minTempTime: itemTime(minTempItem, 'min_temperature_time'),
|
||||||
maxTempTime: maxTempItem ? format(new Date(maxTempItem.datetime), timeFormat, { locale: de }) : null,
|
maxTempTime: itemTime(maxTempItem, 'max_temperature_time'),
|
||||||
minHumidity: minHumidityItem?.humidity ?? null,
|
minHumidity: minHumidityItem?.humidity ?? null,
|
||||||
maxHumidity: maxHumidityItem?.humidity ?? null,
|
maxHumidity: maxHumidityItem?.humidity ?? null,
|
||||||
minHumidityTime: minHumidityItem ? format(new Date(minHumidityItem.datetime), timeFormat, { locale: de }) : null,
|
minHumidityTime: itemTime(minHumidityItem, 'min_humidity_time'),
|
||||||
maxHumidityTime: maxHumidityItem ? format(new Date(maxHumidityItem.datetime), timeFormat, { locale: de }) : null,
|
maxHumidityTime: itemTime(maxHumidityItem, 'max_humidity_time'),
|
||||||
minPressure: minPressureItem?.pressure ?? null,
|
minPressure: minPressureItem?.pressure ?? null,
|
||||||
maxPressure: maxPressureItem?.pressure ?? null,
|
maxPressure: maxPressureItem?.pressure ?? null,
|
||||||
minPressureTime: minPressureItem ? format(new Date(minPressureItem.datetime), timeFormat, { locale: de }) : null,
|
minPressureTime: itemTime(minPressureItem, 'min_pressure_time'),
|
||||||
maxPressureTime: maxPressureItem ? format(new Date(maxPressureItem.datetime), timeFormat, { locale: de }) : null,
|
maxPressureTime: itemTime(maxPressureItem, 'max_pressure_time'),
|
||||||
maxWindGust: maxWindGustItem?.wind_gust ?? null,
|
maxWindGust: maxWindGustItem?.wind_gust ?? null,
|
||||||
maxWindGustTime: maxWindGustItem ? format(new Date(maxWindGustItem.datetime), timeFormat, { locale: de }) : null
|
maxWindGustTime: itemTime(maxWindGustItem, 'max_wind_gust_time'),
|
||||||
}
|
}
|
||||||
}, [sortedData, timeRange])
|
}, [sortedData, timeRange])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user