1
0
Fork 0
happy-cat/src/commonMain/kotlin/fi/schro/data/ConfigurationRepository.kt

75 lines
2.8 KiB
Kotlin

/*
* Copyright (c) 2022 Florian Schrofner
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package fi.schro.data
import com.github.ajalt.clikt.output.TermUi.echo
import fi.schro.util.*
import kotlinx.datetime.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
interface ConfigurationRepository {
suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int? = null)
}
class ConfigurationRepositoryImpl(
private val lightRepository: LightRepository,
private val fileUtil: FileUtil
): ConfigurationRepository {
private val timezone = TimeZone.currentSystemDefault()
override suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int?) {
val configString = fileUtil.readAllText(configurationFilePath)
val configuration = Json.decodeFromString<Configuration>(configString)
val statusToApply = determineCurrentStatus(configuration)
statusToApply?.let { newStatus ->
applyLightStatus(lightAddress, port, newStatus)
}
}
private fun determineCurrentStatus(configuration: Configuration): LightStatus? {
val currentTime = Clock.System.now().toLocalDateTime(timezone)
val currentDate = TimeUtil.getCurrentDate()
return configuration.config.firstOrNull { timedConfiguration ->
val start = currentDate.atTime(timedConfiguration.start)
val end = currentDate.atTime(timedConfiguration.end)
//timespan crosses midnight
if(start > end){
currentTime in currentDate.atTime(0,0) .. end
|| currentTime in start .. currentDate.plus(1, DateTimeUnit.DAY).atTime(0,0)
} else currentTime in start..end
}?.status
}
private suspend fun applyLightStatus(lightAddress: String, port: Int?, status: LightStatus){
val currentStatus = lightRepository.getLightStatus(lightAddress)
currentStatus.getNecessaryChanges(status)?.let { statusUpdate ->
echo("applying status changes:")
echo(statusUpdate)
lightRepository.setLightStatus(lightAddress, port, statusUpdate)
}
}
}
@Serializable
data class Configuration(
@SerialName("config") val config: List<TimedStatusConfiguration>
)
@Serializable
data class TimedStatusConfiguration(
@SerialName("start") @Serializable(with = LocalTimeSerializer::class) val start: LocalTime,
@SerialName("end") @Serializable(with = LocalTimeSerializer::class) val end: LocalTime,
@SerialName("status") val status: LightStatus
)