Closed thevinz62 closed 5 years ago
I don't know exactly how it is calculated.
Here are some examples of colors (it is the protocols that requires this, this is kind of ugly, I fully agree with you on this but I can't do anything about it):
0xFF = Red, 0xD9 = Lavender, 0xBA = Blue, 0x85 = Aqua, 0x7A = Green, 0x54 = Lime, 0x3B = Yellow, 0x1E = Orange
https://github.com/QuentinCG/Milight-Wifi-Bridge-3.0-Python-Library/blob/master/MilightWifiBridge/MilightWifiBridge.py#L574
It seems to be the same logic in other scripts using the protocol: https://git.zotha.de/gsgh/gsgh-plugin-milight/blob/bb9c012b0b3913e651b4174fa7f1cc321bd3ee09/milight/milight.go#L14
I have a function written in php that take in entry the hex value of a color (like html) and return the milight color ! Please feel free to use and convert in python to integrate on the script ;-)
function rgbHexToMiLight($hexColor)
{
$hexColor = ltrim($hexColor, '#');
$hexColorLenghth = strlen($hexColor);
if ($hexColorLenghth != 8 && $hexColorLenghth != 6) {
throw new \Exception('Color hex code must match 8 or 6 characters');
}
if ($hexColorLenghth == 8) {
$r = hexdec(substr($hexColor, 2, 2));
$g = hexdec(substr($hexColor, 4, 2));
$b = hexdec(substr($hexColor, 6, 2));
if (($r == 0 && $g == 0 && $b == 0) || ($r == 255 && $g == 255 && $b == 255)) {
throw new \Exception('Color cannot be black or white');
}
return array($r, $g, $b);
}
$r = hexdec(substr($hexColor, 0, 2));
$g = hexdec(substr($hexColor, 2, 2));
$b = hexdec(substr($hexColor, 4, 2));
if (($r == 0 && $g == 0 && $b == 0) || ($r == 255 && $g == 255 && $b == 255)) {
throw new \Exception('Color cannot be black or white');
}
$r = $r / 255;
$g = $g / 255;
$b = $b / 255;
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$l = ($max + $min) / 2;
$d = $max - $min;
$h = '';
if ($d == 0) {
$h = $s = 0;
} else {
$s = $d / (1 - abs(2 * $l - 1));
switch ($max) {
case $r:
$h = 60 * fmod((($g - $b) / $d), 6);
if ($b > $g) {
$h += 360;
}
break;
case $g:
$h = 60 * (($b - $r) / $d + 2);
break;
case $b:
$h = 60 * (($r - $g) / $d + 4);
break;
}
}
$color = ((int)($h / 360.0 * 255.0)) % 256;
return $color;
}```
Nice, thank you, I'll add this when I'll have some time.
Hi @thevinz62
I tried your function (in php) but it doesn't work properly whatever rgb value I use.
My other problem is that, $s
is used nowhere in your algorithm...
Are you sure you gave the entire algorithm?
To not lose my work while waiting an answer, here is the php -> python edit:
import re
import math
def rgbToMilightColor(rgbColor):
"""Convert RGB color into Milight color format
Keyword arguments:
milightColor -- (string) RGB color ('#000000' -> '#FFFFFF')
return: (int) Milight color (between 0 and 255)
"""
trimmedRgbColor = re.sub('#', '', rgbColor)
if len(trimmedRgbColor) != 6:
logging.error("Invalid '{}' RGB color (must be between '#000000' and '#FFFFFF')".format(str(rgbColor)))
return 0
red = int(trimmedRgbColor[0:2], 16)
green = int(trimmedRgbColor[2:4], 16)
blue = int(trimmedRgbColor[4:6], 16)
# Absolute black or white are not possible with RGB to Milight algorithm
if (red == 0 and green == 0 and blue == 0):
red = 1
if (red == 255 and green == 255 and blue == 255):
red = 254
red = float(red) / 255.0
green = float(green) / 255.0
blue = float(blue) / 255.0
max_value = (max(red, green, blue))
min_value = (min(red, green, blue))
mid_range_value = (max_value + min_value) / 2
range_value = (max_value) - (min_value)
# No idea what 'h' and 's' mean... (if you know, tell me so I can put better name)
# Maybe it is hsv values? but not using s and v?????
h = 0
if range_value != 0:
#s = range_value / (1 - abs(2 * mid_range_value - 1))
if max_value == red:
h = 60.0 * math.fmod((green - blue) / range_value, 6)
if blue > green:
h += 360.0
elif max_value == green:
h = 60.0 * ((blue - red) / (range_value + 2))
elif max_value == blue:
h = 60.0 * ((red - green) / (range_value + 4))
return ((int)(h / 360.0 * 255.0)) % 256`
Since there is no information anywhere (even from milight documentation) on how to convert correctly from rgb to milight color format, I will close this issue.
Feel free to do reverse engineering on milight and update this issue (or open a new issue).
I have just a new question, how is the color calculated ? I used to use the old library with the 3 components R G and B to have a color. Now i see that in your script it's only one number beteween 0 and 255 ! Is that a way to convert 0-255 R, 0,255 G and 0-255 B to that number between 0 and 255 ? Thank you for help !