parent
b74e361a2c
commit
af082829e5
18
README.md
18
README.md
|
@ -1,15 +1,14 @@
|
||||||
# Happy Cat 🐈🌞
|
# Happy Cat 🐈🌞
|
||||||
A commandline utility to control your [Elgato Key Light](https://www.elgato.com/de/key-light) and [Key Light Air](https://www.elgato.com/de/key-light-air).
|
A commandline utility to control your [Elgato Key Light](https://www.elgato.com/en/key-light) and [Key Light Air](https://www.elgato.com/en/key-light-air).
|
||||||
Change your light settings easily inside scripts or use configuration files to automatically apply your preferred setup over the course of the day, possibly even exploring the use as a [light therapy](https://en.wikipedia.org/wiki/Light_therapy) device.
|
Change your light settings easily inside scripts or use configuration files to automatically apply your preferred setup over the course of the day, possibly even exploring the use as a [light therapy](https://en.wikipedia.org/wiki/Light_therapy) device.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
Happy cat is split up into multiple subcommands, each of which uses its own parameters.
|
Happy cat is split up into multiple subcommands, each of which have their own parameters.
|
||||||
To find out more about each command, check out the help pages by appending `--help` after the command.
|
To find out more about each command, check out the help pages by appending `--help` after the command.
|
||||||
|
|
||||||
*Important: Although the Elgato API uses its own values for light temperature internally, the happy cat command line is intended to use Kelvin. However, the conversion is currently broken and might not work properly.*
|
*Important: Happy cat uses Kelvin to measure light temperature, while Elgato lamps use their own format internally. Conversion between the two is done on the fly*
|
||||||
|
|
||||||
#### Apply
|
#### Apply
|
||||||
Reads the provided configuration file, determines the currently active state and applies the state to the given light once.
|
Reads the provided configuration file, determines the currently active state based on time definitions and applies the state to the given light once.
|
||||||
It's basically a oneshot version of the `daemon` command. For examples of the configuration file, check the corresponding paragraph below.
|
It's basically a oneshot version of the `daemon` command. For examples of the configuration file, check the corresponding paragraph below.
|
||||||
|
|
||||||
*Example*
|
*Example*
|
||||||
|
@ -26,7 +25,7 @@ hc daemon ./elgato.config elgato.local
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Get
|
#### Get
|
||||||
Reads and prints the current configuration of the specified light.
|
Reads and prints the current status of the specified light.
|
||||||
|
|
||||||
*Example*
|
*Example*
|
||||||
```shell
|
```shell
|
||||||
|
@ -77,5 +76,12 @@ Timeframes can cross midnight, but *must not* overlap. If there are overlapping
|
||||||
## Automation
|
## Automation
|
||||||
Probably one could automate the setup using systemd and/or cronjobs, but so far I didn't get to that.
|
Probably one could automate the setup using systemd and/or cronjobs, but so far I didn't get to that.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
It should be enough to do a simple:
|
||||||
|
```bash
|
||||||
|
./gradlew build
|
||||||
|
```
|
||||||
|
You can then find the executable in `build/bin/native/releaseExecutable`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This software is licensed under the MPL 2.0, see the [LICENSE](LICENSE) file.
|
This software is licensed under the MPL 2.0, see the [LICENSE](LICENSE) file.
|
|
@ -45,7 +45,8 @@ class ConfigurationRepositoryImpl(
|
||||||
|
|
||||||
//timespan crosses midnight
|
//timespan crosses midnight
|
||||||
if(start > end){
|
if(start > end){
|
||||||
currentTime in currentDate.atTime(0,0) .. end || currentTime in start .. currentDate.atTime(24, 0)
|
currentTime in currentDate.atTime(0,0) .. end
|
||||||
|
|| currentTime in start .. currentDate.plus(1, DateTimeUnit.DAY).atTime(0,0)
|
||||||
} else currentTime in start..end
|
} else currentTime in start..end
|
||||||
}?.status
|
}?.status
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@
|
||||||
|
|
||||||
package fi.schro.data
|
package fi.schro.data
|
||||||
|
|
||||||
|
import fi.schro.data.ElgatoLightRepository.Companion.MAX_TEMPERATURE
|
||||||
|
import fi.schro.data.ElgatoLightRepository.Companion.MIN_TEMPERATURE
|
||||||
import fi.schro.ui.LightPowerStatus
|
import fi.schro.ui.LightPowerStatus
|
||||||
|
import fi.schro.util.clamp
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.client.statement.*
|
import io.ktor.client.statement.*
|
||||||
|
@ -21,6 +24,11 @@ import org.koin.core.component.get
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class ElgatoLightRepository: LightRepository, KoinComponent {
|
class ElgatoLightRepository: LightRepository, KoinComponent {
|
||||||
|
companion object {
|
||||||
|
const val MIN_TEMPERATURE = 143
|
||||||
|
const val MAX_TEMPERATURE = 344
|
||||||
|
}
|
||||||
|
|
||||||
private val PATH_SEPARATOR = "/"
|
private val PATH_SEPARATOR = "/"
|
||||||
private val DEFAULT_PATH = "elgato"
|
private val DEFAULT_PATH = "elgato"
|
||||||
private val LIGHT_PATH = "lights"
|
private val LIGHT_PATH = "lights"
|
||||||
|
@ -104,13 +112,17 @@ data class ElgatoLight(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: these calculations seem weird, maybe they could be improved
|
//these calculations are based on the official elgato control center app 1.2.0 for android
|
||||||
private fun convertKelvinToElgatoTemperature(kelvinTemperature: Int): Int {
|
private fun convertKelvinToElgatoTemperature(kelvinTemperature: Int): Int {
|
||||||
//based on: https://github.com/justinforlenza/keylight-control/blob/main/src/keylight.js
|
return ((1000000/kelvinTemperature.toFloat()).roundToInt()).clamp(MIN_TEMPERATURE, MAX_TEMPERATURE)
|
||||||
return (((kelvinTemperature - 1993300/201f) * 201f)/-4100f).roundToInt()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertElgatoTemperatureToKelvin(elgatoTemperature: Int): Int {
|
private fun convertElgatoTemperatureToKelvin(elgatoTemperature: Int): Int {
|
||||||
//based on: https://github.com/justinforlenza/keylight-control/blob/main/src/keylight.js
|
var value = (1000000/elgatoTemperature.toFloat()).roundToInt()
|
||||||
return (((-4100*elgatoTemperature) / 201f) + 1993300/201f).roundToInt()
|
|
||||||
|
//round to closest multiple of 50
|
||||||
|
val remainder = value % 50
|
||||||
|
if(remainder > 25) value += 50
|
||||||
|
|
||||||
|
return value - remainder
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package fi.schro.util
|
||||||
|
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
fun Int.clamp(start: Int, end: Int): Int {
|
||||||
|
return min(end, max(start, this))
|
||||||
|
}
|
Loading…
Reference in New Issue