From 92a4c47d93dfab1b4a49744dbddd26b342d82010 Mon Sep 17 00:00:00 2001 From: ntruchsess <> Date: Sat, 15 Mar 2014 10:56:24 +0000 Subject: [PATCH] FRM: defer initialization after global init is done (all FRM-devices) git-svn-id: https://svn.fhem.de/fhem/trunk@5226 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_OWX.pm | 2 +- fhem/FHEM/10_FRM.pm | 137 +++++++++++++++++++++++------------- fhem/FHEM/20_FRM_AD.pm | 27 ++++--- fhem/FHEM/20_FRM_I2C.pm | 41 +++++++---- fhem/FHEM/20_FRM_IN.pm | 119 ++++++++++++++++--------------- fhem/FHEM/20_FRM_LCD.pm | 57 +++++++++------ fhem/FHEM/20_FRM_OUT.pm | 28 +++++--- fhem/FHEM/20_FRM_PWM.pm | 28 +++++--- fhem/FHEM/20_FRM_RGB.pm | 55 +++++++++------ fhem/FHEM/20_FRM_ROTENC.pm | 26 ++++--- fhem/FHEM/20_FRM_SERVO.pm | 35 +++++---- fhem/FHEM/20_FRM_STEPPER.pm | 28 +++++--- 12 files changed, 348 insertions(+), 235 deletions(-) diff --git a/fhem/FHEM/00_OWX.pm b/fhem/FHEM/00_OWX.pm index 0303f54be..ef888b9dd 100644 --- a/fhem/FHEM/00_OWX.pm +++ b/fhem/FHEM/00_OWX.pm @@ -225,7 +225,7 @@ sub OWX_Define ($$) { if (!OWX_Detect($hash)){ $hash->{PRESENT} = 0; readingsSingleUpdate($hash,"state","failed",1); - $init_done = 1; + # $init_done = 1; return undef; } #-- Fourth step: discovering devices on the bus diff --git a/fhem/FHEM/10_FRM.pm b/fhem/FHEM/10_FRM.pm index 3c38f091d..51613a34b 100755 --- a/fhem/FHEM/10_FRM.pm +++ b/fhem/FHEM/10_FRM.pm @@ -48,7 +48,8 @@ sub FRM_Initialize($) { $hash->{GetFn} = "FRM_Get"; $hash->{SetFn} = "FRM_Set"; $hash->{AttrFn} = "FRM_Attr"; - + $hash->{NotifyFn} = "FRM_Notify"; + $hash->{AttrList} = "model:nano dummy:1,0 sampling-interval i2c-config $main::readingFnAttributes"; } @@ -57,35 +58,19 @@ sub FRM_Define($$) { my ( $hash, $def ) = @_; my ($name, $type, $dev, $global) = split("[ \t]+", $def); + $hash->{DeviceName} = $dev; - my $isServer = 1 if($dev && $dev =~ m/^(IPV6:)?\d+$/); -# my $isClient = 1 if($dev && $dev =~ m/^(IPV6:)?.*:\d+$/); - -# return "Usage: define FRM {[@] | [IPV6:] [global]}" -# if(!($isServer || $isClient) || -# ($isClient && $global) || -# ($global && $global ne "global")); - - # Make sure that fhem only runs once - if($isServer) { - my $ret = TcpServer_Open($hash, $dev, $global); - if (!$ret) { - $hash->{STATE}="listening"; - } - return $ret; - } - - DevIo_CloseDev($hash); + $hash->{NOTIFYDEV} = "global"; if ( $dev eq "none" ) { Log3 $name,3,"device is none, commands will be echoed only"; $main::attr{$name}{dummy} = 1; - return undef; } - $hash->{DeviceName} = $dev; + if ($main::init_done) { + return FRM_Start($hash); + } - my $ret = DevIo_OpenDev($hash, 0, "FRM_DoInit"); - return $ret; + return undef; } ##################################### @@ -110,6 +95,46 @@ sub FRM_Undef($) { return undef; } +sub FRM_Start { + my ($hash) = @_; + + my ($dev, $global) = split("[ \t]+", $hash->{DEF}); + $hash->{DeviceName} = $dev; + + my $isServer = 1 if($dev && $dev =~ m/^(IPV6:)?\d+$/); +# my $isClient = 1 if($dev && $dev =~ m/^(IPV6:)?.*:\d+$/); + +# return "Usage: define FRM {[@] | [IPV6:] [global]}" +# if(!($isServer || $isClient) || +# ($isClient && $global) || +# ($global && $global ne "global")); + + # Make sure that fhem only runs once + if($isServer) { + my $ret = TcpServer_Open($hash, $dev, $global); + if (!$ret) { + $hash->{STATE}="listening"; + } + return $ret; + } + + DevIo_CloseDev($hash); + + my $ret = DevIo_OpenDev($hash, 0, "FRM_DoInit"); + return $ret; +} + +sub FRM_Notify { + my ($hash,$dev) = @_; + my $name = $hash->{NAME}; + my $type = $hash->{TYPE}; + + if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) { + FRM_Start($hash); + } elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) { + } +} + ##################################### sub FRM_Set($@) { my ($hash, @a) = @_; @@ -297,22 +322,28 @@ sub FRM_DoInit($) { my ($hash) = @_; - my $name = $hash->{SNAME}; #is this a serversocket-connection? - my $shash = defined $name ? $main::defs{$name} : $hash; - $name = $hash->{NAME};# if (!defined $name); + my $sname = $hash->{SNAME}; #is this a serversocket-connection? + my $shash = defined $sname ? $main::defs{$sname} : $hash; + + my $name = $shash->{NAME}; my $firmata_io = Firmata_IO->new($hash); my $device = Device::Firmata::Platform->attach($firmata_io) or return 1; - $hash->{FirmataDevice} = $device; - $device->observe_string(\&FRM_string_observer,$hash); + $shash->{FirmataDevice} = $device; + if (defined $sname) { + $shash->{SocketDevice} = $hash; + #as FRM_Read gets the connected socket hash, but calls firmatadevice->poll(): + $hash->{FirmataDevice} = $device; + } + $device->observe_string(\&FRM_string_observer,$shash); my $found; # we cannot call $device->probe() here, as it doesn't select bevore read, so it would likely cause IODev to close the connection on the first attempt to read from empty stream my $endTicks = time+5; my $queryTicks = time+2; $device->system_reset(); do { - FRM_poll($hash); + FRM_poll($shash); if ($device->{metadata}{firmware} && $device->{metadata}{firmware_version}) { $device->{protocol}->{protocol_version} = $device->{metadata}{firmware_version}; $main::defs{$name}{firmware} = $device->{metadata}{firmware}; @@ -321,7 +352,7 @@ sub FRM_DoInit($) { $device->analog_mapping_query(); $device->capability_query(); do { - FRM_poll($hash); + FRM_poll($shash); if ($device->{metadata}{analog_mappings} and $device->{metadata}{capabilities}) { my $inputpins = $device->{metadata}{input_pins}; $main::defs{$name}{input_pins} = join(",", sort{$a<=>$b}(@$inputpins)) if (defined $inputpins and scalar @$inputpins); @@ -392,8 +423,6 @@ sub FRM_DoInit($) { } } while (time < $endTicks and !$found); if ($found) { - $shash->{FirmataDevice} = $device; - $shash->{SocketDevice} = $hash; FRM_apply_attribute($shash,"sampling-interval"); FRM_apply_attribute($shash,"i2c-config"); FRM_forall_clients($shash,\&FRM_Init_Client,undef); @@ -401,8 +430,9 @@ sub FRM_DoInit($) { return undef; } Log3 $name,3,"no response from Firmata, closing DevIO"; - DevIo_Disconnected($hash); - delete $hash->{FirmataDevice}; + DevIo_Disconnected($shash); + delete $shash->{FirmataDevice}; + delete $shash->{SocketDevice}; return "FirmataDevice not responding"; } @@ -430,7 +460,7 @@ FRM_Init_Client($@) { my $name = $hash->{NAME}; my $ret = CallFn($name,"InitFn",$hash,$args); if ($ret) { - Log3 $name,2,"error initializing ".$hash->{NAME}.": ".$ret; + Log3 $name,2,"error initializing '".$hash->{NAME}."': ".$ret; } } @@ -449,7 +479,7 @@ FRM_Init_Pin_Client($$$) { if ($@) { $@ =~ /^(.*)( at.*FHEM.*)$/; $hash->{STATE} = "error initializing: ".$1; - return "error initializing '".$hash->{NAME}."': ".$1; + return $1; } return undef; } @@ -462,10 +492,16 @@ FRM_Client_Define($$) $hash->{STATE}="defined"; - eval { - FRM_Init_Client($hash,[@a[2..scalar(@a)-1]]); - }; - return $@; + if ($main::init_done) { + eval { + FRM_Init_Client($hash,[@a[2..scalar(@a)-1]]); + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + return $1; + } + } + return undef; } sub @@ -496,17 +532,17 @@ FRM_Client_Unassign($) } sub -FRM_Client_AssignIOPort($) +FRM_Client_AssignIOPort($@) { - my $hash = shift; + my ($hash,$iodev) = @_; my $name = $hash->{NAME}; - if (my $iodev = AttrVal($name,"IODev",undef)) { - $hash->{IODev} = $defs{$iodev}; - } - AssignIoPort($hash) unless defined($hash->{IODev}); + AssignIoPort($hash,defined $iodev ? $iodev : AttrVal($hash->{NAME},"IODev",undef)); die "unable to assign IODev to '$name'" unless defined ($hash->{IODev}); - $hash->{IODev} = $main::defs{$hash->{IODev}->{SNAME}} if (defined($hash->{IODev}->{SNAME})); + if (defined($hash->{IODev}->{SNAME})) { + $hash->{IODev} = $main::defs{$hash->{IODev}->{SNAME}}; + $attr{$name}{IODev} = $hash->{IODev}{NAME}; + } foreach my $d ( sort keys %main::defs ) { if ( defined( my $dev = $main::defs{$d} )) { @@ -516,7 +552,8 @@ FRM_Client_AssignIOPort($) && $dev->{IODev} == $hash->{IODev} && grep {$_ == $hash->{PIN}} split(" ",$dev->{PIN}) ) { delete $hash->{IODev}; - die "Device $main::defs{$d}{NAME} allready defined for pin $hash->{PIN}"; + delete $attr{$name}{IODev}; + die "Device '$main::defs{$d}{NAME}' allready defined for pin $hash->{PIN}"; } } } @@ -542,7 +579,7 @@ sub new { sub data_write { my ( $self, $buf ) = @_; my $hash = $self->{hash}; - main::Log3 $hash->{NAME},5,">".join(",",map{sprintf"%02x",ord$_}split//,$buf); + main::Log3 $hash->{NAME},5,$hash->{FD}.">".join(",",map{sprintf"%02x",ord$_}split//,$buf); main::DevIo_SimpleWrite($hash,$buf,undef); } @@ -551,7 +588,7 @@ sub data_read { my $hash = $self->{hash}; my $string = main::DevIo_SimpleRead($hash); if (defined $string ) { - main::Log3 $hash->{NAME},5,"<".join(",",map{sprintf"%02x",ord$_}split//,$string); + main::Log3 $hash->{NAME},5,$hash->{FD}."<".join(",",map{sprintf"%02x",ord$_}split//,$string); } return $string; } diff --git a/fhem/FHEM/20_FRM_AD.pm b/fhem/FHEM/20_FRM_AD.pm index 769ed2a56..9f5fcd87a 100755 --- a/fhem/FHEM/20_FRM_AD.pm +++ b/fhem/FHEM/20_FRM_AD.pm @@ -113,17 +113,24 @@ FRM_AD_Get($) sub FRM_AD_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_I2C.pm b/fhem/FHEM/20_FRM_I2C.pm index f6f587817..f7a0c7239 100755 --- a/fhem/FHEM/20_FRM_I2C.pm +++ b/fhem/FHEM/20_FRM_I2C.pm @@ -42,9 +42,16 @@ FRM_I2C_Init($) $hash->{"i2c-register"} = @$args[1]; $hash->{"i2c-bytestoread"} = @$args[2]; - eval { - FRM_Client_FirmataDevice($hash)->i2c_read(@$args[0],@$args[1],@$args[2]); - }; + eval { + FRM_Client_AssignIOPort($hash); + FRM_Client_FirmataDevice($hash)->i2c_read(@$args[0],@$args[1],@$args[2]); + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error initializing: ".$1; + return "error initializing '".$hash->{NAME}."': ".$1; + } + return "error calling i2c_read: ".$@ if ($@); if (! (defined AttrVal($hash->{NAME},"event-min-interval",undef))) { $main::attr{$hash->{NAME}}{"event-min-interval"} = 5; @@ -55,18 +62,24 @@ FRM_I2C_Init($) sub FRM_I2C_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_IN.pm b/fhem/FHEM/20_FRM_IN.pm index ad8a6f8cb..ab6ab416b 100755 --- a/fhem/FHEM/20_FRM_IN.pm +++ b/fhem/FHEM/20_FRM_IN.pm @@ -153,83 +153,82 @@ FRM_IN_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; my $hash = $main::defs{$name}; my $pin = $hash->{PIN}; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $attribute eq "count-mode" and do { - if ($value ne "none" and !defined main::ReadingsVal($name,"count",undef)) { - main::readingsSingleUpdate($main::defs{$name},"count",$sets{count},1); - } - last; - }; - $attribute eq "reset-on-threshold-reached" and do { - if ($value eq "yes" - and defined (my $threshold = main::AttrVal($name,"count-threshold",undef))) { - if (main::ReadingsVal($name,"count",0) > $threshold) { + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + $attribute eq "count-mode" and do { + if ($value ne "none" and !defined main::ReadingsVal($name,"count",undef)) { main::readingsSingleUpdate($main::defs{$name},"count",$sets{count},1); } - } - last; - }; - $attribute eq "count-threshold" and do { - if (main::ReadingsVal($name,"count",0) > $value) { - main::readingsBeginUpdate($hash); - if (main::ReadingsVal($name,"alarm","off") ne "on") { - main::readingsBulkUpdate($hash,"alarm","on",1); + last; + }; + $attribute eq "reset-on-threshold-reached" and do { + if ($value eq "yes" + and defined (my $threshold = main::AttrVal($name,"count-threshold",undef))) { + if (main::ReadingsVal($name,"count",0) > $threshold) { + main::readingsSingleUpdate($main::defs{$name},"count",$sets{count},1); + } } - if (main::AttrVal($name,"reset-on-threshold-reached","no") eq "yes") { - main::readingsBulkUpdate($main::defs{$name},"count",0,1); + last; + }; + $attribute eq "count-threshold" and do { + if (main::ReadingsVal($name,"count",0) > $value) { + main::readingsBeginUpdate($hash); + if (main::ReadingsVal($name,"alarm","off") ne "on") { + main::readingsBulkUpdate($hash,"alarm","on",1); + } + if (main::AttrVal($name,"reset-on-threshold-reached","no") eq "yes") { + main::readingsBulkUpdate($main::defs{$name},"count",0,1); + } + main::readingsEndUpdate($hash,1); } - main::readingsEndUpdate($hash,1); - } - last; - }; - $attribute eq "internal-pullup" and do { - eval { + last; + }; + $attribute eq "internal-pullup" and do { my $firmata = FRM_Client_FirmataDevice($hash); $firmata->digital_write($pin,$value eq "on" ? 1 : 0); - }; - #ignore any errors here, the attribute-value will be applied next time FRM_IN_init() is called. - last; - }; - $attribute eq "activeLow" and do { - my $oldval = AttrVal($hash->{NAME},"activeLow","no"); - if ($oldval ne $value) { - $main::attr{$hash->{NAME}}{activeLow} = $value; - eval { + #ignore any errors here, the attribute-value will be applied next time FRM_IN_init() is called. + last; + }; + $attribute eq "activeLow" and do { + my $oldval = AttrVal($hash->{NAME},"activeLow","no"); + if ($oldval ne $value) { + $main::attr{$hash->{NAME}}{activeLow} = $value; my $firmata = FRM_Client_FirmataDevice($hash); FRM_IN_observer($pin,undef,$firmata->digital_read($pin),$hash); }; + last; }; - last; - }; - } - } elsif ($command eq "del") { - ARGUMENT_HANDLER: { - $attribute eq "internal-pullup" and do { - eval { + } + } elsif ($command eq "del") { + ARGUMENT_HANDLER: { + $attribute eq "internal-pullup" and do { my $firmata = FRM_Client_FirmataDevice($hash); $firmata->digital_write($pin,0); - }; - last; - }; - $attribute eq "activeLow" and do { - if (AttrVal($hash->{NAME},"activeLow","no") eq "yes") { - delete $main::attr{$hash->{NAME}}{activeLow}; - eval { + last; + }; + $attribute eq "activeLow" and do { + if (AttrVal($hash->{NAME},"activeLow","no") eq "yes") { + delete $main::attr{$hash->{NAME}}{activeLow}; my $firmata = FRM_Client_FirmataDevice($hash); FRM_IN_observer($pin,undef,$firmata->digital_read($pin),$hash); }; + last; }; - last; - }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_LCD.pm b/fhem/FHEM/20_FRM_LCD.pm index f8688db13..13f5b6960 100755 --- a/fhem/FHEM/20_FRM_LCD.pm +++ b/fhem/FHEM/20_FRM_LCD.pm @@ -62,20 +62,26 @@ FRM_LCD_Init($) $hash->{sizey} = shift @$args; $hash->{address} = shift @$args if (@$args); - return "no IODev set" unless defined $hash->{IODev}; - return "no FirmataDevice assigned to ".$hash->{IODev}->{NAME} unless defined $hash->{IODev}->{FirmataDevice}; - my $name = $hash->{NAME}; if (($hash->{type} eq "i2c") and defined $hash->{address}) { - require LiquidCrystal_I2C; - my $lcd = LiquidCrystal_I2C->new($hash->{address},$hash->{sizex},$hash->{sizey}); - $lcd->attach($hash->{IODev}->{FirmataDevice}); - $lcd->init(); - $hash->{lcd} = $lcd; - FRM_LCD_Apply_Attribute($name,"backLight"); -# FRM_LCD_Apply_Attribute($name,"autoscroll"); -# FRM_LCD_Apply_Attribute($name,"direction"); - FRM_LCD_Apply_Attribute($name,"blink"); + eval { + FRM_Client_AssignIOPort($hash); + my $firmata = FRM_Client_FirmataDevice($hash); + require LiquidCrystal_I2C; + my $lcd = LiquidCrystal_I2C->new($hash->{address},$hash->{sizex},$hash->{sizey}); + $lcd->attach($firmata); + $lcd->init(); + $hash->{lcd} = $lcd; + FRM_LCD_Apply_Attribute($name,"backLight"); +# FRM_LCD_Apply_Attribute($name,"autoscroll"); +# FRM_LCD_Apply_Attribute($name,"direction"); + FRM_LCD_Apply_Attribute($name,"blink"); + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error initializing: ".$1; + return "error initializing '".$hash->{NAME}."': ".$1; + } } if (! (defined AttrVal($name,"stateFormat",undef))) { $main::attr{$name}{"stateFormat"} = "text"; @@ -92,19 +98,26 @@ FRM_LCD_Init($) sub FRM_LCD_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; $main::attr{$name}{$attribute}=$value; FRM_LCD_Apply_Attribute($name,$attribute); + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_OUT.pm b/fhem/FHEM/20_FRM_OUT.pm index f5ffbda3a..967105d37 100755 --- a/fhem/FHEM/20_FRM_OUT.pm +++ b/fhem/FHEM/20_FRM_OUT.pm @@ -89,18 +89,24 @@ STATEHANDLER: { sub FRM_OUT_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_PWM.pm b/fhem/FHEM/20_FRM_PWM.pm index 1cbae9797..ad10bd68b 100755 --- a/fhem/FHEM/20_FRM_PWM.pm +++ b/fhem/FHEM/20_FRM_PWM.pm @@ -246,18 +246,24 @@ sub FRM_PWM_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_RGB.pm b/fhem/FHEM/20_FRM_RGB.pm index 14fe3740e..2b040dda2 100644 --- a/fhem/FHEM/20_FRM_RGB.pm +++ b/fhem/FHEM/20_FRM_RGB.pm @@ -73,17 +73,24 @@ FRM_RGB_Init($$) my $ret = FRM_Init_Pin_Client($hash,$args,PIN_PWM); return $ret if (defined $ret); my @pins = (); - my $firmata = FRM_Client_FirmataDevice($hash); - $hash->{PIN} = ""; - foreach my $pin (@{$args}) { - $firmata->pin_mode($pin,PIN_PWM); - push @pins,{ - pin => $pin, - "shift" => defined $firmata->{metadata}{pwm_resolutions} ? $firmata->{metadata}{pwm_resolutions}{$pin}-8 : 0, - }; - $hash->{PIN} .= $hash->{PIN} eq "" ? $pin : " $pin"; + eval { + my $firmata = FRM_Client_FirmataDevice($hash); + $hash->{PIN} = ""; + foreach my $pin (@{$args}) { + $firmata->pin_mode($pin,PIN_PWM); + push @pins,{ + pin => $pin, + "shift" => defined $firmata->{metadata}{pwm_resolutions} ? $firmata->{metadata}{pwm_resolutions}{$pin}-8 : 0, + }; + $hash->{PIN} .= $hash->{PIN} eq "" ? $pin : " $pin"; + } + $hash->{PINS} = \@pins; + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error initializing: ".$1; + return "error initializing '".$hash->{NAME}."': ".$1; } - $hash->{PINS} = \@pins; if (! (defined AttrVal($name,"stateFormat",undef))) { $attr{$name}{"stateFormat"} = "rgb"; } @@ -254,18 +261,24 @@ sub FRM_RGB_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_ROTENC.pm b/fhem/FHEM/20_FRM_ROTENC.pm index 47d1b47be..eacedf938 100755 --- a/fhem/FHEM/20_FRM_ROTENC.pm +++ b/fhem/FHEM/20_FRM_ROTENC.pm @@ -139,17 +139,23 @@ sub FRM_ROTENC_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; my $hash = $main::defs{$name}; - my $pin = $hash->{PIN}; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_SERVO.pm b/fhem/FHEM/20_FRM_SERVO.pm index de35017a6..30f08efbc 100755 --- a/fhem/FHEM/20_FRM_SERVO.pm +++ b/fhem/FHEM/20_FRM_SERVO.pm @@ -52,21 +52,28 @@ FRM_SERVO_Init($$) sub FRM_SERVO_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; - if ( $attribute eq "min-pulse" || $attribute eq "max-pulse" ) { - FRM_SERVO_apply_attribute($main::defs{$name},$attribute); - } + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + $main::attr{$name}{$attribute}=$value; + if ( $attribute eq "min-pulse" || $attribute eq "max-pulse" ) { + FRM_SERVO_apply_attribute($main::defs{$name},$attribute); + } + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } } diff --git a/fhem/FHEM/20_FRM_STEPPER.pm b/fhem/FHEM/20_FRM_STEPPER.pm index 55da32662..a05d78974 100755 --- a/fhem/FHEM/20_FRM_STEPPER.pm +++ b/fhem/FHEM/20_FRM_STEPPER.pm @@ -202,18 +202,24 @@ STATEHANDLER: { sub FRM_STEPPER_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; - if ($command eq "set") { - ARGUMENT_HANDLER: { - $attribute eq "IODev" and do { - my $hash = $main::defs{$name}; - if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { - $hash->{IODev} = $defs{$value}; - FRM_Init_Client($hash) if (defined ($hash->{IODev})); - } - last; - }; - $main::attr{$name}{$attribute}=$value; + my $hash = $main::defs{$name}; + eval { + if ($command eq "set") { + ARGUMENT_HANDLER: { + $attribute eq "IODev" and do { + if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) { + FRM_Client_AssignIOPort($hash,$value); + FRM_Init_Client($hash) if (defined ($hash->{IODev})); + } + last; + }; + } } + }; + if ($@) { + $@ =~ /^(.*)( at.*FHEM.*)$/; + $hash->{STATE} = "error setting $attribute to $value: ".$1; + return "cannot $command attribute $attribute to $value for $name: ".$1; } }