/graph API endpoint for proxy to elastic, all use this endpoint or lib/server functions to get data

This commit is contained in:
2023-05-30 17:23:58 +02:00
parent 9824421b34
commit 8526b0e552
5 changed files with 111 additions and 101 deletions

View File

@@ -83,8 +83,8 @@ function buildQuery(field: String, from: Date, to: Date, interval: String) {
{ {
range: { range: {
'@timestamp': { '@timestamp': {
gte: toDateString, gte: fromDateString,
lte: fromDateString, lte: toDateString,
format: 'strict_date_optional_time' format: 'strict_date_optional_time'
} }
} }
@@ -138,7 +138,7 @@ function calculateInterval(from, to, interval, size) {
if (interval !== 'auto') { if (interval !== 'auto') {
return interval; return interval;
} }
const dateMathInterval = roundInterval((from - to) / size); const dateMathInterval = roundInterval((to - from) / size);
// const dateMathIntervalMs = toMS(dateMathInterval); // const dateMathIntervalMs = toMS(dateMathInterval);
// const minMs = toMS(min); // const minMs = toMS(min);
// if (dateMathIntervalMs !== undefined && minMs !== undefined && dateMathIntervalMs < minMs) { // if (dateMathIntervalMs !== undefined && minMs !== undefined && dateMathIntervalMs < minMs) {
@@ -148,6 +148,7 @@ function calculateInterval(from, to, interval, size) {
} }
function parseTempResponse(data: IESTelemetry): IChartFrame[] { function parseTempResponse(data: IESTelemetry): IChartFrame[] {
console.log('got temp response:', data);
return data?.aggregations?.data?.buckets.map((bucket) => { return data?.aggregations?.data?.buckets.map((bucket) => {
return { return {
value: bucket?.maxValue?.value, value: bucket?.maxValue?.value,
@@ -161,12 +162,7 @@ function parseLatestResponse(data: IESTelemetry) {
return data?.hits?.hits[0]?._source; return data?.hits?.hits[0]?._source;
} }
export function fetchTemperature( export function fetchTemperature(from: Date, to: Date, size: number = 50): Promise<IChartFrame[]> {
from: Date,
to: Date,
size: number = 50,
fetch: Function
): Promise<IChartFrame[]> {
const fromMS = from.getTime(); const fromMS = from.getTime();
const toMS = to.getTime(); const toMS = to.getTime();
const interval = calculateInterval(fromMS, toMS, 'auto', size); const interval = calculateInterval(fromMS, toMS, 'auto', size);
@@ -181,18 +177,14 @@ export function fetchTemperature(
}, },
body: JSON.stringify(esSearchQuery) body: JSON.stringify(esSearchQuery)
}; };
console.log('temp options:', options);
return fetch(TELEMETRY_ENDPOINT, options) return fetch(TELEMETRY_ENDPOINT, options)
.then((resp) => resp.json()) .then((resp) => resp.json())
.then(parseTempResponse); .then(parseTempResponse);
} }
export function fetchHumidity( export function fetchHumidity(from: Date, to: Date, size: number = 50): Promise<IChartFrame[]> {
from: Date,
to: Date,
size: number = 50,
fetch: Function
): Promise<IChartFrame[]> {
const fromMS = from.getTime(); const fromMS = from.getTime();
const toMS = to.getTime(); const toMS = to.getTime();
const interval = calculateInterval(fromMS, toMS, 'auto', size); const interval = calculateInterval(fromMS, toMS, 'auto', size);
@@ -213,12 +205,7 @@ export function fetchHumidity(
.then(parseTempResponse); .then(parseTempResponse);
} }
export function fetchPressure( export function fetchPressure(from: Date, to: Date, size: number = 50): Promise<IChartFrame[]> {
from: Date,
to: Date,
size: number = 50,
fetch: Function
): Promise<IChartFrame[]> {
const fromMS = from.getTime(); const fromMS = from.getTime();
const toMS = to.getTime(); const toMS = to.getTime();
const interval = calculateInterval(fromMS, toMS, 'auto', size); const interval = calculateInterval(fromMS, toMS, 'auto', size);

View File

@@ -1,7 +1,5 @@
import { getLatestInsideReadings, getLatestOutsideReadings } from '$lib/graphQueryGenerator';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
let DEFAULT_MINUTES = 14400;
const host = 'http://brewpi.schleppe:5000'; const host = 'http://brewpi.schleppe:5000';
const sensorsUrl = `${host}/api/sensors`; const sensorsUrl = `${host}/api/sensors`;
const relaysUrl = `${host}/api/relays`; const relaysUrl = `${host}/api/relays`;
@@ -24,8 +22,6 @@ async function getRelays() {
export const load: PageServerLoad = async () => { export const load: PageServerLoad = async () => {
const [sensors, relays] = await Promise.all([getSensors(), getRelays()]); const [sensors, relays] = await Promise.all([getSensors(), getRelays()]);
console.log('got sensors and relays');
console.log(sensors, relays);
const inside = sensors.find((sensor) => sensor.location === 'inside'); const inside = sensors.find((sensor) => sensor.location === 'inside');
const outside = sensors.find((sensor) => sensor.location === 'outside'); const outside = sensors.find((sensor) => sensor.location === 'outside');

View File

@@ -0,0 +1,39 @@
import { json, RequestEvent } from '@sveltejs/kit';
import {
fetchTemperature,
fetchHumidity,
fetchPressure
} from '../../../../lib/server/graphQueryGenerator';
import type { RequestHandler } from './$types';
const UNITS = ['temperature', 'humidity', 'pressure'];
const UNITS_STRING = UNITS.join(', ');
export const POST = (async (event: RequestEvent) => {
const { request, params } = event;
const { unit } = params;
if (!unit || UNITS.indexOf(unit) == -1) {
return json({
success: false,
message: `Unit ${unit} not found. Choose from: ${UNITS_STRING}`
});
}
const bodyData = await request.json();
let data;
let { from, to } = bodyData;
const { size } = bodyData;
from = new Date(from);
to = new Date(to);
if (unit === 'temperature') {
data = await fetchTemperature(from, to, size);
} else if (unit === 'humidity') {
data = await fetchHumidity(from, to, size);
} else if (unit === 'pressure') {
data = await fetchPressure(from, to, size);
}
return json({ success: true, data });
}) satisfies RequestHandler;

View File

@@ -1,13 +1,21 @@
import { fetchTemperature, fetchHumidity, fetchPressure } from '$lib/graphQueryGenerator'; import {
fetchTemperature,
fetchHumidity,
fetchPressure
} from '../../lib/server/graphQueryGenerator';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
import type IChartFrame from '$lib/interfaces/IChartFrame'; import type IChartFrame from '../../lib/interfaces/IChartFrame';
let DEFAULT_MINUTES = 10080; const DEFAULT_MINUTES = 10080;
export const load: PageServerLoad = async ({ fetch }) => { export const load: PageServerLoad = async ({ fetch }) => {
const temperatureData: IChartFrame[] = await getTemp(DEFAULT_MINUTES, fetch); const to = new Date();
const humidityData: IChartFrame[] = await getHumidity(DEFAULT_MINUTES, fetch); const from = new Date(to.getTime() - DEFAULT_MINUTES * 60 * 1000);
const pressureData: IChartFrame[] = await getPressure(DEFAULT_MINUTES, fetch); const size = 40;
const temperatureData: IChartFrame[] = await fetchTemperature(from, to, size);
const humidityData: IChartFrame[] = await fetchHumidity(from, to, size);
const pressureData: IChartFrame[] = await fetchPressure(from, to, size);
return { return {
temperatureData, temperatureData,
@@ -16,23 +24,3 @@ export const load: PageServerLoad = async ({ fetch }) => {
DEFAULT_MINUTES DEFAULT_MINUTES
}; };
}; };
function getSensor(func: Function, minutes: number, fetch: Function) {
const from: Date = new Date();
const to = new Date(from.getTime() - minutes * 60 * 1000);
const size = 40;
return func(from, to, size, fetch);
}
function getTemp(minutes: number, fetch: Function): IChartFrame[] {
return getSensor(fetchTemperature, minutes, fetch);
}
function getHumidity(minutes: number, fetch: Function): IChartFrame[] {
return getSensor(fetchHumidity, minutes, fetch);
}
function getPressure(minutes: number, fetch: Function): IChartFrame[] {
return getSensor(fetchPressure, minutes, fetch);
}

View File

@@ -1,55 +1,48 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { fetchTemperature, fetchHumidity, fetchPressure } from '$lib/graphQueryGenerator'; import Graph from '../../lib/components/Graph.svelte';
import Graph from '$lib/components/Graph.svelte'; import type IChartFrame from '../../lib/interfaces/IChartFrame';
import type IChartFrame from '$lib/interfaces/IChartFrame';
import type { PageData } from './$types'; import type { PageData } from './$types';
export let data: PageData export let data: PageData;
let temperatureData: IChartFrame[] = data?.temperatureData; let temperatureData: IChartFrame[] = data?.temperatureData;
let humidityData: IChartFrame[] = data?.temperatureData; let humidityData: IChartFrame[] = data?.humidityData;
let pressureData: IChartFrame[] = data?.temperatureData; let pressureData: IChartFrame[] = data?.pressureData;
let DEFAULT_MINUTES: number = data?.DEFAULT_MINUTES let DEFAULT_MINUTES: number = data?.DEFAULT_MINUTES;
let minutes: number = DEFAULT_MINUTES; let minutes: number = DEFAULT_MINUTES;
const buttonMinutes = [{ async function fetchData(unit: string, from: Date, to: Date, size: number) {
value: 15, const options = {
name: 'Last 15 minutes' method: 'POST',
}, { body: JSON.stringify({ from, to, size })
value: 60, };
name: 'Last hour'
}, { return fetch(`/api/graph/${unit}`, options).then((resp) => resp.json());
value: 1440, }
name: 'Last day'
}, { const buttonMinutes = [
value: 10080, { value: 15, name: 'Last 15 minutes' },
name: 'Last week' { value: 60, name: 'Last hour' },
}, { { value: 360, name: 'Last 6 hours' },
value: 43200, { value: 1440, name: 'Last day' },
name: 'Last month' { value: 10080, name: 'Last week' },
}, { { value: 43200, name: 'Last month' },
value: 129600, { value: 129600, name: 'Last 3 months' },
name: 'Last 3 months' { value: 259200, name: 'Last 6 months' },
}, { { value: 518400, name: 'Last year' }
value: 259200, ];
name: 'Last 6 months'
}, {
value: 518400,
name: 'Last year',
}]
function reload(mins: number) { function reload(mins: number) {
minutes = mins minutes = mins;
const from: Date = new Date(); const to: Date = new Date();
const to = new Date(from.getTime() - minutes * 60 * 1000); const from = new Date(to.getTime() - minutes * 60 * 1000);
const size = 40; const size = 40;
fetchTemperature(from, to, size, window.fetch).then((resp) => (temperatureData = resp)); fetchData('temperature', from, to, size).then((resp) => (temperatureData = resp?.data));
fetchHumidity(from, to, size, window.fetch).then((resp) => (humidityData = resp)); fetchData('humidity', from, to, size).then((resp) => (humidityData = resp?.data));
fetchPressure(from, to, size, window.fetch).then((resp) => (pressureData = resp)); fetchData('pressure', from, to, size).then((resp) => (pressureData = resp?.data));
} }
</script>
<!-- <h1>Server: {emoji.emoji}</h1> --> <!-- <h1>Server: {emoji.emoji}</h1> -->
@@ -57,24 +50,27 @@
<div class="button-wrapper"> <div class="button-wrapper">
{#each buttonMinutes as button} {#each buttonMinutes as button}
<button on:click={() => reload(button.value)} class="{button.value === minutes ? 'selected' : ''}">{ button.name }</button> <button
on:click="{() => reload(button.value)}"
class="{button.value === minutes ? 'selected' : ''}">{button.name}</button
>
{/each} {/each}
</div> </div>
<section class="graphs"> <section class="graphs">
{#if temperatureData} {#if temperatureData}
<div class="graphWrapper"> <div class="card">
<Graph dataFrames={temperatureData} name="Temperature" /> <Graph dataFrames="{temperatureData}" name="Temperature" />
</div> </div>
{/if} {/if}
{#if humidityData} {#if humidityData}
<div class="graphWrapper"> <div class="card">
<Graph dataFrames={humidityData} name="Humidity" beginAtZero={false} /> <Graph dataFrames="{humidityData}" name="Humidity" />
</div> </div>
{/if} {/if}
{#if pressureData} {#if pressureData}
<div class="graphWrapper"> <div class="card">
<Graph dataFrames={pressureData} name="Pressure" beginAtZero={false} /> <Graph dataFrames="{pressureData}" name="Pressure" />
</div> </div>
{/if} {/if}
</section> </section>
@@ -89,17 +85,21 @@
width: 100%; width: 100%;
@include mobile { @include mobile {
grid-template-columns: 1fr; display: block;
> *:not(*:first-child) {
margin-top: 1rem;
}
} }
.graphWrapper { .card {
max-width: 100vw; padding: 1rem;
} }
} }
.button-wrapper { .button-wrapper {
display: flex; display: flex;
width: min-content; margin: 1rem 0;
overflow-y: scroll;
} }
button { button {