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:
parent
edde8770d4
commit
92a4c47d93
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user