add apply command functionality
parent
ddd7fb7ed6
commit
6ba0952486
|
@ -41,6 +41,7 @@ kotlin {
|
||||||
implementation("io.insert-koin:koin-core:3.1.5")
|
implementation("io.insert-koin:koin-core:3.1.5")
|
||||||
implementation("com.github.ajalt.clikt:clikt:3.4.0")
|
implementation("com.github.ajalt.clikt:clikt:3.4.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
|
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-core:1.6.7")
|
||||||
implementation("io.ktor:ktor-client-cio:1.6.7")
|
implementation("io.ktor:ktor-client-cio:1.6.7")
|
||||||
implementation("io.ktor:ktor-client-serialization:1.6.7")
|
implementation("io.ktor:ktor-client-serialization:1.6.7")
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package fi.schro.data
|
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.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import platform.posix.fopen
|
|
||||||
|
|
||||||
interface ConfigurationRepository {
|
interface ConfigurationRepository {
|
||||||
suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int? = null)
|
suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int? = null)
|
||||||
|
@ -14,7 +17,25 @@ class ConfigurationRepositoryImpl(
|
||||||
): ConfigurationRepository {
|
): ConfigurationRepository {
|
||||||
override suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int?) {
|
override suspend fun applyConfiguration(configurationFilePath: String, lightAddress: String, port: Int?) {
|
||||||
val configString = FileUtil.readAllText(configurationFilePath)
|
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){
|
private suspend fun applyLightStatus(lightAddress: String, port: Int?, status: LightStatus){
|
||||||
|
@ -24,3 +45,15 @@ class ConfigurationRepositoryImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
|
@ -13,7 +13,7 @@ import io.ktor.client.features.json.*
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val commandModule = module {
|
val commandModule = module {
|
||||||
single{ ApplyCommand() }
|
single{ ApplyCommand(get()) }
|
||||||
single{ SetCommand(get()) }
|
single{ SetCommand(get()) }
|
||||||
single{ GetCommand(get()) }
|
single{ GetCommand(get()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.options.option
|
||||||
import com.github.ajalt.clikt.parameters.types.enum
|
import com.github.ajalt.clikt.parameters.types.enum
|
||||||
import com.github.ajalt.clikt.parameters.types.int
|
import com.github.ajalt.clikt.parameters.types.int
|
||||||
|
import fi.schro.data.ConfigurationRepository
|
||||||
import fi.schro.data.LightRepository
|
import fi.schro.data.LightRepository
|
||||||
import fi.schro.data.LightStatus
|
import fi.schro.data.LightStatus
|
||||||
import kotlinx.coroutines.runBlocking
|
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 configurationFile: String by argument(ARG_CONFIGURATION_FILE)
|
||||||
private val targetLamp: String by argument(ARG_TARGET_LAMP)
|
private val targetLamp: String by argument(ARG_TARGET_LAMP)
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
echo("Configuration applied")
|
runBlocking {
|
||||||
|
configurationRepository.applyConfiguration(configurationFile, targetLamp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue