diff --git a/.gitignore b/.gitignore index 5a979af..9860ca8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ out/ ### Kotlin ### .kotlin + +# simpler tests +test_steering_signals.log diff --git a/src/main/kotlin/com/frankenergie/smartasset/client/SteeringSignalClient.kt b/src/main/kotlin/com/frankenergie/smartasset/client/SteeringSignalClient.kt new file mode 100644 index 0000000..e9e76f6 --- /dev/null +++ b/src/main/kotlin/com/frankenergie/smartasset/client/SteeringSignalClient.kt @@ -0,0 +1,39 @@ +package com.frankenergie.smartasset.client + +import com.frankenergie.smartasset.model.SteeringSignal +import org.springframework.beans.factory.annotation.Value +import org.springframework.stereotype.Component +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption + +@Component +class SteeringSignalClient( + @Value("\${steering.signals.file:steering_signals.log}") private val filePath: String +) { + private val file: Path = Path.of(filePath) + + init { + if (!Files.exists(file)) { + Files.createFile(file) + } + } + + fun sendSignal(signal: SteeringSignal) { + val line = formatSignal(signal) + Files.writeString(file, "$line\n", StandardOpenOption.APPEND) + } + + fun getAllSignals(): List { + if (!Files.exists(file)) return emptyList() + return Files.readAllLines(file).filter { it.isNotBlank() } + } + + fun clear() { + Files.writeString(file, "") + } + + private fun formatSignal(signal: SteeringSignal): String { + return "${signal.timestamp}|${signal.groupId}|${signal.quarterStart}|${signal.quarterEnd}|${signal.chargePowerMW}" + } +} diff --git a/src/main/kotlin/com/frankenergie/smartasset/model/StreetingSignal.kt b/src/main/kotlin/com/frankenergie/smartasset/model/StreetingSignal.kt new file mode 100644 index 0000000..523b3dd --- /dev/null +++ b/src/main/kotlin/com/frankenergie/smartasset/model/StreetingSignal.kt @@ -0,0 +1,13 @@ +package com.frankenergie.smartasset.model + +import java.math.BigDecimal +import java.time.Instant +import java.time.LocalDateTime + +data class SteeringSignal( + val groupId: String, + val quarterStart: LocalDateTime, + val quarterEnd: LocalDateTime, + val chargePowerMW: BigDecimal, + val timestamp: Instant = Instant.now() +) diff --git a/src/test/kotlin/com/frankenergie/smartasset/client/SteeringSignalClientTest.kt b/src/test/kotlin/com/frankenergie/smartasset/client/SteeringSignalClientTest.kt new file mode 100644 index 0000000..8a21ad5 --- /dev/null +++ b/src/test/kotlin/com/frankenergie/smartasset/client/SteeringSignalClientTest.kt @@ -0,0 +1,84 @@ +package com.frankenergie.smartasset.client + +import com.frankenergie.smartasset.model.SteeringSignal +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.math.BigDecimal +import java.nio.file.Files +import java.nio.file.Path +import java.time.LocalDateTime + +class SteeringSignalClientTest { + + private val testFilePath = "./test_steering_signals.log" + private lateinit var client: SteeringSignalClient + + @BeforeEach + fun setUp() { + Files.deleteIfExists(Path.of(testFilePath)) + client = SteeringSignalClient(testFilePath) + } + + @AfterEach + fun tearDown() { + Files.deleteIfExists(Path.of(testFilePath)) + } + + @Test + fun `sendSignal writes signal to file`() { + val signal = SteeringSignal( + groupId = "A", + quarterStart = LocalDateTime.of(2024, 1, 15, 10, 0), + quarterEnd = LocalDateTime.of(2024, 1, 15, 10, 15), + chargePowerMW = BigDecimal("2.0") + ) + + client.sendSignal(signal) + + val lines = client.getAllSignals() + assertEquals(1, lines.size) + assertTrue(lines[0].contains("A")) + assertTrue(lines[0].contains("2.0")) + } + + @Test + fun `multiple signals written on separate lines`() { + val signal1 = SteeringSignal( + "A", + LocalDateTime.of(2024, 1, 15, 10, 0), + LocalDateTime.of(2024, 1, 15, 10, 15), + BigDecimal("2.0") + ) + val signal2 = SteeringSignal( + "B", + LocalDateTime.of(2024, 1, 15, 10, 15), + LocalDateTime.of(2024, 1, 15, 10, 30), + BigDecimal("3.0") + ) + + client.sendSignal(signal1) + client.sendSignal(signal2) + + val lines = client.getAllSignals() + assertEquals(2, lines.size) + assertTrue(lines[0].contains("A")) + assertTrue(lines[1].contains("B")) + } + + @Test + fun `clear removes all signals`() { + val signal = SteeringSignal( + "A", + LocalDateTime.of(2024, 1, 15, 10, 0), + LocalDateTime.of(2024, 1, 15, 10, 15), + BigDecimal("2.0") + ) + client.sendSignal(signal) + + client.clear() + + assertTrue(client.getAllSignals().isEmpty()) + } +}