diff --git a/fhem/CHANGED b/fhem/CHANGED index c5a341718..b1c54d6b1 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -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. + - bugfix: 30_MilightBridge/31_MilightDevice: Fix startup restore. Fix crash on invalid hostname. - feature: 30_pilight_xyz: possibility to change IO-Device (IODEV) - bugfix: YAMAHA_AVR: fixing not correctly volume smoothing - change: 49_SSCam: turned completly to HttpUtils_NonblockingGet for diff --git a/fhem/FHEM/30_MilightBridge.pm b/fhem/FHEM/30_MilightBridge.pm index 8cada688e..769efd3c3 100644 --- a/fhem/FHEM/30_MilightBridge.pm +++ b/fhem/FHEM/30_MilightBridge.pm @@ -296,7 +296,7 @@ sub MilightBridge_CmdQueue_Send(@) # Check if we are called again before send interval has elapsed my $now = gettimeofday(); - if (($hash->{cmdLastSent} + ($hash->{INTERVAL} / 1000)) < $now) + if ((($hash->{cmdLastSent} + ($hash->{INTERVAL} / 1000)) < $now) && $init_done) { # Lock cmdQueue $hash->{cmdQueueLock} = 1; @@ -318,7 +318,14 @@ sub MilightBridge_CmdQueue_Send(@) # Check bridge is not disabled, and send command if (!IsDisabled($hash->{NAME})) { - my $portaddr = sockaddr_in($hash->{PORT}, inet_aton($hash->{HOST})); + my $hostip = inet_aton($hash->{HOST}); + if (!defined($hostip) || $hostip eq '') + { + Log3 ($hash, 3, "$hash->{NAME}: Could not resolve hostname " . $hash->{HOST}); + return undef; + } + # sockaddr_in crashes if ip address is undef + my $portaddr = sockaddr_in($hash->{PORT}, $hostip); if (!send($hash->{SOCKET}, $command, 0, $portaddr)) { # Send failed @@ -334,6 +341,11 @@ sub MilightBridge_CmdQueue_Send(@) } } } + elsif (!$init_done) + { + # fhem not initialized, wait for init + Log3 ($hash, 3, "$hash->{NAME}_cmdQueue_Send: init not done, delay sending from queue"); + } else { # We were called again before send interval elapsed diff --git a/fhem/FHEM/31_MilightDevice.pm b/fhem/FHEM/31_MilightDevice.pm index 0234984e9..d1b168ba4 100644 --- a/fhem/FHEM/31_MilightDevice.pm +++ b/fhem/FHEM/31_MilightDevice.pm @@ -119,7 +119,8 @@ sub MilightDevice_Define($$) my ($hash, $def) = @_; my @args = split("[ \t][ \t]*", $def); my ($name, $type, $ledtype, $iodev, $slot) = @args; - + + $hash->{INIT} = 0; # Set to 1 when lamp initialised (MilightDevice_Restore) $hash->{LEDTYPE} = $ledtype; $hash->{SLOT} = $slot; $hash->{SLOTID} = $slot; @@ -204,8 +205,6 @@ sub MilightDevice_Define($$) # IODev $attr{$name}{IODev} = $hash->{IODev} if (!defined($attr{$name}{IODev})); - InternalTimer(gettimeofday() + 5, "MilightDevice_Init", $hash, 0); - return undef; } @@ -216,7 +215,7 @@ sub MilightDevice_Init($) if( AttrVal($hash->{NAME}, "gamma", "1.0") eq "1.0") { - Log3 $name, 5, $name." dimstep ".MilightDevice_roundfunc(100/MilightDevice_DimSteps($hash))." / gamma 1.0"; + Log3 ($name, 5, $name." dimstep ".MilightDevice_roundfunc(100 / MilightDevice_DimSteps($hash))." / gamma 1.0"); } else { $hash->{helper}->{COMMANDSET} =~ s/dim:slider,0,.*,100/dim:slider,0,1,100/g; $hash->{helper}->{COMMANDSET} =~ s/brightness:slider,0,.*,100/brightness:slider,0,1,100/g; @@ -224,7 +223,6 @@ sub MilightDevice_Init($) $hash->{helper}->{GAMMAMAP} = MilightDevice_CreateGammaMapping($hash, AttrVal($hash->{NAME}, "gamma", "1.0")); } - # Colormap / Commandsets if (($hash->{LEDTYPE} eq 'RGBW') || ($hash->{LEDTYPE} eq 'RGB')) { @@ -240,10 +238,8 @@ sub MilightDevice_Init($) } } $hash->{helper}->{COLORMAP} = MilightDevice_ColorConverter($hash, @a); - } - return undef; } @@ -729,23 +725,43 @@ sub MilightDevice_Attr(@) sub MilightDevice_Notify(@) { my ($hash,$dev) = @_; - my $events = deviceEvents($dev, 1); - my ($hue, $sat, $val); + #my $events = deviceEvents($dev, 1); + #my ($hue, $sat, $val); - return if($dev->{NAME} ne "global"); - - Log3 ($hash, 5, "$hash->{NAME}_Notify: Triggered by $dev->{NAME}"); - - return if(!grep(m/^INITIALIZED|REREADCFG|DEFINED$/, @{$dev->{CHANGED}})); - - # Clear inProgress flag - readingsSingleUpdate($hash, "transitionInProgress", 0, 1); + return MilightDevice_Restore($hash); + + #return if($dev->{NAME} ne "global"); + #Log3 ($hash, 5, "$hash->{NAME}_Notify: Triggered by $dev->{NAME}"); + #return if(!grep(m/^INITIALIZED|REREADCFG|DEFINED$/, @{$dev->{CHANGED}})); # Restore previous state (as defined in statefile) # wait for global: INITIALIZED after start up - if (@{$events}[0] eq 'INITIALIZED') - { + #if (@{$events}[0] eq 'INITIALIZED') + #{ + # MilightDevice_Restore($hash); + #} + + return undef; +} + +##################################### +# Restore HSV settings from readings. +# Called after initialization to synchronise lamp state with fhem. +sub MilightDevice_Restore(@) +{ + my ($hash) = @_; + + return if ($hash->{INIT}); + if ($init_done) + { + Log3 ($hash, 4, "$hash->{NAME}_Restore: Restoring saved HSV values"); + $hash->{INIT} = 1; + # Initialize device + MilightDevice_Init($hash); + # Clear inProgress flag: MJW Do we still need to do this? + readingsSingleUpdate($hash, "transitionInProgress", 0, 1); # Default to OFF if not defined + my ($hue, $sat, $val); $hue = ReadingsVal($hash->{NAME}, "hue", 0); $sat = ReadingsVal($hash->{NAME}, "saturation", 0); $val = ReadingsVal($hash->{NAME}, "brightness", 0); @@ -755,8 +771,6 @@ sub MilightDevice_Notify(@) return MilightDevice_White_SetHSV($hash, $hue, $sat, $val, 1) if ($hash->{LEDTYPE} eq 'White'); return MilightDevice_RGB_SetHSV($hash, $hue, $sat, $val, 1) if ($hash->{LEDTYPE} eq 'RGB'); } - - return undef; } ############################################################################### @@ -1990,11 +2004,12 @@ sub MilightDevice_CmdQueue_Add(@) sub MilightDevice_CmdQueue_Exec(@) { my ($hash) = @_; - - if ($hash->{IODev}->{STATE} ne "ok" && $hash->{IODev}->{STATE} ne "Initialized") { - InternalTimer(gettimeofday() + 60, "MilightDevice_CmdQueue_Exec", $hash, 0); - return undef; - } + RemoveInternalTimer($hash); + #if ($hash->{IODev}->{STATE} ne "ok" && $hash->{IODev}->{STATE} ne "Initialized") { + # InternalTimer(gettimeofday() + 60, "MilightDevice_CmdQueue_Exec", $hash, 0); + # return undef; + #} + my $actualCmd = @{$hash->{helper}->{cmdQueue}}[0]; @@ -2051,24 +2066,24 @@ sub MilightDevice_CmdQueue_Exec(@) sub MilightDevice_CmdQueue_Clear(@) { my ($hash) = @_; - - if ($hash->{IODev}->{STATE} ne "ok" && $hash->{IODev}->{STATE} ne "Initialized") { - InternalTimer(gettimeofday() + 60, "MilightDevice_CmdQueue_Exec", $hash, 0); - return undef; - } - Log3 ($hash, 4, "$hash->{NAME}_CmdQueue_Clear"); - + RemoveInternalTimer($hash); + #if ($hash->{IODev}->{STATE} ne "ok" && $hash->{IODev}->{STATE} ne "Initialized") { + # InternalTimer(gettimeofday() + 60, "MilightDevice_CmdQueue_Exec", $hash, 0); + # return undef; + #} + readingsSingleUpdate($hash, "transitionInProgress", 0, 1); # Clear inProgress flag - foreach my $args (keys %intAt) - { - if (($intAt{$args}{ARG} eq $hash) && ($intAt{$args}{FN} eq 'MilightDevice_CmdQueue_Exec')) - { - Log3 ($hash, 5, "$hash->{NAME}_CmdQueue_Clear: Remove timer at: ".$intAt{$args}{TRIGGERTIME}); - delete($intAt{$args}); - } - } + #foreach my $args (keys %intAt) + #{ + # if (($intAt{$args}{ARG} eq $hash) && ($intAt{$args}{FN} eq 'MilightDevice_CmdQueue_Exec')) + # { + # Log3 ($hash, 5, "$hash->{NAME}_CmdQueue_Clear: Remove timer at: ".$intAt{$args}{TRIGGERTIME}); + # delete($intAt{$args}); + # } + #} + $hash->{helper}->{cmdQueue} = []; return undef;