# $Id$ package main; use strict; use warnings; use vars qw($FW_ME); sub Color_Initialize() { FHEM_colorpickerInit(); } sub FHEM_colorpickerInit() { $data{webCmdFn}{colorpicker} = "FHEM_colorpickerFn"; $data{FWEXT}{colorpicker}{SCRIPT} = "/jscolor/jscolor.js"; } sub FHEM_colorpickerFn($$$) { my ($FW_wname, $d, $FW_room, $cmd, $values) = @_; my @args = split("[ \t]+", $cmd); return undef if($values !~ m/^colorpicker,(.*)$/); my ($mode) = ($1); $mode = "RGB" if( !defined($mode) ); my $srf = $FW_room ? "&room=$FW_room" : ""; my $cv = CommandGet("","$d $cmd"); $cmd = "" if($cmd eq "state"); if( $args[1] ) { my $c = "cmd=set $d $cmd$srf"; return ''. "
'. '' if( AttrVal($FW_wname, "longpoll", 1)); return ''. "". '
'. '
'. ''; } elsif(AttrVal($d,"realtimePicker",0)) { my $c = "$FW_ME?XHR=1&cmd=set $d $cmd %$srf"; my $ci = $c; $ci = "$FW_ME?XHR=1&cmd=set $d $cmd % : transitiontime 0 : noUpdate$srf" if($defs{$d}->{TYPE} eq "HUEDevice"); return ''. "". ''; } else { my $c = "$FW_ME?XHR=1&cmd=set $d $cmd %$srf"; return ''. "". ''; } } my %dim_values = ( 0 => "dim06%", 1 => "dim12%", 2 => "dim18%", 3 => "dim25%", 4 => "dim31%", 5 => "dim37%", 6 => "dim43%", 7 => "dim50%", 8 => "dim56%", 9 => "dim62%", 10 => "dim68%", 11 => "dim75%", 12 => "dim81%", 13 => "dim87%", 14 => "dim93%", ); sub Color_devStateIcon($) { my ($rgb) = @_; my @channels = Color::RgbToChannels($rgb,3); my $dim = Color::ChannelsToBrightness(@channels); my $percent = $dim->{bri}; my $RGB = Color::ChannelsToRgb(@{$dim->{channels}}); return ".*:off:toggle" if( $rgb eq "off" || $rgb eq "000000" || $percent == 0 ); $percent = 100 if( $rgb eq "on" ); my $s = $dim_values{int($percent/7)}; $s="on" if( $percent eq "100" ); return ".*:$s@#$RGB:toggle" if( $percent < 100 ); return ".*:on@#$rgb:toggle"; } package Color; require Exporter; our @ISA = qw(Exporter); our %EXPORT_TAGS = (all => [qw(RgbToChannels ChannelsToRgb ChannelsToBrightness BrightnessToChannels)]); Exporter::export_tags('all'); sub RgbToChannels($$) { my ($rgb,$numChannels) = @_; my @channels = (); foreach my $channel (unpack("(A2)[$numChannels]",$rgb)) { push @channels,hex($channel); } return @channels; } sub ChannelsToRgb(@) { my @channels = @_; return sprintf("%02X" x @_, @_); } sub ChannelsToBrightness(@) { my (@channels) = @_; my $max = 0; foreach my $value (@channels) { $max = $value if ($max < $value); } my @bri = (); if( $max == 0) { @bri = (0) x @channels; } else { my $norm = 255/$max; foreach my $value (@channels) { push @bri,int($value*$norm); } } return { bri => int($max/2.55), channels => \@bri, } } sub BrightnessToChannels($) { my $arg = shift; my @channels = (); my $bri = $arg->{bri}; foreach my $value (@{$arg->{channels}}) { push @channels,$value*$bri/100; } return @channels; } sub rgb2hsv($$$) { my( $r, $g, $b ) = @_; my( $h, $s, $v ); my $M = ::maxNum( $r, $g, $b ); my $m = ::minNum( $r, $g, $b ); my $c = $M - $m; if ( $c == 0 ) { $h = 0; } elsif ( $M == $r ) { $h = ( 60 * ( ( $g - $b ) / $c ) % 360 ) / 360; } elsif ( $M == $g ) { $h = ( 60 * ( ( $b - $r ) / $c ) + 120 ) / 360; } elsif ( $M == $b ) { $h = ( 60 * ( ( $r - $g ) / $c ) + 240 ) / 360; } if ( $M == 0 ) { $s = 0; } else { $s = $c / $M; } $v = $M; return( $h,$s,$v ); } sub hsv2rgb($$$) { my ( $h, $s, $v ) = @_; my $r = 0.0; my $g = 0.0; my $b = 0.0; if ( $s == 0 ) { $r = $v; $g = $v; $b = $v; } else { my $i = int( $h * 6.0 ); my $f = ( $h * 6.0 ) - $i; my $p = $v * ( 1.0 - $s ); my $q = $v * ( 1.0 - $s * $f ); my $t = $v * ( 1.0 - $s * ( 1.0 - $f ) ); $i = $i % 6; if ( $i == 0 ) { $r = $v; $g = $t; $b = $p; } elsif ( $i == 1 ) { $r = $q; $g = $v; $b = $p; } elsif ( $i == 2 ) { $r = $p; $g = $v; $b = $t; } elsif ( $i == 3 ) { $r = $p; $g = $q; $b = $v; } elsif ( $i == 4 ) { $r = $t; $g = $p; $b = $v; } elsif ( $i == 5 ) { $r = $v; $g = $p; $b = $q; } } return( $r,$g,$b ); } 1;