# $Id$ #################################################################################################### # # 55_PIFACE.pm # # An FHEM Perl module to control RaspberryPi extension board PiFace # # The PiFace is an add-on board for the Raspberry Pi featuring 8 open-collector outputs, # with 2 relays and 8 inputs (with 4 on-board buttons). # These functions are fairly well fixed in the hardware, # so only the read, write and internal pull-up commands are implemented. # # Please read commandref for details on prerequisits! # Depends on wiringPi library from http://wiringpi.com # # Copyright: betateilchen ® # e-mail: fhem.development@betateilchen.de # # This file is part of fhem. # # Fhem is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # Fhem is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with fhem. If not, see . # #################################################################################################### package main; use strict; use warnings; sub PIFACE_Define($$); sub PIFACE_Undefine($$); sub PIFACE_Set($@); sub PIFACE_Get($@); my $base = 199; sub PIFACE_Initialize($){ my ($hash) = @_; $hash->{DefFn} = "PIFACE_Define"; $hash->{UndefFn} = "PIFACE_Undefine"; $hash->{SetFn} = "PIFACE_Set"; $hash->{GetFn} = "PIFACE_Get"; $hash->{AttrList} = $readingFnAttributes; } sub PIFACE_Define($$){ my ($hash, $def) = @_; my $name = $hash->{NAME}; Log3($name, 3, "PIFACE $name: created"); readingsSingleUpdate($hash, "state", "active",1); PI_read_outports($hash); PI_read_inports($hash,0); PI_read_inports($hash,1); return undef; } sub PIFACE_Undefine($$){ my($hash, $name) = @_; RemoveInternalTimer($hash); return; } sub PIFACE_Set($@){ my ($hash, @a) = @_; my $name = $hash->{NAME}; my $port = $a[1]; my $val = $a[2]; my ($adr, $cmd, $i, $j, $k); my $usage = "Unknown argument $port, choose one of 0 1:0,1 2:0,1 3:0,1 4:0,1 5:0,1 6:0,1 7:0,1 8:0,1 "; return $usage if $port eq "?"; if ($port ne "0") { $adr = $base + $port; Log3($name, 3, "PIFACE $name: set port $port $val"); $cmd = "/usr/local/bin/gpio -p write $adr $val"; $cmd = `$cmd`; readingsSingleUpdate($hash, 'out'.$port, $val, 1); } else { $adr = $base + 1; Log3($name, 3, "PIFACE $name: set ports $val"); readingsBeginUpdate($hash); for($i=0; $i<8; $i++){ $j = 2**$i; $k = ($val & $j); $k = ($k) ? 1 : 0; $adr = 1 + $i; Log3($name, 3, "PIFACE $name: set port $adr $k"); $adr += $base; $cmd = "/usr/local/bin/gpio -p write $adr $k"; $cmd = `$cmd`; $j = $i + 1; readingsBulkUpdate($hash, 'out'.$j, $k); } readingsEndUpdate($hash, 1); } return ""; } sub PIFACE_Get($@){ my ($hash, @a) = @_; my $name = $hash->{NAME}; my $port = $a[1]; my ($adr, $cmd, $pin, $pull, $val); my $usage = "Unknown argument $port, choose one of 0:noArg ". "1:noArg 2:noArg 3:noArg 4:noArg ". "5:noArg 6:noArg 7:noArg 8:noArg ". "11:noArg 12:noArg 13:noArg 14:noArg ". "15:noArg 16:noArg 17:noArg 18:noArg ". "21:noArg 22:noArg 23:noArg 24:noArg ". "25:noArg 26:noArg 27:noArg 28:noArg "; return $usage if $port eq "?"; if ($port eq "0") { PI_read_outports($hash); PI_read_inports($hash,0); PI_read_inports($hash,1); } elsif ($port ~~ [1..8]) { # read inport $adr = $base + $port; $cmd = '/usr/local/bin/gpio -p read '.$adr; $val = `$cmd`; readingsSingleUpdate($hash, 'in'.$port, $val, 1); } elsif ($port ~~ [11..18]) { # read inport with pullup $pin = $port - 10; $adr = $base + $pin; $cmd = '/usr/local/bin/gpio -p mode '.$adr.' up'; $val = `$cmd`; $cmd = '/usr/local/bin/gpio -p read '.$adr; $val = `$cmd`; readingsSingleUpdate($hash, 'in'.$port, $val, 1); } elsif ($port ~~ [21..28]) { # read outport $pin = $port - 12; $port -= 20; $adr = $base + $pin; $cmd = '/usr/local/bin/gpio -p read '.$adr; $val = `$cmd`; readingsSingleUpdate($hash, 'out'.$port, $val, 1); } return ""; } sub PI_read_outports($){ my ($hash) = @_; my $val = '?'; my ($cmd, $i, $port); readingsBeginUpdate($hash); for($i=1; $i<9; $i++){ $port = $base + $i + 8; $cmd = '/usr/local/bin/gpio -p read '.$port; $val = `$cmd`; readingsBulkUpdate($hash, 'out'.$i, $val); } readingsEndUpdate($hash, 0); return } sub PI_read_inports($;$){ my ($hash,$pull) = @_; my $val = '?'; my ($cmd, $i, $j, $port); readingsBeginUpdate($hash); for($i=1; $i<9; $i++){ $port = $base + $i; if($pull eq '1'){ $cmd = '/usr/local/bin/gpio -p mode '.$port.' up'; $val = `$cmd`; $cmd = '/usr/local/bin/gpio -p read '.$port; $val = `$cmd`; $j = 10 + $i; readingsBulkUpdate($hash, 'in'.$j, chomp($val)); } else { $cmd = '/usr/local/bin/gpio -p mode '.$port.' tri'; $val = `$cmd`; $cmd = '/usr/local/bin/gpio -p read '.$port; $val = `$cmd`; readingsBulkUpdate($hash, 'in'.$i, chomp($val)); } } readingsEndUpdate($hash, 1); return } 1; =pod =begin html

PIFACE

=end html =cut