null, 'powerExportW' => null, 'energyImportWh' => null, 'energyExportWh' => null, 'currentA' => [1 => null, 2 => null, 3 => null], 'voltageV' => [1 => null, 2 => null, 3 => null], 'powerPhaseW' => [1 => null, 2 => null, 3 => null], 'soc' => null, 'temperature' => null, 'quality' => 'OCPP-MeterValue', 'timestamp' => time() ]; foreach ($this->extractSamples($payload) as $sample) { $measurand = (string)($sample['measurand'] ?? 'Energy.Active.Import.Register'); $value = $this->normalizeValue($sample); $phase = $this->phaseIndex((string)($sample['phase'] ?? '')); switch ($measurand) { case 'Power.Active.Import': $this->writePower($result, 'powerImportW', $value, $phase); break; case 'Power.Active.Export': $this->writePower($result, 'powerExportW', $value, $phase); break; case 'Energy.Active.Import.Register': case 'Energy.Active.Import.Interval': $result['energyImportWh'] = $value; break; case 'Energy.Active.Export.Register': case 'Energy.Active.Export.Interval': $result['energyExportWh'] = $value; break; case 'Current.Import': if ($phase > 0) { $result['currentA'][$phase] = $value; } break; case 'Voltage': if ($phase > 0) { $result['voltageV'][$phase] = $value; } break; case 'SoC': $result['soc'] = $value; break; case 'Temperature': $result['temperature'] = $value; break; } if (isset($sample['timestamp'])) { $ts = strtotime((string)$sample['timestamp']); if ($ts !== false) { $result['timestamp'] = $ts; } } } if ($result['powerImportW'] === null) { $result['powerImportW'] = $this->sumPhases($result['powerPhaseW']); } return $result; } private function extractSamples(array $payload): array { $samples = []; $containers = $payload['meterValue'] ?? $payload['meterValues'] ?? [$payload]; if (!is_array($containers)) { return []; } foreach ($containers as $container) { if (!is_array($container)) { continue; } $timestamp = $container['timestamp'] ?? null; $sampled = $container['sampledValue'] ?? $container['sampledValues'] ?? []; if (!is_array($sampled)) { continue; } foreach ($sampled as $sample) { if (!is_array($sample)) { continue; } if ($timestamp !== null && !isset($sample['timestamp'])) { $sample['timestamp'] = $timestamp; } $samples[] = $sample; } } return $samples; } private function normalizeValue(array $sample): float { $rawValue = $sample['value'] ?? 0; if (is_array($rawValue)) { $rawValue = $rawValue['value'] ?? 0; } $value = (float)$rawValue; $unit = $sample['unit'] ?? ($sample['unitOfMeasure']['unit'] ?? ''); $unit = strtolower((string)$unit); if ($unit === 'kwh') { return $value * 1000.0; } if ($unit === 'kw') { return $value * 1000.0; } return $value; } private function phaseIndex(string $phase): int { if (stripos($phase, 'L1') !== false) { return 1; } if (stripos($phase, 'L2') !== false) { return 2; } if (stripos($phase, 'L3') !== false) { return 3; } return 0; } private function writePower(array &$result, string $key, float $value, int $phase): void { if ($phase > 0) { $result['powerPhaseW'][$phase] = $value; return; } $result[$key] = $value; } private function sumPhases(array $values): ?float { $sum = 0.0; $found = false; foreach ($values as $value) { if ($value !== null) { $sum += (float)$value; $found = true; } } return $found ? $sum : null; } } ?>