51_RPI_GPIO.pm: interrupt after restart works now, paths editable

52_I2C_MCP342x.pm: bugfix (definition parameters will work now)


git-svn-id: https://svn.fhem.de/fhem/trunk@11120 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klauswitt 2016-03-23 23:49:16 +00:00
parent c563dc07fe
commit e12d1c11c1
2 changed files with 258 additions and 233 deletions

View File

@ -22,13 +22,39 @@ use SetExtensions;
sub RPI_GPIO_fileaccess($$;$); sub RPI_GPIO_fileaccess($$;$);
my $gpiodir = ""; #GPIO base directory
my @gpiodirs = ("/sys/class/aml_gpio", "/sys/class/gpio" );
my $gpioprg = ""; #WiringPi GPIO utility
my @gpioprgs = ("/usr/local/bin/gpio", "/usr/bin/gpio");
sub RPI_GPIO_Initialize($) { sub RPI_GPIO_Initialize($) {
my ($hash) = @_; my ($hash) = @_;
foreach (@gpioprgs) {
if(-x $_) {
$gpioprg = $_;
Log3 undef, 4, "RPI_GPIO: wiringpi gpio utility exists: $gpioprg";
last;
} elsif (-e $_) {
Log3 undef, 3, "RPI_GPIO: Attention, WiringPi gpio utility exists: $gpioprg but is not executable";
}
}
foreach (@gpiodirs) {
if(-e $_) {
$gpiodir = $_;
Log3 undef, 4, "RPI_GPIO: gpio directory exists: $gpiodir";
last;
}
}
Log3 undef, 3, "RPI_GPIO: could not find gpio base directory, please add correct path in define" unless defined $gpiodir;
Log3 undef, 4, "RPI_GPIO: could not find/use WiringPi gpio utility base directory" unless defined $gpioprg;
$hash->{DefFn} = "RPI_GPIO_Define"; $hash->{DefFn} = "RPI_GPIO_Define";
$hash->{GetFn} = "RPI_GPIO_Get"; $hash->{GetFn} = "RPI_GPIO_Get";
$hash->{SetFn} = "RPI_GPIO_Set"; $hash->{SetFn} = "RPI_GPIO_Set";
$hash->{StateFn} = "RPI_GPIO_State"; $hash->{StateFn} = "RPI_GPIO_State";
$hash->{AttrFn} = "RPI_GPIO_Attr"; $hash->{AttrFn} = "RPI_GPIO_Attr";
$hash->{ShutdownFn} = "RPI_GPIO_Shutdown";
$hash->{UndefFn} = "RPI_GPIO_Undef"; $hash->{UndefFn} = "RPI_GPIO_Undef";
$hash->{ExceptFn} = "RPI_GPIO_Except"; $hash->{ExceptFn} = "RPI_GPIO_Except";
$hash->{AttrList} = "poll_interval" . $hash->{AttrList} = "poll_interval" .
@ -36,14 +62,10 @@ sub RPI_GPIO_Initialize($) {
" interrupt:none,falling,rising,both" . " interrupt:none,falling,rising,both" .
" toggletostate:no,yes active_low:no,yes" . " toggletostate:no,yes active_low:no,yes" .
" debounce_in_ms restoreOnStartup:no,yes,on,off,last" . " debounce_in_ms restoreOnStartup:no,yes,on,off,last" .
" unexportpin:no,yes" . " unexportpin:no,yes longpressinterval" .
" longpressinterval " .
" $readingFnAttributes"; " $readingFnAttributes";
} }
my $gpiodir = "/sys/class/gpio"; #GPIO base directory
my $gpioprg = "/usr/local/bin/gpio"; #WiringPi GPIO utility
my %setsoutp = ( my %setsoutp = (
'on:noArg' => 0, 'on:noArg' => 0,
'off:noArg' => 0, 'off:noArg' => 0,
@ -51,12 +73,11 @@ my %setsoutp = (
); );
my %setsinpt = ( my %setsinpt = (
'readValue' => 0, 'readValue:noArg' => 0,
); );
sub RPI_GPIO_Define($$) { sub RPI_GPIO_Define($$) {
my ($hash, $def) = @_; my ($hash, $def) = @_;
my @args = split("[ \t]+", $def); my @args = split("[ \t]+", $def);
my $menge = int(@args); my $menge = int(@args);
if (int(@args) < 3) if (int(@args) < 3)
@ -67,67 +88,87 @@ sub RPI_GPIO_Define($$) {
#Pruefen, ob GPIO bereits verwendet #Pruefen, ob GPIO bereits verwendet
foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) { foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) {
if ($args[2] eq InternalVal($dev,"RPI_pin","")) { if ($args[2] eq InternalVal($dev,"RPI_pin","") && $hash->{NAME} ne InternalVal($dev,"NAME","") ) {
return "GPIO $args[2] already used by $dev"; return "GPIO $args[2] already used by $dev";
} }
} }
my $name = $args[0]; my $name = $args[0];
$hash->{RPI_pin} = $args[2]; $hash->{RPI_pin} = $args[2];
if ( defined $args[3] ) {
return "unable to find gpio basedir $args[3]" unless (-e $args[3]);
$hash->{GPIO_Basedir} = $args[3];
} else {
return "unable to find gpio basedir $gpiodir" unless defined $gpiodir;
$hash->{GPIO_Basedir} = $gpiodir;
}
if ( defined $args[4] ) {
return "unable to find wiringpi gpio utility: $gpioprg" unless (-e $args[4]);
$hash->{WiringPi_gpio} = $args[4];
} else {
return "unable to find wiringpi gpio utility: $gpioprg" unless defined $gpioprg;
$hash->{WiringPi_gpio} = $gpioprg;
}
$hash->{dir_not_set} = 1; $hash->{dir_not_set} = 1;
if(-e "$gpiodir/gpio$hash->{RPI_pin}" && -w "$gpiodir/gpio$hash->{RPI_pin}/value" && -w "$gpiodir/gpio$hash->{RPI_pin}/direction") { #GPIO bereits exportiert? if(-e "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}" &&
-w "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value" &&
-w "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/direction") { #GPIO bereits exportiert?
Log3 $hash, 4, "$name: gpio$hash->{RPI_pin} already exists"; Log3 $hash, 4, "$name: gpio$hash->{RPI_pin} already exists";
#nix tun...ist ja schon da #nix tun...ist ja schon da
} elsif (-w "$gpiodir/export") { #gpio export Datei mit schreibrechten? } elsif (-w "$hash->{GPIO_Basedir}/export") { #gpio export Datei mit schreibrechten?
Log3 $hash, 4, "$name: write access to file $gpiodir/export, use it to export GPIO"; Log3 $hash, 4, "$name: write access to file $hash->{GPIO_Basedir}/export, use it to export GPIO";
my $exp = IO::File->new("> $gpiodir/export"); #gpio ueber export anlegen my $exp = IO::File->new("> $hash->{GPIO_Basedir}/export"); #gpio ueber export anlegen
print $exp "$hash->{RPI_pin}"; print $exp "$hash->{RPI_pin}";
$exp->close; $exp->close;
} else { } else {
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) { #Abbbruch da kein gpio utility vorhanden if ( defined $hash->{WiringPi_gpio} ) { #GPIO Utility Vorhanden?
Log3 $hash, 1, "$name: can't export gpio$hash->{RPI_pin}, no write access to $gpiodir/export and " . $ret;
return "$name: can't export gpio$hash->{RPI_pin}, no write access to $gpiodir/export and " . $ret;
} else { #nutze GPIO Utility?
Log3 $hash, 4, "$name: using gpio utility to export pin"; Log3 $hash, 4, "$name: using gpio utility to export pin";
RPI_GPIO_exuexpin($hash, "in"); RPI_GPIO_exuexpin($hash, "in");
} else { #Abbbruch da kein gpio utility vorhanden
my $msg = "$name: can't export gpio$hash->{RPI_pin}, no write access to $hash->{GPIO_Basedir}/export and WiringPi gpio utility not (correct) installed";
Log3 $hash, 1, $msg;
return $msg;
} }
} }
# wait for Pin export (max 5s) # wait for Pin export (max 5s)
my $checkpath = qq($gpiodir/gpio$hash->{RPI_pin}/value); my $checkpath = qq($hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value);
my $counter = 100; my $counter = 100;
while( $counter ){ while( $counter ){
last if( -e $checkpath && -w $checkpath ); last if( -e $checkpath && -w $checkpath );
Time::HiRes::sleep( 0.05 ); Time::HiRes::sleep( 0.05 );
$counter --; $counter --;
} }
unless( $counter ) { #abbrechen wenn export fehlgeschlagen unless( $counter ) { # nur wenn export fehlgeschlagen
# nochmal probieren wenn keine Schreibrechte auf GPIO Dateien ########## # nochmal probieren wenn keine Schreibrechte auf GPIO Dateien ##########
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) { #Abbbruch da kein gpio utility vorhanden if ( defined $hash->{WiringPi_gpio} ) { # nutze GPIO Utility fuer zweiten Exportversuch
if ( -e "$gpiodir/export") { Log3 $hash, 4, "$name: using gpio utility to export pin (first export via $hash->{GPIO_Basedir}/export failed)";
Log3 $hash, 1, "$name: \"$gpiodir/export\" exists and is " . ( ( -w "$gpiodir/export") ? "" : "NOT " ) . "writable"; RPI_GPIO_exuexpin($hash, "in");
} else { # Abbbruch da kein gpio utility vorhanden
Log3 $hash, 1, "$name: second attempt to export gpio$hash->{RPI_pin} also failed: WiringPi gpio utility not (correct) installed, possibly reasons for first fail:";
if ( -e "$hash->{GPIO_Basedir}/export") {
Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/export\" exists and is " . ( ( -w "$hash->{GPIO_Basedir}/export") ? "" : "NOT " ) . "writable";
} else { } else {
Log3 $hash, 1, "$name: gpio$hash->{RPI_pin}/value doesnt exist"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/export\" doesnt exist";
} }
if(-e "$gpiodir/gpio$hash->{RPI_pin}") { if(-e "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}") {
Log3 $hash, 1, "$name: \"$gpiodir/gpio$hash->{RPI_pin}\" exported but define aborted:"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}\" exported but define aborted:";
if ( -e "$gpiodir/gpio$hash->{RPI_pin}/value") { if ( -e "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value") {
Log3 $hash, 1, "$name: \"$gpiodir/gpio$hash->{RPI_pin}/value\" exists and is " . ( ( -w "$gpiodir/gpio$hash->{RPI_pin}/value") ? "" : "NOT " ) . "writable"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value\" exists and is " . ( ( -w "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value") ? "" : "NOT " ) . "writable";
} else { } else {
Log3 $hash, 1, "$name: \"$gpiodir/gpio$hash->{RPI_pin}/value\" doesnt exist"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/value\" doesnt exist";
} }
if ( -e "$gpiodir/gpio$hash->{RPI_pin}/direction") { if ( -e "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/direction") {
Log3 $hash, 1, "$name: \"$gpiodir/gpio$hash->{RPI_pin}/direction\" exists and is " . ( ( -w "$gpiodir/gpio$hash->{RPI_pin}/direction") ? "" : "NOT " ) . "writable"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/direction\" exists and is " . ( ( -w "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/direction") ? "" : "NOT " ) . "writable";
} else { } else {
Log3 $hash, 1, "$name: \"$gpiodir/gpio$hash->{RPI_pin}/direction\" doesnt exist"; Log3 $hash, 1, "$name: \"$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/direction\" doesnt exist";
} }
Log3 $hash, 1, "$name: second attempt to export gpio$hash->{RPI_pin} failed: " . $ret;
} }
return "$name: failed to export pin gpio$hash->{RPI_pin}, see logfile"; return "$name: failed to export pin gpio$hash->{RPI_pin}, see logfile";
} else { #nutze GPIO Utility fuer zweiten Exportversuch
Log3 $hash, 4, "$name: using gpio utility to export pin (first export via $gpiodir/export failed)";
RPI_GPIO_exuexpin($hash, "in");
} }
} }
@ -160,51 +201,33 @@ sub RPI_GPIO_Set($@) {
my ($hash, @a) = @_; my ($hash, @a) = @_;
my $name =$a[0]; my $name =$a[0];
my $cmd = $a[1]; my $cmd = $a[1];
#my $val = $a[2]; my $mt = AttrVal($name, 'direction', 'input');
if(defined($attr{$name}) && defined($attr{$name}{"direction"})) {
my $mt = $attr{$name}{"direction"};
if($mt && $mt eq "output") { if($mt && $mt eq "output") {
#if ($cmd eq 'toggle') {
# my $val = RPI_GPIO_fileaccess($hash, "value"); #alten Wert des GPIO direkt auslesen
# $cmd = $val eq "0" ? "on" :"off";
#}
if ($cmd eq 'on') { if ($cmd eq 'on') {
RPI_GPIO_fileaccess($hash, "value", "1"); RPI_GPIO_fileaccess($hash, "value", "1");
#$hash->{STATE} = 'on'; readingsSingleUpdate($hash, 'state', $cmd, 1);
readingsBeginUpdate($hash);
#readingsBulkUpdate($hash, 'Pinlevel', $valalt);
readingsBulkUpdate($hash, 'state', "on");
readingsEndUpdate($hash, 1);
} elsif ($cmd eq 'off') { } elsif ($cmd eq 'off') {
RPI_GPIO_fileaccess($hash, "value", "0"); RPI_GPIO_fileaccess($hash, "value", "0");
#$hash->{STATE} = 'off'; readingsSingleUpdate($hash, 'state', $cmd, 1);
readingsBeginUpdate($hash);
#readingsBulkUpdate($hash, 'Pinlevel', $valalt);
readingsBulkUpdate($hash, 'state', "off");
readingsEndUpdate($hash, 1);
} else { } else {
my $slist = join(' ', keys %setsoutp); my $slist = join(' ', keys %setsoutp);
Log3 $hash, 5, "wird an setextensions gesendet: @a"; Log3 $hash, 5, "wird an setextensions gesendet: @a";
return SetExtensions($hash, $slist, @a); return SetExtensions($hash, $slist, @a);
} }
} else { } elsif ($mt && $mt eq "input") {
if(!defined($setsinpt{$cmd})) { if ($cmd eq 'readValue') {
return 'Unknown argument ' . $cmd . ', choose one of ' . join(' ', keys %setsinpt)
} else {
}
}
}
if ($cmd eq 'readValue') { #noch bei input einpflegen
RPI_GPIO_updatevalue($hash); RPI_GPIO_updatevalue($hash);
} else {
return 'Unknown argument ' . $cmd . ', choose one of ' . join(' ', keys %setsinpt)
} }
} }
return undef;
}
sub RPI_GPIO_State($$$$) { #reload readings at FHEM start sub RPI_GPIO_State($$$$) { #reload readings at FHEM start
my ($hash, $tim, $sname, $sval) = @_; my ($hash, $tim, $sname, $sval) = @_;
Log3 $hash, 4, "$hash->{NAME}: $sname kann auf $sval wiederhergestellt werden $tim"; Log3 $hash, 4, "$hash->{NAME}: $sname kann auf $sval wiederhergestellt werden $tim";
#if ( (AttrVal($hash->{NAME},"restoreOnStartup","yes") eq "yes") && ($sname ne "STATE") ) {
if ( $sname ne "STATE" && AttrVal($hash->{NAME},"restoreOnStartup","last") ne "no") { if ( $sname ne "STATE" && AttrVal($hash->{NAME},"restoreOnStartup","last") ne "no") {
if (AttrVal($hash->{NAME},"direction","") eq "output") { if (AttrVal($hash->{NAME},"direction","") eq "output") {
$hash->{READINGS}{$sname}{VAL} = $sval; $hash->{READINGS}{$sname}{VAL} = $sval;
@ -254,7 +277,6 @@ sub RPI_GPIO_State($$$$) { #reload readings at FHEM start
$hash->{READINGS}{$sname}{VAL} = $sval; $hash->{READINGS}{$sname}{VAL} = $sval;
$hash->{READINGS}{$sname}{TIME} = $tim; $hash->{READINGS}{$sname}{TIME} = $tim;
} }
#}
} }
} }
} }
@ -330,14 +352,12 @@ sub RPI_GPIO_Attr(@) {
$msg = "$hash->{NAME}: Wrong $attr value. Use none, falling, rising or both"; $msg = "$hash->{NAME}: Wrong $attr value. Use none, falling, rising or both";
} }
} }
#Tastfunktion: bei jedem Tastendruck wird State invertiert if ($attr eq 'toggletostate') { # Tastfunktion: bei jedem Tastendruck wird State invertiert
if ($attr eq 'toggletostate') {
unless ( !$val || ($val eq ("yes" || "no") ) ) { unless ( !$val || ($val eq ("yes" || "no") ) ) {
$msg = "$hash->{NAME}: Wrong $attr value. Use yes or no"; $msg = "$hash->{NAME}: Wrong $attr value. Use yes or no";
} }
} }
#invertierte Logik if ($attr eq 'active_low') { # invertierte Logik
if ($attr eq 'active_low') {
if ( !$val || ($val eq "no" ) ) { if ( !$val || ($val eq "no" ) ) {
RPI_GPIO_fileaccess($hash, "active_low", "0"); RPI_GPIO_fileaccess($hash, "active_low", "0");
Log3 $hash, 5, "$hash->{NAME}: set attr active_low: no"; Log3 $hash, 5, "$hash->{NAME}: set attr active_low: no";
@ -348,26 +368,25 @@ sub RPI_GPIO_Attr(@) {
$msg = "$hash->{NAME}: Wrong $attr value. Use yes or no"; $msg = "$hash->{NAME}: Wrong $attr value. Use yes or no";
} }
} }
#Entprellzeit if ($attr eq 'debounce_in_ms') { # Entprellzeit
if ($attr eq 'debounce_in_ms') {
if ( $val && ( ($val > 250) || ($val < 0) ) ) { if ( $val && ( ($val > 250) || ($val < 0) ) ) {
$msg = "$hash->{NAME}: debounce_in_ms value to big. Use 0 to 250"; $msg = "$hash->{NAME}: debounce_in_ms value to big. Use 0 to 250";
} }
} }
if ($attr eq "pud_resistor" && $val) { if ($attr eq "pud_resistor" && $val) { # interner pullup/down Widerstand
if($val =~ /^(off|up|down)$/) { if($val =~ /^(off|up|down)$/) {
if(-w "$gpiodir/gpio$hash->{RPI_pin}/pull") { if(-w "$hash->{GPIO_Basedir}/gpio$hash->{RPI_pin}/pull") {
$val =~ s/off/disable/; $val =~ s/off/disable/;
RPI_GPIO_fileaccess($hash, "pull", $val); RPI_GPIO_fileaccess($hash, "pull", $val);
} else { #nur fuer Raspberry (ueber gpio utility) } else { #nur fuer Raspberry (ueber gpio utility)
my $pud; #my $pud;
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) { if ( defined $hash->{WiringPi_gpio} ) {
Log3 $hash, 1, "$hash->{NAME}: unable to change pud resistor:" . $ret;
return "$hash->{NAME}: " . $ret;
} else {
$val =~ s/off/tri/; $val =~ s/off/tri/;
$pud = $gpioprg." -g mode ".$hash->{RPI_pin}." ".$val; RPI_GPIO_exuexpin($hash, $val);
$pud = `$pud`; } else {
my $ret = "$hash->{NAME}: unable to change pud resistor: WiringPi gpio utility not (correct) installed";
Log3 $hash, 1, $ret;
return $ret;
} }
} }
} else { } else {
@ -388,6 +407,33 @@ sub RPI_GPIO_Poll($) { #for attr poll_intervall -> readout pin value
return; return;
} }
sub RPI_GPIO_Shutdown($$) {
my ($hash, $arg) = @_;
if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) { # remove internal timer
RemoveInternalTimer($hash);
}
if ( ( AttrVal($hash->{NAME}, "interrupt", "none") ) ne ( "none" ) ) { # detach interrupt
delete $selectlist{$hash->{NAME}};
close($hash->{filehandle});
Log3 $hash, 5, "$hash->{NAME}: interrupt detached";
}
# to have a chance to externaly setup the GPIOs -
# leave GPIOs untouched if attr unexportpin is set to "no"
# only delete inputs (otherwise outputs will flicker during restart of FHEM)
if( AttrVal($hash->{NAME},"direction","") ne "output" and AttrVal($hash->{NAME},"unexportpin","") ne "no" ) {
if (-w "$hash->{GPIO_Basedir}/unexport") {# unexport if write access to unexport
my $uexp = IO::File->new("> $hash->{GPIO_Basedir}/unexport");
print $uexp "$hash->{RPI_pin}";
$uexp->close;
} else {# else use gpio utility
RPI_GPIO_exuexpin($hash, "unexport");
}
Log3 $hash, 5, "$hash->{NAME}: gpio$hash->{RPI_pin} removed";
}
return undef;
}
sub RPI_GPIO_Undef($$) { sub RPI_GPIO_Undef($$) {
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) { if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) {
@ -400,15 +446,15 @@ sub RPI_GPIO_Undef($$) {
# to have a chance to externaly setup the GPIOs - # to have a chance to externaly setup the GPIOs -
# leave GPIOs untouched if attr unexportpin is set to "no" # leave GPIOs untouched if attr unexportpin is set to "no"
if(AttrVal($hash->{NAME},"unexportpin","") ne "no") { if(AttrVal($hash->{NAME},"unexportpin","") ne "no") {
if (-w "$gpiodir/unexport") {#unexport Pin alte Version if (-w "$hash->{GPIO_Basedir}/unexport") {#unexport Pin alte Version
my $uexp = IO::File->new("> $gpiodir/unexport"); my $uexp = IO::File->new("> $hash->{GPIO_Basedir}/unexport");
print $uexp "$hash->{RPI_pin}"; print $uexp "$hash->{RPI_pin}";
$uexp->close; $uexp->close;
} else {#alternative unexport Pin: } else {#alternative unexport Pin:
RPI_GPIO_exuexpin($hash, "unexport"); RPI_GPIO_exuexpin($hash, "unexport");
} }
} }
Log3 $hash, 1, "$hash->{NAME}: entfernt"; Log3 $hash, 4, "$hash->{NAME}: entfernt";
return undef; return undef;
} }
@ -460,21 +506,26 @@ sub RPI_GPIO_Except($) { #called from main if an interrupt occured
$valcnt = $hash->{READINGS}{Counter}{VAL} + 1; $valcnt = $hash->{READINGS}{Counter}{VAL} + 1;
Log3 $hash, 5, "Zaehler ist jetzt $valcnt"; Log3 $hash, 5, "Zaehler ist jetzt $valcnt";
} }
#Doppelklick (noch im Teststatus)
my $testtt = (gettimeofday() - $hash->{lasttrg} );
$hash->{lasttrg} = gettimeofday();
readingsSingleUpdate($hash, 'Dblclick', "on", 1) if $testtt < 2;
#langer Testendruck #langer Testendruck
} elsif ($eval eq "both") { } elsif ($eval eq "both") {
if ( $val == 1 ) { if ( $val == 1 ) {
my $lngpressInterval = AttrVal($hash->{NAME}, "longpressinterval", "1"); my $lngpressInterval = AttrVal($hash->{NAME}, "longpressinterval", "1");
InternalTimer(gettimeofday() + $lngpressInterval, 'RPI_GPIO_longpress', $hash, 0); InternalTimer(gettimeofday() + $lngpressInterval, 'RPI_GPIO_longpress', $hash, 0);
#$hash->{Anzeit} = gettimeofday();
} else { } else {
RemoveInternalTimer('RPI_GPIO_longpress'); RemoveInternalTimer('RPI_GPIO_longpress');
$vallp = 'off'; $vallp = 'off';
#my $zeit = $acttime; }
#$zeit -= $hash->{Anzeit}; #Doppelklick (noch im Teststatus)
#Log3 $hash, 5, "Anzeit: $zeit"; if ( $val == AttrVal($hash->{NAME}, "dblclicklevel", "1") ) {
#readingsBeginUpdate($hash); my $testtt = (gettimeofday() - $hash->{lasttrg} );
#readingsBulkUpdate($hash, 'Anzeit', $zeit); $hash->{lasttrg} = gettimeofday();
#readingsEndUpdate($hash, 1); readingsSingleUpdate($hash, 'Dblclick', "on", 1) if $testtt < 2;
} else {
readingsSingleUpdate($hash, 'Dblclick', "off", 1);
} }
} }
@ -495,9 +546,7 @@ sub RPI_GPIO_longpress($) { #for reading longpress
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $val = RPI_GPIO_fileaccess($hash, "value"); my $val = RPI_GPIO_fileaccess($hash, "value");
if ($val == 1) { if ($val == 1) {
readingsBeginUpdate($hash); readingsSingleUpdate($hash, 'Longpress', 'on', 1);
readingsBulkUpdate($hash, 'Longpress', 'on');
readingsEndUpdate($hash, 1);
} }
} }
@ -527,10 +576,9 @@ sub RPI_GPIO_updatevalue($) { #update value for Input devices
} }
sub RPI_GPIO_fileaccess($$;$) { #Fileaccess for GPIO base directory sub RPI_GPIO_fileaccess($$;$) { #Fileaccess for GPIO base directory
#my ($hash, $fname, $value) = @_;
my ($hash, @args) = @_; my ($hash, @args) = @_;
my $fname = $args[0]; my $fname = $args[0];
my $pinroot = qq($gpiodir/gpio$hash->{RPI_pin}); my $pinroot = qq($hash->{GPIO_Basedir}/gpio$hash->{RPI_pin});
my $file =qq($pinroot/$fname); my $file =qq($pinroot/$fname);
Log3 $hash, 5, "$hash->{NAME}, in fileaccess: $fname " . (defined($args[1])?$args[1]:""); Log3 $hash, 5, "$hash->{NAME}, in fileaccess: $fname " . (defined($args[1])?$args[1]:"");
@ -562,12 +610,6 @@ sub RPI_GPIO_fileaccess($$;$) { #Fileaccess for GPIO base directory
if ($fname eq "direction" && (not -w $file)) { #wenn direction und diese nicht schreibbar mit gpio utility versuchen if ($fname eq "direction" && (not -w $file)) { #wenn direction und diese nicht schreibbar mit gpio utility versuchen
Log3 $hash, 4, "$hash->{NAME}: direction ueber gpio utility einstellen"; Log3 $hash, 4, "$hash->{NAME}: direction ueber gpio utility einstellen";
RPI_GPIO_exuexpin($hash, $value); RPI_GPIO_exuexpin($hash, $value);
#if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) {
# Log3 $hash, 1, "$hash->{NAME}: " . $ret;
#} else {
#my $exp = $gpioprg.' -g mode '.$hash->{RPI_pin}. ' '.$value;
#$exp = `$exp`;
#}
} else { } else {
my $fh = IO::File->new("> $file"); my $fh = IO::File->new("> $file");
if (defined $fh) { if (defined $fh) {
@ -580,50 +622,35 @@ sub RPI_GPIO_fileaccess($$;$) { #Fileaccess for GPIO base directory
} }
} }
sub RPI_GPIO_exuexpin($$) { #export, unexport and direction Pin via GPIO utility sub RPI_GPIO_exuexpin($$) { #export, unexport, direction, pud_resistor via GPIO utility
my ($hash, $dir) = @_; my ($hash, $dir) = @_;
my $gpioutility = $hash->{WiringPi_gpio};
if ( defined $hash->{WiringPi_gpio} ) {
my $sw; my $sw;
if ($dir eq "unexport") { if ($dir eq "unexport") {
$sw = $dir; $sw = $dir;
$dir = ""; $dir = "";
} elsif ($dir eq "up" || $dir eq "down"|| $dir eq "tri") {
$sw = "-g mode";
} else { } else {
$sw = "export"; $sw = "export";
$dir = "out" if ( $dir eq "high" || $dir eq "low" ); #auf out zurueck, da gpio tool dies nicht unterst?tzt $dir = "out" if ( $dir eq "high" || $dir eq "low" ); #auf out zurueck, da gpio tool dies nicht unterst?tzt
$dir = " ".$dir;
} }
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) { my $exp = $gpioutility.' '.$sw.' '.$hash->{RPI_pin}. (defined $dir ? " " . $dir : "");
Log3 $hash, 1, "$hash->{NAME}: " . $ret;
} else {
my $exp = $gpioprg.' '.$sw.' '.$hash->{RPI_pin}.$dir;
$exp = `$exp`; $exp = `$exp`;
}
#######################
}
sub RPI_GPIO_CHECK_GPIO_UTIL {
my ($gpioprg) = @_;
my $ret = undef;
#unless (defined($hash->{gpio_util_exists})) {
if(-e $gpioprg) {
if(-x $gpioprg) {
unless(-u $gpioprg) {
$ret = "file $gpioprg is not setuid";
}
} else { } else {
$ret = "file $gpioprg is not executable"; my $ret = "WiringPi gpio utility not (correct) installed";
} Log3 $hash, 1, "$hash->{NAME}: $ret";
} else {
$ret = "file $gpioprg doesnt exist";
}
return $ret; return $ret;
} }
}
sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
my $msg = ''; my $msg = '';
if ( $arg eq "start") { if ( $arg eq "start") {
#FH fuer value-datei #FH fuer value-datei
my $pinroot = qq($gpiodir/gpio$hash->{RPI_pin}); my $pinroot = qq($hash->{GPIO_Basedir}/gpio$hash->{RPI_pin});
my $valfile = qq($pinroot/value); my $valfile = qq($pinroot/value);
$hash->{filehandle} = IO::File->new("< $valfile"); $hash->{filehandle} = IO::File->new("< $valfile");
if (!defined $hash->{filehandle}) { if (!defined $hash->{filehandle}) {
@ -683,13 +710,14 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
<a name="RPI_GPIODefine"></a> <a name="RPI_GPIODefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define <name> RPI_GPIO &lt;GPIO number&gt;</code><br><br> <code>define <name> RPI_GPIO &lt;GPIO number&gt;[ &lt;GPIO-Basedir&gt;[ &lt;WiringPi-gpio-utility&gt;]]</code><br><br>
all usable <code>GPIO number</code> can be found <a href="http://www.panu.it/raspberry/">here</a><br><br> all usable <code>GPIO number</code> can be found <a href="http://www.panu.it/raspberry/">here</a><br><br>
Examples: Examples:
<pre> <pre>
define Pin12 RPI_GPIO 18 define Pin12 RPI_GPIO 18
attr Pin12 poll_interval 5 attr Pin12 poll_interval 5
define Pin12 RPI_GPIO 18 /sys/class/gpio /usr/somewhere/bin/gpio
</pre> </pre>
</ul> </ul>
@ -828,13 +856,14 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
<a name="RPI_GPIODefine"></a> <a name="RPI_GPIODefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define &lt;name&gt; RPI_GPIO &lt;GPIO number&gt;</code><br><br> <code>define &lt;name&gt; RPI_GPIO &lt;GPIO number&gt;[ &lt;GPIO-Basedir&gt;[ &lt;WiringPi-gpio-utility&gt;]]</code><br><br>
Alle verf&uuml;gbaren <code>GPIO number</code> sind z.B. <a href="http://www.panu.it/raspberry/">hier</a> zu finden<br><br> Alle verf&uuml;gbaren <code>GPIO number</code> sind z.B. <a href="http://www.panu.it/raspberry/">hier</a> zu finden<br><br>
Beispiele: Beispiele:
<pre> <pre>
define Pin12 RPI_GPIO 18 define Pin12 RPI_GPIO 18
attr Pin12 poll_interval 5 attr Pin12 poll_interval 5
define Pin12 RPI_GPIO 18 /sys/class/gpio /usr/somewhere/bin/gpio
</pre> </pre>
</ul> </ul>

View File

@ -90,27 +90,23 @@ sub I2C_MCP342x_Init($$) {
my ( $hash, $args ) = @_; my ( $hash, $args ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
Log3 $hash, 1, "$hash->{NAME}: Init Argumente1: $args";
if (defined $args && int(@$args) > 1) if (defined $args && int(@$args) < 1) {
{ Log3 $hash, 0, "Define: Wrong syntax. Usage:\n" .
return "Define: Wrong syntax. Usage:\n" .
"define <name> MCP342x [<i2caddress>] [<type>]"; "define <name> MCP342x [<i2caddress>] [<type>]";
} }
if (defined (my $address = shift @$args)) { if (defined (my $address = shift @$args)) {
$hash->{I2C_Address} = $address =~ /^0.*$/ ? oct($address) : $address; $hash->{I2C_Address} = $address =~ /^0x.*$/ ? oct($address) : $address;
return "$name I2C Address not valid" unless ($address < 128 && $address > 3); Log3 $hash, 0, "$name: I2C Address not valid" unless ($hash->{I2C_Address} < 128 && $hash->{I2C_Address} > 3);
} else { } else {
$hash->{I2C_Address} = hex(MCP3422_I2C_ADDRESS); $hash->{I2C_Address} = hex(MCP3422_I2C_ADDRESS);
} }
if (defined (my $channels = shift @$args)) { if (defined (my $channels = shift @$args)) {
$hash->{channels} = $channels if $channels == 2 || $channels == 4; $hash->{channels} = ($channels == 4 ? 4 : 2);
} else { } else {
$hash->{channels} = 2; $hash->{channels} = 2;
} }
my $msg = ''; my $msg = '';
# create default attributes # create default attributes
if (AttrVal($name, 'poll_interval', '?') eq '?') { if (AttrVal($name, 'poll_interval', '?') eq '?') {