Accuracy of HSB <--> RGB conversion

Hi all, I am currently writing rules to control a LED RGB strip. The device is controlled via MQTT and expects RGB values. The current value is reported back via MQTT. So I have a String item that sends and receives the raw RGB data to/from the device and a proxy Color item to control the device. The proxy item has autoupdate="false" set, so it always reflects the current color set by the device. Conversion between both is done via rules. This all works quite well.

However, when I wrote a rule to cycle through colors by incrementing the hue of the proxy Color item (modulo 360), I noticed that the brightness will change with each step until it reaches zero (aka lights off). I figured that there seems to be a problem regarding the accuracy of the HSB to RGB conversion. The following test code:

  val red = 134
  val green = 255
  val blue = 4
  
  val color = HSBType.fromRGB(red, green, blue)
  val redAfter = color.red.intValue * 255 / 100
  val greenAfter = color.green.intValue * 255 / 100
  val blueAfter = color.blue.intValue * 255 / 100
  
  logInfo("RGB", "in: {},{},{}", red, green, blue)
  logInfo("RGB", "out: {},{},{}", redAfter, greenAfter, blueAfter)

gives the following result:

21:48:44.914 [INFO ] [rg.eclipse.smarthome.model.script.RGB] - in: 134,255,4
21:48:44.970 [INFO ] [rg.eclipse.smarthome.model.script.RGB] - out: 137,255,5

Note the difference in the red and blue values. The error accumulates with every step and leads to the behaviour described above.

Am I making some sort of stupid mistake or is this due to accuracy that HSBType uses internally?
If it is indeed due to the internals of HSBType, is there an alternative solution to achieve accurate conversion?

Thank you!

PS: I am on openHAB 2.3

Standard RGB is able to represent a little under 16.8m colors.

HSB is able to represent a little over 3.6 million colors (assuming 360 values for H instead of decimal values).

When you are converting between the two you are trying to map between two coordinate systems that cannot exactly map to each other. There will be errors between then and if any conversion calculation relies on a previous calculation, those errors will accumulate.

You cannot expect to convert to one coordinate system and then convert back and get the exact same answer. It should be really close, but it will never be exactly the same. They’re are over 13 million RGB values that cannot be represented in HSB.

Yes, that makes sense. I guess I hoped that HSBType uses floats internally which would circumvent this problem…

Luckily, the device in question is DIY so I can easily change the MQTT interface to accept/post HSB values.