20_FRM_OUT.pm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. ##############################################
  2. # $Id: 20_FRM_OUT.pm 5927 2014-05-21 21:56:37Z ntruchsess $
  3. ##############################################
  4. package main;
  5. use strict;
  6. use warnings;
  7. #add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though...
  8. BEGIN {
  9. if (!grep(/FHEM\/lib$/,@INC)) {
  10. foreach my $inc (grep(/FHEM$/,@INC)) {
  11. push @INC,$inc."/lib";
  12. };
  13. };
  14. };
  15. use Device::Firmata::Constants qw/ :all /;
  16. use SetExtensions;
  17. #####################################
  18. sub
  19. FRM_OUT_Initialize($)
  20. {
  21. my ($hash) = @_;
  22. $hash->{SetFn} = "FRM_OUT_Set";
  23. $hash->{DefFn} = "FRM_Client_Define";
  24. $hash->{InitFn} = "FRM_OUT_Init";
  25. $hash->{UndefFn} = "FRM_Client_Undef";
  26. $hash->{AttrFn} = "FRM_OUT_Attr";
  27. $hash->{StateFn} = "FRM_OUT_State";
  28. $hash->{AttrList} = "restoreOnReconnect:on,off restoreOnStartup:on,off activeLow:yes,no IODev $main::readingFnAttributes";
  29. main::LoadModule("FRM");
  30. }
  31. sub
  32. FRM_OUT_Init($$)
  33. {
  34. my ($hash,$args) = @_;
  35. my $ret = FRM_Init_Pin_Client($hash,$args,PIN_OUTPUT);
  36. return $ret if (defined $ret);
  37. my $name = $hash->{NAME};
  38. if (! (defined AttrVal($name,"stateFormat",undef))) {
  39. $main::attr{$name}{"stateFormat"} = "value";
  40. }
  41. my $value = ReadingsVal($name,"value",undef);
  42. if (defined $value and AttrVal($hash->{NAME},"restoreOnReconnect","on") eq "on") {
  43. FRM_OUT_Set($hash,$name,$value);
  44. }
  45. main::readingsSingleUpdate($hash,"state","Initialized",1);
  46. return undef;
  47. }
  48. sub
  49. FRM_OUT_Set($$$)
  50. {
  51. my ($hash, $name, $cmd, @a) = @_;
  52. my $value;
  53. my $invert = AttrVal($hash->{NAME},"activeLow","no");
  54. if ($cmd eq "on") {
  55. $value = $invert eq "yes" ? PIN_LOW : PIN_HIGH;
  56. } elsif ($cmd eq "off") {
  57. $value = $invert eq "yes" ? PIN_HIGH : PIN_LOW;
  58. } else {
  59. my $list = "on off";
  60. return SetExtensions($hash, $list, $name, $cmd, @a);
  61. }
  62. eval {
  63. FRM_Client_FirmataDevice($hash)->digital_write($hash->{PIN},$value);
  64. main::readingsSingleUpdate($hash,"value",$cmd, 1);
  65. };
  66. return $@;
  67. }
  68. sub FRM_OUT_State($$$$)
  69. {
  70. my ($hash, $tim, $sname, $sval) = @_;
  71. STATEHANDLER: {
  72. $sname eq "value" and do {
  73. if (AttrVal($hash->{NAME},"restoreOnStartup","on") eq "on") {
  74. FRM_OUT_Set($hash,$hash->{NAME},$sval);
  75. }
  76. last;
  77. }
  78. }
  79. }
  80. sub
  81. FRM_OUT_Attr($$$$) {
  82. my ($command,$name,$attribute,$value) = @_;
  83. my $hash = $main::defs{$name};
  84. eval {
  85. if ($command eq "set") {
  86. ARGUMENT_HANDLER: {
  87. $attribute eq "IODev" and do {
  88. if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value)) {
  89. FRM_Client_AssignIOPort($hash,$value);
  90. FRM_Init_Client($hash) if (defined ($hash->{IODev}));
  91. }
  92. last;
  93. };
  94. }
  95. }
  96. };
  97. if ($@) {
  98. $@ =~ /^(.*)( at.*FHEM.*)$/;
  99. $hash->{STATE} = "error setting $attribute to $value: ".$1;
  100. return "cannot $command attribute $attribute to $value for $name: ".$1;
  101. }
  102. }
  103. 1;
  104. =pod
  105. =begin html
  106. <a name="FRM_OUT"></a>
  107. <h3>FRM_OUT</h3>
  108. <ul>
  109. represents a pin of an <a href="http://www.arduino.cc">Arduino</a> running <a href="http://www.firmata.org">Firmata</a>
  110. configured for digital output.<br>
  111. Requires a defined <a href="#FRM">FRM</a>-device to work.<br><br>
  112. <a name="FRM_OUTdefine"></a>
  113. <b>Define</b>
  114. <ul>
  115. <code>define &lt;name&gt; FRM_OUT &lt;pin&gt;</code> <br>
  116. Defines the FRM_OUT device. &lt;pin&gt> is the arduino-pin to use.
  117. </ul>
  118. <br>
  119. <a name="FRM_OUTset"></a>
  120. <b>Set</b><br>
  121. <ul>
  122. <code>set &lt;name&gt; on|off</code><br><br>
  123. </ul>
  124. <ul>
  125. <a href="#setExtensions">set extensions</a> are supported<br>
  126. </ul>
  127. <a name="FRM_OUTget"></a>
  128. <b>Get</b><br>
  129. <ul>
  130. N/A
  131. </ul><br>
  132. <a name="FRM_OUTattr"></a>
  133. <b>Attributes</b><br>
  134. <ul>
  135. <li>restoreOnStartup &lt;on|off&gt;</li>
  136. <li>restoreOnReconnect &lt;on|off&gt;</li>
  137. <li>activeLow &lt;yes|no&gt;</li>
  138. <li><a href="#IODev">IODev</a><br>
  139. Specify which <a href="#FRM">FRM</a> to use. (Optional, only required if there is more
  140. than one FRM-device defined.)
  141. </li>
  142. <li><a href="#eventMap">eventMap</a><br></li>
  143. <li><a href="#readingFnAttributes">readingFnAttributes</a><br></li>
  144. </ul>
  145. </ul>
  146. <br>
  147. =end html
  148. =cut