2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-19 12:46:03 +00:00

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
This commit is contained in:
ntruchsess 2014-03-15 10:56:24 +00:00
parent edde8770d4
commit 92a4c47d93
12 changed files with 348 additions and 235 deletions

View File

@ -225,7 +225,7 @@ sub OWX_Define ($$) {
if (!OWX_Detect($hash)){ if (!OWX_Detect($hash)){
$hash->{PRESENT} = 0; $hash->{PRESENT} = 0;
readingsSingleUpdate($hash,"state","failed",1); readingsSingleUpdate($hash,"state","failed",1);
$init_done = 1; # $init_done = 1;
return undef; return undef;
} }
#-- Fourth step: discovering devices on the bus #-- Fourth step: discovering devices on the bus

View File

@ -48,6 +48,7 @@ sub FRM_Initialize($) {
$hash->{GetFn} = "FRM_Get"; $hash->{GetFn} = "FRM_Get";
$hash->{SetFn} = "FRM_Set"; $hash->{SetFn} = "FRM_Set";
$hash->{AttrFn} = "FRM_Attr"; $hash->{AttrFn} = "FRM_Attr";
$hash->{NotifyFn} = "FRM_Notify";
$hash->{AttrList} = "model:nano dummy:1,0 sampling-interval i2c-config $main::readingFnAttributes"; $hash->{AttrList} = "model:nano dummy:1,0 sampling-interval i2c-config $main::readingFnAttributes";
} }
@ -57,35 +58,19 @@ sub FRM_Define($$) {
my ( $hash, $def ) = @_; my ( $hash, $def ) = @_;
my ($name, $type, $dev, $global) = split("[ \t]+", $def); my ($name, $type, $dev, $global) = split("[ \t]+", $def);
$hash->{DeviceName} = $dev;
my $isServer = 1 if($dev && $dev =~ m/^(IPV6:)?\d+$/); $hash->{NOTIFYDEV} = "global";
# my $isClient = 1 if($dev && $dev =~ m/^(IPV6:)?.*:\d+$/);
# return "Usage: define <name> FRM {<device>[@<baudrate>] | [IPV6:]<tcp-portnr> [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);
if ( $dev eq "none" ) { if ( $dev eq "none" ) {
Log3 $name,3,"device is none, commands will be echoed only"; Log3 $name,3,"device is none, commands will be echoed only";
$main::attr{$name}{dummy} = 1; $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 undef;
return $ret;
} }
##################################### #####################################
@ -110,6 +95,46 @@ sub FRM_Undef($) {
return 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 <name> FRM {<device>[@<baudrate>] | [IPV6:]<tcp-portnr> [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($@) { sub FRM_Set($@) {
my ($hash, @a) = @_; my ($hash, @a) = @_;
@ -297,22 +322,28 @@ sub FRM_DoInit($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{SNAME}; #is this a serversocket-connection? my $sname = $hash->{SNAME}; #is this a serversocket-connection?
my $shash = defined $name ? $main::defs{$name} : $hash; my $shash = defined $sname ? $main::defs{$sname} : $hash;
$name = $hash->{NAME};# if (!defined $name);
my $name = $shash->{NAME};
my $firmata_io = Firmata_IO->new($hash); my $firmata_io = Firmata_IO->new($hash);
my $device = Device::Firmata::Platform->attach($firmata_io) or return 1; my $device = Device::Firmata::Platform->attach($firmata_io) or return 1;
$shash->{FirmataDevice} = $device;
if (defined $sname) {
$shash->{SocketDevice} = $hash;
#as FRM_Read gets the connected socket hash, but calls firmatadevice->poll():
$hash->{FirmataDevice} = $device; $hash->{FirmataDevice} = $device;
$device->observe_string(\&FRM_string_observer,$hash); }
$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 $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 $endTicks = time+5;
my $queryTicks = time+2; my $queryTicks = time+2;
$device->system_reset(); $device->system_reset();
do { do {
FRM_poll($hash); FRM_poll($shash);
if ($device->{metadata}{firmware} && $device->{metadata}{firmware_version}) { if ($device->{metadata}{firmware} && $device->{metadata}{firmware_version}) {
$device->{protocol}->{protocol_version} = $device->{metadata}{firmware_version}; $device->{protocol}->{protocol_version} = $device->{metadata}{firmware_version};
$main::defs{$name}{firmware} = $device->{metadata}{firmware}; $main::defs{$name}{firmware} = $device->{metadata}{firmware};
@ -321,7 +352,7 @@ sub FRM_DoInit($) {
$device->analog_mapping_query(); $device->analog_mapping_query();
$device->capability_query(); $device->capability_query();
do { do {
FRM_poll($hash); FRM_poll($shash);
if ($device->{metadata}{analog_mappings} and $device->{metadata}{capabilities}) { if ($device->{metadata}{analog_mappings} and $device->{metadata}{capabilities}) {
my $inputpins = $device->{metadata}{input_pins}; my $inputpins = $device->{metadata}{input_pins};
$main::defs{$name}{input_pins} = join(",", sort{$a<=>$b}(@$inputpins)) if (defined $inputpins and scalar @$inputpins); $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); } while (time < $endTicks and !$found);
if ($found) { if ($found) {
$shash->{FirmataDevice} = $device;
$shash->{SocketDevice} = $hash;
FRM_apply_attribute($shash,"sampling-interval"); FRM_apply_attribute($shash,"sampling-interval");
FRM_apply_attribute($shash,"i2c-config"); FRM_apply_attribute($shash,"i2c-config");
FRM_forall_clients($shash,\&FRM_Init_Client,undef); FRM_forall_clients($shash,\&FRM_Init_Client,undef);
@ -401,8 +430,9 @@ sub FRM_DoInit($) {
return undef; return undef;
} }
Log3 $name,3,"no response from Firmata, closing DevIO"; Log3 $name,3,"no response from Firmata, closing DevIO";
DevIo_Disconnected($hash); DevIo_Disconnected($shash);
delete $hash->{FirmataDevice}; delete $shash->{FirmataDevice};
delete $shash->{SocketDevice};
return "FirmataDevice not responding"; return "FirmataDevice not responding";
} }
@ -430,7 +460,7 @@ FRM_Init_Client($@) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $ret = CallFn($name,"InitFn",$hash,$args); my $ret = CallFn($name,"InitFn",$hash,$args);
if ($ret) { 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 ($@) { if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/; $@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error initializing: ".$1; $hash->{STATE} = "error initializing: ".$1;
return "error initializing '".$hash->{NAME}."': ".$1; return $1;
} }
return undef; return undef;
} }
@ -462,10 +492,16 @@ FRM_Client_Define($$)
$hash->{STATE}="defined"; $hash->{STATE}="defined";
if ($main::init_done) {
eval { eval {
FRM_Init_Client($hash,[@a[2..scalar(@a)-1]]); FRM_Init_Client($hash,[@a[2..scalar(@a)-1]]);
}; };
return $@; if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
return $1;
}
}
return undef;
} }
sub sub
@ -496,17 +532,17 @@ FRM_Client_Unassign($)
} }
sub sub
FRM_Client_AssignIOPort($) FRM_Client_AssignIOPort($@)
{ {
my $hash = shift; my ($hash,$iodev) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if (my $iodev = AttrVal($name,"IODev",undef)) { AssignIoPort($hash,defined $iodev ? $iodev : AttrVal($hash->{NAME},"IODev",undef));
$hash->{IODev} = $defs{$iodev};
}
AssignIoPort($hash) unless defined($hash->{IODev});
die "unable to assign IODev to '$name'" unless defined ($hash->{IODev}); 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 ) { foreach my $d ( sort keys %main::defs ) {
if ( defined( my $dev = $main::defs{$d} )) { if ( defined( my $dev = $main::defs{$d} )) {
@ -516,7 +552,8 @@ FRM_Client_AssignIOPort($)
&& $dev->{IODev} == $hash->{IODev} && $dev->{IODev} == $hash->{IODev}
&& grep {$_ == $hash->{PIN}} split(" ",$dev->{PIN}) ) { && grep {$_ == $hash->{PIN}} split(" ",$dev->{PIN}) ) {
delete $hash->{IODev}; 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 { sub data_write {
my ( $self, $buf ) = @_; my ( $self, $buf ) = @_;
my $hash = $self->{hash}; 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); main::DevIo_SimpleWrite($hash,$buf,undef);
} }
@ -551,7 +588,7 @@ sub data_read {
my $hash = $self->{hash}; my $hash = $self->{hash};
my $string = main::DevIo_SimpleRead($hash); my $string = main::DevIo_SimpleRead($hash);
if (defined $string ) { 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; return $string;
} }

View File

@ -113,18 +113,25 @@ FRM_AD_Get($)
sub sub
FRM_AD_Attr($$$$) { FRM_AD_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;

View File

@ -43,8 +43,15 @@ FRM_I2C_Init($)
$hash->{"i2c-bytestoread"} = @$args[2]; $hash->{"i2c-bytestoread"} = @$args[2];
eval { eval {
FRM_Client_AssignIOPort($hash);
FRM_Client_FirmataDevice($hash)->i2c_read(@$args[0],@$args[1],@$args[2]); 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 ($@); return "error calling i2c_read: ".$@ if ($@);
if (! (defined AttrVal($hash->{NAME},"event-min-interval",undef))) { if (! (defined AttrVal($hash->{NAME},"event-min-interval",undef))) {
$main::attr{$hash->{NAME}}{"event-min-interval"} = 5; $main::attr{$hash->{NAME}}{"event-min-interval"} = 5;
@ -55,19 +62,25 @@ FRM_I2C_Init($)
sub sub
FRM_I2C_Attr($$$$) { FRM_I2C_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
$main::attr{$name}{$attribute}=$value;
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;

View File

@ -153,11 +153,12 @@ FRM_IN_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name}; my $hash = $main::defs{$name};
my $pin = $hash->{PIN}; my $pin = $hash->{PIN};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
$hash->{IODev} = $defs{$value}; FRM_Client_AssignIOPort($hash,$value);
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
@ -191,10 +192,8 @@ FRM_IN_Attr($$$$) {
last; last;
}; };
$attribute eq "internal-pullup" and do { $attribute eq "internal-pullup" and do {
eval {
my $firmata = FRM_Client_FirmataDevice($hash); my $firmata = FRM_Client_FirmataDevice($hash);
$firmata->digital_write($pin,$value eq "on" ? 1 : 0); $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. #ignore any errors here, the attribute-value will be applied next time FRM_IN_init() is called.
last; last;
}; };
@ -202,35 +201,35 @@ FRM_IN_Attr($$$$) {
my $oldval = AttrVal($hash->{NAME},"activeLow","no"); my $oldval = AttrVal($hash->{NAME},"activeLow","no");
if ($oldval ne $value) { if ($oldval ne $value) {
$main::attr{$hash->{NAME}}{activeLow} = $value; $main::attr{$hash->{NAME}}{activeLow} = $value;
eval {
my $firmata = FRM_Client_FirmataDevice($hash); my $firmata = FRM_Client_FirmataDevice($hash);
FRM_IN_observer($pin,undef,$firmata->digital_read($pin),$hash); FRM_IN_observer($pin,undef,$firmata->digital_read($pin),$hash);
}; };
};
last; last;
}; };
} }
} elsif ($command eq "del") { } elsif ($command eq "del") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "internal-pullup" and do { $attribute eq "internal-pullup" and do {
eval {
my $firmata = FRM_Client_FirmataDevice($hash); my $firmata = FRM_Client_FirmataDevice($hash);
$firmata->digital_write($pin,0); $firmata->digital_write($pin,0);
};
last; last;
}; };
$attribute eq "activeLow" and do { $attribute eq "activeLow" and do {
if (AttrVal($hash->{NAME},"activeLow","no") eq "yes") { if (AttrVal($hash->{NAME},"activeLow","no") eq "yes") {
delete $main::attr{$hash->{NAME}}{activeLow}; delete $main::attr{$hash->{NAME}}{activeLow};
eval {
my $firmata = FRM_Client_FirmataDevice($hash); my $firmata = FRM_Client_FirmataDevice($hash);
FRM_IN_observer($pin,undef,$firmata->digital_read($pin),$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;
}
} }
1; 1;

View File

@ -62,20 +62,26 @@ FRM_LCD_Init($)
$hash->{sizey} = shift @$args; $hash->{sizey} = shift @$args;
$hash->{address} = shift @$args if (@$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}; my $name = $hash->{NAME};
if (($hash->{type} eq "i2c") and defined $hash->{address}) { if (($hash->{type} eq "i2c") and defined $hash->{address}) {
eval {
FRM_Client_AssignIOPort($hash);
my $firmata = FRM_Client_FirmataDevice($hash);
require LiquidCrystal_I2C; require LiquidCrystal_I2C;
my $lcd = LiquidCrystal_I2C->new($hash->{address},$hash->{sizex},$hash->{sizey}); my $lcd = LiquidCrystal_I2C->new($hash->{address},$hash->{sizex},$hash->{sizey});
$lcd->attach($hash->{IODev}->{FirmataDevice}); $lcd->attach($firmata);
$lcd->init(); $lcd->init();
$hash->{lcd} = $lcd; $hash->{lcd} = $lcd;
FRM_LCD_Apply_Attribute($name,"backLight"); FRM_LCD_Apply_Attribute($name,"backLight");
# FRM_LCD_Apply_Attribute($name,"autoscroll"); # FRM_LCD_Apply_Attribute($name,"autoscroll");
# FRM_LCD_Apply_Attribute($name,"direction"); # FRM_LCD_Apply_Attribute($name,"direction");
FRM_LCD_Apply_Attribute($name,"blink"); 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))) { if (! (defined AttrVal($name,"stateFormat",undef))) {
$main::attr{$name}{"stateFormat"} = "text"; $main::attr{$name}{"stateFormat"} = "text";
@ -92,12 +98,13 @@ FRM_LCD_Init($)
sub sub
FRM_LCD_Attr($$$$) { FRM_LCD_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
@ -106,6 +113,12 @@ FRM_LCD_Attr($$$$) {
FRM_LCD_Apply_Attribute($name,$attribute); 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;
}
} }
sub FRM_LCD_Apply_Attribute { sub FRM_LCD_Apply_Attribute {

View File

@ -89,19 +89,25 @@ STATEHANDLER: {
sub sub
FRM_OUT_Attr($$$$) { FRM_OUT_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
$main::attr{$name}{$attribute}=$value;
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;

View File

@ -246,19 +246,25 @@ sub
FRM_PWM_Attr($$$$) FRM_PWM_Attr($$$$)
{ {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
$main::attr{$name}{$attribute}=$value;
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;

View File

@ -73,6 +73,7 @@ FRM_RGB_Init($$)
my $ret = FRM_Init_Pin_Client($hash,$args,PIN_PWM); my $ret = FRM_Init_Pin_Client($hash,$args,PIN_PWM);
return $ret if (defined $ret); return $ret if (defined $ret);
my @pins = (); my @pins = ();
eval {
my $firmata = FRM_Client_FirmataDevice($hash); my $firmata = FRM_Client_FirmataDevice($hash);
$hash->{PIN} = ""; $hash->{PIN} = "";
foreach my $pin (@{$args}) { foreach my $pin (@{$args}) {
@ -84,6 +85,12 @@ FRM_RGB_Init($$)
$hash->{PIN} .= $hash->{PIN} eq "" ? $pin : " $pin"; $hash->{PIN} .= $hash->{PIN} eq "" ? $pin : " $pin";
} }
$hash->{PINS} = \@pins; $hash->{PINS} = \@pins;
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error initializing: ".$1;
return "error initializing '".$hash->{NAME}."': ".$1;
}
if (! (defined AttrVal($name,"stateFormat",undef))) { if (! (defined AttrVal($name,"stateFormat",undef))) {
$attr{$name}{"stateFormat"} = "rgb"; $attr{$name}{"stateFormat"} = "rgb";
} }
@ -254,19 +261,25 @@ sub
FRM_RGB_Attr($$$$) FRM_RGB_Attr($$$$)
{ {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
$main::attr{$name}{$attribute}=$value;
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;

View File

@ -139,18 +139,24 @@ sub
FRM_ROTENC_Attr($$$$) { FRM_ROTENC_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name}; my $hash = $main::defs{$name};
my $pin = $hash->{PIN}; eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
$hash->{IODev} = $defs{$value}; FRM_Client_AssignIOPort($hash,$value);
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
sub sub

View File

@ -52,12 +52,13 @@ FRM_SERVO_Init($$)
sub sub
FRM_SERVO_Attr($$$$) { FRM_SERVO_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
@ -68,6 +69,12 @@ FRM_SERVO_Attr($$$$) {
} }
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
sub FRM_SERVO_apply_attribute { sub FRM_SERVO_apply_attribute {

View File

@ -202,19 +202,25 @@ STATEHANDLER: {
sub sub
FRM_STEPPER_Attr($$$$) { FRM_STEPPER_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_; my ($command,$name,$attribute,$value) = @_;
my $hash = $main::defs{$name};
eval {
if ($command eq "set") { if ($command eq "set") {
ARGUMENT_HANDLER: { ARGUMENT_HANDLER: {
$attribute eq "IODev" and do { $attribute eq "IODev" and do {
my $hash = $main::defs{$name}; if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) { FRM_Client_AssignIOPort($hash,$value);
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev})); FRM_Init_Client($hash) if (defined ($hash->{IODev}));
} }
last; last;
}; };
$main::attr{$name}{$attribute}=$value;
} }
} }
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error setting $attribute to $value: ".$1;
return "cannot $command attribute $attribute to $value for $name: ".$1;
}
} }
1; 1;