Use Kelvin for light color temperature if available (#3477)

- When using at least HA 2022.11, use Kelvins for the color temperature instead of mireds to match the frontend
This commit is contained in:
Joris Pelgröm 2023-04-25 03:06:42 +02:00 committed by GitHub
parent 1eb6ea61f4
commit 608a11211e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 21 deletions

View file

@ -120,7 +120,7 @@
<string name="choose_server">Choose server</string>
<string name="clear_favorites">Clear Favorites</string>
<string name="close">Close</string>
<string name="color_temp">Color temperature: %1$d</string>
<string name="color_temp">Color temperature: %1$s</string>
<string name="collapse">Collapse</string>
<string name="complication_entity_invalid">Invalid entity</string>
<string name="complication_entity_state_content_description">Entity state</string>

View file

@ -19,7 +19,7 @@ interface HomePresenter {
suspend fun onEntityClicked(entityId: String, state: String)
suspend fun onFanSpeedChanged(entityId: String, speed: Float)
suspend fun onBrightnessChanged(entityId: String, brightness: Float)
suspend fun onColorTempChanged(entityId: String, colorTemp: Float)
suspend fun onColorTempChanged(entityId: String, colorTemp: Float, isKelvin: Boolean)
fun onLogoutClicked()
fun onInvalidAuthorization()
fun onFinish()

View file

@ -141,14 +141,15 @@ class HomePresenterImpl @Inject constructor(
}
}
override suspend fun onColorTempChanged(entityId: String, colorTemp: Float) {
override suspend fun onColorTempChanged(entityId: String, colorTemp: Float, isKelvin: Boolean) {
try {
val colorTempKey = if (isKelvin) "color_temp_kelvin" else "color_temp"
serverManager.integrationRepository().callService(
entityId.split(".")[0],
"turn_on",
hashMapOf(
"entity_id" to entityId,
"color_temp" to colorTemp.toInt()
colorTempKey to colorTemp.toInt()
)
)
} catch (e: Exception) {

View file

@ -314,9 +314,9 @@ class MainViewModel @Inject constructor(
homePresenter.onBrightnessChanged(entityId, brightness)
}
}
fun setColorTemp(entityId: String, colorTemp: Float) {
fun setColorTemp(entityId: String, colorTemp: Float, isKelvin: Boolean) {
viewModelScope.launch {
homePresenter.onColorTempChanged(entityId, colorTemp)
homePresenter.onColorTempChanged(entityId, colorTemp, isKelvin)
}
}

View file

@ -54,7 +54,7 @@ fun DetailsPanelView(
onEntityToggled: (String, String) -> Unit,
onFanSpeedChanged: (Float) -> Unit,
onBrightnessChanged: (Float) -> Unit,
onColorTempChanged: (Float) -> Unit,
onColorTempChanged: (Float, Boolean) -> Unit,
isToastEnabled: Boolean,
isHapticEnabled: Boolean
) {
@ -269,16 +269,18 @@ fun BrightnessSlider(
@Composable
fun ColorTempSlider(
attributes: Map<*, *>,
onColorTempChanged: (Float) -> Unit,
onColorTempChanged: (Float, Boolean) -> Unit,
isToastEnabled: Boolean,
isHapticEnabled: Boolean
) {
val haptic = LocalHapticFeedback.current
val context = LocalContext.current
val minValue = (attributes["min_mireds"] as? Number)?.toFloat() ?: 0f
val maxValue = (attributes["max_mireds"] as? Number)?.toFloat() ?: 0f
var currentValue = (attributes["color_temp"] as? Number)?.toFloat() ?: 0f
val useKelvin = attributes.containsKey("color_temp_kelvin") // Added in 2022.11
val minValue = ((if (useKelvin) attributes["min_color_temp_kelvin"] else attributes["min_mireds"]) as? Number)?.toFloat() ?: 0f
val maxValue = ((if (useKelvin) attributes["max_color_temp_kelvin"] else attributes["max_mireds"]) as? Number)?.toFloat() ?: 0f
var currentValue = ((if (useKelvin) attributes["color_temp_kelvin"] else attributes["color_temp"]) as? Number)?.toFloat() ?: 0f
if (currentValue < minValue) {
currentValue = minValue
}
@ -288,7 +290,10 @@ fun ColorTempSlider(
Column {
Text(
stringResource(R.string.color_temp, currentValue.toInt()),
stringResource(
R.string.color_temp,
"${currentValue.toInt()}${if (useKelvin) " K" else ""}"
),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
@ -296,7 +301,7 @@ fun ColorTempSlider(
InlineSlider(
value = currentValue,
onValueChange = {
onColorTempChanged(it)
onColorTempChanged(it, useKelvin)
onSliderChangedFeedback(
isToastEnabled,
isHapticEnabled,
@ -322,7 +327,8 @@ fun ColorTempSlider(
},
colors = InlineSliderDefaults.colors(
selectedBarColor = getColorTemperature(
(currentValue - minValue).toDouble() / (maxValue - minValue).toDouble()
ratio = (currentValue - minValue).toDouble() / (maxValue - minValue).toDouble(),
isKelvin = useKelvin
)
),
modifier = Modifier.padding(bottom = 8.dp)
@ -362,7 +368,7 @@ private fun PreviewDetailsPaneView() {
onEntityToggled = { _, _ -> },
onFanSpeedChanged = {},
onBrightnessChanged = {},
onColorTempChanged = {},
onColorTempChanged = { _, _ -> },
isToastEnabled = false,
isHapticEnabled = false
)

View file

@ -91,10 +91,11 @@ fun LoadHomePage(
brightness
)
},
onColorTempChanged = { colorTemp ->
onColorTempChanged = { colorTemp, isKelvin ->
mainViewModel.setColorTemp(
entity.entityId,
colorTemp
colorTemp,
isKelvin
)
},
isToastEnabled = mainViewModel.isToastEnabled.value,

View file

@ -4,8 +4,8 @@ import androidx.compose.ui.graphics.Color
import java.util.TreeMap
import kotlin.math.abs
fun getColorTemperature(ratio: Double): Color {
val colorMap = sortedMapOf<Double, Long>(
fun getColorTemperature(ratio: Double, isKelvin: Boolean): Color {
val colorMap = sortedMapOf(
0.00 to 0xffa6d1ff,
0.05 to 0xffafd6ff,
0.10 to 0xffb8dbff,
@ -29,8 +29,9 @@ fun getColorTemperature(ratio: Double): Color {
1.00 to 0xffffa000
) as TreeMap<Double, Long>
val previous = colorMap.floorEntry(ratio)
val next = colorMap.ceilingEntry(ratio)
val useRatio = if (isKelvin) (1 - ratio) else ratio
val previous = colorMap.floorEntry(useRatio)
val next = colorMap.ceilingEntry(useRatio)
if (previous == null) return Color(next?.value ?: 0xffa6d1ff) // next and previous should never both be null
if (next == null) return Color(previous.value)
return if (abs(ratio - previous.key) < abs(ratio - next.key)) Color(previous.value) else Color(next.value)