2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-05-02 06:55:26 +00:00

51_RPI_GPIO: Added possibility to access active_low file

53_GHoma: changed Id to Hex


git-svn-id: https://svn.fhem.de/fhem/trunk@10177 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klauswitt 2015-12-15 00:07:00 +00:00
parent 69366a0ec5
commit 80c8e6efaa
2 changed files with 62 additions and 46 deletions

View File

@ -36,6 +36,7 @@ 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" .
" longpressinterval " . " longpressinterval " .
"$readingFnAttributes"; "$readingFnAttributes";
} }
@ -353,28 +354,27 @@ sub RPI_GPIO_Attr(@) {
$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') {#nur fuer Raspberry (ueber gpio utility) if ($attr eq "pud_resistor" && $val) {
my $pud; if($val =~ /^(off|up|down)$/) {
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) { if(-w "$gpiodir/gpio$hash->{RPI_pin}/pull") {
Log3 $hash, 1, "$hash->{NAME}: unable to change pud resistor:" . $ret; $val =~ s/off/disable/;
return "$hash->{NAME}: " . $ret; RPI_GPIO_fileaccess($hash, "pull", $val);
} else { } else { #nur fuer Raspberry (ueber gpio utility)
if ( !$val ) { my $pud;
} elsif ($val eq "off") { if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) {
$pud = $gpioprg.' -g mode '.$hash->{RPI_pin}.' tri'; Log3 $hash, 1, "$hash->{NAME}: unable to change pud resistor:" . $ret;
$pud = `$pud`; return "$hash->{NAME}: " . $ret;
} elsif ($val eq "up") { } else {
$pud = $gpioprg.' -g mode '.$hash->{RPI_pin}.' up'; $val =~ s/off/tri/;
$pud = `$pud`; $pud = $gpioprg." -g mode ".$hash->{RPI_pin}." ".$val;
} elsif ($val eq "down") { $pud = `$pud`;
$pud = $gpioprg.' -g mode '.$hash->{RPI_pin}.' down'; }
$pud = `$pud`; }
} else { } else {
$msg = "$hash->{NAME}: Wrong $attr value. Use off, up or down"; $msg = "$hash->{NAME}: Wrong $attr value. Use off, up or down";
} }
} }
} return ($msg) ? $msg : undef;
return ($msg) ? $msg : undef;
} }
sub RPI_GPIO_Poll($) { #for attr poll_intervall -> readout pin value sub RPI_GPIO_Poll($) { #for attr poll_intervall -> readout pin value
@ -397,13 +397,17 @@ sub RPI_GPIO_Undef($$) {
delete $selectlist{$hash->{NAME}}; delete $selectlist{$hash->{NAME}};
close($hash->{filehandle}); close($hash->{filehandle});
} }
if (-w "$gpiodir/unexport") {#unexport Pin alte Version # to have a chance to externaly setup the GPIOs -
# leave GPIOs untouched if attr unexportpin is set to "no"
if(AttrVal($hash->{NAME},"unexportpin","") ne "no") {
if (-w "$gpiodir/unexport") {#unexport Pin alte Version
my $uexp = IO::File->new("> $gpiodir/unexport"); my $uexp = IO::File->new("> $gpiodir/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, 1, "$hash->{NAME}: entfernt";
return undef; return undef;
} }
@ -651,7 +655,7 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
In addition to the Raspberry Pi, also BBB, Cubie, Banana Pi and almost every linux system which provides gpio access in userspace is supported.<br> In addition to the Raspberry Pi, also BBB, Cubie, Banana Pi and almost every linux system which provides gpio access in userspace is supported.<br>
<b>Warning: Never apply any external voltage to an output configured pin! GPIO's internal logic operate with 3,3V. Don't exceed this Voltage!</b><br><br> <b>Warning: Never apply any external voltage to an output configured pin! GPIO's internal logic operate with 3,3V. Don't exceed this Voltage!</b><br><br>
<b>preliminary:</b><br> <b>preliminary:</b><br>
GPIO Pins accessed by sysfs. The files are located in folder <code>/system/class/gpio</code> and belong to the gpio group (on actual Raspbian distributions since jan 2014).<br> GPIO Pins accessed by sysfs. The files are located in folder <code>/system/class/gpio</code> and belong to the gpio group (on actual Raspbian distributions since jan 2014). It will work even on an Jessie version but NOT if you perform an kerlen update<br>
After execution of following commands, GPIO's are usable whithin PRI_GPIO:<br> After execution of following commands, GPIO's are usable whithin PRI_GPIO:<br>
<ul><code> <ul><code>
sudo adduser fhem gpio<br> sudo adduser fhem gpio<br>
@ -675,7 +679,7 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
echo 23 > /sys/class/gpio/export<br> echo 23 > /sys/class/gpio/export<br>
chown -R fhem:root /sys/devices/virtual/gpio/* (or chown -R fhem:gpio /sys/devices/platform/gpio-sunxi/gpio/* for Banana Pi)<br> chown -R fhem:root /sys/devices/virtual/gpio/* (or chown -R fhem:gpio /sys/devices/platform/gpio-sunxi/gpio/* for Banana Pi)<br>
chown -R fhem:root /sys/class/gpio/*<br> chown -R fhem:root /sys/class/gpio/*<br>
</code></ul><br> </code></ul><br>
<a name="RPI_GPIODefine"></a> <a name="RPI_GPIODefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
@ -815,8 +819,12 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
Restore Readings and sets after reboot<br> Restore Readings and sets after reboot<br>
Default: last, valid values: last, on, off, no<br><br> Default: last, valid values: last, on, off, no<br><br>
</li> </li>
<li>longpressinterval<br> <li>unexportpin<br>
<b>works with interrupt set to both only</b><br> do an unexport to /sys/class/gpio/unexport if the pin definition gets cleared (e.g. by rereadcmd, delete,...)<br>
Default: yes, valid values: yes, no<br><br>
</li>
<li>longpressinterval<br>
<b>works with interrupt set to both only</b><br>
time in seconds, a port need to be high to set reading longpress to on<br> time in seconds, a port need to be high to set reading longpress to on<br>
Default: 1, valid values: 0.1 - 10<br><br> Default: 1, valid values: 0.1 - 10<br><br>
</li> </li>
@ -840,7 +848,7 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
Neben dem Raspberry Pi k&ouml;nnen auch die GPIO's von BBB, Cubie, Banana Pi und jedem Linuxsystem, das diese im Userspace zug&auml;gig macht, genutzt werden.<br> Neben dem Raspberry Pi k&ouml;nnen auch die GPIO's von BBB, Cubie, Banana Pi und jedem Linuxsystem, das diese im Userspace zug&auml;gig macht, genutzt werden.<br>
<b>Wichtig: Niemals Spannung an einen GPIO anlegen, der als Ausgang eingestellt ist! Die interne Logik der GPIO's arbeitet mit 3,3V. Ein &uuml;berschreiten der 3,3V zerst&ouml;rt den GPIO und vielleicht auch den ganzen Prozessor!</b><br><br> <b>Wichtig: Niemals Spannung an einen GPIO anlegen, der als Ausgang eingestellt ist! Die interne Logik der GPIO's arbeitet mit 3,3V. Ein &uuml;berschreiten der 3,3V zerst&ouml;rt den GPIO und vielleicht auch den ganzen Prozessor!</b><br><br>
<b>Vorbereitung:</b><br> <b>Vorbereitung:</b><br>
Auf GPIO Pins wird im Modul &uuml;ber sysfs zugegriffen. Die Dateien befinden sich unter <code>/system/class/gpio</code> und sind in der aktuellen Raspbian Distribution (ab Jan 2014) in der Gruppe gpio.<br> Auf GPIO Pins wird im Modul &uuml;ber sysfs zugegriffen. Die Dateien befinden sich unter <code>/system/class/gpio</code> und sind in der aktuellen Raspbian Distribution (ab Jan 2014) in der Gruppe gpio. Es funktioniert auch mit der Jessie Version. Allerdings NICHT wenn ein Kernelupgrade durchgef&uuml;hrt wird<br>
Nach dem ausf&uuml;hren folgender Befehle sind die GPIO's von PRI_GPIO aus nutzbar:<br> Nach dem ausf&uuml;hren folgender Befehle sind die GPIO's von PRI_GPIO aus nutzbar:<br>
<ul><code> <ul><code>
sudo adduser fhem gpio<br> sudo adduser fhem gpio<br>
@ -1001,6 +1009,10 @@ sub RPI_GPIO_inthandling($$) { #start/stop Interrupthandling
Wartezeit in ms bis nach ausgel&ouml;stem Interrupt der entsprechende Pin abgefragt wird. Kann zum entprellen von mechanischen Schaltern verwendet werden<br> Wartezeit in ms bis nach ausgel&ouml;stem Interrupt der entsprechende Pin abgefragt wird. Kann zum entprellen von mechanischen Schaltern verwendet werden<br>
Standard: 0, g&uuml;ltige Werte: Dezimalzahl<br><br> Standard: 0, g&uuml;ltige Werte: Dezimalzahl<br><br>
</li> </li>
<li>unexportpin<br>
F&uuml;hre unexport &uuml;ber /sys/class/gpio/unexport aus wenn die Pin-Definition gel&ouml;scht wird (z.B. durch rereadcfg, delete,...)<br>
Standard: yes, , g&uuml;ltige Werte: yes, no<br><br>
</li>
<li>restoreOnStartup<br> <li>restoreOnStartup<br>
Wiederherstellen der Portzust&auml;nde nach Neustart<br> Wiederherstellen der Portzust&auml;nde nach Neustart<br>
Standard: last, g&uuml;ltige Werte: last, on, off, no<br><br> Standard: last, g&uuml;ltige Werte: last, on, off, no<br><br>

View File

@ -133,7 +133,7 @@ sub GHoma_ClientDisconnect($$) { # im Mom unnuetz
##################################### #####################################
sub GHoma_Shutdown($) { # sub GHoma_Shutdown($) { #
my ($hash) = @_; my ($hash) = @_;
return unless defined $hash->{Id}; return unless defined $hash->{Id}; #nicht für Server
# state auf letzten Schaltwert setzen oder auf fixen Startwert (wird bereitsbeim Shutdown ausgefuehrt) # state auf letzten Schaltwert setzen oder auf fixen Startwert (wird bereitsbeim Shutdown ausgefuehrt)
if (AttrVal($hash->{NAME},"restoreOnStartup","last") eq "on") { if (AttrVal($hash->{NAME},"restoreOnStartup","last") eq "on") {
readingsSingleUpdate($hash, "state", "on", 1); readingsSingleUpdate($hash, "state", "on", 1);
@ -148,7 +148,7 @@ sub GHoma_Shutdown($) { #
sub GHoma_Define($$$) { # sub GHoma_Define($$$) { #
my ($hash, $def) = @_; my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def); #my @a = split("[ \t][ \t]*", $def);
my ($name, $type, $pport, $global) = split("[ \t]+", $def); my ($name, $type, $pport, $global) = split("[ \t]+", $def);
my $port = $pport; my $port = $pport;
@ -161,12 +161,12 @@ sub GHoma_Define($$$) { #
#return "Usage: define <name> GHoma { [IPV6:]<tcp-portnr>|<serverName:port> }" if(!($isServer || $isClient || $isSerCli)); #return "Usage: define <name> GHoma { [IPV6:]<tcp-portnr>|<serverName:port> }" if(!($isServer || $isClient || $isSerCli));
return "Usage: define <name> GHoma { [IPV6:]<tcp-portnr> }" if(!($isServer || $isClient || $isSerCli)); return "Usage: define <name> GHoma { [IPV6:]<tcp-portnr> }" if(!($isServer || $isClient || $isSerCli));
$hash->{DeviceName} = $pport; #$hash->{DeviceName} = $pport;
if($isSerCli) { #ServerClient if($isSerCli) { #ServerClient
my $name = $a[0]; #my $name = $a[0];
my $addr = $a[2]; # my $addr = $a[2];
$hash->{Id} = pack('C*', ( hex(substr($addr,0,2)), hex(substr($addr,2,2)), hex(substr($addr,4,2)) ) ); #$hash->{Id} = pack('C*', ( hex(substr($pport,0,2)), hex(substr($pport,2,2)), hex(substr($pport,4,2)) ) );
$hash->{Id} = $pport;
return; return;
} }
@ -247,7 +247,7 @@ sub GHoma_Read($) { # wird von der globalen loop aufgerufen (ueber $hash->{F
return; return;
} }
if ( substr($buf,0,10) eq ($prefix . $dosehb )) { # Heartbeat if ( substr($buf,0,10) eq ($prefix . $dosehb )) { # Heartbeat (Dosen Id wird nicht ueberprueft)
#DevIo_SimpleWrite($hash, GHoma_BuildString($hbeat) , undef); #DevIo_SimpleWrite($hash, GHoma_BuildString($hbeat) , undef);
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
$buf =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; #empfangene Zeichen in Hexwerte wandeln $buf =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; #empfangene Zeichen in Hexwerte wandeln
@ -275,9 +275,10 @@ sub GHoma_Read($) { # wird von der globalen loop aufgerufen (ueber $hash->{F
Log3 $hash, 5, "$hash->{NAME} RX: 5A A5 $smsg"; # ...und ins Log schreiben Log3 $hash, 5, "$hash->{NAME} RX: 5A A5 $smsg"; # ...und ins Log schreiben
if ( substr($_,2,6) eq ($cinit1)) { # Antwort auf erstes Init if ( substr($_,2,6) eq ($cinit1)) { # Antwort auf erstes Init
$hash->{Id} = substr($_,8,3); #$hash->{Id} = substr($_,8,3);
$hash->{Id} = unpack('H*', substr($_,8,3) );
unless ($hash->{isClient}) { unless ($hash->{isClient}) {
# fuer Server Loesung bei erster Antwort von Dose nach bestehendem Devicem it gleicher Id suchen und Verbindung auf dieses Modul uebertragen # fuer Server Loesung bei erster Antwort von Dose nach bestehendem Device mit gleicher Id suchen und Verbindung auf dieses Modul uebertragen
my $clientdefined = undef; my $clientdefined = undef;
foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) { # bereits bestehendes define mit dieser Id suchen foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) { # bereits bestehendes define mit dieser Id suchen
if ($hash->{Id} eq InternalVal($dev,"Id","") && $hash->{NAME} ne $dev && InternalVal($dev,"TEMPORARY","") ne "1") { if ($hash->{Id} eq InternalVal($dev,"Id","") && $hash->{NAME} ne $dev && InternalVal($dev,"TEMPORARY","") ne "1") {
@ -288,10 +289,13 @@ sub GHoma_Read($) { # wird von der globalen loop aufgerufen (ueber $hash->{F
} }
} }
unless ( defined $clientdefined) { # ...ein Neues anlegen, falls keins existiert unless ( defined $clientdefined) { # ...ein Neues anlegen, falls keins existiert
my $id = unpack('H*', $hash->{Id} ); #my $id = unpack('H*', $hash->{Id} );
Log3 $name, 4, "GHoma Unknown device $id, please define it"; #Log3 $name, 4, "GHoma Unknown device $id, please define it";
DoTrigger("global", "UNDEFINED GHoma_$id GHoma $id"); #DoTrigger("global", "UNDEFINED GHoma_$id GHoma $id");
GHoma_moveclient($hash, $defs{"GHoma_$id"}) if ($defs{"GHoma_$id"}); #GHoma_moveclient($hash, $defs{"GHoma_$id"}) if ($defs{"GHoma_$id"});
Log3 $name, 4, "GHoma Unknown device $hash->{Id}, please define it";
DoTrigger("global", "UNDEFINED GHoma_$hash->{Id} GHoma $hash->{Id}");
GHoma_moveclient($hash, $defs{"GHoma_$hash->{Id}"}) if ($defs{"GHoma_$hash->{Id}"});
} }
} else { } else {
readingsSingleUpdate($hash, "state", "Initialize...", 1); readingsSingleUpdate($hash, "state", "Initialize...", 1);
@ -390,7 +394,7 @@ sub GHoma_Set($@) { #
return SetExtensions($hash, $slist, @a); return SetExtensions($hash, $slist, @a);
} }
if (defined $hash->{CD}) { if (defined $hash->{CD}) {
syswrite( $hash->{CD}, GHoma_BuildString($switch1 . $hash->{Id} . $switch2 . $type) ); syswrite( $hash->{CD}, GHoma_BuildString($switch1 . pack('C*', ( hex(substr($hash->{Id},0,2)), hex(substr($hash->{Id},2,2)), hex(substr($hash->{Id},4,2)) ) ) . $switch2 . $type) );
} }
return undef; return undef;
} }
@ -398,7 +402,7 @@ sub GHoma_Set($@) { #
sub GHoma_State($$$$) { # reload readings at FHEM start sub GHoma_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 ( $sname eq "state" && defined $hash->{Id} ) { if ( $sname eq "state" && defined $hash->{Id} ) { #wenn kein Server
$hash->{LASTSTATE} = $sval; $hash->{LASTSTATE} = $sval;
readingsSingleUpdate($hash, "state", "offline", 1) readingsSingleUpdate($hash, "state", "offline", 1)
} }