0 && $emsAge > (int)($state['emsWatchdogSeconds'] ?? 120)) { $warnings[] = 'EMS watchdog expired'; $safePowerW = $this->safePower($state); } $heartbeatAge = $now - (int)($state['lastOcppHeartbeat'] ?? 0); if (($state['ocppOnline'] ?? false) && ($state['lastOcppHeartbeat'] ?? 0) > 0 && $heartbeatAge > (int)($state['ocppHeartbeatTimeoutSeconds'] ?? 90)) { $warnings[] = 'OCPP heartbeat timeout'; $blockingReason = 'OCPP timeout'; } if (($state['criticalFault'] ?? false) === true) { $warnings[] = 'Critical fault'; $blockingReason = 'Critical fault'; $safePowerW = 0; } return [ 'warnings' => $warnings, 'blockingReason' => $blockingReason, 'safePowerW' => $safePowerW ]; } private function safePower(array $state): int { $strategy = (string)($state['safeOffStrategy'] ?? 'SafeCurrent'); if ($strategy === '0A' || $strategy === 'Unavailable') { return 0; } $phases = PhaseManager::normalizePhaseCount((int)($state['numberPhases'] ?? 3)); $safeCurrent = (float)($state['safeCurrentA'] ?? 6.0); return PhaseManager::wattsFromCurrent($safeCurrent, $phases); } } ?>