Repository: openhab/openhab-android (language: kotlin)

Issue:
Support of command options
Items with command options are currently rendered as a simple switch (commands are so ignored).

These items, when associated to a Switch widget, should be rendered similar as items with state options, that is with one button for each command/state.

PS: I was planning to replace few switch channels in bindings by string channels with command options, but until it is supported by the Android app, it is not worth it.


Discussion hints:
Is there a difference between "command options" and "item options" (as in #912)?
No real difference in UI perspective.
But for command options, you will not receive state updates because this is used with channels that have no state.
Can you post a rest api response of an item with command options?

Pull request: Support command options
Fixes #2655

Signed-off-by: mueller-ma <mueller-ma@users.noreply.github.com>

Test command: ./gradlew :mobile:testFossBetaDebugUnitTest --tests "org.openhab.habdroid.model.ItemTest"

Fix patch:
diff --git a/mobile/src/main/java/org/openhab/habdroid/model/Item.kt b/mobile/src/main/java/org/openhab/habdroid/model/Item.kt
index c0cc987668..db58bb994d 100644
--- a/mobile/src/main/java/org/openhab/habdroid/model/Item.kt
+++ b/mobile/src/main/java/org/openhab/habdroid/model/Item.kt
@@ -290,11 +290,20 @@ fun JSONObject.toItem(): Item {
 
     val stateDescription = optJSONObject("stateDescription")
     val readOnly = stateDescription != null && stateDescription.optBoolean("readOnly", false)
+    val commandDescription = optJSONObject("commandDescription")
 
-    val options = if (stateDescription?.has("options") == true) {
-        stateDescription.getJSONArray("options").map { obj -> obj.toLabeledValue("value", "label") }
-    } else {
-        null
+    val options = when {
+        commandDescription?.has("commandOptions") == true -> {
+            commandDescription.getJSONArray("commandOptions")
+                .map { obj -> obj.toLabeledValue("command", "label") }
+        }
+        stateDescription?.has("options") == true -> {
+            stateDescription.getJSONArray("options")
+                .map { obj -> obj.toLabeledValue("value", "label") }
+        }
+        else -> {
+            null
+        }
     }
 
     val members = if (has("members")) {


Test patch:
diff --git a/mobile/src/test/java/org/openhab/habdroid/model/ItemTest.kt b/mobile/src/test/java/org/openhab/habdroid/model/ItemTest.kt
index 61df39b2ec..fe73dd2c89 100644
--- a/mobile/src/test/java/org/openhab/habdroid/model/ItemTest.kt
+++ b/mobile/src/test/java/org/openhab/habdroid/model/ItemTest.kt
@@ -104,6 +104,13 @@ class ItemTest {
         assertEquals("Location 2", sut.members[1].label)
     }
 
+    @Test
+    fun getCommandOptions() {
+        val sut = itemWithCommandOptions.toItem()
+        assertEquals(LabeledValue("1", "One"), sut.options!!.component1())
+        assertEquals(LabeledValue("2", "Two"), sut.options!!.component2())
+    }
+
     @Test
     fun getTags() {
         val sut = itemAsJsonObject.toItem()
@@ -192,5 +199,25 @@ class ItemTest {
                 'name': 'LocationGroup' }
             """.trimIndent()
         )
+        private val itemWithCommandOptions = JSONObject(
+            """
+              { 'state': 'NULL',
+                'type': 'Number',
+                'name': 'Foo',
+                'commandDescription': {
+                  'commandOptions': [
+                    {
+                      'command': '1',
+                      'label': 'One'
+                    },
+                    {
+                      'command': '2',
+                      'label': 'Two'
+                    },
+                  ]
+                }
+              }
+            """.trimIndent()
+        )
     }
 }