mirror of
https://github.com/KevinMidboe/brewPi.git
synced 2025-10-29 08:40:13 +00:00
DTO interfaces for API responses.
This commit is contained in:
@@ -1,22 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte';
|
||||||
import CardButton from "./CardButton.svelte";
|
import CardButton from './CardButton.svelte';
|
||||||
import Activity from "../icons/Activity.svelte";
|
import Activity from '../icons/Activity.svelte';
|
||||||
|
import { ISensorDTO } from '../interfaces/ISensorDTO';
|
||||||
|
import { IRelaysDTO } from '../interfaces/IRelaysDTO';
|
||||||
|
import { IStateDTO } from '../interfaces/IStateDTO';
|
||||||
|
|
||||||
export let inside;
|
export let inside: ISensorDTO;
|
||||||
export let outside;
|
export let outside: ISensorDTO;
|
||||||
|
export let relays: IRelaysDTO[] = [];
|
||||||
|
export let state: IStateDTO;
|
||||||
|
|
||||||
let loadedTime: number = new Date().getTime();
|
let loadedTime: number = new Date().getTime();
|
||||||
let currentTime: number = new Date().getTime();
|
let currentTime: number = new Date().getTime();
|
||||||
let autoReload = false;
|
let autoReload = false;
|
||||||
const currentGoal = 18.5;
|
|
||||||
|
|
||||||
function updateTime() {
|
function updateTime() {
|
||||||
currentTime = new Date().getTime();
|
currentTime = new Date().getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
function flipCard(): void {
|
function flipCard(): void {
|
||||||
console.log("flip-a-delphia")
|
console.log('flip-a-delphia');
|
||||||
|
}
|
||||||
|
|
||||||
|
function tempToStateClass(temp: number | undefined) {
|
||||||
|
if (temp === undefined || !!isNaN(temp)) return 'idle';
|
||||||
|
return Number(temp) > 14 ? 'heating' : 'cooling';
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => setInterval(updateTime, 1000));
|
onMount(() => setInterval(updateTime, 1000));
|
||||||
@@ -24,41 +33,47 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<h1>Fridge sensors</h1>
|
||||||
<CardButton>
|
<CardButton>
|
||||||
<Activity on:click={flipCard} />
|
<Activity on:click="{flipCard}" />
|
||||||
</CardButton>
|
</CardButton>
|
||||||
|
|
||||||
<h2>Current target temperature</h2>
|
<h2>Current target temperature</h2>
|
||||||
<div class="sensor-reading">
|
<div class="sensor-reading">
|
||||||
<div class="blue">
|
<div class="{state.state}">
|
||||||
<span class="value">{currentGoal}</span>
|
<span class="value">{state.goal}</span>
|
||||||
<span class="unit">°C</span>
|
<span class="unit">°C</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Inside temperature</h2>
|
|
||||||
<div class="sensor-reading">
|
|
||||||
<div class="blue">
|
|
||||||
<span class="value">{inside?.temperature}</span>
|
|
||||||
<span class="unit">{inside?.temperature_unit}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span class="value">{Math.floor(inside?.humidity)}</span>
|
<span class="value"></span>
|
||||||
|
<span class="unit">{state.state}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Inside frigde temperature</h2>
|
||||||
|
<div class="sensor-reading">
|
||||||
|
<div class="{tempToStateClass(inside?.temperature)}">
|
||||||
|
<span class="value">{inside?.temperature || 0}</span>
|
||||||
|
<span class="unit">{inside?.temperature_unit || '°C'}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="value">{Math.floor(inside?.humidity || 0)}</span>
|
||||||
<span class="unit">{inside?.humidity_unit || '%'}</span>
|
<span class="unit">{inside?.humidity_unit || '%'}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Outside temperature</h2>
|
<h2>Outside temperature</h2>
|
||||||
<div class="sensor-reading">
|
<div class="sensor-reading">
|
||||||
<div class="red">
|
<div class="{tempToStateClass(outside?.temperature)}">
|
||||||
<span class="value">{outside?.temperature}</span>
|
<span class="value">{outside?.temperature || 0}</span>
|
||||||
<span class="unit">{outside?.temperature_unit}</span>
|
<span class="unit">{outside?.temperature_unit || '°C'}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span class="value">{Math.floor(outside?.humidity)}</span>
|
<span class="value">{Math.floor(outside?.humidity || 0)}</span>
|
||||||
<span class="unit">{outside?.humidity_unit}</span>
|
<span class="unit">{outside?.humidity_unit || '%'}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -70,14 +85,16 @@
|
|||||||
|
|
||||||
<div class="button-timer">
|
<div class="button-timer">
|
||||||
<span>Updated {secondsSinceUpdate === 0 ? 'now' : secondsSinceUpdate + 's ago'}</span>
|
<span>Updated {secondsSinceUpdate === 0 ? 'now' : secondsSinceUpdate + 's ago'}</span>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss" module="scoped">
|
<style lang="scss" module="scoped">
|
||||||
@import '../../styles/media-queries.scss';
|
@import '../../styles/media-queries.scss';
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
@@ -92,6 +109,7 @@
|
|||||||
.sensor-reading {
|
.sensor-reading {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
margin-bottom: 1.75rem;
|
margin-bottom: 1.75rem;
|
||||||
|
|
||||||
font-size: 2.2rem;
|
font-size: 2.2rem;
|
||||||
@@ -117,13 +135,24 @@
|
|||||||
margin-left: 0.3rem;
|
margin-left: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red {
|
.info {
|
||||||
|
font-size: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heating {
|
||||||
color: var(--red);
|
color: var(--red);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blue {
|
.cooling {
|
||||||
color: var(--blue);
|
color: var(--blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.idle {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-timer {
|
.button-timer {
|
||||||
|
|||||||
17
src/lib/interfaces/IRelaysDTO.ts
Normal file
17
src/lib/interfaces/IRelaysDTO.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
enum Controls {
|
||||||
|
heating = 'heating',
|
||||||
|
cooling = 'cooling',
|
||||||
|
fan = 'fan',
|
||||||
|
lights = 'lights'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRelaysDTO {
|
||||||
|
controls: Controls;
|
||||||
|
pin: number;
|
||||||
|
state: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
IRelaysDTO,
|
||||||
|
Controls
|
||||||
|
}
|
||||||
19
src/lib/interfaces/ISensorDTO.ts
Normal file
19
src/lib/interfaces/ISensorDTO.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
enum Location {
|
||||||
|
inside = 'inside',
|
||||||
|
outside = 'outside'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISensorDTO {
|
||||||
|
location: Location;
|
||||||
|
temperature?: number
|
||||||
|
temperature_unit?: string
|
||||||
|
humidity?: number
|
||||||
|
humidity_unit?: string
|
||||||
|
pressure?: number
|
||||||
|
pressure_unit?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
ISensorDTO,
|
||||||
|
Location
|
||||||
|
}
|
||||||
15
src/lib/interfaces/IStateDTO.ts
Normal file
15
src/lib/interfaces/IStateDTO.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
enum State {
|
||||||
|
idle = 'idle',
|
||||||
|
cooling = 'cooling',
|
||||||
|
heating = 'heating'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IStateDTO {
|
||||||
|
goal: number;
|
||||||
|
state: State
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
IStateDTO,
|
||||||
|
State
|
||||||
|
}
|
||||||
@@ -1,34 +1,36 @@
|
|||||||
import { BREWLOGGER_HOST } from '$env/static/private';
|
import { BREWLOGGER_HOST } from '$env/static/private';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
import type { ISensorDTO } from '../lib/interfaces/ISensorDTO'
|
||||||
|
import { IRelaysDTO } from '../lib/interfaces/IRelaysDTO';
|
||||||
|
import { IStateDTO } from '../lib/interfaces/IStateDTO';
|
||||||
|
|
||||||
const sensorsUrl = `${BREWLOGGER_HOST}/api/sensors`;
|
const sensorsUrl = `${BREWLOGGER_HOST}/api/sensors`;
|
||||||
const relaysUrl = `${BREWLOGGER_HOST}/api/relays`;
|
const relaysUrl = `${BREWLOGGER_HOST}/api/relays`;
|
||||||
|
const stateUrl = `${BREWLOGGER_HOST}/api/regulator`;
|
||||||
|
|
||||||
async function getSensors() {
|
async function getFromEndpoint(endpoint: string) {
|
||||||
return fetch(sensorsUrl)
|
return fetch(endpoint)
|
||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
.then((response) => {
|
.catch((error) => {
|
||||||
return response?.sensors;
|
console.error('Failed to fetch endpoint:', endpoint);
|
||||||
});
|
console.error(error);
|
||||||
}
|
return null
|
||||||
|
|
||||||
async function getRelays() {
|
|
||||||
return fetch(relaysUrl)
|
|
||||||
.then((resp) => resp.json())
|
|
||||||
.then((response) => {
|
|
||||||
return response?.relays || [];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const load: PageServerLoad = async () => {
|
export const load: PageServerLoad = async () => {
|
||||||
const [sensors, relays] = await Promise.all([getSensors(), getRelays()]);
|
const [sensorsResp, relaysResp, stateResp] = await Promise.all([getFromEndpoint(sensorsUrl), getFromEndpoint(relaysUrl), getFromEndpoint(stateUrl)]);
|
||||||
|
const sensors: ISensorDTO[] = sensorsResp?.sensors || []
|
||||||
|
const relays: IRelaysDTO[] = relaysResp?.relays || []
|
||||||
|
const state: IStateDTO = stateResp
|
||||||
|
|
||||||
const inside = sensors.find((sensor) => sensor.location === 'inside');
|
const inside = sensors.find((sensor: ISensorDTO) => sensor.location === 'inside');
|
||||||
const outside = sensors.find((sensor) => sensor.location === 'outside');
|
const outside = sensors.find((sensor: ISensorDTO) => sensor.location === 'outside');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inside: inside || null,
|
inside: inside || null,
|
||||||
outside: outside || null,
|
outside: outside || null,
|
||||||
relays
|
relays,
|
||||||
|
state
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Logo from '../lib/components/Logo.svelte';
|
import Logo from '../lib/components/Logo.svelte';
|
||||||
import VerticalSensorDisplay from '../lib/components/VerticalSensorDisplay.svelte';
|
import VerticalSensorDisplay from '../lib/components/VerticalSensorDisplay.svelte';
|
||||||
// import Livestream from '$lib/components/Livestream.svelte'
|
|
||||||
import BrewProgress from '../lib/components/BrewProgress.svelte';
|
import BrewProgress from '../lib/components/BrewProgress.svelte';
|
||||||
import type { PageData } from './$types';
|
|
||||||
import RelayControls from '../lib/components/RelayControls.svelte';
|
import RelayControls from '../lib/components/RelayControls.svelte';
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
import type { IStateDTO } from '../lib/interfaces/IStateDTO';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
const { inside, outside, relays } = data;
|
const { inside, outside, relays } = data;
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="vertical-grid">
|
<div class="vertical-grid">
|
||||||
<BrewProgress />
|
<BrewProgress />
|
||||||
|
|
||||||
<VerticalSensorDisplay inside="{inside}" outside="{outside}" />
|
<VerticalSensorDisplay {inside} {outside} {relays} {state} />
|
||||||
|
|
||||||
<RelayControls relays="{relays}" />
|
<RelayControls relays="{relays}" />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user