Switched from influx to victoria metrics (more light weight for pi)

This commit is contained in:
2026-06-26 23:58:32 -04:00
parent 0c0ebfd20b
commit 6eefd1b86b
3 changed files with 168 additions and 282 deletions

View File

@@ -1,7 +1,7 @@
import {cfg} from './config.mjs';
async function query(c, q, start, end) {
const url = new URL('/api/v1/query_range', c.INFLUX_URL);
const url = new URL('/api/v1/query_range', c.VM_URL);
url.searchParams.set('query', q);
url.searchParams.set('step', '60s');
if (start) url.searchParams.set('start', start);
@@ -12,7 +12,7 @@ async function query(c, q, start, end) {
}
async function queryInstant(c, q) {
const url = new URL('/api/v1/query', c.INFLUX_URL);
const url = new URL('/api/v1/query', c.VM_URL);
url.searchParams.set('query', q);
const res = await fetch(url);
const json = await res.json();
@@ -22,22 +22,16 @@ async function queryInstant(c, q) {
function metricToFields(results) {
const out = {};
for (const r of results) {
const field = r.metric.__name__ || r.metric.field;
const val = r.value?.[1] ?? r.values?.at(-1)?.[1];
if (val !== undefined) out[field] = parseFloat(val);
const val = r.value?.[1] ?? r.values?.at(-1)?.[1];
if (val !== undefined) out[r.metric.__name__] = parseFloat(val);
}
return out;
}
// vm.mjs
export async function queryCurrent() {
const c = cfg();
const out = {time: new Date()};
// Query all metrics at once, no measurement filter needed
const c = cfg();
const results = await queryInstant(c, `{__name__!=""}`);
Object.assign(out, metricToFields(results));
return out;
return {time: new Date(), ...metricToFields(results)};
}
export async function queryHourly(start, end) {
@@ -48,11 +42,10 @@ export async function queryHourly(start, end) {
const results = await query(c, `avg_over_time({__name__!=""}[1h])`, s, e);
results.forEach(r => {
const field = r.metric.__name__;
r.values.forEach(([ts, val]) => {
const time = new Date(ts * 1000).toISOString().slice(0, 13) + ':00';
if (!byTime[time]) byTime[time] = {time};
byTime[time][field] = parseFloat(val);
byTime[time][r.metric.__name__] = parseFloat(val);
});
});
return Object.values(byTime).sort((a, b) => a.time.localeCompare(b.time));
@@ -78,24 +71,30 @@ export async function queryDaily(start, end) {
});
});
const applyMinMax = (results, suffix) => results.forEach(r => {
mins.forEach(r => {
if (r.metric.__name__ !== 'temperature') return;
r.values.forEach(([ts, val]) => {
const time = new Date(ts * 1000).toISOString().slice(0, 10);
if (!byTime[time]) byTime[time] = {time};
byTime[time][suffix] = parseFloat(val);
byTime[time].env_temp_min_c = parseFloat(val);
});
});
applyMinMax(mins, 'env_temp_min_c');
applyMinMax(maxs, 'env_temp_max_c');
maxs.forEach(r => {
if (r.metric.__name__ !== 'temperature') return;
r.values.forEach(([ts, val]) => {
const time = new Date(ts * 1000).toISOString().slice(0, 10);
if (!byTime[time]) byTime[time] = {time};
byTime[time].env_temp_max_c = parseFloat(val);
});
});
return Object.values(byTime).sort((a, b) => a.time.localeCompare(b.time));
}
export async function getCoords() {
const c = cfg();
const results = await queryInstant(c, `{measurement="gps"}`);
const results = await queryInstant(c, `{__name__=~"latitude|longitude|altitude"}`);
const fields = metricToFields(results);
if (fields.latitude && fields.longitude) {

View File

@@ -2,7 +2,7 @@ import express from 'express';
import {resolve, dirname} from 'path';
import {fileURLToPath} from 'url';
import {cfg, localDateStr} from './config.mjs';
import {queryCurrent, queryHourly, queryDaily, getCoords} from './influx.mjs';
import {queryCurrent, queryHourly, queryDaily, getCoords} from './sensors.mjs';
import {getCelestialCurrent, getCelestialForecast} from './celestial.mjs';
import {apiReference} from '@scalar/express-api-reference';
import {spec} from './spec.mjs';
@@ -12,7 +12,6 @@ import {getADSB, getADSBHistory, getADSBRange, initAircraftDb} from './adsb.mjs'
import {fetchIcon, getWeatherCondition} from './openweather.mjs';
import {lastForecast, getForecast, forecastTTL} from './forecast.mjs';
import {dailyWeather, hourlyWeather} from './openmeteo.mjs';
// import {Aurora} from './aurora.mjs';
// ── Uncaught error handlers ───────────────────────────────────────────────────