Add weather summary

This commit is contained in:
2024-03-04 01:49:28 +00:00
parent 4aaa9064fb
commit d396ec785f
5 changed files with 197 additions and 0 deletions

View File

@@ -15,5 +15,6 @@ declare module 'vue' {
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
WeatherSummary: typeof import('./src/components/WeatherSummary.vue')['default']
} }
} }

View File

@@ -0,0 +1,161 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { useWeatherStore } from '@/stores/weatherStore';
import { subHours } from 'date-fns';
import { WeatherAggregates } from '@/models/weather/weather-aggregates';
const weatherAggregates = ref<WeatherAggregates | undefined>();
const weatherStore = useWeatherStore();
const end = new Date();
const start = subHours(end, 24);
weatherStore
.getReadingAggregate(start, end)
.then((newWeatherAggregates) => {
weatherAggregates.value = newWeatherAggregates;
});
</script>
<template>
<DashboardItem title="Weather Summary">
<div className="weather-summary">
<div v-if="!weatherAggregates">Loading...</div>
<table v-else>
<tbody>
<tr>
<th></th>
<th>Minimum</th>
<th>Average</th>
<th>Maximum</th>
</tr>
<tr>
<td class="weather-summary-header">Temperature</td>
<td>
{{
weatherAggregates!.temperature.min.toFixed(2)
}}°F
</td>
<td>
{{
weatherAggregates!.temperature.average.toFixed(
2
)
}}°F
</td>
<td>
{{
weatherAggregates!.temperature.max.toFixed(2)
}}°F
</td>
</tr>
<tr>
<td class="weather-summary-header">Humidity</td>
<td>
{{ weatherAggregates!.humidity.min.toFixed(2) }}%
</td>
<td>
{{
weatherAggregates!.humidity.average.toFixed(2)
}}%
</td>
<td>
{{ weatherAggregates!.humidity.max.toFixed(2) }}%
</td>
</tr>
<tr>
<td class="weather-summary-header">Pressure</td>
<td>
{{
(
weatherAggregates!.pressure.min /
33.864 /
100
).toFixed(2)
}}"
</td>
<td>
{{
(
weatherAggregates!.pressure.average /
33.864 /
100
).toFixed(2)
}}"
</td>
<td>
{{
(
weatherAggregates!.pressure.max /
33.864 /
100
).toFixed(2)
}}"
</td>
</tr>
<tr>
<td class="weather-summary-header">Light</td>
<td>
{{ weatherAggregates!.light.min.toFixed(2) }} lx
</td>
<td>
{{ weatherAggregates!.light.average.toFixed(2) }} lx
</td>
<td>
{{ weatherAggregates!.light.max.toFixed(2) }} lx
</td>
</tr>
<tr>
<td class="weather-summary-header">Wind Speed</td>
<td>
{{ weatherAggregates!.windSpeed.min.toFixed(2) }}
mph
</td>
<td>
{{
weatherAggregates!.windSpeed.average.toFixed(2)
}}
mph
</td>
<td>
{{ weatherAggregates!.windSpeed.max.toFixed(2) }}
mph
</td>
</tr>
<tr>
<td class="weather-summary-header">Wind Direction</td>
<td></td>
<td>
{{ weatherAggregates!.windDirectionAverage }}
</td>
<td></td>
</tr>
<tr>
<td class="weather-summary-header">Rain</td>
<td></td>
<td></td>
<td>{{ weatherAggregates!.rainTotal.toFixed(2) }}"</td>
</tr>
</tbody>
</table>
</div>
</DashboardItem>
</template>
<style scoped>
.weather-summary {
font-size: 14px;
padding: 6px 12px;
}
.weather-summary-header {
font-weight: 500;
text-align: right;
padding-right: 10px;
}
th {
padding-right: 30px;
}
</style>

View File

@@ -0,0 +1,15 @@
export interface WeatherAggregates {
humidity: WeatherAggregate;
temperature: WeatherAggregate;
pressure: WeatherAggregate;
light: WeatherAggregate;
windSpeed: WeatherAggregate;
windDirectionAverage: number;
rainTotal: number;
}
export interface WeatherAggregate {
min: number;
max: number;
average: number;
}

View File

@@ -19,6 +19,11 @@
<CurrentLaundryStatus></CurrentLaundryStatus> <CurrentLaundryStatus></CurrentLaundryStatus>
</v-col> </v-col>
</v-row> </v-row>
<v-row>
<v-col cols="4">
<WeatherSummary></WeatherSummary>
</v-col>
</v-row>
</v-container> </v-container>
</template> </template>

View File

@@ -6,6 +6,7 @@ import WeatherUpdate from '@/models/weather/weather-update';
import WeatherRecent from '@/models/weather/weather-recent'; import WeatherRecent from '@/models/weather/weather-recent';
import WeatherValueType from '@/models/weather/weather-value-type'; import WeatherValueType from '@/models/weather/weather-value-type';
import WeatherValueGrouped from '@/models/weather/weather-value-grouped'; import WeatherValueGrouped from '@/models/weather/weather-value-grouped';
import { WeatherAggregates } from '@/models/weather/weather-aggregates';
export const useWeatherStore = defineStore('weather', { export const useWeatherStore = defineStore('weather', {
state: () => { state: () => {
@@ -62,6 +63,20 @@ export const useWeatherStore = defineStore('weather', {
`/api/weather/readings/value-history-grouped?weatherValueType=${valueType}&start=${startString}&end=${endString}&bucketMinutes=${bucketMinutes}` `/api/weather/readings/value-history-grouped?weatherValueType=${valueType}&start=${startString}&end=${endString}&bucketMinutes=${bucketMinutes}`
); );
return response.data;
},
async getReadingAggregate(
start: Date,
end: Date
): Promise<WeatherAggregates | undefined> {
const startString = start.toISOString();
const endString = end.toISOString();
const response = await axios.get<WeatherAggregates>(
Environment.getUrlPrefix() +
`/api/weather/readings/aggregate?start=${startString}&end=${endString}`
);
return response.data; return response.data;
} }
} }