Help to map complex multiple params command from a thing to items

Hi guys,

I’m currently looking into finalizing the serial lgtv binding (after more than a year that I haven’t worked on it…) and there are a few commands I’m having a hard time mapping to items from a users perspective point.

In short, alot of the commands to send over the serial wire are of the form “[Command1][Command2][ ][Set ID][ ][Data][Cr]” which can be quite easily mapped to an item because there is only 1 “data” field to manage for a command1/command2 combination.

However, some commands have many data parameters, for instance the “3D command” or the “3D extended” at page 97 where the relevant parameters change or the “Channel tuning command” at page 98 which is even worse to configure because it implies playing with bits on the data parameter, found in the document located at http://gscs-b2c.lge.com/downloadFile?fileId=ujpO8yH69djwNZzwuavqpQ (This link comes from the LG support website and is legit)

While I can make an option list for all the different combinaison of both “3D” commands, this makes it very bad from a UX perspective. The 3d command (not extended) will end up being a 30 choices list where I don’t even know how to approach the channel tuning.

While I can probably make some very specialized component for habpanel, this will not be reflected on other UIs. I feel like my only choice is for users to make their own “dummy” component and have rules to send the proper values to the item so it sends the right command on the wire.

Does anyone have some hints on how to map such complex commands to items from a UI stand point ?

I don’t see it being any different from any other delimiter-based protocol. It’s basically same as a csv

pg 97 example:
[x][v][ ][Set ID][ ][Data01][ ][Data02][Cr]

I would split them up and transform/map them accordingly. You might need further splitting/regexing if you need deeper nesting

test.map
It will default to NotFound

[Command1][Command2]=Some combo of command
[Set_ID]=Some ID
[Data][Cr]=Some combo of data
=NotFound

Rule

rule "TESTER"
when
    System started
then
    logInfo("TESTER", "Started")
     
    val testSerialOrig = "[Command1][Command2][ ][Set ID][ ][Data][Cr]"
    
    // You need to replace spaces with something else.
    // Because *.map files do not work if keys have spaces 
    val testSerialReplaced = testSerialOrig.replace(" ", "_")
    logInfo("TESTER", "New string: " + testSerialReplaced)
    
    // Then Split
    val parts = testSerialReplaced.split("\\[_\\]")
    val part1 = parts.get(0)
    val part2 = parts.get(1)
    val part3 = parts.get(2)
    
    logInfo("TESTER", "Part1:" + part1 )
    logInfo("TESTER", "Part2:" + part2 )
    logInfo("TESTER", "Part3:" + part3 )
    
    logInfo("TESTER", "Transformed1: " + transform("MAP", "test.map", part1))
    logInfo("TESTER", "Transformed2: " + transform("MAP", "test.map", part2))
    logInfo("TESTER", "Transformed3: " + transform("MAP", "test.map", part3))
    
    logInfo("TESTER", "Ended") 
end 

Output

2019-01-20 21:04:57.862 [INFO ] [clipse.smarthome.model.script.TESTER] - Started

2019-01-20 21:04:57.867 [INFO ] [clipse.smarthome.model.script.TESTER] - New string: [Command1][Command2][_][Set_ID][_][Data][Cr]

2019-01-20 21:04:57.875 [INFO ] [clipse.smarthome.model.script.TESTER] - Part1:[Command1][Command2]

2019-01-20 21:04:57.879 [INFO ] [clipse.smarthome.model.script.TESTER] - Part2:[Set_ID]

2019-01-20 21:04:57.884 [INFO ] [clipse.smarthome.model.script.TESTER] - Part3:[Data][Cr]

2019-01-20 21:04:57.890 [INFO ] [clipse.smarthome.model.script.TESTER] - Transformed1: Some combo of command

2019-01-20 21:04:57.896 [INFO ] [clipse.smarthome.model.script.TESTER] - Transformed2: Some ID

2019-01-20 21:04:57.902 [INFO ] [clipse.smarthome.model.script.TESTER] - Transformed3: Some combo of data

2019-01-20 21:04:57.906 [INFO ] [clipse.smarthome.model.script.TESTER] - Ended


I have something working like this on my OH. But I use the Javascript transform for more complex stuff such as these since JavaScript is my preferred language.

Apologies as I probably didn’t describe my problem properly, I’ll try to rephrase it better.

I’m upgrading a current binding I have worked on (with pending pull request) for the lgtvserial binding, and I’m mapping all those commands to a channel.

The problem is not to parse the data but on how to make a good UX experience for a user for channels that requires multiple parameters.

The problem is how to make it easy for a user to “send” the proper data to the handler for complex commands that have either multiple data fields or where the data has many criteria to take into account from a UX perspective and requires logic to generate the proper data.

The current problem is in UIs, an item is usually displayed with a basic single field to “update” in order to change the item value, which then communicate this value to the channel handler “to interpret” and make the proper api request to update the value on the device.

For instance, if you take the 3d command, the are actually 4 parameters to take into account. I can’t really have 4 parameters represented with a single UI fields. Actually I can have a list of all the possible matches maped to their internal command representation, but 3d command generate 30 different values where it would be more intuitive to have 4 select fields to select the proper values and only show/hide those that are relevant.

For instance, the 3d command data values are all dependent on the value of data1 part. Looking at the truth table on page 97, data2, data3 and data4 are only relevant when data1 is 00 or 03.

Of course I can make a single string item to map to the binding channel, and have the user implement it’s “own” logic in rules to send the proper commands, but I feel this is cumbersome for all the users who will use this binding (and potentially other bindings complex commands) that require multiple parameters.

For instance, we could have a hidden input field that represents the current value, but have it “upgraded” to interactive field, similar on how a datetime picker works, where you select the first data, and depending on the value you selected, the next “step” will adapt from that value.

If I select “3D on” (00) for data1, only data2 and data3 needs to have their value specified, and the UI component would allow a user to only set those 2 values. On the other side, if a user select “3D off” or “3D to 2D”, there is no need to specify the other 3 fields which they wouldn’t be displayed to the user either. If you choose “2D to 3D”, only the values for data4 are relevant for the user to select.

The solution I’m trying to find is to solve that problem to have multiple fields for a single item, and only show those that are relevant to the current context of “selected values” so a user would only have to select the data that makes sense to send the proper command behind the scene in order to update the thing and actuate it properly.

While I can use a webview and have such complex interaction manually created, this requires the user to make the proper integration himself instead of being provided by the binding directly.

What I’m looking for is if there is a better way than a webview for such case or if such “complex rendering system” is being worked on.

You are overthinking it. You cannot possibly (in a practical sense) provide everything a user will require so let users provide the input. Take a look on how we did Alarm Decoder binding.

It is a difficult issue to decide. The purpose of a binding is to hide the technology from openHAB, to standardize the “moving parts” to simple OH Items like switch, dateTime, Dimmer.
The hint there is that the purpose is not to hide complexity.

If it helps thinking about it, how are these TV functions carried out from a remote?
If its some kind of interactive display/response routine, you’re not going to be able to emulate that in a binding.
If its a case of a sequence P + Q + R + S, maybe just make those available to OH.
Could be as separate channels, could be a combined string. Your choice.

Exec binding v2 gives a use model where the user (rules) pre-loads arguments, and then pulls a “go” trigger.

I suppose what I’m suggesting is to make your binding at the most basic nuts and bolts level, maximum flexibility; and let the user worry about presentation. You can offer ‘helper’ scripts etc. as well!