Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/main/kotlin/DateTimeUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.zenmo.timeseries

import java.time.Duration
import java.time.temporal.TemporalAmount

private const val SECONDS_IN_HOUR = 3600.0

internal fun TemporalAmount.hours(): Double = Duration.from(this).toSeconds() / SECONDS_IN_HOUR

internal fun TemporalAmount.multiplicateInverseHours(): Double {
return 1 / (this.hours())
}
4 changes: 4 additions & 0 deletions src/main/kotlin/TimeSeriesBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.zenmo.timeseries

import com.zenmo.timeseries.typed.ElectricityKwhTimeSeries
import com.zenmo.timeseries.typed.ElectricityTimeSeries
import com.zenmo.timeseries.untyped.ArrayTimeSeries
import com.zenmo.timeseries.untyped.TimeSeries
import com.zenmo.timeseries.untyped.TimeSeriesAccessor
Expand Down Expand Up @@ -34,6 +36,8 @@ class TimeSeriesBuilder {
}
}

fun buildElectricityKwhTimeSeries(): ElectricityTimeSeries = ElectricityKwhTimeSeries(build())

/**
* Start of the first interval of the [values].
* Must support arithmetic using the [step].
Expand Down
20 changes: 20 additions & 0 deletions src/main/kotlin/typed/ElectricityKwhTimeSeries.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.zenmo.timeseries.typed

import com.zenmo.timeseries.multiplicateInverseHours
import com.zenmo.timeseries.untyped.TimeSeries
import java.time.temporal.Temporal

/**
* A time series of electric energy backed by a raw time series of kWh.
* Can directly take the quarter-hourly values given by an electricity supplier.
*/
internal class ElectricityKwhTimeSeries(
internal val kwhTimeSeries: TimeSeries,
) : ElectricityTimeSeries {
override fun getKwh(intervalStart: Temporal): Double = kwhTimeSeries[intervalStart]

private val multiplicateInverseHours: Double = kwhTimeSeries.step.multiplicateInverseHours()

override fun getKw(intervalStart: Temporal): Double =
getKwh(intervalStart) * multiplicateInverseHours
}
3 changes: 3 additions & 0 deletions src/main/kotlin/typed/ElectricityTimeSeries.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.zenmo.timeseries.typed

interface ElectricityTimeSeries: EnergyTimeSeries, PowerTimeSeries
7 changes: 7 additions & 0 deletions src/main/kotlin/typed/EnergyTimeSeries.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.zenmo.timeseries.typed

import java.time.temporal.Temporal

interface EnergyTimeSeries {
fun getKwh(intervalStart: Temporal): Double
}
7 changes: 7 additions & 0 deletions src/main/kotlin/typed/PowerTimeSeries.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.zenmo.timeseries.typed

import java.time.temporal.Temporal

interface PowerTimeSeries {
fun getKw(intervalStart: Temporal): Double
}
2 changes: 1 addition & 1 deletion src/main/kotlin/untyped/ArrayTimeSeries.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ internal open class ArrayTimeSeries(
return result
}

fun size() = values.size
internal fun size() = values.size

fun toBuilder() = TimeSeriesBuilder().start(start).step(step).values(values)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.zenmo.timeseries.typed;

import com.zenmo.timeseries.untyped.TimeSeries;
import org.junit.jupiter.api.Test;

import java.time.Duration;
import java.time.Instant;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class ElectricityTimeSeriesTest {
@Test
void test() {
var start = Instant.parse("2025-01-01T00:00:00Z");
var electricityTimeSeries = TimeSeries.builder()
.values(new double[]{2.0, 3.0, 4.0})
.start(start)
.step(Duration.ofMinutes(15))
.buildElectricityKwhTimeSeries();

assertEquals(2.0, electricityTimeSeries.getKwh(start));
assertEquals(8.0, electricityTimeSeries.getKw(start));
assertEquals(3.0, electricityTimeSeries.getKwh(start.plus(Duration.ofMinutes(15))));
assertEquals(12.0, electricityTimeSeries.getKw(start.plus(Duration.ofMinutes(15))));
assertEquals(4.0, electricityTimeSeries.getKwh(start.plus(Duration.ofMinutes(30))));
assertEquals(16.0, electricityTimeSeries.getKw(start.plus(Duration.ofMinutes(30))));
assertThrows(IndexOutOfBoundsException.class, () -> electricityTimeSeries.getKwh(start.plus(Duration.ofMinutes(45))));
assertThrows(IndexOutOfBoundsException.class, () -> electricityTimeSeries.getKw(start.plus(Duration.ofMinutes(45))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.time.Instant;
import java.time.Period;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.util.stream.DoubleStream;

Expand Down