Skip to content

Commit

Permalink
Fix backwards compatibility of Vallum TimeSeries
Browse files Browse the repository at this point in the history
  • Loading branch information
Erikvv committed Jan 17, 2025
1 parent b884f5f commit 9fd1ee1
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ fun createMockSurvey(projectName: String = "Project") = Survey(
hourlyDelivery_m3 = TimeSeries(
type = TimeSeriesType.GAS_DELIVERY,
start = kotlinx.datetime.Instant.parse("2022-01-01T00:00:00+01"),
timeStep = DateTimeUnit.HOUR * 2,
timeStep = DateTimeUnit.HOUR,
values = floatArrayOf(1.2f, 2.2f, 3.2f, 4.2f),
)
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class SurveyRepositoryTest {
assertEquals(survey, storedSurvey)
val gasTimeStep = storedSurvey.addresses.single().gridConnections.single().naturalGas.hourlyDelivery_m3?.timeStep
assertNotNull(gasTimeStep)
assertEquals(2, gasTimeStep.toDuration().inWholeHours)
assertEquals(1, gasTimeStep.toDuration().inWholeHours)
}

@Test
Expand Down
25 changes: 24 additions & 1 deletion zummon/src/commonMain/kotlin/companysurvey/TimeSeries.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuid4
import com.zenmo.zummon.BenasherUuidSerializer
import kotlinx.datetime.*
import kotlinx.serialization.encodeToString
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlin.js.JsExport
import kotlin.math.roundToInt
import kotlin.reflect.typeOf
import kotlin.time.Duration
import kotlin.time.Duration.Companion.nanoseconds

Expand All @@ -30,6 +36,7 @@ data class TimeSeries (
* It would be easier to use [DateTimeUnit.TimeBased] or [Duration] instead of [DateTimeUnit]
* but then we would lose the ability to process month-based time series.
*/
@Serializable(with = BackwardCompatilbeDateTimeUnitSerializer::class)
val timeStep: DateTimeUnit = type.defaultStep(),
val unit: TimeSeriesUnit = type.defaultUnit(),
val values: FloatArray = floatArrayOf(),
Expand Down Expand Up @@ -259,6 +266,7 @@ fun DateTimeUnit.toDuration(): Duration = when (this) {
@JsExport
fun isoStringToDateTimeUnit(isoString: String): DateTimeUnit = when (isoString) {
"PT15M" -> DateTimeUnit.MINUTE * 15
"PT1H" -> DateTimeUnit.HOUR
"P1D" -> DateTimeUnit.DAY
"P1M" -> DateTimeUnit.MONTH
else -> throw Exception("Not implemented parsing iso string \"$isoString\"")
Expand All @@ -267,7 +275,22 @@ fun isoStringToDateTimeUnit(isoString: String): DateTimeUnit = when (isoString)
@JsExport
fun dateTimeUnitToIsoString(dateTimeUnit: DateTimeUnit): String = when (dateTimeUnit) {
DateTimeUnit.MINUTE * 15 -> "PT15M"
DateTimeUnit.HOUR -> "PT1H"
DateTimeUnit.DAY -> "P1D"
DateTimeUnit.MONTH -> "P1M"
else -> throw Exception("Not implemented creating iso string from ${dateTimeUnit}")
}

/**
* This makes serialization of DateTimeUnit backwards compatible with the previous format.
* The previous format was based on Duration.
*/
private class BackwardCompatilbeDateTimeUnitSerializer : KSerializer<DateTimeUnit> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlinx.datetime.DateTimeUnit", PrimitiveKind.STRING)

override fun serialize(encoder: Encoder, value: DateTimeUnit) {
encoder.encodeString(dateTimeUnitToIsoString(value))
}

override fun deserialize(decoder: Decoder): DateTimeUnit = isoStringToDateTimeUnit(decoder.decodeString())
}

0 comments on commit 9fd1ee1

Please sign in to comment.