Skip to content

Commit

Permalink
Improve state generation logic when fetching icons (#3456)
Browse files Browse the repository at this point in the history
  • Loading branch information
maniac103 authored Aug 31, 2023
1 parent 60887bb commit cc4d18a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 26 deletions.
49 changes: 25 additions & 24 deletions mobile/src/main/java/org/openhab/habdroid/model/IconResource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -128,42 +128,43 @@ internal fun String?.toOH2WidgetIconResource(
state: ParsedState?,
item: Item?,
type: Widget.Type,
hasMappings: Boolean
hasMappings: Boolean,
useState: Boolean
): IconResource? {
if (isNullOrEmpty() || this == "none") {
return null
}

val itemState = item?.state
var iconState = state?.asString.orEmpty()
if (itemState != null) {
if (item.isOfTypeOrGroupType(Item.Type.Color)) {
// For items that control a color item fetch the correct icon
if (type == Widget.Type.Slider || type == Widget.Type.Switch && !hasMappings) {
try {
iconState = itemState.asBrightness.toString()
if (type == Widget.Type.Switch) {
iconState = if (iconState == "0") "OFF" else "ON"
}
} catch (e: Exception) {
iconState = "OFF"
}
} else if (itemState.asHsv != null) {
val color = itemState.asHsv.toColor()
iconState = String.format(
Locale.US, "#%02x%02x%02x",
Color.red(color), Color.green(color), Color.blue(color)
)
val stateToUse = state ?: item?.state
val iconState = when {
!useState || item == null -> null
// For NULL states, we send 'null' as state when fetching the icon (BasicUI set a predecent for doing so)
stateToUse == null -> "null"
// Number items need to use state formatted as per their state description
item.isOfTypeOrGroupType(Item.Type.Number) || item.isOfTypeOrGroupType(Item.Type.NumberWithDimension)-> {
stateToUse.asNumber.toString()
}
item.isOfTypeOrGroupType(Item.Type.Color) -> when {
// Color sliders just use the brightness part of the color
type == Widget.Type.Slider -> stateToUse.asBrightness.toString()
// Color toggles should behave similarly to the logic below (but using the brightness value)
type == Widget.Type.Switch && !hasMappings -> if (stateToUse.asBrightness == 0) "OFF" else "ON"
stateToUse.asHsv != null -> {
val color = stateToUse.asHsv.toColor()
String.format(Locale.US, "#%02x%02x%02x", Color.red(color), Color.green(color), Color.blue(color))
}
} else if (type == Widget.Type.Switch && !hasMappings && !item.isOfTypeOrGroupType(Item.Type.Rollershutter)) {
else -> stateToUse.asString
}
type == Widget.Type.Switch && !hasMappings && !item.isOfTypeOrGroupType(Item.Type.Rollershutter) -> {
// For switch items without mappings (just ON and OFF) that control a dimmer item
// and which are not ON or OFF already, set the state to "OFF" instead of 0
// or to "ON" to fetch the correct icon
iconState = if (itemState.asString == "0" || itemState.asString == "OFF") "OFF" else "ON"
if (stateToUse.asString == "0" || stateToUse.asString == "OFF") "OFF" else "ON"
}
else -> stateToUse.asString
}

return IconResource(this, true, iconState)
return IconResource(this, true, iconState.orEmpty())
}

enum class IconFormat {
Expand Down
7 changes: 5 additions & 2 deletions mobile/src/main/java/org/openhab/habdroid/model/Widget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ data class Widget(
val item = Item.updateFromEvent(source.item, eventPayload.optJSONObject("item"))
val state = determineWidgetState(eventPayload.optStringOrNull("state"), item)
val iconName = eventPayload.optStringOrFallback("icon", source.icon?.icon)
val icon = iconName.toOH2WidgetIconResource(state, item, source.type, source.mappings.isNotEmpty())
val staticIcon = source.icon?.customState?.isEmpty() == true
val hasMappings = source.mappings.isNotEmpty()
val icon = iconName.toOH2WidgetIconResource(state, item, source.type, hasMappings, !staticIcon)
return Widget(
id = source.id,
parentId = source.parentId,
Expand Down Expand Up @@ -338,12 +340,13 @@ fun JSONObject.collectWidgets(parent: Widget?): List<Widget> {
val type = getString("type").toWidgetType()
val icon = optStringOrNull("icon")
val state = Widget.determineWidgetState(optStringOrNull("state"), item)
val staticIcon = optBoolean("staticIcon", false)

val widget = Widget(
id = getString("widgetId"),
parentId = parent?.id,
rawLabel = optString("label", ""),
icon = icon.toOH2WidgetIconResource(state, item, type, mappings.isNotEmpty()),
icon = icon.toOH2WidgetIconResource(state, item, type, mappings.isNotEmpty(), !staticIcon),
state = state,
type = type,
url = optStringOrNull("url"),
Expand Down

0 comments on commit cc4d18a

Please sign in to comment.