option('stale'); $email = $this->option('notify') ?: env('HEALTHCHECK_EMAIL'); $sms = $this->option('sms') ?: env('HEALTHCHECK_SMS'); $th = now()->subMinutes($stale); $problems = 0; foreach (Device::all() as $d) { $down = !$d->last_seen_at || $d->last_seen_at->lt($th); $prev = Cache::get("hc:d:{$d->id}", 'ok'); $new = $down ? 'down' : 'ok'; $this->line("$d->name: $new"); if ($new !== $prev) { $this->notify($d, $new, $email, $sms); Cache::put("hc:d:{$d->id}", $new, now()->addDays(30)); } $problems += $down ? 1 : 0; } return $problems > 0 ? 1 : 0; } private function notify(Device $d, string $state, ?string $email, ?string $sms): void { if ($state === 'down') { $subj = "[ALARM] Heizung {$d->name} offline"; $body = "'{$d->name}' seit ".($d->last_seen_at?->diffForHumans() ?? 'immer'). " keine Daten.\nLast seen: ".($d->last_seen_at?->toDateTimeString() ?? 'nie'); } else { $subj = "[OK] Heizung {$d->name} wieder online"; $body = "'{$d->name}' liefert wieder Daten.\nLast seen: ".$d->last_seen_at?->toDateTimeString(); } if ($email) $this->sendMail($email, $subj, $body); if ($sms) $this->sendSms($sms, $subj, $body); $this->warn("notify: $subj"); } private function sendMail(string $to, string $subj, string $body): void { try { Mail::raw($body, function ($m) use ($to, $subj) { $m->to($to)->subject($subj); }); } catch (\Throwable $e) { $this->error("Mail failed: ".$e->getMessage()); } } private function sendSms(string $number, string $subj, string $body): void { // mail2sms Gateway: subject=Nummer, body=Text try { Mail::raw(substr($subj.' '.$body, 0, 140), function ($m) use ($number) { $m->to('mail2sms@dimedtec.net')->subject($number); }); } catch (\Throwable $e) { $this->error("SMS failed: ".$e->getMessage()); } } }