1
0
Fork 0

add apply command functionality

master
Florian Schrofner 2022-02-19 17:37:09 +01:00
parent ddd7fb7ed6
commit 6ba0952486
5 changed files with 84 additions and 7 deletions

View File

@ -41,6 +41,7 @@ kotlin {
implementation("io.insert-koin:koin-core:3.1.5")
implementation("com.github.ajalt.clikt:clikt:3.4.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2")
implementation("io.ktor:ktor-client-core:1.6.7")
implementation("io.ktor:ktor-client-cio:1.6.7")
implementation("io.ktor:ktor-client-serialization:1.6.7")

View File

@ -1,9 +1,12 @@
package fi.schro.data
import fi.schro.util.FileUtil
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
import platform.posix.fopen
interface ConfigurationRepository {
suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int? = null)
@ -14,7 +17,25 @@ class ConfigurationRepositoryImpl(
): ConfigurationRepository {
override suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int?) {
val configString = FileUtil.readAllText(configurationFilePath)
TODO("Not yet implemented")
val configuration = Json.decodeFromString<Configuration>(configString)
val statusToApply = determineCurrentStatus(configuration)
statusToApply?.let { newStatus ->
echo("applying new status:")
echo(newStatus.toString())
applyLightStatus(lightAddress, port, newStatus)
}
}
private fun determineCurrentStatus(configuration: Configuration): LightStatus? {
val currentTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val currentDate = TimeUtil.getCurrentDate()
return configuration.config.firstOrNull { timedConfiguration ->
val start = currentDate.atTime(timedConfiguration.start)
val end = currentDate.atTime(timedConfiguration.end)
currentTime in start..end
}?.status
}
private suspend fun applyLightStatus(lightAddress: String, port: Int?, status: LightStatus){
@ -23,4 +44,16 @@ class ConfigurationRepositoryImpl(
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
)

View File

@ -13,7 +13,7 @@ import io.ktor.client.features.json.*
import org.koin.dsl.module
val commandModule = module {
single{ ApplyCommand() }
single{ ApplyCommand(get()) }
single{ SetCommand(get()) }
single{ GetCommand(get()) }
}

View File

@ -7,6 +7,7 @@ import com.github.ajalt.clikt.parameters.options.check
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.enum
import com.github.ajalt.clikt.parameters.types.int
import fi.schro.data.ConfigurationRepository
import fi.schro.data.LightRepository
import fi.schro.data.LightStatus
import kotlinx.coroutines.runBlocking
@ -77,12 +78,16 @@ class GetCommand(
}
}
class ApplyCommand: CliktCommand(name = "apply", help = "Applies the given configuration to the specified light"){
class ApplyCommand(
private val configurationRepository: ConfigurationRepository
): CliktCommand(name = "apply", help = "Applies the given configuration to the specified light"){
private val configurationFile: String by argument(ARG_CONFIGURATION_FILE)
private val targetLamp: String by argument(ARG_TARGET_LAMP)
override fun run() {
echo("Configuration applied")
runBlocking {
configurationRepository.applyConfiguration(configurationFile, targetLamp)
}
}
}

View File

@ -0,0 +1,38 @@
package fi.schro.util
import kotlinx.datetime.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
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
object TimeUtil {
fun getCurrentDate(): LocalDate {
val currentTime = Clock.System.now()
return currentTime.toLocalDateTime(TimeZone.currentSystemDefault()).date
}
}
fun LocalDate.atTime(time: LocalTime): LocalDateTime{
return LocalDateTime(year, month, dayOfMonth, time.hour, time.minute, 0, 0)
}
@Serializable
data class LocalTime(val hour: Int, val minute: Int)
object LocalTimeSerializer: KSerializer<LocalTime>{
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Time", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): LocalTime {
val stringValue = decoder.decodeString()
val values = stringValue.split(":").map { it.toInt() }
return LocalTime(values[0], values[1])
}
override fun serialize(encoder: Encoder, value: LocalTime) {
encoder.encodeString("${value.hour}:${value.minute}")
}
}