feat: klein grafiekje van het temperatuurverloop van vandaag

In de lege ruimte rechts van de grote buitentemperatuur staat nu het
verloop van vandaag: onderschrift "Vandaag", de lijn, en tijdlabels op
hele uren met "nu" rechts. Geen y-as, want de laagste en hoogste waarde
van vandaag staan al onder de balk en dat is precies de schaal.

Het getal en het grafiekje staan in een flexrij, zodat het grafiekje de
resterende ruimte pakt en meebeweegt als het getal smaller of breder
wordt. Vlak na middernacht zijn er nog geen twee meetpunten; dan blijft
het blokje verborgen in plaats van een leeg kader te tonen.

Data uit een extra getmeasure (scale=30min, type=Temperature, op de
buitenmodule) vanaf middernacht lokale tijd, cache 15 minuten, in de
payload als outdoor_history: {points, stale} zodat een storing daar de
rest niet raakt. PressureHistory is generiek gemaakt tot MeasureSeries
met de naam van het waardeveld als parameter, in plaats van er een bijna
identieke tweede klasse naast te zetten. StationMapper geeft nu ook het
id van de buitenmodule door.

Onderweg gevonden: FixtureSource deed een modulo op een float, wat een
PHP-deprecation vóór de JSON in de response zette. Dat verklaart de
kapotte JSON die eerder in de browserconsole langskwam. Opgelost met
intdiv. Servicewerker naar v10.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-13 11:50:40 +02:00
co-authored by Claude Opus 5
parent 5058bb850d
commit 107978b265
20 changed files with 318 additions and 55 deletions
+20 -4
View File
@@ -60,17 +60,33 @@ final class NetatmoClient
/** @return array<string|int, mixed> timestamp => [hPa], per 30 minuten, van het basisstation */
public function getPressureHistory(string $deviceId, int $begin, int $end): array
{
$json = $this->apiGet('getmeasure', [
'device_id' => $deviceId,
return $this->measureSeries('Pressure', ['device_id' => $deviceId], $begin, $end);
}
/** @return array<string|int, mixed> timestamp => [°C], per 30 minuten, van de opgegeven module */
public function getTemperatureHistory(string $deviceId, string $moduleId, int $begin, int $end): array
{
return $this->measureSeries('Temperature', ['device_id' => $deviceId, 'module_id' => $moduleId], $begin, $end);
}
/**
* Eén meetreeks per 30 minuten ophalen. $target bevat device_id en eventueel module_id.
*
* @param array<string, string> $target
* @return array<string|int, mixed>
*/
private function measureSeries(string $type, array $target, int $begin, int $end): array
{
$json = $this->apiGet('getmeasure', $target + [
'scale' => '30min',
'type' => 'Pressure',
'type' => $type,
'date_begin' => $begin,
'date_end' => $end,
'optimize' => 'false',
'real_time' => 'false',
]);
if (!is_array($json['body'] ?? null)) {
throw new UpstreamException('getmeasure (Pressure): geen body in antwoord');
throw new UpstreamException("getmeasure ($type): geen body in antwoord");
}
return $json['body'];
}