add apply command functionality
This commit is contained in:
		
							parent
							
								
									ddd7fb7ed6
								
							
						
					
					
						commit
						6ba0952486
					
				
					 5 changed files with 84 additions and 7 deletions
				
			
		| 
						 | 
					@ -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){
 | 
				
			||||||
| 
						 | 
					@ -23,4 +44,16 @@ class ConfigurationRepositoryImpl(
 | 
				
			||||||
            lightRepository.setLightStatus(lightAddress, port, 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
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/nativeMain/kotlin/fi/schro/util/TimeUtil.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/nativeMain/kotlin/fi/schro/util/TimeUtil.kt
									
										
									
									
									
										Normal 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}")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue