Skip to content

Commit c4e13b6

Browse files
committed
Add voltage and current units
Signed-off-by: Geert Mulders <gmulders@gmail.com>
1 parent 2734c78 commit c4e13b6

5 files changed

Lines changed: 60 additions & 40 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,4 @@ Please read [SUPPORT](SUPPORT.md) for how to connect and get into contact with t
6363
[github:create-from-template]: https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/creating-a-repository-from-a-template
6464
[kotlin]: https://kotlinlang.org/
6565
[gradle]: https://gradle.org/
66+

measure/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010
`java-library`
1111

1212
// Apply dokka plugin to allow extraction of ducumentation from KDoc comments
13-
id("org.jetbrains.dokka") version "1.4.20"
13+
id("org.jetbrains.dokka") version "1.9.20"
1414

1515
// Make sure we can publish to maven
1616
`maven-publish`

measure/src/main/kotlin/com/alliander/open/measure/Measure.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,16 @@ data class Measure<U : Units>(val amount: BigDecimal, val units: U) : Comparable
117117
val absoluteFactor = (factor `in` base).abs()
118118
return dividend.roundToMultiple(absoluteFactor, roundingMode) * base
119119
}
120-
121120
}
122121

123122
private fun BigDecimal.roundToMultiple(factor: BigDecimal, roundingMode: RoundingMode): BigDecimal =
124-
this.divide(factor, 0, roundingMode) * factor
123+
this.divide(factor, 0, roundingMode) * factor
124+
125+
operator fun <U : Units> BigDecimal.times(m: Measure<U>): Measure<U> =
126+
Measure(amount = m.amount.times(this), units = m.units)
127+
128+
operator fun <U : Units> Int.times(m: Measure<U>): Measure<U> =
129+
BigDecimal.valueOf(this.toLong()) * m
130+
131+
operator fun <U : Units> Long.times(m: Measure<U>): Measure<U> =
132+
BigDecimal.valueOf(this) * m

measure/src/main/kotlin/com/alliander/open/measure/SpecificUnits.kt

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,60 @@
44

55
package com.alliander.open.measure
66

7+
import com.alliander.open.measure.Current.Companion.ampere
78
import com.alliander.open.measure.Energy.Companion.joule
89
import com.alliander.open.measure.Power.Companion.watt
910
import com.alliander.open.measure.Time.Companion.seconds
11+
import com.alliander.open.measure.Voltage.Companion.volt
1012
import java.math.BigDecimal
1113

14+
@JvmName("powerTimesTime")
1215
operator fun Measure<Power>.times(duration: Measure<Time>): Measure<Energy> {
13-
val p = this `as` watt
14-
val dt = duration `as` seconds
16+
val p = this `in` watt
17+
val dt = duration `in` seconds
18+
return Measure(p * dt, joule)
19+
}
20+
21+
@JvmName("currentTimesVoltage")
22+
operator fun Measure<Current>.times(voltage: Measure<Voltage>): Measure<Power> {
23+
val i = this `in` ampere
24+
val v = voltage `in` volt
25+
return Measure(i * v, watt)
26+
}
27+
28+
@JvmName("voltageTimesCurrent")
29+
operator fun Measure<Voltage>.times(current: Measure<Current>): Measure<Power> {
30+
val v = this `in` volt
31+
val i = current `in` ampere
32+
return Measure(i * v, watt)
33+
}
34+
35+
@JvmName("powerDivVoltage")
36+
operator fun Measure<Power>.div(voltage: Measure<Voltage>): Measure<Current> {
37+
val p = this `in` watt
38+
val v = voltage `in` volt
39+
return Measure(p / v, ampere)
40+
}
41+
42+
@JvmName("powerDivCurrent")
43+
operator fun Measure<Power>.div(current: Measure<Current>): Measure<Voltage> {
44+
val p = this `in` watt
45+
val i = current `in` ampere
46+
return Measure(p / i, volt)
47+
}
48+
49+
class Voltage(suffix: String, ratio: BigDecimal = BigDecimal.ONE) : Units(suffix, ratio) {
50+
companion object {
51+
val volt = Voltage("V")
52+
val kiloVolt = Voltage("kV", 1_000.toBigDecimal())
53+
}
54+
}
1555

