refactor: centralize telemetry metadata formatting
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
package com.lingniu.ingest.api.event;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stable string formatting for metadata values shared across protocol mappers.
|
||||||
|
*/
|
||||||
|
public final class TelemetryMetadataValues {
|
||||||
|
|
||||||
|
private TelemetryMetadataValues() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String doubleValue(double value) {
|
||||||
|
if (!Double.isFinite(value)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String formatted = String.format(Locale.ROOT, "%.6f", value);
|
||||||
|
return formatted.indexOf('.') < 0
|
||||||
|
? formatted
|
||||||
|
: formatted.replaceAll("0+$", "").replaceAll("\\.$", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.lingniu.ingest.api.event;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class TelemetryMetadataValuesTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void formatsDoubleWithoutFloatingPointNoise() {
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(123456.70000000001)).isEqualTo("123456.7");
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(1234.5)).isEqualTo("1234.5");
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(1234.0)).isEqualTo("1234");
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(1.23456789)).isEqualTo("1.234568");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsNonFiniteDoubleValuesAsBlankMetadata() {
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(Double.NaN)).isEmpty();
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(Double.POSITIVE_INFINITY)).isEmpty();
|
||||||
|
assertThat(TelemetryMetadataValues.doubleValue(Double.NEGATIVE_INFINITY)).isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||||||
import com.lingniu.ingest.api.ProtocolId;
|
import com.lingniu.ingest.api.ProtocolId;
|
||||||
import com.lingniu.ingest.api.event.LocationPayload;
|
import com.lingniu.ingest.api.event.LocationPayload;
|
||||||
import com.lingniu.ingest.api.event.RealtimePayload;
|
import com.lingniu.ingest.api.event.RealtimePayload;
|
||||||
|
import com.lingniu.ingest.api.event.TelemetryMetadataValues;
|
||||||
import com.lingniu.ingest.api.event.VehicleEvent;
|
import com.lingniu.ingest.api.event.VehicleEvent;
|
||||||
import com.lingniu.ingest.api.spi.EventMapper;
|
import com.lingniu.ingest.api.spi.EventMapper;
|
||||||
import com.lingniu.ingest.identity.VehicleIdentity;
|
import com.lingniu.ingest.identity.VehicleIdentity;
|
||||||
@@ -16,7 +17,6 @@ import java.time.Instant;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public final class YutongEventMapper implements EventMapper<MqttPayload> {
|
|||||||
0, 0);
|
0, 0);
|
||||||
Map<String, String> locationMeta = mileage == null
|
Map<String, String> locationMeta = mileage == null
|
||||||
? meta
|
? meta
|
||||||
: withMeta(meta, "total_mileage_km", formatDouble(mileage));
|
: withMeta(meta, "total_mileage_km", TelemetryMetadataValues.doubleValue(mileage));
|
||||||
out.add(new VehicleEvent.Location(
|
out.add(new VehicleEvent.Location(
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
vin, ProtocolId.MQTT_YUTONG, payload.deviceTime(), ingestTime,
|
vin, ProtocolId.MQTT_YUTONG, payload.deviceTime(), ingestTime,
|
||||||
@@ -237,13 +237,6 @@ public final class YutongEventMapper implements EventMapper<MqttPayload> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatDouble(double value) {
|
|
||||||
String formatted = String.format(Locale.ROOT, "%.6f", value);
|
|
||||||
return formatted.indexOf('.') < 0
|
|
||||||
? formatted
|
|
||||||
: formatted.replaceAll("0+$", "").replaceAll("\\.$", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private record IdentityResolution(VehicleIdentity identity, String errorMessage) {
|
private record IdentityResolution(VehicleIdentity identity, String errorMessage) {
|
||||||
private static IdentityResolution ok(VehicleIdentity identity) {
|
private static IdentityResolution ok(VehicleIdentity identity) {
|
||||||
return new IdentityResolution(identity, null);
|
return new IdentityResolution(identity, null);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.lingniu.ingest.api.ProtocolId;
|
|||||||
import com.lingniu.ingest.api.event.AlarmPayload;
|
import com.lingniu.ingest.api.event.AlarmPayload;
|
||||||
import com.lingniu.ingest.api.event.LocationPayload;
|
import com.lingniu.ingest.api.event.LocationPayload;
|
||||||
import com.lingniu.ingest.api.event.RealtimePayload;
|
import com.lingniu.ingest.api.event.RealtimePayload;
|
||||||
|
import com.lingniu.ingest.api.event.TelemetryMetadataValues;
|
||||||
import com.lingniu.ingest.api.event.VehicleEvent;
|
import com.lingniu.ingest.api.event.VehicleEvent;
|
||||||
import com.lingniu.ingest.api.spi.EventMapper;
|
import com.lingniu.ingest.api.spi.EventMapper;
|
||||||
import com.lingniu.ingest.protocol.gb32960.model.CommandBody;
|
import com.lingniu.ingest.protocol.gb32960.model.CommandBody;
|
||||||
@@ -16,7 +17,6 @@ import java.time.Instant;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -166,7 +166,7 @@ public final class Gb32960EventMapper implements EventMapper<Gb32960Message> {
|
|||||||
v != null && v.speedKmh != null ? v.speedKmh : 0.0,
|
v != null && v.speedKmh != null ? v.speedKmh : 0.0,
|
||||||
0.0, 0, p.statusFlag);
|
0.0, 0, p.statusFlag);
|
||||||
Map<String, String> locationMeta = v != null && v.totalMileageKm != null
|
Map<String, String> locationMeta = v != null && v.totalMileageKm != null
|
||||||
? withMeta(meta, "total_mileage_km", formatDouble(v.totalMileageKm))
|
? withMeta(meta, "total_mileage_km", TelemetryMetadataValues.doubleValue(v.totalMileageKm))
|
||||||
: meta;
|
: meta;
|
||||||
out.add(new VehicleEvent.Location(
|
out.add(new VehicleEvent.Location(
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
@@ -341,10 +341,4 @@ public final class Gb32960EventMapper implements EventMapper<Gb32960Message> {
|
|||||||
return Map.copyOf(copy);
|
return Map.copyOf(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatDouble(double value) {
|
|
||||||
String formatted = String.format(Locale.ROOT, "%.6f", value);
|
|
||||||
return formatted.indexOf('.') < 0
|
|
||||||
? formatted
|
|
||||||
: formatted.replaceAll("0+$", "").replaceAll("\\.$", "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.lingniu.ingest.protocol.jt808.mapper;
|
|||||||
|
|
||||||
import com.lingniu.ingest.api.ProtocolId;
|
import com.lingniu.ingest.api.ProtocolId;
|
||||||
import com.lingniu.ingest.api.event.LocationPayload;
|
import com.lingniu.ingest.api.event.LocationPayload;
|
||||||
|
import com.lingniu.ingest.api.event.TelemetryMetadataValues;
|
||||||
import com.lingniu.ingest.api.event.VehicleEvent;
|
import com.lingniu.ingest.api.event.VehicleEvent;
|
||||||
import com.lingniu.ingest.api.spi.EventMapper;
|
import com.lingniu.ingest.api.spi.EventMapper;
|
||||||
import com.lingniu.ingest.identity.VehicleIdentity;
|
import com.lingniu.ingest.identity.VehicleIdentity;
|
||||||
@@ -287,7 +288,7 @@ public final class Jt808EventMapper implements EventMapper<Jt808Message> {
|
|||||||
copy.putAll(Jt808LocationAdditionalInfo.decode(loc.extensionItems()));
|
copy.putAll(Jt808LocationAdditionalInfo.decode(loc.extensionItems()));
|
||||||
Double totalMileageKm = totalMileageKm(loc);
|
Double totalMileageKm = totalMileageKm(loc);
|
||||||
if (totalMileageKm != null) {
|
if (totalMileageKm != null) {
|
||||||
copy.put("total_mileage_km", Double.toString(totalMileageKm));
|
copy.put("total_mileage_km", TelemetryMetadataValues.doubleValue(totalMileageKm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Map.copyOf(copy);
|
return Map.copyOf(copy);
|
||||||
|
|||||||
Reference in New Issue
Block a user