2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 07:16: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)){
$hash->{PRESENT} = 0;
readingsSingleUpdate($hash,"state","failed",1);
$init_done = 1;
# $init_done = 1;
return undef;
}
#-- Fourth step: discovering devices on the bus

View File

@ -48,6 +48,7 @@ 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 <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);
$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 <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($@) {
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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}