9) { $errno = ord($buffer{8}); if ($errno == false) return $buffer; } } return false; } function SetAllBulbState($State) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { $args = str_repeat(chr(0xFF), 8).chr(($State == 0) ? 0 : 1); $buffer = SendRequest($socket, chr(0x00), OSR_SETDEVICESTATE, $args); CloseSocket($socket); if ($buffer) { $Child = IPS_GetChildrenIDs(OSR_CATEGORYLIGHTS); foreach($Child as $key => $value) { $StateID = @IPS_GetObjectIDByIdent("STATE", $value); SetValueBoolean($StateID, (($State == 0) ? false : true)); } return true; } } return false; } function SetDeviceState($id, $State) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { $flag = (IPS_GetParent($id) == OSR_CATEGORYGROUPS) ? chr(0x02) : chr(0x00); $args = AddresstoChr(GetValue($id)).chr(($State == 0) ? 0 : 1); $buffer = SendRequest($socket, $flag, OSR_SETDEVICESTATE, $args); CloseSocket($socket); if ($buffer) { $StateID = @IPS_GetObjectIDByIdent("STATE", $id); SetValueBoolean($StateID, (($State == 0) ? false : true)); return true; } } return false; } function SetBulbBrightness($id, $Value, $Transition = OSR_TRANSITION) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { if ($Value < 0) { IPS_LogMessage("SetBulbBrightness", "Brightness [".$Value."] out of range. Setting to 0%"); $Value = 0; } elseif ($Value > 100) { IPS_LogMessage("SetBulbBrightness", "Brightness [".$Value."] out of range. Setting to 100%"); $Value = 100; } $Transition = CheckTransitionValue($Transition); $flag = (IPS_GetParent($id) == OSR_CATEGORYGROUPS) ? chr(0x02) : chr(0x00); $args = AddresstoChr(GetValue($id)).chr($Value).chr($Transition).chr(0x00); $buffer = SendRequest($socket, $flag, OSR_SETBULBBRIGHT, $args); CloseSocket($socket); if ($buffer) { $StateID = @IPS_GetObjectIDByIdent("STATE", $id); $BrightID = @IPS_GetObjectIDByIdent("BRIGHTNESS", $id); SetValueBoolean($StateID, (($Value == 0) ? false : true)); SetValueInteger($BrightID, $Value); return true; } } return false; } function SetBulbColor($id, $Value, $Transition = OSR_TRANSITION) { $HueID = @IPS_GetObjectIDByIdent("HUE", $id); $hex = str_pad(dechex($Value), 6, 0, STR_PAD_LEFT); if ($HueID && $hex != 64) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { $Transition = CheckTransitionValue($Transition); $rgb = HEX2RGB(str_pad(dechex($Value), 6, 0, STR_PAD_LEFT)); $flag = (IPS_GetParent($id) == OSR_CATEGORYGROUPS) ? chr(0x02) : chr(0x00); $args = AddresstoChr(GetValue($id)).chr($rgb['r']).chr($rgb['g']).chr($rgb['b']).chr(0xFF).chr($Transition).chr(0x00); $buffer = SendRequest($socket, $flag, OSR_SETBULBCOLOR, $args); CloseSocket($socket); if ($buffer) { $ColorID = @IPS_GetObjectIDByIdent("COLOR", $id); $SaturationID = @IPS_GetObjectIDByIdent("SATURATION", $id); $hsv = HEX2HSV($hex); SetValueInteger($HueID, $hsv['h']); SetValueInteger($ColorID, $Value); SetValueInteger($SaturationID, $hsv['s']); return true; } } } return false; } function SetColorTemperature($id, $Value, $Transition = OSR_TRANSITION) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { $HueID = @IPS_GetObjectIDByIdent("HUE", $id); $minTemp = ($HueID) ? 2000 : 2700; if ($Value < $minTemp) { IPS_LogMessage("SetColorTemperature", "Color Temperature [".$Value."] out of range. Setting to ".$minTemp."K"); $Value = $minTemp; } elseif ($Value > 6500) { IPS_LogMessage("SetColorTemperature", "Color Temperature [".$Value."] out of range. Setting to 6500K"); $Value = 6500; } $Transition = CheckTransitionValue($Transition); $hex = dechex($Value); if (strlen($hex) < 4) $hex = str_repeat("0", 4-strlen($hex)).$hex; $flag = (IPS_GetParent($id) == OSR_CATEGORYGROUPS) ? chr(0x02) : chr(0x00); $args = AddresstoChr(GetValue($id)).chr(hexdec(substr($hex, 2, 2))).chr(hexdec(substr($hex, 0, 2))).chr($Transition).chr(0x00); $buffer = SendRequest($socket, $flag, OSR_SETCOLORTEMP, $args); CloseSocket($socket); if ($buffer) { $ColorTempID = @IPS_GetObjectIDByIdent("COLOR_TEMPERATURE", $id); SetValueInteger($ColorTempID, $Value); return true; } } return false; } function BulbColorCycle($id, $cycle, $Agility = 300) { $HueID = @IPS_GetObjectIDByIdent("HUE", $id); if ($HueID) { $socket = OpenSocket(OSR_GATEWAYIP, 1); if ($socket) { if ($Agility > 65535) $Agility = 65535; //Maximum time is 1092 minutes and 15 seconds if ($Agility < 5) $Agility = 5; //Minimum time is 5 seconds $Agility = dechex($Agility); $Agility = str_repeat("0", 4-strlen($Agility)).$Agility; $args = AddresstoChr(GetValue($id)).(($cycle) ? chr(0x01) : chr(0x00)).chr(hexdec(substr($Agility, 2, 2))).chr(hexdec(substr($Agility, 0, 2))); $buffer = SendRequest($socket, chr(0x00), OSR_BULBCOLORCYCLE, $args); CloseSocket($socket); if ($buffer) return true; } } return false; } function GetPairedDevices($data) { if (strlen($data) > 10) { $cnt = ord($data{9})+ord($data{10}); $data = substr($data, 11); //Renove 11 bytes header for ($i = 0; $i < $cnt; $i++) { GetPairedDevicesData($data, $i+1); $data = substr($data, 50); //Remove 50 bytes device } return true; } return false; } function GetPairedDevicesData($socket, $MAC, $data, $idx) { switch(DeviceType(ord($data{10}))) { case OSR_CATEGORYLIGHTS: $id = CreateIPSVariable(OSR_CATEGORYLIGHTS, (string)trim(substr($data, 26, 15)), ChrToAddress($MAC), 0); $Firmware = DeviceFirmware($data{11}).DeviceFirmware($data{12}).DeviceFirmware($data{13}).DeviceFirmware($data{14}); CreateIPSVariable($id, "Firmware", (string)$Firmware, 12, "FIRMWARE"); CreateIPSVariable($id, "ID", (int)$idx, 0, "ID"); GetDeviceInfo($MAC, $socket, $data, $idx); break; } return true; } function GetDeviceInfo($MAC, $socket = null, $data = null, $idx = 0) { if ($socket == null) { $socket = OpenSocket(OSR_GATEWAYIP); $local = true; } if ($socket) { $flag = chr(0x00); $args = (($idx) ? $MAC : AddresstoChr($MAC)); $buffer = SendRequest($socket, $flag, OSR_GETDEVICEINFO, $args); if ($buffer) { $length = strlen($buffer); $MAC = ($idx) ? ChrToAddress($MAC) : $MAC; if ($data == null) { $data = substr($buffer, 9); $bytes = 0; } else { $bytes = 6; } if ($length == 32) $Type = (ord($buffer{30}) == 0) ? "tw" : "rgbw"; $State = GetDeviceData($MAC, $data, $bytes, (($length == 20) ? false : true), (isset($Type) ? $Type : "tw")); return (isset($State) ? true : false); } if (isset($local)) CloseSocket($socket); } return false; } function GetDeviceData($MAC, $data, $bytes, $Online, $Type) { $State = false; $Child = IPS_GetChildrenIDs(OSR_CATEGORYLIGHTS); foreach($Child as $key => $value) { if (GetValue($value) == $MAC) { $id = $value; break; } } if (isset($id)) { if ($Online) { $rgb = ord($data{16+$bytes}).ord($data{17+$bytes}). ord($data{18+$bytes}); if (dechex($rgb) != 64) { //$White = ord($data{19+$bytes}); $hex = RGB2HEX(array('r' => ord($data{16+$bytes}), 'g' => ord($data{17+$bytes}), 'b' => ord($data{18+$bytes}))); $hsv = HEX2HSV($hex); $hsl = HEX2HSL($hex); $Color = hexdec($hex); //IPS_LogMessage("GetDeviceData", "Bulb [".$MAC."] Color RGB: ".ord($data{16+$bytes}).",".ord($data{17+$bytes}).",".ord($data{18+$bytes})); //IPS_LogMessage("", "Bulb [".$MAC."] Color HEX: ".strtoupper($hex)); CreateIPSVariable($id, "Hue", (int)$hsv['h'], 1, "HUE", "OSR.Hue"); CreateIPSVariable($id, "Color", (int)$Color, 4, "COLOR", "~HexColor"); CreateIPSVariable($id, "Saturation", (int)$hsv['s'], 7, "SATURATION", "~Intensity.100"); //CreateIPSVariable($id, "Luminance", (string)$hsl['l'], 8, "LUMINANCE"); } $ColorTemp = hexdec(dechex(ord($data{15+$bytes})).dechex(ord($data{14+$bytes}))); CreateIPSVariable($id, "Color Temperature", (int)$ColorTemp, 4, "COLOR_TEMPERATURE", "OSR.ColorTemperature"); CreateIPSVariable($id, "Brightness", (int)ord($data{13+$bytes}), 6, "BRIGHTNESS", "~Intensity.100"); } $State = (bool)(($Online) ? ((ord($data{12+$bytes}) == 1) ? true : false) : false); CreateIPSVariable($id, "State",(bool)$State, 2, "STATE", "~Switch"); CreateIPSVariable($id, "Online", (bool)(($Online) ? true : false), 3, "ONLINE"); } return $State; } function GetGroupList($socket, $data) { $Address = substr($data, 0, 2); $id = CreateIPSVariable(OSR_CATEGORYGROUPS, (string)trim(substr($data, 2, 15)), (string)ChrToAddress($Address), 0); GetGroupInfo($Address, $socket); return true; } function GetGroupInfo($Address, $socket = null) { if ($socket == null) { $socket = OpenSocket(OSR_GATEWAYIP); $local = true; } if ($socket) { $flag = chr(0x00); $buffer = SendRequest($socket, $flag, OSR_GETGROUPINFO, $Address); if (strlen($buffer) > 10) { $cnt = ord($buffer{27}); $Group = (string)trim(substr($buffer, 11, 15)); $buffer = substr($buffer, 28); //Renove 28 byte header for ($i = 0; $i < $cnt; $i++) { $MAC = ChrtoAddress(substr($buffer, 0, 8)); CreateDeviceLink($Group, $MAC); $buffer = substr($buffer, 8); //Remove 8 bytes MAC } } if (isset($local)) CloseSocket($socket); } } function DeviceFirmware($data) { $String = ord($data); return (strlen($String) == 1) ? "0".$String : $String; } function DeviceType($type) { switch ($type) { case OSR_CLASSICA60TW: case OSR_CLASSICA60RGBW: return OSR_CATEGORYLIGHTS; case OSR_DEVICESWITCH: case OSR_DEVICEDIMMER: return OSR_CATEGORYSWITCHES; case OSR_DEVICEMOTION: return OSR_CATEGORYMOTION; case OSR_DEVICEPLUG: return OSR_CATEGORYPLUGS; } } function CreateDeviceProfile() { if (!IPS_VariableProfileExists("OSR.Hue")) { IPS_CreateVariableProfile("OSR.Hue", vtInteger); IPS_SetVariableProfileDigits("OSR.Hue", 0); IPS_SetVariableProfileText("OSR.Hue", "", "°"); IPS_SetVariableProfileValues("OSR.Hue", 0, 360, 1); } if (!IPS_VariableProfileExists("OSR.ColorTemperature")) { IPS_CreateVariableProfile("OSR.ColorTemperature", vtInteger); IPS_SetVariableProfileIcon("OSR.ColorTemperature", "Intensity"); IPS_SetVariableProfileDigits("OSR.ColorTemperature", 0); IPS_SetVariableProfileText("OSR.ColorTemperature", "", " K"); IPS_SetVariableProfileValues("OSR.ColorTemperature", 2000, 8000, 1); } } function CreateIPSVariable($ParentID, $Name, $Value, $pos, $Ident = null, $Profile = null) { $id = @IPS_GetVariableIDByName($Name, $ParentID); if (!$id) { $id = IPS_CreateVariable(PHPTypeToIPS(gettype($Value))); if ($Ident) IPS_SetIdent($id, $Ident); IPS_SetName($id, $Name); IPS_SetParent($id, $ParentID); IPS_SetPosition($id, $pos); } if ($Profile) IPS_SetVariableCustomProfile($id, $Profile); if (GetValue($id) != $Value) SetValue($id, $Value); return $id; } function CreateDeviceLink($Group, $MAC) { $Address = @IPS_GetVariableIDByName($Group, OSR_CATEGORYGROUPS); if ($Address) { $Child = IPS_GetChildrenIDs(OSR_CATEGORYLIGHTS); foreach($Child as $key => $value) { if (GetValue($value) == $MAC) { $Name = IPS_GetName($value); $LinkID = @IPS_GetLinkIDByName($Name, $Address); if (!$LinkID) { $LinkID = IPS_CreateLink(); IPS_SetName($LinkID, $Name); IPS_SetParent($LinkID, $Address); IPS_SetLinkTargetID($LinkID, $value); } } } } } function GenerateRequestID() { $random = substr(str_shuffle('ABCDEF0123456789'), 0, 8); $id = ""; for ($i = 0; $i < 8; $i += 2) { $id .= chr(ord(substr($random, $i, 2))); } return $id; } function CheckTransitionValue($Value) { if ($Value < OSR_TRANSITION) { IPS_LogMessage("CheckTransitionValue", "Transition time [".$Value."] out of range. Setting to ".OSR_TRANSITMIN." sec"); $Value = OSR_TRANSITMIN; } elseif ($Value > OSR_TRANSITMAX) { IPS_LogMessage("CheckTransitionValue", "Transition time [".$Value."] out of range. Setting to ".hexdec(OSR_TRANSITMAX/10)." sec"); $Value = OSR_TRANSITMAX; } return $Value; } function AddresstoChr($Address) { $Address = explode(":", $Address); $result = ""; foreach($Address as $value) $result = chr(hexdec($value)).$result; return ((strlen($result) == 8) ? $result : $result.chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00)); } function ChrToAddress($Address) { $length = strlen($Address); $result = array(); for($i = 0; $i < $length; $i++) { $hex = dechex(ord(substr($Address, $i, 1))); if (strlen($hex) == 1) $hex = "0".$hex; $result[] = $hex; } return implode(":", array_reverse($result)); } function PHPTypeToIPS($type) { switch (strtolower($type)) { case "boolean": return 0; case "integer": return 1; case "float": case "double": return 2; case "string": return 3; } } function HEX2HSL($hex) { $r = substr($hex, 0, 2); $g = substr($hex, 2, 2); $b = substr($hex, 4, 2); return RGB2HSL(hexdec($r), hexdec($g), hexdec($b)); } function RGB2HSL($r, $g, $b) { $r/=255; $g/=255; $b/=255; $maxRGB = max($r, $g, $b); $minRGB = min($r, $g, $b); $h; $s; $l = ($maxRGB+$minRGB)/2; $chroma = $maxRGB-$minRGB; if($chroma == 0) { $h = $s = 0; } else { switch($maxRGB) { case $r: $h = 60*fmod((($g-$b)/$chroma), 6); if ($b > $g) $h += 360; break; case $g: $h = 60*(($b-$r)/$chroma+2); break; case $b: $h = 60*(($r-$g)/$chroma+4); break; } $s = $chroma/(1-abs(2*$l-1)); } return array('h' => round($h), 's' => round($s, 2), 'l' => round($l)); } function HSL2HEX($h, $s, $l) { $rgb = HSL2RGB($h, $s, $l); $r = str_pad(dechex($rgb['r']), 2, 0, STR_PAD_LEFT); $g = str_pad(dechex($rgb['g']), 2, 0, STR_PAD_LEFT); $b = str_pad(dechex($rgb['b']), 2, 0, STR_PAD_LEFT); return $r.$g.$b; } function HSL2RGB($h, $s, $l, $array = false, $format = 'rgb(%d, %d, %d)') { $r; $g; $b; $c = (1-abs(2*$l-1))*$s; $x = $c*(1-abs(fmod(($h/60), 2)-1)); $m = $l-($c/2); switch($h) { case ($h < 60): $r = $c; $g = $x; $b = 0; break; case ($h < 120): $r = $x; $g = $c; $b = 0; break; case ($h < 180): $r = 0; $g = $c; $b = $x; break; case ($h < 240): $r = 0; $g = $x; $b = $c; break; case ($h < 300): $r = $x; $g = 0; $b = $c; break; default: $r = $c; $g = 0; $b = $x; } $r = floor(($r+$m)*255); $g = floor(($g+$m)*255); $b = floor(($b+$m)*255); $return = ($array) ? array('r' => $r, 'g' => $g, 'b' => $b) : sprintf($format, round($r), round($g), round($b)); return $return; } function HEX2HSV($hex) { $r = substr($hex, 0, 2); $g = substr($hex, 2, 2); $b = substr($hex, 4, 2); return RGB2HSV(hexdec($r), hexdec($g), hexdec($b)); } function RGB2HSV($r, $g, $b) { $r /= 255; $g /= 255; $b /= 255; $maxRGB = max($r, $g, $b); $minRGB = min($r, $g, $b); $chroma = $maxRGB-$minRGB; $dV = 100*$maxRGB; if ($chroma == 0) return array('h' => 0, 's' => 0, 'v' => round($dV, 2)); $dS = 100*($chroma/$maxRGB); switch ($minRGB) { case $r: $h = 3-(($g-$b)/$chroma); break; case $b: $h = 1-(($r-$g)/$chroma); break; default: $h = 5-(($b-$r)/$chroma); } $dH = 60*$h; return array('h' => round($dH), 's' => round($dS, 2), 'v' => round($dV)); } function HSV2HEX($h, $s, $v, $array = false) { $rgb = HSV2RGB($h, $s, $v, $array); $r = str_pad(dechex($rgb['r']), 2, 0, STR_PAD_LEFT); $g = str_pad(dechex($rgb['g']), 2, 0, STR_PAD_LEFT); $b = str_pad(dechex($rgb['b']), 2, 0, STR_PAD_LEFT); return $r.$g.$b; } function HSV2RGB($h, $s, $v, $array = false, $format = 'rgb(%d, %d, %d)') { if ($h < 0) $h = 0; if ($h > 360) $h = 360; if ($s < 0) $s = 0; if ($s > 100) $s = 100; if ($v < 0) $v = 0; if ($v > 100) $v = 100; $dS = $s/100.0; $dV = $v/100.0; $dC = $dV*$dS; $dH = $h/60.0; $dT = $dH; while ($dT >= 2.0) $dT -= 2.0; $dX = $dC*(1-abs($dT-1)); switch(floor($dH)) { case 0: $dR = $dC; $dG = $dX; $dB = 0.0; break; case 1: $dR = $dX; $dG = $dC; $dB = 0.0; break; case 2: $dR = 0.0; $dG = $dC; $dB = $dX; break; case 3: $dR = 0.0; $dG = $dX; $dB = $dC; break; case 4: $dR = $dX; $dG = 0.0; $dB = $dC; break; case 5: $dR = $dC; $dG = 0.0; $dB = $dX; break; default: $dR = 0.0; $dG = 0.0; $dB = 0.0; } $dM = $dV-$dC; $dR += $dM; $dG += $dM; $dB += $dM; $dR *= 255; $dG *= 255; $dB *= 255; $rgb = ($array) ? array('r' => round($dR), 'g' => round($dG), 'b' => round($dB)) : sprintf($format, round($dR), round($dG), round($dB)); return $rgb; } function RGB2HEX($rgb) { $hex = str_pad(dechex($rgb['r']), 2, "0", STR_PAD_LEFT); $hex .= str_pad(dechex($rgb['g']), 2, "0", STR_PAD_LEFT); $hex .= str_pad(dechex($rgb['b']), 2, "0", STR_PAD_LEFT); //return sprintf("#%02x", $RGBW['r']).sprintf('%02x', $RGBW['g']).sprintf('%02x', $RGBW['b']sprintf('%02x', $RGBW['w']); return $hex; } function HEX2RGB($hex) { if(strlen($hex) == 3) { $r = hexdec($hex[0].$hex[0]); $g = hexdec($hex[1].$hex[1]); $b = hexdec($hex[2].$hex[2]); } else { $r = hexdec($hex[0].$hex[1]); $g = hexdec($hex[2].$hex[3]); $b = hexdec($hex[4].$hex[5]); } //return sscanf($hex, "#%02x%02x%02x"); return array('r' => $r, 'g' => $g, 'b' => $b); } ?>