mirror of
https://github.com/ckaczor/HomeMonitor.git
synced 2026-01-14 01:25:38 -05:00
Add weather summary
This commit is contained in:
1
WebDisplay/components.d.ts
vendored
1
WebDisplay/components.d.ts
vendored
@@ -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']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
161
WebDisplay/src/components/WeatherSummary.vue
Normal file
161
WebDisplay/src/components/WeatherSummary.vue
Normal 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>
|
||||||
15
WebDisplay/src/models/weather/weather-aggregates.ts
Normal file
15
WebDisplay/src/models/weather/weather-aggregates.ts
Normal 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;
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user