Skip to content

Commit

Permalink
Merge branch 'Schnittcher:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Burki24 authored Feb 28, 2024
2 parents aafeee4 + f0e4cd1 commit d9f2db9
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 4 deletions.
111 changes: 111 additions & 0 deletions libs/ColorHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,115 @@ protected function RGBToHSB($R, $G, $B)
$this->SendDebug(__FUNCTION__ . ' Output HSB', "Hue: $hue, Saturation: $saturation, Brightness: $brightness", 0);
return ['hue' => $hue, 'saturation' => $saturation, 'brightness' => $brightness];
}















protected function xyToRGB($x,$y,$bri){

// Calculate XYZ values
$z = 1 - $x - $y;
$Y = $bri / 254; // Brightness coeff.
if ($y == 0){
$X = 0;
$Z = 0;
} else {
$X = ($Y / $y) * $x;
$Z = ($Y / $y) * $z;
}

// Convert to sRGB D65 (official formula on meethue)
// old formula
// $r = $X * 3.2406 - $Y * 1.5372 - $Z * 0.4986;
// $g = - $X * 0.9689 + $Y * 1.8758 + $Z * 0.0415;
// $b = $X * 0.0557 - $Y * 0.204 + $Z * 1.057;
// formula 2016
$r = $X * 1.656492 - $Y * 0.354851 - $Z * 0.255038;
$g = - $X * 0.707196 + $Y * 1.655397 + $Z * 0.036152;
$b = $X * 0.051713 - $Y * 0.121364 + $Z * 1.011530;

// Apply reverse gamma correction
$r = ($r <= 0.0031308 ? 12.92 * $r : (1.055) * pow($r, (1 / 2.4)) - 0.055);
$g = ($g <= 0.0031308 ? 12.92 * $g : (1.055) * pow($g, (1 / 2.4)) - 0.055);
$b = ($b <= 0.0031308 ? 12.92 * $b : (1.055) * pow($b, (1 / 2.4)) - 0.055);

// Calculate final RGB
$r = ($r < 0 ? 0 : round($r * 255));
$g = ($g < 0 ? 0 : round($g * 255));
$b = ($b < 0 ? 0 : round($b * 255));

$r = ($r > 255 ? 255 : $r);
$g = ($g > 255 ? 255 : $g);
$b = ($b > 255 ? 255 : $b);

// Create a web RGB string (format #xxxxxx)
$this->SendDebug('RGB', 'R: ' . $r . ' G: ' . $g . ' B: ' . $b, 0);

//$RGB = "#".substr("0".dechex($r),-2).substr("0".dechex($g),-2).substr("0".dechex($b),-2);
$color = sprintf('#%02x%02x%02x', $r, $g, $b);

return $color;
}


protected function RGBToXy($RGB){
// Get decimal RGB
$RGB = sprintf('#%02x%02x%02x', $RGB[0], $RGB[1], $RGB[2]);
$r = hexdec(substr($RGB,1,2));
$g = hexdec(substr($RGB,3,2));
$b = hexdec(substr($RGB,5,2));

// Calculate rgb as coef
$r = $r / 255;
$g = $g / 255;
$b = $b / 255;

// Apply gamma correction
$r = ($r > 0.04045 ? pow(($r + 0.055) / 1.055, 2.4) : ($r / 12.92));
$g = ($g > 0.04045 ? pow(($g + 0.055) / 1.055, 2.4) : ($g / 12.92));
$b = ($b > 0.04045 ? pow(($b + 0.055) / 1.055, 2.4) : ($b / 12.92));

// Convert to XYZ (official formula on meethue)
// old formula
//$X = $r * 0.649926 + $g * 0.103455 + $b * 0.197109;
//$Y = $r * 0.234327 + $g * 0.743075 + $b * 0.022598;
//$Z = $r * 0 + $g * 0.053077 + $b * 1.035763;
// formula 2016
$X = $r * 0.664511 + $g * 0.154324 + $b * 0.162028;
$Y = $r * 0.283881 + $g * 0.668433 + $b * 0.047685;
$Z = $r * 0.000088 + $g * 0.072310 + $b * 0.986039;

// Calculate xy and bri
if (($X+$Y+$Z) == 0){
$x = 0;
$y = 0;
} else { // round to 4 decimal max (=api max size)
$x = round($X / ($X + $Y + $Z),4);
$y = round($Y / ($X + $Y + $Z),4);
}
$bri = round($Y * 254);
if ($bri > 254){$bri = 254;}

$cie['x'] = $x;
$cie['y'] = $y;
$cie['bri'] = $bri;
return $cie;
}






}
12 changes: 8 additions & 4 deletions libs/Zigbee2MQTTHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -1803,9 +1803,9 @@ public function ReceiveData($JSONString)
if (array_key_exists('x', $Payload['color'])) {
$this->SendDebug(__FUNCTION__ . ' Color', $Payload['color']['x'], 0);
if (array_key_exists('brightness', $Payload)) {
$RGBColor = ltrim($this->CIEToRGB($Payload['color']['x'], $Payload['color']['y'], $Payload['brightness']), '#');
$RGBColor = ltrim($this->xyToRGB($Payload['color']['x'], $Payload['color']['y'], $Payload['brightness']), '#');
} else {
$RGBColor = ltrim($this->CIEToRGB($Payload['color']['x'], $Payload['color']['y']), '#');
$RGBColor = ltrim($this->xyToRGB($Payload['color']['x'], $Payload['color']['y'],255), '#');
}
$this->SendDebug(__FUNCTION__ . ' Color RGB HEX', $RGBColor, 0);
$this->SetValue('Z2M_Color', hexdec(($RGBColor)));
Expand Down Expand Up @@ -2588,15 +2588,19 @@ private function setColor(int $color, string $mode, string $Z2MMode = 'color')
switch ($mode) {
case 'cie':
$RGB = $this->HexToRGB($color);
$cie = $this->RGBToCIE($RGB[0], $RGB[1], $RGB[2]);
//$cie = $this->RGBToCIE($RGB[0], $RGB[1], $RGB[2]);
$cie = $this->RGBToXy($RGB);
if ($Z2MMode = 'color') {
$Payload['color'] = $cie;
$Payload['brightness'] = $cie['bri'];
} elseif ($Z2MMode == 'color_rgb') {
$Payload['color_rgb'] = $cie;
} else {
return;
}
// No break. Add additional comment above this line if intentional
$PayloadJSON = json_encode($Payload, JSON_UNESCAPED_SLASHES);
$this->Z2MSet($PayloadJSON);
break;
case 'hs':
$this->SendDebug('setColor - Input Color', json_encode($color), 0);
if (!is_array($color)) {
Expand Down

0 comments on commit d9f2db9

Please sign in to comment.