0

I have managed to find code to convert RGB to XY. Can't make it work the other way around.

I have looked through Philips Hue SDK https://github.com/johnciech/PhilipsHueSDK/blob/master/ApplicationDesignNotes/RGB%20to%20xy%20Color%20conversion.md

I have found this javascript code: Philips hue, convert xy from api to HEX or RGB and converted it to c# but it doesn't work as expected. I think my math is not strong enough.. please advise.

    public class PhilipsHueRgbObject
    {
        public int Red { get; set; }
        public int Green { get; set; }
        public int Blue { get; set; }

    }

        public static PhilipsHueRgbObject xyBriToRgb(double x, double y, double bri)
        {
            double z = 1.0d - x - y;

            double Y = bri / 255.0d; // Brightness of lamp
            double X = (Y / y) * x;
            double Z = (Y / y) * z;

            double r = X * 1.612d - Y * 0.203d - Z * 0.302d;
            double g = -X * 0.509d + Y * 1.412d + Z * 0.066d;
            double b = X * 0.026d - Y * 0.072d + Z * 0.962d;

            r =  (r <= 0.0031308d ? 12.92d * r : (1.0d + 0.055d) * Math.Pow(r, (1.0d / 2.4d)) - 0.055d);
            g =  (g <= 0.0031308d ? 12.92d * g : (1.0d + 0.055d) * Math.Pow(g, (1.0d / 2.4d)) - 0.055d);
            b =  (b <= 0.0031308d ? 12.92d * b : (1.0d + 0.055d) * Math.Pow(b, (1.0d / 2.4d)) - 0.055d);

            double maxValue = Math.Max(r, Math.Max(g, b));

            r /= maxValue;
            g /= maxValue;
            b /= maxValue;

            r = r * 255;
            if (r < 0)
            {
                r = 255; 
            }

            g = g * 255;
            if (g < 0)
            {
                g = 255; 
            }

            b = b * 255;
            if (b < 0)
            {
                b = 255; 
            }

            return new PhilipsHueRgbObject()
            {
                Red = (int)r,
                Green = (int)g,
                Blue = (int)b
            };
        }
        public static string groupRBG(string ipAddress, string userName, int groupNumber, int red, int green, int blue)
        {
            try
            {
                float redArg = (red > 0.04045f) ? (float) Math.Pow((red + 0.055f)/(1.0f + 0.055f), 2.4f) : (red/12.92f);
                    // Convert RGB to Hue
                float greenArg = (green > 0.04045f)
                    ? (float) Math.Pow((green + 0.055f)/(1.0f + 0.055f), 2.4f)
                    : (green/12.92f);
                float blueArg = (blue > 0.04045f)
                    ? (float) Math.Pow((blue + 0.055f)/(1.0f + 0.055f), 2.4f)
                    : (blue/12.92f);

                float X = redArg*0.664511f + greenArg*0.154324f + blueArg*0.162028f;
                float Y = redArg*0.283881f + greenArg*0.668433f + blueArg*0.047685f;
                float Z = redArg*0.000088f + greenArg*0.072310f + blueArg*0.986039f;

                float x = X/(X + Y + Z);
                float y = Y/(X + Y + Z);

                return
                    httpRequest(
                        @"http://" + ipAddress + @"/api/" + userName + @"/groups/" + groupNumber.ToString() +
                        @"/action/", @"{" + "\"on\": true,\"xy\": [" + x.ToString() + "," + y.ToString() + "]" + @"}");
            }
            catch (Exception ex)
            {
                ErrorLog.Error("Error : {0}", ex.Message);
                return null;
            }
        }
function xyBriToRgb(x, y, bri){
            z = 1.0 - x - y;
            Y = bri / 255.0; // Brightness of lamp
            X = (Y / y) * x;
            Z = (Y / y) * z;
            r = X * 1.612 - Y * 0.203 - Z * 0.302;
            g = -X * 0.509 + Y * 1.412 + Z * 0.066;
            b = X * 0.026 - Y * 0.072 + Z * 0.962;
            r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055;
            g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055;
            b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055;
            maxValue = Math.max(r,g,b);
            r /= maxValue;
            g /= maxValue;
            b /= maxValue;
            r = r * 255;   if (r < 0) { r = 255 };
            g = g * 255;   if (g < 0) { g = 255 };
            b = b * 255;   if (b < 0) { b = 255 };
            return {
                r :r,
                g :g,
                b :b
            }
        }

I expect to see exact same values coming back for the group. http:// --HueBridgeIP --/api/ -- UserString --/groups

1 Answers1

0

I can't make it work for xy. Instead I have decided to convert hsv to rgb and vice versa.

https://www.programmingalgorithms.com/algorithm/hsv-to-rgb

https://www.programmingalgorithms.com/algorithm/rgb-to-hsv

Works like a charm. Remember to convert Philips Hue 0-65535 to 0-360 and 0-254 to 0 to 1.