diff --git a/fhem/FHEM/00_OWX.pm b/fhem/FHEM/00_OWX.pm index 08399a595..bb930d333 100644 --- a/fhem/FHEM/00_OWX.pm +++ b/fhem/FHEM/00_OWX.pm @@ -18,6 +18,7 @@ # # define OWX for USB interfaces or # define OWX for a CUNO or COC interface +# define OWX for a Arduino/Firmata (10_FRM.pm) interface # # where may be replaced by any name string # is a serial (USB) device @@ -129,6 +130,9 @@ sub OWX_Initialize ($) { $hash->{GetFn} = "OWX_Get"; $hash->{SetFn} = "OWX_Set"; $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 buspower:real,parasitic"; + + #-- Adapt to FRM + $hash->{InitFn} = "FRM_OWX_Init"; } ######################################################################################## @@ -151,7 +155,7 @@ sub OWX_Define ($$) { } #-- check syntax - Log 1,"OWX: Warning - Some parameter(s) ignored, must be define OWX |" + Log 1,"OWX: Warning - Some parameter(s) ignored, must be define OWX ||" if(int(@a) > 3); #-- If this line contains 3 parameters, it is the bus master definition my $dev = $a[2]; @@ -187,6 +191,10 @@ sub OWX_Define ($$) { #-- store with OWX device $hash->{INTERFACE} = "serial"; $hash->{HWDEVICE} = $owx_hwdevice; + #-- check if we are connecting to Arduino (via FRM): + } elsif ($dev =~ /\d{1,2}/) { + $hash->{INTERFACE} = "firmata"; + FRM_Client_Define($hash,$def); } else { $hash->{DeviceName} = $dev; #-- Second step in case of CUNO: See if we can open it @@ -260,10 +268,14 @@ sub OWX_Alarms ($) { $hash->{ALARMDEVS}=(); - #-- Discover all alarmed devices on the 1-Wire bus - my $res = OWX_First_SER($hash,"alarm"); - while( $owx_LastDeviceFlag==0 && $res != 0){ - $res = $res & OWX_Next_SER($hash,"alarm"); + if ($hash->{INTERFACE} eq "firmata") { + FRM_OWX_Alarms($hash); + } else { + #-- Discover all alarmed devices on the 1-Wire bus + my $res = OWX_First_SER($hash,"alarm"); + while( $owx_LastDeviceFlag==0 && $res != 0){ + $res = $res & OWX_Next_SER($hash,"alarm"); + } } if( @{$hash->{ALARMDEVS}} == 0){ return "OWX: No alarmed 1-Wire devices found on bus $name"; @@ -326,6 +338,10 @@ sub OWX_Complex ($$$$) { }elsif( ($owx_interface eq "COC") || ($owx_interface eq "CUNO") ){ return OWX_Complex_CCC($hash,$owx_dev,$data,$numread); + #-- here we treat Arduino/Firmata devices + }elsif( $owx_interface eq "firmata" ) { + return FRM_OWX_Complex( $hash, $owx_dev, $data, $numread ); + #-- interface error }else{ Log 3,"OWX: Complex called with unknown interface $owx_interface on bus $name"; @@ -562,6 +578,9 @@ sub OWX_Detect ($) { $ress.=sprintf "0x%1x%1x ",$j,$k; } } + #-- nothing to do for Arduino (already done in FRM) + } elsif($owx_interface eq "firmata") { + $ret=1; #-- here we treat the COC/CUNO } else { select(undef,undef,undef,2); @@ -636,6 +655,9 @@ sub OWX_Discover ($) { #-- Ask the COC/CUNO }elsif( ($owx_interface eq "COC" ) || ($owx_interface eq "CUNO") ){ $res = OWX_Discover_CCC($hash); + #-- ask the Arduino + }elsif ( $owx_interface eq "firmata") { + $res = FRM_OWX_Discover($hash); #-- Something else } else { Log 1,"OWX: Discover called with unknown interface"; @@ -896,6 +918,8 @@ sub OWX_Reset ($) { return OWX_Reset_CCC($hash); }elsif( $owx_interface eq "CUNO" ){ return OWX_Reset_CCC($hash); + }elsif( $owx_interface eq "firmata" ) { + return FRM_OWX_Reset($hash); }else{ Log 3,"OWX: Reset called with unknown interface $owx_interface"; return 0; @@ -996,6 +1020,8 @@ sub OWX_Verify ($$) { #-- Ask the COC/CUNO }elsif( ($owx_interface eq "COC" ) || ($owx_interface eq "CUNO") ){ return OWX_Verify_CCC($hash,$dev) + }elsif( $owx_interface eq "firmata" ){ + return FRM_OWX_Verify($hash,$dev); } else { Log 1,"OWX: Verify called with unknown interface"; return 0; diff --git a/fhem/FHEM/10_FRM.pm b/fhem/FHEM/10_FRM.pm index 164d3ab5c..799f172e3 100755 --- a/fhem/FHEM/10_FRM.pm +++ b/fhem/FHEM/10_FRM.pm @@ -356,10 +356,8 @@ sub FRM_OWX_Init($$) { my ($hash,$args) = @_; - if(defined $args and (@$args == 4)) { - $hash->{PIN} = @$args[3]; - } - $hash->{INTERFACE} = "FRM"; + FRM_Init_Pin_Client($hash,$args); + $hash->{INTERFACE} = "firmata"; if (defined $hash->{IODev}) { my $firmata = $hash->{IODev}->{FirmataDevice}; if (defined $firmata and defined $hash->{PIN}) { @@ -388,13 +386,17 @@ sub FRM_OWX_observer $hash->{FRM_OWX_REPLIES}->{$owx_device} = $owx_data; last; }; - $command eq "SEARCH_REPLY" and do { + ($command eq "SEARCH_REPLY" or $command eq "SEARCH_ALARMS_REPLY") and do { my @owx_devices = (); foreach my $device (@{$data->{devices}}) { push @owx_devices, FRM_OWX_firmata_to_device($device); } - $hash->{DEVS} = \@owx_devices; - $main::attr{$hash->{NAME}}{"ow-devices"} = join " ",@owx_devices; + if ($command eq "SEARCH_REPLY") { + $hash->{DEVS} = \@owx_devices; + $main::attr{$hash->{NAME}}{"ow-devices"} = join " ",@owx_devices; + } else { + $hash->{ALARMDEVS} = \@owx_devices; + } last; }; } @@ -421,6 +423,41 @@ sub FRM_OWX_firmata_to_device return sprintf ("%02X.%02X%02X%02X%02X%02X%02X.%02X",$device->{family},@{$device->{identity}},$device->{crc}); } +sub FRM_OWX_Verify { + my ($hash,$dev) = @_; + foreach my $found ($hash->{DEVS}) { + if ($dev eq $found) { + return 1; + } + } + return 0; +} + +sub FRM_OWX_Alarms { + my ($hash) = @_; + + #-- get the interface + my $frm = $hash->{IODev}; + return 0 unless defined $frm; + my $firmata = $frm->{FirmataDevice}; + my $pin = $hash->{PIN}; + return 0 unless ( defined $firmata and defined $pin ); + $hash->{ALARMDEVS} = undef; + $firmata->onewire_search_alarms($hash->{PIN}); + my $times = AttrVal($hash,"ow-read-timeout",1000) / 50; #timeout in ms, defaults to 1 sec + for (my $i=0;$i<$times;$i++) { + if (FRM_poll($hash->{IODev})) { + if (defined $hash->{ALARMDEVS}) { + return 1; + } + } else { + select (undef,undef,undef,0.05); + } + } + $hash->{ALARMDEVS} = []; + return 1; +} + sub FRM_OWX_Reset { my ($hash) = @_; #-- get the interface