From e4e765c2cb6cb078d0ef4412e5090c98176952a2 Mon Sep 17 00:00:00 2001 From: Stephan Knull Date: Wed, 10 Jan 2024 22:10:46 +0100 Subject: [PATCH] Make color pickers working again. --- .../klanglicht/model/hybrid/HybridScene.kt | 14 ++- .../rest/configuration/ConfigHolder.kt | 9 ++ .../controller/HybridStageRestController.kt | 17 ++- .../rest/hybrid/handler/HybridStageHandler.kt | 28 ++++- .../rest/lightmanager/model/html/LMScenes.kt | 12 +- .../rest/lightmanager/model/html/LMZones.kt | 2 +- .../rest/lightmanager/widgets/ColorWheel.kt | 108 ++++++++++++++---- .../shelly/controller/ShellyRestController.kt | 21 +++- .../rest/shelly/model/html/ShellyStatus.kt | 2 +- 9 files changed, 172 insertions(+), 41 deletions(-) diff --git a/klanglicht-module-dmx/src/main/kotlin/de/visualdigits/kotlin/klanglicht/model/hybrid/HybridScene.kt b/klanglicht-module-dmx/src/main/kotlin/de/visualdigits/kotlin/klanglicht/model/hybrid/HybridScene.kt index 6a7e4fd..3ca626c 100644 --- a/klanglicht-module-dmx/src/main/kotlin/de/visualdigits/kotlin/klanglicht/model/hybrid/HybridScene.kt +++ b/klanglicht-module-dmx/src/main/kotlin/de/visualdigits/kotlin/klanglicht/model/hybrid/HybridScene.kt @@ -83,12 +83,14 @@ class HybridScene() : Fadeable { initializeFromFadeables() } + fun fadeableMap(): Map> = fadeables.toMap() + fun fadeables(): List> = fadeables.values.toList() fun getFadeable(id: String): Fadeable<*>? = fadeables[id] fun putFadeable(id: String, fadeable: Fadeable<*>) { - fadeables[id] = fadeable + fadeables[id] = fadeable.clone() initializeFromFadeables() } @@ -239,8 +241,12 @@ class HybridScene() : Fadeable { coroutineScope { // call shelly interface which is pretty slow with native fading (RGBW shelly devices can fade on their own) // but api calls cost around 100 millis - other.fadeables().filterIsInstance().forEach { - launch { it.write(preferences, true, fadeDuration) } + other.fadeableMap().filter { it.value is ShellyColor }.forEach { + val otherFadeable = it.value as ShellyColor + val fadeable = fadeables[otherFadeable.getId()] + if (fadeable != null && otherFadeable.getRgbColor() != fadeable.getRgbColor()) { + launch { (otherFadeable as ShellyColor).write(preferences, true, fadeDuration) } + } } } @@ -274,7 +280,7 @@ class HybridScene() : Fadeable { // first collect all frame data for the dmx frame to avoid lots of costly write operations to a serial interface otherParameterSets.forEach { (id, otherParameterSet) -> val parameterSet = parameterSets[id] - if (parameterSet != null) { + if (parameterSet != null && otherParameterSet.getRgbColor() != parameterSet.getRgbColor()) { val faded = parameterSet.fade(otherParameterSet, factor) preferences.setDmxData( baseChannel = faded.baseChannel, diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/configuration/ConfigHolder.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/configuration/ConfigHolder.kt index 8dbc8b4..b36e9cc 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/configuration/ConfigHolder.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/configuration/ConfigHolder.kt @@ -23,6 +23,7 @@ class ConfigHolder { val klanglichtDirectory: File = File(SystemUtils.getUserHome(), ".klanglicht") var currentScene: HybridScene? = null + val colorStore: MutableMap = mutableMapOf() @PostConstruct fun initialize() { @@ -54,4 +55,12 @@ class ConfigHolder { fun updateScene(nextScene: HybridScene) { currentScene?.update(nextScene) } + + fun putColor(id: String, hexColor: String) { + colorStore[id] = hexColor + } + + fun getColor(id: String): String? { + return colorStore[id] + } } diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/controller/HybridStageRestController.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/controller/HybridStageRestController.kt index 128a3ae..d68dc4e 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/controller/HybridStageRestController.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/controller/HybridStageRestController.kt @@ -22,7 +22,8 @@ class HybridStageRestController { @RequestParam(value = "gains", required = false, defaultValue = "") gains: String, @RequestParam(value = "transition", required = false) transitionDuration: Long?, @RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean, - @RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean + @RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean, + @RequestParam(value = "storeName", required = false) storeName: String? ) { hybridStageHandler?.hexColor( ids = ids, @@ -30,7 +31,19 @@ class HybridStageRestController { gains = gains, transitionDuration = transitionDuration, turnOn = turnOn, - store = store + store = store, + storeName = storeName + ) + } + + @GetMapping("putColor") + fun putColor( + @RequestParam(value = "id") id: String, + @RequestParam(value = "hexColor") hexColor: String + ) { + hybridStageHandler?.putColor( + id = id, + hexColor = hexColor ) } } diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/handler/HybridStageHandler.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/handler/HybridStageHandler.kt index 63ee2f0..49dc693 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/handler/HybridStageHandler.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/hybrid/handler/HybridStageHandler.kt @@ -25,6 +25,7 @@ class HybridStageHandler { * @param transitionDuration The fade duration in milli seconds. * @param turnOn Determines if the device should be turned on. * @param store Determines if the colors should be saved in the ConfigHolder. + * @param storeName An additional name to strore values. */ fun hexColor( ids: String, @@ -32,18 +33,35 @@ class HybridStageHandler { gains: String, transitionDuration: Long?, turnOn: Boolean, - store: Boolean = true + store: Boolean = true, + storeName: String? ) { val currentScene = configHolder?.currentScene?.clone() - val nextScene = HybridScene(ids, hexColors, gains, turnOn.toString(), preferences = configHolder?.preferences) + val nextScene = configHolder?.currentScene?.clone()?.let { n -> + HybridScene(ids, hexColors, gains, turnOn.toString(), preferences = configHolder.preferences).fadeableMap().forEach { + n.putFadeable(it.key, it.value) + } + n + } if (store) { - configHolder?.updateScene(nextScene) + configHolder?.updateScene(nextScene!!) + if (storeName != null) { + configHolder?.putColor(storeName, hexColors) + } } - log.info("nextScene : $nextScene") + log.info("nextScene: $nextScene") - currentScene?.fade(nextScene, transitionDuration?:configHolder?.preferences?.fadeDurationDefault?:1000, configHolder?.preferences!!) + currentScene?.fade(nextScene!!, transitionDuration?:configHolder?.preferences?.fadeDurationDefault?:1000, configHolder?.preferences!!) } + fun putColor( + id: String, + hexColor: String, + ) { + configHolder?.putColor(id, hexColor) + } + + fun restoreColors( ids: String, transitionDuration: Long? diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMScenes.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMScenes.kt index 15d6f57..6b77826 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMScenes.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMScenes.kt @@ -37,7 +37,7 @@ class LMScenes( override fun toHtml(configHolder: ConfigHolder): String { val sb = StringBuilder() - sb.append("
") + sb.append("
") .append(name) .append("
\n") sb.append("
\n") @@ -61,6 +61,16 @@ class LMScenes( groupScenes ) } + sb.append("
\n") + renderLabel(sb, "All") + sb.append(ColorWheel("All").toHtml(configHolder)) + sb.append("
\n") + + sb.append("
\n") + renderLabel(sb, "All Odd Even") + sb.append(ColorWheel("All").toHtml(configHolder, true)) + sb.append("
\n") + sb.append("
\n\n") return sb.toString() } diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMZones.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMZones.kt index 6832622..f9123b1 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMZones.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/model/html/LMZones.kt @@ -169,7 +169,7 @@ class LMZones( override fun toHtml(configHolder: ConfigHolder): String { val sb = StringBuilder() - sb.append("
") + sb.append("
") .append(name) .append("
\n") sb.append("
\n") diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/widgets/ColorWheel.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/widgets/ColorWheel.kt index 8ae7352..a9db72e 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/widgets/ColorWheel.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/lightmanager/widgets/ColorWheel.kt @@ -13,27 +13,93 @@ class ColorWheel( private val log: Logger = LoggerFactory.getLogger(javaClass) override fun toHtml(configHolder: ConfigHolder): String { + return toHtml(configHolder, false) + } + + fun toHtml(configHolder: ConfigHolder, oddEven: Boolean): String { val wheelId = id!!.replace(" ", "") - val lastColorState = configHolder.getFadeable(id) - val hexColor = lastColorState?.getRgbColor()?.web()?:"#000000" - log.debug("Got color '${RGBColor(hexColor).ansiColor()}' for id '$id'") - return "\t
\n" + - "\t\t
COLORPICKER - " + id + "
\n" + - "\t\t
\n" + - "\t\t\t
\n" + - "\t\t
\n" + - "\t\t\n" + - "\t\t
" + + val sb = StringBuilder() + + if (oddEven) { + sb.append("\t
\n") + renderColorWheelPanel(sb, wheelId, true) + renderColorWheelPanel(sb, wheelId, false) + + renderScript(sb, wheelId, true, configHolder) + sb.append("\t\t
\n") + } else { + sb.append("\t
\n") + renderColorWheelPanel(sb, wheelId, null) + + renderScript(sb, wheelId, false, configHolder) + sb.append("\t\t
\n") + } + + + return sb.toString() + } + + private fun renderColorWheelPanel(sb: StringBuilder, wheelId: String, odd: Boolean?) { + sb.append("\t\t
\n") + if (odd != null) { + sb.append("\t\t
COLORPICKER - $id - ${if (odd) "Odd" else "Even"}
\n") + sb.append("\t\t\t
\n") + } else { + sb.append("\t\t
COLORPICKER - $id
\n") + sb.append("\t\t\t
\n") + } + sb.append("\t\t
\n") + } + + private fun renderScript(sb: StringBuilder, wheelId: String, oddEven: Boolean, configHolder: ConfigHolder) { + if (oddEven) { + sb.append("\t\t\n") + } else { + val hexColor = configHolder.getFadeable(wheelId) + ?.getRgbColor()?.web() + ?:configHolder.getColor(wheelId) + ?:"000000" + sb.append("\t\t\n") + } } } diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/controller/ShellyRestController.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/controller/ShellyRestController.kt index b2627ea..8933e33 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/controller/ShellyRestController.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/controller/ShellyRestController.kt @@ -32,7 +32,7 @@ class ShellyRestController { @RequestParam(value = "scene", required = false, defaultValue = "0") sceneId: Int, @RequestParam(value = "index", required = false, defaultValue = "0") index: Int ) { - shellyHandler?.control(sceneId, index) + shellyHandler?.control(sceneId = sceneId, index = index) } @GetMapping("power") @@ -41,7 +41,7 @@ class ShellyRestController { @RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean, @RequestParam(value = "transition", required = false) transitionDuration: Long? ) { - shellyHandler?.power(ids, turnOn, transitionDuration) + shellyHandler?.power(ids = ids, turnOn = turnOn, transitionDuration = transitionDuration) } @GetMapping("hexColor") @@ -51,9 +51,18 @@ class ShellyRestController { @RequestParam(value = "gains", required = false, defaultValue = "") gains: String, @RequestParam(value = "transition", required = false) transitionDuration: Long?, @RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean, - @RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean + @RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean, + @RequestParam(value = "storeName", required = false) storeName: String? ) { - hybridStageHandler?.hexColor(ids, hexColors, gains, transitionDuration, turnOn, store) + hybridStageHandler?.hexColor( + ids = ids, + hexColors = hexColors, + gains = gains, + transitionDuration = transitionDuration, + turnOn = turnOn, + store = store, + storeName = storeName + ) } @GetMapping("restore") @@ -61,7 +70,7 @@ class ShellyRestController { @RequestParam(value = "ids", required = false, defaultValue = "") ids: String, @RequestParam(value = "transition", required = false) transitionDuration: Long? ) { - hybridStageHandler?.restoreColors(ids, transitionDuration) + hybridStageHandler?.restoreColors(ids = ids, transitionDuration = transitionDuration) } @GetMapping("gain") @@ -70,6 +79,6 @@ class ShellyRestController { @RequestParam(value = "gain", required = false, defaultValue = "") gain: Int, @RequestParam(value = "transition", required = false) transitionDuration: Long? ) { - hybridStageHandler?.gain(ids, gain, transitionDuration) + hybridStageHandler?.gain(ids = ids, gain = gain, transitionDuration = transitionDuration) } } diff --git a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/model/html/ShellyStatus.kt b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/model/html/ShellyStatus.kt index 6fa0606..fd8ae8f 100644 --- a/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/model/html/ShellyStatus.kt +++ b/klanglicht-rest/src/main/kotlin/de/visualdigits/kotlin/klanglicht/rest/shelly/model/html/ShellyStatus.kt @@ -11,7 +11,7 @@ class ShellyStatus : HtmlRenderable { fun toHtml(shellyHandler: ShellyHandler): String { val sb = StringBuilder() - sb.append("
") + sb.append("
") .append("Current Power Values") .append("
\n") sb.append("
\n")