From 98ea153a79283c4ccc59ad3c841196b8f7eea58b Mon Sep 17 00:00:00 2001 From: jensb <> Date: Sat, 27 Jan 2018 20:11:34 +0000 Subject: [PATCH] 20_FRM_IN.pm: added Firmata 2.5 feature PIN_MODE_PULLUP (requires perl-firmata 0.64) (Forum #81815) git-svn-id: https://svn.fhem.de/fhem/trunk@16012 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/20_FRM_IN.pm | 145 ++++++++++++++++++++++++++++++++--------- fhem/MAINTAINER.txt | 2 +- 3 files changed, 118 insertions(+), 31 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 054be8154..359602d80 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 20_FRM_IN: added Firmata 2.5 feature PIN_MODE_PULLUP + note: requires perl-firmata 0.64 - change: 74_Unifi: SSIDs-Readings and drop-downs use goodReadingName() - feature: new module 37_NotifyAndroidTV.pm to send notifications to Notifications for Android TV/Fire TV apps (justme1968) diff --git a/fhem/FHEM/20_FRM_IN.pm b/fhem/FHEM/20_FRM_IN.pm index aec5a5b34..2a480ec4a 100755 --- a/fhem/FHEM/20_FRM_IN.pm +++ b/fhem/FHEM/20_FRM_IN.pm @@ -1,12 +1,43 @@ -############################################## +######################################################################################## +# # $Id$ -############################################## +# +# FHEM module for one Firmata digial input pin +# +######################################################################################## +# +# LICENSE AND COPYRIGHT +# +# Copyright (C) 2013 ntruchess +# Copyright (C) 2018 jensb +# +# All rights reserved +# +# This script 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. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script 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. +# +# This copyright notice MUST APPEAR in all copies of the script! +# +######################################################################################## + package main; use strict; use warnings; -#add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though... +#add FHEM/lib to @INC if it's not already included. Should rather be in fhem.pl than here though... BEGIN { if (!grep(/FHEM\/lib$/,@INC)) { foreach my $inc (grep(/FHEM$/,@INC)) { @@ -42,26 +73,48 @@ FRM_IN_Initialize($) $hash->{DefFn} = "FRM_Client_Define"; $hash->{InitFn} = "FRM_IN_Init"; $hash->{UndefFn} = "FRM_Client_Undef"; - + $hash->{AttrList} = "IODev count-mode:none,rising,falling,both count-threshold reset-on-threshold-reached:yes,no internal-pullup:on,off activeLow:yes,no $main::readingFnAttributes"; main::LoadModule("FRM"); } +sub +FRM_IN_PinModePullupSupported($) +{ + my ($hash) = @_; + my $iodev = $hash->{IODev}; + my $pullupPins = defined($iodev)? $iodev->{pullup_pins} : undef; + + return defined($pullupPins); +} + sub FRM_IN_Init($$) { my ($hash,$args) = @_; - my $ret = FRM_Init_Pin_Client($hash,$args,PIN_INPUT); - return $ret if (defined $ret); - eval { - my $firmata = FRM_Client_FirmataDevice($hash); - my $pin = $hash->{PIN}; - if (defined (my $pullup = AttrVal($hash->{NAME},"internal-pullup",undef))) { - $firmata->digital_write($pin,$pullup eq "on" ? 1 : 0); - } - $firmata->observe_digital($pin,\&FRM_IN_observer,$hash); - }; - return FRM_Catch($@) if $@; + if (FRM_IN_PinModePullupSupported($hash)) { + my $pullup = AttrVal($hash->{NAME},"internal-pullup","off"); + my $ret = FRM_Init_Pin_Client($hash,$args,defined($pullup) && ($pullup eq "on")? PIN_PULLUP : PIN_INPUT); + return $ret if (defined $ret); + eval { + my $firmata = FRM_Client_FirmataDevice($hash); + my $pin = $hash->{PIN}; + $firmata->observe_digital($pin,\&FRM_IN_observer,$hash); + }; + return FRM_Catch($@) if $@; + } else { + my $ret = FRM_Init_Pin_Client($hash,$args,PIN_INPUT); + return $ret if (defined $ret); + eval { + my $firmata = FRM_Client_FirmataDevice($hash); + my $pin = $hash->{PIN}; + if (defined (my $pullup = AttrVal($hash->{NAME},"internal-pullup",undef))) { + $firmata->digital_write($pin,$pullup eq "on" ? 1 : 0); + } + $firmata->observe_digital($pin,\&FRM_IN_observer,$hash); + }; + return FRM_Catch($@) if $@; + } if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) { $main::attr{$hash->{NAME}}{"stateFormat"} = "reading"; } @@ -99,7 +152,7 @@ FRM_IN_observer } } main::readingsBulkUpdate($hash,"count",$count,1); - } + } }; } main::readingsBulkUpdate($hash,"reading",$new == PIN_HIGH ? "on" : "off", $changed); @@ -171,7 +224,7 @@ FRM_IN_Attr($$$$) { 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))) { @@ -197,8 +250,12 @@ FRM_IN_Attr($$$$) { $attribute eq "internal-pullup" and do { if ($main::init_done) { 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. + if (FRM_IN_PinModePullupSupported($hash)) { + $firmata->pin_mode($pin,$value eq "on"? PIN_PULLUP : PIN_INPUT); + } else { + $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; }; @@ -218,7 +275,11 @@ FRM_IN_Attr($$$$) { ARGUMENT_HANDLER: { $attribute eq "internal-pullup" and do { my $firmata = FRM_Client_FirmataDevice($hash); - $firmata->digital_write($pin,0); + if (FRM_IN_PinModePullupSupported($hash)) { + $firmata->pin_mode($pin,PIN_INPUT); + } else { + $firmata->digital_write($pin,0); + } last; }; $attribute eq "activeLow" and do { @@ -241,23 +302,37 @@ FRM_IN_Attr($$$$) { 1; =pod + + CHANGES + + 03.01.2018 jensb + o implemented Firmata 2.5 feature PIN_MODE_PULLUP (requires perl-firmata 0.64 or higher) + +=cut + +=pod +=item device +=item summary Firmata: digital input +=item summary_DE Firmata: digitaler Eingang =begin html
define <name> FRM_IN <pin>