16-
return Measure(p.amount * dt.amount, joule)
56+
class Current(suffix: String, ratio: BigDecimal = BigDecimal.ONE) : Units(suffix, ratio) {
57+
companion object {
58+
val ampere = Current("A")
59+
val kiloAmpere = Current("kA", 1_000.toBigDecimal())
60+
}
1761
}
1862

1963
class Power(suffix: String, ratio: BigDecimal = BigDecimal.ONE) : Units(suffix, ratio) {
@@ -30,7 +74,7 @@ class Energy(suffix: String, ratio: BigDecimal = BigDecimal.ONE) : Units(suffix,
3074
val kiloJoule = Energy("kJ", 1_000.toBigDecimal())
3175
val megaJoule = Energy("MJ", 1_000_000.toBigDecimal())
3276
val kiloWattHour = Energy("kWh", 3_600_000.toBigDecimal())
33-
val megaWattHour = Energy("mWh", 3_600_000_000.toBigDecimal())
77+
val megaWattHour = Energy("MWh", 3_600_000_000.toBigDecimal())
3478
}
3579
}
3680

@@ -41,4 +85,3 @@ class Time(suffix: String, ratio: BigDecimal = BigDecimal.ONE) : Units(suffix, r
4185
val hours = Time("h", 3_600.toBigDecimal())
4286
}
4387
}
44-

measure/src/test/kotlin/com/alliander/open/measure/MeasureTest.kt

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,21 @@ import com.alliander.open.measure.Energy.Companion.joule
88
import com.alliander.open.measure.Energy.Companion.kiloJoule
99
import com.alliander.open.measure.Energy.Companion.kiloWattHour
1010
import com.alliander.open.measure.Energy.Companion.megaJoule
11-
import com.alliander.open.measure.Energy.Companion.megaWattHour
1211
import com.alliander.open.measure.Power.Companion.kiloWatt
1312
import com.alliander.open.measure.Power.Companion.megaWatt
14-
import com.alliander.open.measure.Power.Companion.watt
1513
import com.alliander.open.measure.Time.Companion.hours
1614
import com.alliander.open.measure.Time.Companion.minutes
1715
import com.alliander.open.measure.Time.Companion.seconds
18-
import com.alliander.open.measure.extension.sum
1916
import io.kotest.core.spec.style.StringSpec
2017
import io.kotest.data.headers
2118
import io.kotest.data.row
2219
import io.kotest.data.table
2320
import io.kotest.matchers.shouldBe
24-
import io.kotest.matchers.shouldNotBe
2521
import io.kotest.property.checkAll
2622
import java.math.BigDecimal
2723
import java.math.RoundingMode.UP
2824

2925
class MeasureTest : StringSpec({
30-
"Joule, Watt and seconds are different units" {
31-
joule shouldNotBe watt
32-
joule shouldNotBe seconds
33-
34-
watt shouldNotBe joule
35-
watt shouldNotBe seconds
36-
37-
seconds shouldNotBe joule
38-
seconds shouldNotBe watt
39-
}
40-
4126
"joules and kiloJoules can be added" {
4227
val left = 1000 * joule
4328
val right = 1 * kiloJoule
@@ -47,15 +32,6 @@ class MeasureTest : StringSpec({
4732
sum shouldBe 2000 * joule
4833
}
4934

50-
"power times time is energy" {
51-
val power = 10 * kiloWatt
52-
val duration = 15 * minutes
53-
54-
val energy = power * duration
55-
56-
energy `as` megaJoule shouldBe 9 * megaJoule
57-
}
58-
5935
"joules can be added" {
6036
checkAll { leftQuantity: Int, rightQuantity: Int ->
6137
val left = leftQuantity * joule
@@ -123,14 +99,6 @@ class MeasureTest : StringSpec({
12399
}
124100
}
125101

126-
"energySum returns correct amount of energy when given a list of measures of energy" {
127-
val list = listOf(100 * joule, 1 * megaWattHour, 1 * megaJoule)
128-
val result = list.sum()
129-
130-
val expectedResult = 3601000100 * joule
131-
result shouldBe expectedResult
132-
}
133-
134102
"roundUpToNextMultiple processes different units correctly" {
135103
io.kotest.data.forAll(
136104
table(

0 commit comments

Comments
 (0)