66 lines
2.4 KiB
PHP
66 lines
2.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace Weerscherm;
|
||
|
||
/**
|
||
* Berekent regen vandaag, de 3 vorige dagen en het maandtotaal uit een Netatmo getmeasure-body
|
||
* (scale=1day, type=sum_rain, optimize=false): een map van unix-timestamp naar [mm].
|
||
*
|
||
* Elke timestamp wordt gekoppeld aan een lokale datum in de tijdzone van $now. Bij real_time=false
|
||
* liggen de timestamps van dagwaarden niet op middernacht, dus daar wordt niet van uitgegaan.
|
||
*/
|
||
final class RainCalculator
|
||
{
|
||
private const PREVIOUS_DAYS = 3;
|
||
|
||
/** 00:00 lokale tijd van min(1e van de maand, vandaag − 3 dagen). */
|
||
public static function dateBegin(\DateTimeImmutable $now): \DateTimeImmutable
|
||
{
|
||
$midnight = $now->setTime(0, 0, 0);
|
||
$firstOfMonth = $midnight->setDate((int) $now->format('Y'), (int) $now->format('n'), 1);
|
||
$threeDaysAgo = $midnight->modify('-' . self::PREVIOUS_DAYS . ' days');
|
||
|
||
return $firstOfMonth < $threeDaysAgo ? $firstOfMonth : $threeDaysAgo;
|
||
}
|
||
|
||
/**
|
||
* @param array<string|int, mixed> $body
|
||
* @return array{today: ?float, previous_days: list<array{date: string, mm: ?float}>, month_total: ?float}
|
||
*/
|
||
public static function compute(array $body, \DateTimeImmutable $now, ?float $sumRain24): array
|
||
{
|
||
$tz = $now->getTimezone();
|
||
$perDate = [];
|
||
foreach ($body as $timestamp => $values) {
|
||
if (!is_numeric($timestamp) || !is_array($values) || !isset($values[0]) || !is_numeric($values[0])) {
|
||
continue;
|
||
}
|
||
$date = (new \DateTimeImmutable('@' . (int) $timestamp))->setTimezone($tz)->format('Y-m-d');
|
||
$perDate[$date] = ($perDate[$date] ?? 0.0) + (float) $values[0];
|
||
}
|
||
|
||
$today = $now->format('Y-m-d');
|
||
$previous = [];
|
||
for ($i = self::PREVIOUS_DAYS; $i >= 1; $i--) {
|
||
$date = $now->modify("-$i days")->format('Y-m-d');
|
||
$previous[] = ['date' => $date, 'mm' => $perDate[$date] ?? null];
|
||
}
|
||
|
||
$monthPrefix = $now->format('Y-m') . '-';
|
||
$monthTotal = null;
|
||
foreach ($perDate as $date => $mm) {
|
||
if (str_starts_with($date, $monthPrefix) && $date <= $today) {
|
||
$monthTotal = ($monthTotal ?? 0.0) + $mm;
|
||
}
|
||
}
|
||
|
||
return [
|
||
'today' => $perDate[$today] ?? $sumRain24,
|
||
'previous_days' => $previous,
|
||
'month_total' => $monthTotal,
|
||
];
|
||
}
|
||
}
|