From 038da0856ee41163d4c83a25e325cbd608cc6bf8 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Fri, 28 Jan 2022 23:38:26 +0100 Subject: [PATCH] OSM: Implement output power parsing --- .../api/openstreetmap/OpenStreetMapModel.kt | 27 +++++++++++++++++-- .../openstreetmap/OpenStreetMapModelTest.kt | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModel.kt b/app/src/main/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModel.kt index 69dfda00..d2801a6b 100644 --- a/app/src/main/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModel.kt +++ b/app/src/main/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModel.kt @@ -135,9 +135,9 @@ data class OSMChargingStation( } if (count > 0) { if (socket.evmapKey != null) { - chargepoints.add(Chargepoint(socket.evmapKey, null, count)) + val outputPower = parseOutputPower(this.tags["${socket.osmSocketBaseTag()}:output"]) + chargepoints.add(Chargepoint(socket.evmapKey, outputPower, count)) } - // TODO: Power parsing } } return chargepoints @@ -162,4 +162,27 @@ data class OSMChargingStation( // we could implement an "open now" feature. return null } + + companion object { + /** + * Parse raw OSM output power. + * + * The proper format to map output power for an EV charging station is " kW", + * for example "22 kW" or "3.7 kW". Some fields in the wild are tagged with the unit "kVA" + * instead of "kW", those can be treated as equivalent. + * + * Sometimes people also mapped plain numbers (e.g. 7000, I assume that's 7 kW), + * ranges (5,5 - 11 kW, huh?) or even current (32 A), which is wrong. If we cannot parse, + * just ignore the field. + */ + fun parseOutputPower(rawOutput: String?): Double? { + if (rawOutput == null) { + return null; + } + val pattern = Regex("([0-9.,]+)\\s*(kW|kVA)", setOf(RegexOption.IGNORE_CASE)) + val matchResult = pattern.matchEntire(rawOutput) ?: return null + val numberString = matchResult.groupValues[1].replace(',', '.') + return numberString.toDoubleOrNull() + } + } } \ No newline at end of file diff --git a/app/src/test/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModelTest.kt b/app/src/test/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModelTest.kt index 979b0acf..0fd888cc 100644 --- a/app/src/test/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModelTest.kt +++ b/app/src/test/java/net/vonforst/evmap/api/openstreetmap/OpenStreetMapModelTest.kt @@ -4,6 +4,7 @@ import com.squareup.moshi.Moshi import net.vonforst.evmap.api.openchargemap.ZonedDateTimeAdapter import net.vonforst.evmap.model.Chargepoint import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.junit.Test import java.time.Instant import java.time.Month @@ -80,7 +81,33 @@ class OpenStreetMapModelTest { val type2 = chargeLocation.chargepoints.single { it.type == Chargepoint.TYPE_2_SOCKET } val chademo = chargeLocation.chargepoints.single { it.type == Chargepoint.CHADEMO } assertEquals(2, ccs.count) + assertEquals(150.0, ccs.power) assertEquals(1, type2.count) + assertEquals(22.0, type2.power) assertEquals(2, chademo.count) + assertEquals(60.0, chademo.power) + } + + @Test + fun parseOutputPower() { + // Null input -> null output + assertNull(OSMChargingStation.parseOutputPower(null)) + + // Invalid input -> null output + assertNull(OSMChargingStation.parseOutputPower("")) + assertNull(OSMChargingStation.parseOutputPower("a")) + assertNull(OSMChargingStation.parseOutputPower("22 A")) + + // Invalid number -> null output + assertNull(OSMChargingStation.parseOutputPower("22.0.1 kW")) + + // Valid output power values + assertEquals(22.0, OSMChargingStation.parseOutputPower("22 kW")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22 kVA")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22. kW")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22.0 kW")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22,0 kW")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22kW")) + assertEquals(22.0, OSMChargingStation.parseOutputPower("22 kW")) } } \ No newline at end of file