Color item TCP binding

Hi,

I am using hyperion LED service, and it requires JSON data trough a TCP connection (no HTTP).

I now I can use TCP binding but how can I define the “Color” item in order to “Format” the RGB color data before sending it to the TCP connection.

This is a sample data hyperion server is waiting for:
{"color":[36,34,96],"command":"color","priority":100}

Thanks!

Either write a Rule to generate the formatted String or a Transform to convert the data, maybe through a JavaScript transform.

I’m not very good with transforms so I would probably do it in a rule. But @watou is really good with transforms and perhaps he can recommend an approach.

Can you suggest an example on how to define a Rule that generates an String that can be used on the TCP binding item definition?

Thanks!

If your Item is named MyTCP and it is configured to be outgoing:

rule "TCP rule"
when
    <Some trigger>
then
    // code to build the string str
    MyTCP.sendCommand(str)
end

Rules are independent of the bindings. The above will work no matter what MyTCP is bound to (MQTT, Serial, etc.) as long as the binding config is correct.

1 Like

A rule would work better than a transform in this case, because a rule would give you access to methods of the HSBType which is the command sent to the Color item.

import org.openhab.core.library.types.HSBType

rule SendRGB
when
  Item MyColorItem received command
then
  val HSBType hsb = receivedCommand as HSBType
  val String json = String::format("{\"color\":[%1$d,%2$d,%3$d],\"command\":\"color\",\"priority\":100}", 
    hsb.red, hsb.green, hsb.blue)
  MyTCP.sendCommand(json)
end

I think that the “rule” part is ok:

rule "Set RGB value"
when
	Item cgComedor_Fresiluz received command
then
	var HSBType hsbValue
	var String  redValue
	var String  greenValue
	var String  blueValue
	hsbValue = cgComedor_Fresiluz.state as HSBType
	
	redValue   = hsbValue.red.intValue.toString
	greenValue = hsbValue.green.intValue.toString
	blueValue  = hsbValue.blue.intValue.toString
	
	var String json = '{"color":[' + redValue + ',' + greenValue + ',' + blueValue + '],"command":"color","priority":100}'
	logDebug("prueba", json)
	
	cgComedor_Fresiluz.sendCommand(json)
end

The problem is with the item definition (it is not working):

Color cgComedor_Fresiluz "Fresiluz" <television> (gComedor, Luces) {tcp=">[CHANGED:192.168.1.100:19444]"}

You will instead just want a String item, something like

String cgComedor_Fresiluz "Fresiluz" {tcp=">[192.168.1.100:19444]"}

But in that case I do not have a Color Picker on my UI. The point is that I want to select a color on the UI and send it trough the TCP connection (json format)

That is how is implemented:

Item:
Color cgComedor_Fresiluz "Fresiluz" <television> (gComedor, Luces) {tcp=">[192.168.1.100:19444]"}

Rule:
rule “Set RGB value"
when
Item cgComedor_Fresiluz received command
then
val HSBType hsb = receivedCommand as HSBType
val String json = String::format(”{“color”:[%1$d,%2$d,%3$d],“command”:“color”,“priority”:100}",hsb.red.intValue, hsb.green.intValue, hsb.blue.intValue)
logDebug(“prueba”, json)
cgComedor_Fresiluz.sendCommand(json)
end

But I am getting the following error:
19:34:12.819 [DEBUG] [m.r.internal.engine.RuleEngine:305 ] - Executing rule 'Set RGB value’
19:34:12.835 [DEBUG] [rg.openhab.model.script.prueba:38 ] - {“color”:[24,29,38],“command”:“color”,“priority”:100}
19:34:12.835 [WARN ] [.c.i.events.EventPublisherImpl:58 ] - given command is NULL, couldn’t send command to 'cgComedor_Fresiluz’
19:34:12.850 [INFO ] [runtime.busevents :22 ] - cgComedor_Fresiluz received command 217.200012,36.783440,38.833332

Your Color item would appear in the UI, but not have a { tcp="..." } section in it. Changing the color will trigger a rule which will “convert” the color to the JSON format and send it as a string command to the String item that’s bound to TCP but doesn’t appear in a sitemap, since it’s only existing for the purpose of backend I/O. Does that make sense?

Strange but it make sense and… it is working!! Thanks :slight_smile:

1 Like

Now, the next step is how to handle the ON and OFF commands that are at both sides of the color picker on the UI.

What I want to do is to send another TCP data when any of those buttons are pressed.

In the rule now I have a “receivedCommad” which has RGB values. How can I get the ON/OFF commands?

A Color Item only stores HSBType data. When you send an ON or an OFF to a Color Item it gets converted into an HSB value. I believe you can determine ON or OFF based on the HSB values with 0,0,0 being OFF and anything else being ON.

Something like:

import org.openhab.core.library.types.HSBType
import org.openhab.core.library.types.OnOffType

rule SendRGB
when
  Item MyColorItem received command
then
  if (receivedCommand instanceof HSBType) {
    val HSBType hsb = receivedCommand as HSBType
    val String json = String::format("{\"color\":[%1$d,%2$d,%3$d],\"command\":\"color\",\"priority\":100}", 
      hsb.red, hsb.green, hsb.blue)
    MyTCP.sendCommand(json)
  } else if (receivedCommand instanceof OnOffType) {
    val String json = String::format( "..command %1$s ...", if (receivedCommand == ON ) "1" else "0")
    MyTCP.sendCommand(json)
  }
end

No, the receivedCommand variable is a Command type, and in the rule is casted to HSBType. When the ON/OFF button is pressed I get a OnOffType. How can I check the Command type before casting it to avoid erros?

The Color item can receive several different types of commands. How it stores state is different. Here is the code:

			acceptedCommandTypes.add(OnOffType.class);		
			acceptedCommandTypes.add(IncreaseDecreaseType.class);
			acceptedCommandTypes.add(PercentType.class);
			acceptedCommandTypes.add(HSBType.class);

You will never get casting errors because a Color Item can only ever have a HSBType. The ONOFFType that gets sent to the Color Items is converted to an HSBType before your rule gets triggered and before receivedCommand is populated so it will only ever be an HSBType.

That is unless of course you are actually seeing casting errors in your logs when you press ON/OFF, in which case receivedCommand does not work the way I thought it did.

But in general, you can test what class something is using the instanceof command which returns a boolean. For example:

if(receivedCommand instanceof HSBType)
    // do stuff
else if(receivedCommand instanceof SwitchType)
    // do stuff

Or in this case, instead of using receivedCommand you can just get the state from the Item itself which will always be an HSBType.

Thanks to @rlkoshak and @watou the “instanceof” instruction works perfectly.

In the UI I can only see the ON/OFF buttons and the color picker. How can I get the “PercentType” setting on the UI. I am thinking of using it to adjust the brightness of hyperion LEDs.

Use a Setpoint or Slider (one of which is currently broken in 1.8.2 according to other posts I’ve seen but can’t remember which) on the Sitemap. You can’t have a Setpoint/Slider and ColorPicker on the same line so if you want both you need to use two lines on your sitemap.

Could you add a Slider widget in the sitemap for the same Color item? That ought to send PercentType commands to the item (I think).