58_GPIO4.pm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #############################################################################
  2. #
  3. # $Id$
  4. #
  5. # Copyright notice
  6. #
  7. # (c) 2012 Copyright: Peter J. Flathmann (peter dot flathmann at web dot de)
  8. # All rights reserved
  9. #
  10. # This script free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # The GNU General Public License can be found at
  16. # http://www.gnu.org/copyleft/gpl.html.
  17. # A copy is found in the textfile GPL.txt and important notices to the license
  18. # from the author is found in LICENSE.txt distributed with these scripts.
  19. #
  20. # This script is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. # GNU General Public License for more details.
  24. #
  25. #############################################################################
  26. package main;
  27. use strict;
  28. use warnings;
  29. use POSIX;
  30. use vars qw{%attr %defs};
  31. sub GPIO4_Initialize($) {
  32. my ($hash) = @_;
  33. $hash->{DefFn} = "GPIO4_Define";
  34. $hash->{UndefFn} = "GPIO4_Undef";
  35. $hash->{NotifyFn} = "GPIO4_Notify";
  36. $hash->{GetFn} = "GPIO4_Get";
  37. $hash->{AttrList} = "tempOffset pollingInterval model loglevel:0,1,2,3,4,5,6 ".$readingFnAttributes;
  38. }
  39. sub GPIO4_Notify($$) {
  40. my ($hash, $dev) = @_;
  41. return if($hash->{DEF} ne "BUSMASTER" || $dev->{NAME} ne "global" || !grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}));
  42. # check bus for new devices not before fhem.cfg completely loaded to avoid duplicates
  43. GPIO4_GetSlaves($hash);
  44. delete $modules{GPIO4}{NotifyFn};
  45. return;
  46. }
  47. sub GPIO4_Define($$) {
  48. my ($hash, $def) = @_;
  49. Log 4, "GPIO4: GPIO4_Define($hash->{NAME})";
  50. my @a = split("[ \t][ \t]*", $def);
  51. return "syntax: define <name> GPIO4 <id>|BUSMASTER" if (int(@a) != 3);
  52. $hash->{NAME} = $a[0];
  53. $hash->{TYPE} = 'GPIO4';
  54. if ($a[2] eq "BUSMASTER") {
  55. $hash->{STATE} = "Initialized";
  56. }
  57. else {
  58. my ($family, $id) = split('-',$a[2]);
  59. if ($family eq "28" || $family eq "10") {
  60. # reset failures counter
  61. setReadingsVal($hash,'failures',0,TimeNow());
  62. $hash->{fhem}{interfaces} = "temperature";
  63. GPIO4_DeviceUpdateLoop($hash);
  64. }
  65. else {
  66. return "GPIO4: device family $family not supported";
  67. }
  68. }
  69. return;
  70. }
  71. sub GPIO4_GetSlaves($) {
  72. my ($hash) = @_;
  73. Log 4, "GPIO4: GPIO4_GetSlaves()";
  74. open SLAVES, "/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves";
  75. my @slaves = <SLAVES>;
  76. chomp(@slaves);
  77. close(SLAVES);
  78. $hash->{SLAVES} = join(',',@slaves);
  79. foreach my $slave (@slaves) {
  80. GPIO_GetSlave($hash,$slave);
  81. }
  82. return;
  83. }
  84. sub GPIO_GetSlave($$) {
  85. my ($hash,$slave) = @_;
  86. Log 4, "GPIO4: GPIO4_GetSlave($slave)";
  87. my ($family, $id) = split("-", $slave);
  88. # return if device exists
  89. foreach my $devicename (keys %defs) {
  90. return if (exists $defs{$devicename}{DEF} && $defs{$devicename}{DEF} eq $slave);
  91. }
  92. # device does not exist, let autocreate create it
  93. my $model;
  94. if ($family eq "28") {
  95. $model = "DS18B20";
  96. }
  97. elsif ($family eq "10") {
  98. $model = "DS1820";
  99. }
  100. DoTrigger("global", "UNDEFINED GPIO4_${model}_${id} GPIO4 $slave");
  101. $attr{"GPIO4_${model}_${id}"}{model} = $model;
  102. return;
  103. }
  104. sub GPIO4_DeviceUpdateLoop($) {
  105. my ($hash) = @_;
  106. my $pollingInterval = $attr{$hash->{NAME}}{pollingInterval} || 60;
  107. Log 6, "GPIO4: GPIO4_DeviceUpdateLoop($hash->{NAME}), pollingInterval:$pollingInterval";
  108. GPIO4_Get($hash);
  109. InternalTimer(gettimeofday()+$pollingInterval, "GPIO4_DeviceUpdateLoop", $hash, 0);
  110. return;
  111. }
  112. sub GPIO4_Get($) {
  113. my ($hash) = @_;
  114. Log 6, "GPIO4: GPIO4_Get($hash->{NAME})";
  115. open DATA, "/sys/bus/w1/devices/$hash->{DEF}/w1_slave";
  116. if (<DATA> =~ /YES/) {
  117. <DATA> =~ /t=(-?\d+)/;
  118. my $temp = $1/1000.0;
  119. if ($attr{$hash->{NAME}}{tempOffset}) {
  120. $temp+=$attr{$hash->{NAME}}{tempOffset};
  121. }
  122. readingsBeginUpdate($hash);
  123. readingsBulkUpdate($hash,"state","T: $temp");
  124. readingsBulkUpdate($hash,"temperature",$temp);
  125. readingsEndUpdate($hash,1);
  126. }
  127. else {
  128. readingsSingleUpdate($hash,'failures',ReadingsVal($hash->{NAME},"failures",0)+1,1);
  129. }
  130. close(DATA);
  131. return;
  132. }
  133. sub GPIO4_Undef($) {
  134. my ($hash) = @_;
  135. Log 4, "GPIO4: GPIO4_Undef($hash->{NAME})";
  136. RemoveInternalTimer($hash);
  137. return;
  138. }
  139. 1;
  140. =pod
  141. =begin html
  142. <a name="GPIO4"></a>
  143. <h3>GPIO4</h3>
  144. <ul>
  145. 1-wire temperature sensors connected to Raspberry Pi's GPIO port 4.
  146. <br><br>
  147. <a name="GPIO4define"></a>
  148. <b>Define</b>
  149. <ul>
  150. <code>define &lt;name&gt; GPIO4 ('BUSMASTER'|&lt;id&gt;)</code>
  151. <br><br>
  152. Defines the BUSMASTER or one of the slave devices. The BUSMASTER is necessary
  153. to get the slaves automatically created by autocreate.pm.
  154. <br><br>
  155. Examples:
  156. <ul>
  157. <code>
  158. define RPi GPIO4 BUSMASTER<br>
  159. define mysSensor GPIO4 28-000004715a10<br>
  160. </code>
  161. </ul>
  162. </ul>
  163. <br>
  164. <a name="GPIO4attr"></a>
  165. <b>Attributes</b>
  166. <ul>
  167. <li><a href="#pollingInterval">pollingInterval</a></li>
  168. <li><a href="#tempOffest">tempOffset</a></li>
  169. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  170. </ul>
  171. <br>
  172. </ul>
  173. =end html
  174. =begin html_DE
  175. <a name="GPIO4"></a>
  176. <h3>GPIO4</h3>
  177. <ul>
  178. 1-wire Temperatursensoren an GPIO Port 4 des Raspberry Pi.
  179. <br><br>
  180. <a name="GPIO4define"></a>
  181. <b>Define</b>
  182. <ul>
  183. <code>define &lt;name&gt; GPIO4 ('BUSMASTER'|&lt;id&gt;)</code>
  184. <br><br>
  185. Definiert den BUSMASTER oder die Slave-Devices. Der BUSMASTER ist notwendig,
  186. um die Slave-Devices automatisch via autocreate.pm zu erzeugen.
  187. <br><br>
  188. Examples:
  189. <ul>
  190. <code>
  191. define RPi GPIO4 BUSMASTER<br>
  192. define mysSensor GPIO4 28-000004715a10<br>
  193. </code>
  194. </ul>
  195. </ul>
  196. <br>
  197. <a name="GPIO4attr"></a>
  198. <b>Attributes</b>
  199. <ul>
  200. <li><a href="#pollingInterval">pollingInterval</a></li>
  201. <li><a href="#tempOffest">tempOffset</a></li>
  202. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  203. </ul>
  204. <br>
  205. </ul>
  206. =end html_DE
  207. =cut