Files
Symcon_Belevo_Energiemanage…/Ladestation_OCPP/libs/MeterValueNormalizer.php
T

162 lines
4.9 KiB
PHP

<?php
class MeterValueNormalizer
{
public function normalize(array $payload): array
{
$result = [
'powerImportW' => 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;
}
}
?>