2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

31_MilightDevice: added white "hsv" transitions, fixed RGB

60_allergy: updated help text

git-svn-id: https://svn.fhem.de/fhem/trunk@11024 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
markus-m 2016-03-07 22:20:58 +00:00
parent 66dd148781
commit 244296abea
4 changed files with 239 additions and 42 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
- feature 31_MilightDevice: added white "hsv" transitions, fixed RGB
- feature 49_SSCAM: Reading "CamLastRec" added which contains Path/name
of last recording
- feature: FB_CALLLIST: new attribute "expire-calls-after" to automatically

View File

@ -80,7 +80,8 @@ sub MilightBridge_Define($$)
my $sock = IO::Socket::INET-> new (
PeerPort => 48899,
Blocking => 0,
Proto => $attr{$name}{"protocol"}) or return "can't bind: $@";
Proto => $attr{$name}{"protocol"},
Broadcast => 1) or return "can't bind: $@";
my $select = IO::Select->new($sock);
$hash->{SOCKET} = $sock;
$hash->{SELECT} = $select;

View File

@ -135,7 +135,7 @@ sub MilightDevice_Define($$)
# Validate parameters
return "wrong syntax: define <name> MilightDevice <devType(RGB|RGBW|White)> <IODev> <slot>" if(@args < 5);
return "unknown LED type ($hash->{LEDTYPE}): choose one of RGB, RGBW, White" if !($hash->{LEDTYPE} ~~ ['RGB', 'RGBW', 'White']);
return "unknown LED type ($hash->{LEDTYPE}): choose one of RGB, RGBW, White" if ($hash->{LEDTYPE} !~ /RGBW|White|RGB/);
return "Invalid slot: Select one of 1..4 / A for White" if (($hash->{SLOTID} !~ /^\d*$/) || (($hash->{SLOT} ne 'A') && (($hash->{SLOT} < 1) || ($hash->{SLOT} > 4))) && ($hash->{LEDTYPE} eq 'White'));
return "Invalid slot: Select one of 5..8 / A for RGBW" if (($hash->{SLOTID} !~ /^\d*$/) || (($hash->{SLOT} ne 'A') && (($hash->{SLOT} < 5) || ($hash->{SLOT} > 8))) && ($hash->{LEDTYPE} eq 'RGBW'));
return "Invalid slot: Select 0 for RGB" if (($hash->{SLOTID} !~ /^\d*$/) || ($hash->{SLOTID} != 0 && $hash->{LEDTYPE} eq 'RGB'));
@ -168,14 +168,14 @@ sub MilightDevice_Define($$)
my $baseCmds = "on off toggle dimup dimdown";
my $sharedCmds = "pair unpair";
my $rgbCmds = "hsv rgb:colorpicker,RGB hue:colorpicker,HUE,0,1,360 saturation:slider,0,100,100 restorePreviousState:noArg saveState:noArg restoreState:noArg preset";
my $sharedCmds = "pair unpair restorePreviousState:noArg saveState:noArg restoreState:noArg";
my $rgbCmds = "hsv rgb:colorpicker,RGB hue:colorpicker,HUE,0,1,360 saturation:slider,0,100,100 preset";
$hash->{helper}->{COMMANDSET} = "$baseCmds discoModeUp:noArg discoSpeedUp:noArg discoSpeedDown:noArg night:noArg white:noArg toggleWhite:noArg $sharedCmds $rgbCmds"
if ($hash->{LEDTYPE} eq 'RGBW');
$hash->{helper}->{COMMANDSET} = "$baseCmds discoModeUp:noArg discoModeDown:noArg discoSpeedUp:noArg discoSpeedDown:noArg $sharedCmds $rgbCmds"
if ($hash->{LEDTYPE} eq 'RGB');
$hash->{helper}->{COMMANDSET} = "$baseCmds ct:colorpicker,CT,3000,320,6500 night:noArg $sharedCmds"
$hash->{helper}->{COMMANDSET} = "$baseCmds hsv ct:colorpicker,CT,3000,350,6500 night:noArg $sharedCmds"
if ($hash->{LEDTYPE} eq 'White');
my $defaultcommandset = $hash->{helper}->{COMMANDSET};
@ -342,10 +342,12 @@ sub MilightDevice_Set(@)
elsif ($cmd eq 'hsv')
{
$usage = "Usage: set $name hsv <h(0..360)>,<s(0..100)>,<v(0..100)> [seconds(0..x)] [flags(l=long path|q=don't clear queue)]";
return $usage if ($args[0] !~ /^(\d{1,3}),(\d{1,3}),(\d{1,3})$/);
$usage = "Usage: set $name hsv <h(3000=Warm..6500=Cool)>,<s(-)>,<v(0..100)> [seconds(0..x)] [flags(q=don't clear queue)]" if ($hash->{LEDTYPE} eq 'White');
return $usage if ($args[0] !~ /^(\d{1,4}),(\d{1,3}),(\d{1,3})$/);
my ($h, $s, $v) = ($1, $2, $3);
return "Invalid hue ($h): valid range 0..360" if !(($h >= 0) && ($h <= 360));
return "Invalid saturation ($s): valid range 0..100" if !(($s >= 0) && ($s <= 100));
return "Invalid hue ($h): valid range 0..360" if (!(($h >= 0) && ($h <= 360)) && ($hash->{LEDTYPE} ne 'White'));
return "Invalid color temperature ($h): valid range 3000..6500" if (!(($h >= 3000) && ($h <= 6500)) && ($hash->{LEDTYPE} eq 'White'));
return "Invalid saturation ($s): valid range 0..100" if (!(($s >= 0) && ($s <= 100)) && ($hash->{LEDTYPE} ne 'White'));
return "Invalid brightness ($v): valid range 0..100" if !(($v >= 0) && ($v <= 100));
if (defined($args[1]))
{
@ -357,6 +359,7 @@ sub MilightDevice_Set(@)
return $usage if ($args[2] !~ m/.*[lLqQ].*/); # Flags l=Long way round for transition, q=don't clear queue (add to end)
$flags = $args[2];
}
return MilightDevice_White_Transition($hash, $h, 0, $v, $ramp, $flags) if($hash->{LEDTYPE} eq 'White');
return MilightDevice_HSV_Transition($hash, $h, $s, $v, $ramp, $flags);
}
@ -364,7 +367,7 @@ sub MilightDevice_Set(@)
elsif ($cmd eq 'dim' || $cmd eq 'brightness')
{
$usage = "Usage: set $name dim <percent(0..100)> [seconds(0..x)] [flags(l=long path|q=don't clear queue)]";
return $usage if (($args[0] !~ /^\d+$/) || (!($args[0] ~~ [0..100]))); # Decimal value for percent between 0..100
return $usage if (($args[0] !~ /^\d+$/) || ($args[0] < 0) || ($args[0] > 100)); # Decimal value for percent between 0..100
if (defined($args[1]))
{
return $usage if (($args[1] !~ /^\d+$/) && ($args[1] > 0)); # Decimal value for ramp > 0
@ -395,7 +398,7 @@ sub MilightDevice_Set(@)
elsif ($cmd eq 'hue')
{
$usage = "Usage: set $name hue <h(0..360)> [seconds(0..x)] [flags(l=long path|q=don't clear queue)]";
return $usage if (($args[0] !~ /^(\d+)$/) || (!($args[0] ~~ [0..360])));
return $usage if (($args[0] !~ /^(\d+)$/) || ($args[0] < 0) || ($args[0] > 360));
if (defined($args[1]))
{
return $usage if (($args[1] !~ /^\d+$/) && ($args[1] > 0)); # Decimal value for ramp > 0
@ -416,7 +419,7 @@ sub MilightDevice_Set(@)
{
if (defined($args[0]))
{
return "Usage: set $name ct <3000=Warm..6500=Cool>" if (($args[0] !~ /^\d+$/) || (!($args[0] ~~ [2500..7000])));
return "Usage: set $name ct <3000=Warm..6500=Cool>" if (($args[0] !~ /^\d+$/) || ($args[0] < 2500 || $args[0] > 7000));
}
if (defined($args[1]))
{
@ -436,7 +439,7 @@ sub MilightDevice_Set(@)
{
$usage = "Usage: set $name rgb RRGGBB [seconds(0..x)] [flags(l=long path|q=don't clear queue)]";
return $usage if ($args[0] !~ /^([0-9A-Fa-f]{1,2})([0-9A-Fa-f]{1,2})([0-9A-Fa-f]{1,2})$/);
my( $r, $g, $b ) = (hex($1)/255.0, hex($2)/255.0, hex($3)/255.0);
my( $r, $g, $b ) = (hex($1), hex($2), hex($3)); #change to color.pm?
my( $h, $s, $v ) = Color::rgb2hsv($r,$g,$b);
$h = MilightDevice_roundfunc($h * 360);
$s = MilightDevice_roundfunc($s * 100);
@ -461,7 +464,7 @@ sub MilightDevice_Set(@)
my $percentChange = MilightDevice_roundfunc(100 / MilightDevice_DimSteps($hash)); # Default one dimStep
if (defined($args[0]))
{ # Percent change (0..100%)
return $usage if (($args[0] !~ /^\d+$/) || (!($args[0] ~~ [0..100]))); # Decimal value for percent between 0..100
return $usage if (($args[0] !~ /^\d+$/) || ($args[0] < 0) || ($args[0] > 100)); # Decimal value for percent between 0..100
$percentChange = $args[0]; # Percentage to change, will be converted in dev specific function
}
if (defined($args[1]))
@ -492,7 +495,7 @@ sub MilightDevice_Set(@)
my $percentChange = MilightDevice_roundfunc(100 / MilightDevice_DimSteps($hash)); # Default one dimStep
if (defined($args[0]))
{ # Percent change (0..100%)
return $usage if (($args[0] !~ /^\d+$/) || (!($args[0] ~~ [0..100]))); # Decimal value for percent between 0..100
return $usage if (($args[0] !~ /^\d+$/) || ($args[0] < 0) || ($args[0] > 100)); # Decimal value for percent between 0..100
$percentChange = $args[0]; # Percentage to change, will be converted in dev specific function
}
if (defined($args[1]))
@ -519,7 +522,7 @@ sub MilightDevice_Set(@)
elsif ($cmd eq 'saturation')
{
$usage = "Usage: set $name saturation <h(0..100)> [seconds(0..x)] [flags(q=don't clear queue)]";
return $usage if (($args[0] !~ /^\d+$/) || (!($args[0] ~~ [0..100])));
return $usage if (($args[0] !~ /^\d+$/) || ($args[0] < 0) || ($args[0] > 100));
if (defined($args[1]))
{
return $usage if (($args[1] !~ /^\d+$/) && ($args[1] > 0)); # Decimal value for ramp > 0
@ -659,6 +662,7 @@ sub MilightDevice_Get(@)
return ReadingsVal($name, "rgb", "FFFFFF");
}
elsif($cmd eq "hsv") {
return MilightDevice_HSVToStr($hash, ReadingsVal($hash->{NAME}, "ct", 3000), 0, ReadingsVal($hash->{NAME}, "brightness", 0)) if ($hash->{LEDTYPE} eq 'White');
return MilightDevice_HSVToStr($hash, ReadingsVal($hash->{NAME}, "hue", 0), ReadingsVal($hash->{NAME}, "saturation", 0), ReadingsVal($hash->{NAME}, "brightness", 0));
}
@ -726,7 +730,7 @@ sub MilightDevice_Attr(@)
}
elsif ($cmd eq 'set' && $attribName eq 'defaultBrightness')
{
return "defaultBrighness: has to be between ".MilightDevice_roundfunc(100/MilightDevice_DimSteps($hash))." and 100" unless ($attribVal ~~ [MilightDevice_roundfunc(100/MilightDevice_DimSteps($hash))..100]);
return "defaultBrighness: has to be between ".MilightDevice_roundfunc(100/MilightDevice_DimSteps($hash))." and 100" if ($attribVal < MilightDevice_roundfunc(100/MilightDevice_DimSteps($hash)) || $attribVal > 100);
}
return undef;
@ -1392,7 +1396,7 @@ sub MilightDevice_White_Dim(@)
{
my ($hash, $level, $ramp, $flags) = @_;
Log3 ($hash, 4, "$hash->{NAME}_White_Dim: Brightness: $level; Ramp: $ramp; Flags: $flags");
return MilightDevice_HSV_Transition($hash, 0, 0, $level, $ramp, $flags);
return MilightDevice_HSV_Transition($hash, ReadingsVal($hash->{NAME}, "ct", 3000), 0, $level, $ramp, $flags);
}
#####################################
@ -1408,11 +1412,58 @@ sub MilightDevice_White_SetHSV(@)
# Validate brightness
$val = 100 if ($val > 100);
$val = 0 if ($val < 0);
# Validate colour temperature
$hue = 6500 if ($hue > 6500);
$hue = 3000 if ($hue < 3000);
my $oldHueStep = MilightDevice_White_ct_hwValue($hash, ReadingsVal($hash->{NAME}, "ct", 6500));
my $newHueStep = MilightDevice_White_ct_hwValue($hash, $hue);
$hue = MilightDevice_White_ct_hwValue($hash, $newHueStep);
# Set colour temperature
if ($oldHueStep != $newHueStep)
{
IOWrite($hash, @WhiteCmdsOn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd); # group on
if ($oldHueStep > $newHueStep)
{
Log3 ($hash, 4, "$hash->{NAME}_setColourTemp: Decrease from $oldHueStep to $newHueStep");
for (my $i=$oldHueStep; $i > $newHueStep; $i--)
{
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd); # Cooler (colourtemp up)
}
}
elsif ($oldHueStep < $newHueStep)
{
Log3 ($hash, 4, "$hash->{NAME}_setColourTemp: Increase from $oldHueStep to $newHueStep");
for (my $i=$oldHueStep; $i < $newHueStep; $i++)
{
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd); # Warmer (colourtemp down)
}
}
if(AttrVal($hash->{NAME}, "dimOffWhite", 0) == 1)
{
if($newHueStep == 1)
{
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColDn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
}
elsif($newHueStep == 11)
{
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
IOWrite($hash, @WhiteCmdColUp[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd);
}
}
}
# apply gamma correction
my $gammaVal = $hash->{helper}->{GAMMAMAP}[$val];
# Calculate brightness hardware value (11 steps for white)
# Calculate brightness hardware value (10 steps / 11 positions for white)
my $maxWl = (100 / MilightDevice_DimSteps($hash));
my $wl = MilightDevice_roundfunc($gammaVal / $maxWl);
@ -1426,7 +1477,7 @@ sub MilightDevice_White_SetHSV(@)
}
# Store new values for colourTemperature and Brightness
MilightDevice_SetHSV_Readings($hash, ReadingsVal($hash->{NAME}, "ct", 1), 0, $val);
MilightDevice_SetHSV_Readings($hash, $hue, 0, $val);
# Make sure we actually send off command if we should be off
if ($wl == 0)
@ -1435,7 +1486,6 @@ sub MilightDevice_White_SetHSV(@)
IOWrite($hash, @WhiteCmdsOff[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd) if ($repeat eq 1); # group off
Log3 ($hash, 4, "$hash->{NAME}_White_setHSV: OFF");
}
elsif ($wl == $maxWl)
{
IOWrite($hash, @WhiteCmdsOn[$hash->{SLOTID} -1]."\x00".$WhiteCmdEnd); # group on
@ -1446,7 +1496,6 @@ sub MilightDevice_White_SetHSV(@)
}
Log3 ($hash, 4, "$hash->{NAME}_White_setHSV: Full Brightness");
}
else
{
# Not off or MAX brightness, so make sure we are on
@ -1463,7 +1512,6 @@ sub MilightDevice_White_SetHSV(@)
$hash->{helper}->{whiteLevel} = $i - 1;
}
}
elsif ($hash->{helper}->{whiteLevel} < $wl)
{
# Brightness level should be increased
@ -1475,7 +1523,6 @@ sub MilightDevice_White_SetHSV(@)
$hash->{helper}->{whiteLevel} = $i + 1;
}
}
else
{
Log3 ($hash, 4, "$hash->{NAME}_White_setHSV: ON");
@ -1490,14 +1537,14 @@ sub MilightDevice_White_SetHSV(@)
#####################################
sub MilightDevice_White_SetColourTemp(@)
{
# $hue is colourTemperature (1-10), $val is brightness (0-100%)
# $hue is colourTemperature (1-11), $val is brightness (0-100%)
my ($hash, $hue) = @_;
my $name = $hash->{NAME};
MilightDevice_CmdQueue_Clear($hash);
# Save old value of ct
my $oldHue = MilightDevice_White_ct_hwValue($hash, ReadingsVal($hash->{NAME}, "ct", 1));
my $oldHue = MilightDevice_White_ct_hwValue($hash, ReadingsVal($hash->{NAME}, "ct", 6500));
# Store new values for colourTemperature and Brightness
MilightDevice_SetHSV_Readings($hash, $hue, 0, ReadingsVal($hash->{NAME}, "brightness", AttrVal($hash->{NAME}, "defaultBrightness", 36) ) );
# Validate colourTemperature (11 steps)
@ -1557,17 +1604,28 @@ sub MilightDevice_White_ct_hwValue(@)
my ($hash, $ct) = @_;
# Couldn't get switch statement to work so using if
if ($ct == 11) { return 3000; }
elsif ($ct == 10) { return 3350; }
elsif ($ct == 9) { return 3700; }
elsif ($ct == 8) { return 4050; }
elsif ($ct == 7) { return 4400; }
elsif ($ct == 6) { return 4750; }
elsif ($ct == 5) { return 5100; }
elsif ($ct == 4) { return 5450; }
elsif ($ct == 3) { return 5800; }
elsif ($ct == 2) { return 6150; }
elsif ($ct == 1) { return 6500; }
if ($ct < 3320) { return 11; }
elsif ($ct < 3640) { return 10; }
elsif ($ct < 3960) { return 9; }
elsif ($ct < 4280) { return 8; }
elsif ($ct < 4600) { return 7; }
elsif ($ct < 4920) { return 6; }
elsif ($ct < 5240) { return 5; }
elsif ($ct < 5560) { return 4; }
elsif ($ct < 5880) { return 3; }
elsif ($ct < 6200) { return 2; }
elsif ($ct < 3350) { return 11; }
elsif ($ct < 3700) { return 10; }
elsif ($ct < 4050) { return 9; }
elsif ($ct < 4400) { return 8; }
elsif ($ct < 4750) { return 7; }
elsif ($ct < 5100) { return 6; }
elsif ($ct < 5450) { return 5; }
elsif ($ct < 5800) { return 4; }
elsif ($ct < 6150) { return 3; }
elsif ($ct < 6500) { return 2; }
return 1;
}
@ -1579,7 +1637,7 @@ sub MilightDevice_HSVFromStr(@)
# Convert HSV values from string in format "h,s,v"
my ($hash, @args) = @_;
if ((!defined($args[0])) || ($args[0] !~ /^(\d{1,3}),(\d{1,3}),(\d{1,3})$/))
if ((!defined($args[0])) || ($args[0] !~ /^(\d{1,4}),(\d{1,3}),(\d{1,3})$/))
{
Log3 ($hash, 3, "MilightDevice_HSVFromStr: Could not parse h,s,v values from $args[0]");
return (0, 0, 0);
@ -1608,7 +1666,9 @@ sub MilightDevice_ValidateHSV(@)
# Validate and return valid values for HSV
my ($hash, $h, $s, $v) = @_;
$h = 0 if ($h < 0);
$h = 360 if ($h > 360);
$h = 360 if ($h > 360 && $hash->{LEDTYPE} ne 'White');
$h = 3000 if ($h < 3000 && $hash->{LEDTYPE} eq 'White');
$h = 6500 if ($h > 6500);
$s = 0 if ($s < 0);
$s = 100 if ($s > 100);
$v = 0 if ($v < 0);
@ -1765,6 +1825,14 @@ sub MilightDevice_HSV_Transition(@)
$steps = $maxSteps;
}
# Calculate number of steps, limit to max number (no point running more if they are the same)
$steps = int($ramp * 1000 / $stepWidth);
if ($steps > $maxSteps)
{
$stepWidth *= ($steps/$maxSteps);
$steps = $maxSteps;
}
# Calculate minimum stepWidth
# Min bridge delay as specified by Bridge * 3 (eg. 100*3=300ms).
# On average min 3 commands need to be sent per step (eg. Group On; Mode; Brightness;) so this gets it approximately right
@ -1802,6 +1870,134 @@ sub MilightDevice_HSV_Transition(@)
return undef;
}
#####################################
sub MilightDevice_White_Transition(@)
{
my ($hash, $ct, $sat, $val, $ramp, $flags) = @_;
my ($ctFrom, $valFrom, $timeFrom)=0;
# Clear command queue if flag "q" not specified
MilightDevice_CmdQueue_Clear($hash) if ($flags !~ m/.*[qQ].*/);
# if queue in progress set start vals to last cached hsv target, else set start to actual hsv
if (@{$hash->{helper}->{cmdQueue}} > 0)
{
$ctFrom = $hash->{helper}->{targetCt};
$valFrom = $hash->{helper}->{targetVal};
$timeFrom = $hash->{helper}->{targetTime};
$ctFrom = 3000 if(!defined($ctFrom));
$valFrom = 0 if(!defined($valFrom));
$timeFrom = 0 if(!defined($timeFrom));
Log3 ($hash, 5, "$hash->{NAME}_White_Transition: Prepare Start (cached): $ctFrom,$valFrom@".$timeFrom);
}
else
{
$ctFrom = ReadingsVal($hash->{NAME}, "ct", 3000);
$valFrom = ReadingsVal($hash->{NAME}, "brightness", 0);
$timeFrom = gettimeofday();
Log3 ($hash, 5, "$hash->{NAME}_White_Transition: Prepare Start (actual): $ctFrom,$valFrom@".$timeFrom);
if ($flags !~ m/.*[pP].*/)
{
# Store previous state if different to requested state
if (($ctFrom != $ct) || ($valFrom != $val))
{
readingsSingleUpdate($hash, "previousState", MilightDevice_HSVToStr($hash, $ctFrom, 0, $valFrom),1);
}
}
}
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Current: $ctFrom,$valFrom");
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Set: $ct,$val; Ramp: $ramp; Flags: ". $flags);
# Store target vales
$hash->{helper}->{targetCt} = $ct;
$hash->{helper}->{targetVal} = $val;
# if there is no ramp we don't need transition
if (($ramp || 0) == 0)
{
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Set: $ct,$val; No Ramp");
$hash->{helper}->{targetTime} = $timeFrom;
return MilightDevice_CmdQueue_Add($hash, $ct, 0, $val, undef, 0, undef);
}
my $vFade = abs($val - $valFrom);
my $ctFade = abs($ct - $ctFrom);
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Colour temp: $ctFade, Brightness: $vFade;");
# No transition, so set immediately and ignore ramp setting
if ($ctFade == 0 && $vFade == 0)
{
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Unchanged. Set: $ct,0,$val; Ignoring Ramp");
$hash->{helper}->{targetTime} = $timeFrom;
return MilightDevice_CmdQueue_Add($hash, $ct, 0, $val, undef, 0, undef);
}
my ($stepWidth, $steps, $maxSteps, $ctToSet, $ctStep, $valToSet, $valStep);
# Calculate stepWidth
if ($ctFade >= $vFade)
{
# Transition based on ct, so max steps = colourSteps
$stepWidth = ($ramp * 1000 / $ctFade /100); # how long is one step (set hsv) in ms based on ct
$maxSteps = MilightDevice_ColourSteps($hash);
}
else
{
# Transition based on Brightness, so max steps = dimSteps
$stepWidth = ($ramp * 1000 / $vFade); # how long is one step (set hsv) in ms based on val
$maxSteps = MilightDevice_DimSteps($hash);
}
# Calculate number of steps, limit to max number (no point running more if they are the same)
$steps = int($ramp * 1000 / $stepWidth);
if ($steps > $maxSteps)
{
$stepWidth *= ($steps/$maxSteps);
$steps = $maxSteps;
}
# Calculate number of steps, limit to max number (no point running more if they are the same)
$steps = int($ramp * 1000 / $stepWidth);
if ($steps > $maxSteps)
{
$stepWidth *= ($steps/$maxSteps);
$steps = $maxSteps;
}
# Calculate minimum stepWidth
# Min bridge delay as specified by Bridge * 3 (eg. 100*3=300ms).
# On average min 3 commands need to be sent per step (eg. Group On; Mode; Brightness;) so this gets it approximately right
my $minStepWidth = $hash->{IODev}->{INTERVAL} * 3;
$stepWidth = $minStepWidth if ($stepWidth < $minStepWidth); # Make sure we have min stepWidth
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Steps: $steps; Step Interval(ms): $stepWidth");
# Calculate hue step
$ctToSet = $ctFrom; # Start at current hue
$ctStep = ($ct - $ctFrom) / $steps;
# Calculate brightness step
$valToSet = $valFrom; # Start at current brightness
$valStep = ($val - $valFrom) / $steps;
for (my $i=1; $i <= $steps; $i++)
{
$ctToSet += $ctStep; # Increment new hue by step (negative step decrements)
$valToSet += $valStep; # Increment new brightness by step (negative step decrements)
Log3 ($hash, 4, "$hash->{NAME}_White_Transition: Add to Queue: ct:".(int($ctToSet)).", s:0, v:".(int($valToSet))." ($i/$steps)");
MilightDevice_CmdQueue_Add($hash, MilightDevice_roundfunc($ctToSet), 0, MilightDevice_roundfunc($valToSet), undef, $stepWidth, $timeFrom + (($i-1) * $stepWidth / 1000) );
}
# Set target time for completion of sequence.
# This may be slightly higher than what was requested since $stepWidth > minDelay (($steps * $stepWidth) > $ramp)
$hash->{helper}->{targetTime} = $timeFrom + ($steps * $stepWidth / 1000);
Log3 ($hash, 5, "$hash->{NAME}_White_Transition: TargetTime: $hash->{helper}->{targetTime}");
return undef;
}
#####################################
sub MilightDevice_SetHSV_Readings(@)
{
@ -1840,6 +2036,7 @@ sub MilightDevice_SetHSV_Readings(@)
elsif ($hash->{LEDTYPE} eq 'White')
{
readingsBulkUpdate($hash, "ct", $hue);
readingsBulkUpdate($hash, "hsv", MilightDevice_HSVToStr($hash, $hue,0,$val));
}
readingsBulkUpdate($hash, "state", "on $val") if ($val > 1);
readingsBulkUpdate($hash, "state", "off") if ($val < 2);

View File

@ -290,7 +290,6 @@ sub allergy_utf8clean($) {
<a name="allergy"></a>
<h3>allergy</h3>
<div style="width:800px">
<ul>
This modul provides allergy forecast data for Germany.<br/>
It requires the Perl module XML::Simple to be installed
@ -351,7 +350,7 @@ sub allergy_utf8clean($) {
</li><br>
<li><code>levelsFormat</code>
<br>
Localize levels by adding them comma separated (default: -,low,moderate,high)
Localize levels by adding them comma separated (default: -,low,moderate,high,extreme)
</li><br>
<li><code>weekdaysFormat</code>
<br>
@ -359,7 +358,6 @@ sub allergy_utf8clean($) {
</li><br>
</ul>
</ul>
</div>
=end html
=begin html_DE
@ -430,11 +428,11 @@ sub allergy_utf8clean($) {
<br>
Aktualisierung von Allergenen, die sonst durch die ignoreList entfernt werden.
</li><br>
<li><code>levelsFormat (Standard: -, low, moderate, high)</code>
<li><code>levelsFormat (Standard: -,low,moderate,high,extreme)</code>
<br>
Lokalisierte Levels, durch Kommas getrennt.
</li><br>
<li><code>weekdaysFormat (Standard: Sun, Mon, Tue, Wed, Tue, Fri, Sat)</code>
<li><code>weekdaysFormat (Standard: Sun,Mon,Tue,Wed,Thu,Fri,Sat)</code>
<br>
Lokalisierte Wochentage, durch Kommas getrennt.
</li><br>