20_OWFS.pm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. ################################################################
  2. #
  3. # Copyright notice
  4. #
  5. # (c) 2008 Copyright: Martin Fischer (m_fischer at gmx dot de)
  6. # All rights reserved
  7. #
  8. # This script free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # The GNU General Public License can be found at
  14. # http://www.gnu.org/copyleft/gpl.html.
  15. # A copy is found in the textfile GPL.txt and important notices to the license
  16. # from the author is found in LICENSE.txt distributed with these scripts.
  17. #
  18. # This script is distributed in the hope that it will be useful,
  19. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. # GNU General Public License for more details.
  22. #
  23. ################################################################
  24. # $Id: 20_OWFS.pm 2516 2013-01-14 10:41:48Z mfr69bs $
  25. package main;
  26. use strict;
  27. use warnings;
  28. use Time::HiRes qw(gettimeofday);
  29. use OW;
  30. my %models = (
  31. "DS1420" => "",
  32. "DS9097" => "",
  33. );
  34. my %fc = (
  35. "1:DS9420" => "01",
  36. "2:DS1420" => "81",
  37. "3:DS1820" => "10",
  38. );
  39. my %gets = (
  40. "address" => "",
  41. "alias" => "",
  42. "crc8" => "",
  43. "family" => "",
  44. "id" => "",
  45. "locator" => "",
  46. "present" => "",
  47. # "r_address" => "",
  48. # "r_id" => "",
  49. # "r_locator" => "",
  50. "type" => "",
  51. );
  52. ##############################################
  53. sub
  54. OWFS_Initialize($)
  55. {
  56. my ($hash) = @_;
  57. # Provider
  58. $hash->{WriteFn} = "OWFS_Write";
  59. $hash->{Clients} = ":OWTEMP:";
  60. # Normal devices
  61. $hash->{DefFn} = "OWFS_Define";
  62. $hash->{UndefFn} = "OWFS_Undef";
  63. $hash->{GetFn} = "OWFS_Get";
  64. #$hash->{SetFn} = "OWFS_Set";
  65. $hash->{AttrList} = "IODev do_not_notify:1,0 dummy:1,0 temp-scale:C,F,K,R ".
  66. "showtime:1,0 loglevel:0,1,2,3,4,5,6"; }
  67. #####################################
  68. sub
  69. OWFS_Get($$)
  70. {
  71. my ($hash,@a) = @_;
  72. return "argument is missing @a" if (@a != 2);
  73. return "Passive Adapter defined. No Get function implemented."
  74. if(!defined($hash->{OW_ID}));
  75. return "Unknown argument $a[1], choose one of " . join(",", sort keys %gets)
  76. if(!defined($gets{$a[1]}));
  77. my $ret = OWFS_GetData($hash,$a[1]);
  78. return "$a[0] $a[1] => $ret";
  79. }
  80. #####################################
  81. sub
  82. OWFS_GetData($$)
  83. {
  84. my ($hash,$query) = @_;
  85. my $name = $hash->{NAME};
  86. my $path = $hash->{OW_PATH};
  87. my $ret = undef;
  88. $ret = OW::get("/uncached/$path/$query");
  89. if ($ret) {
  90. # strip spaces
  91. $ret =~ s/^\s+//g;
  92. Log 4, "OWFS $name $query $ret";
  93. $hash->{READINGS}{$query}{VAL} = $ret;
  94. $hash->{READINGS}{$query}{TIME} = TimeNow();
  95. return $ret;
  96. } else {
  97. return undef;
  98. }
  99. }
  100. #####################################
  101. sub
  102. OWFS_DoInit($)
  103. {
  104. my ($hash) = @_;
  105. my $name = $hash->{NAME};
  106. my $path;
  107. my $ret;
  108. if (defined($hash->{OWFS_ID})) {
  109. $path = $hash->{OW_FAMILY}.".".$hash->{OWFS_ID};
  110. foreach my $q (sort keys %gets) {
  111. $ret = OWFS_GetData($hash,$q);
  112. }
  113. }
  114. $hash->{STATE} = "Initialized" if (!$hash->{STATE});
  115. return undef;
  116. }
  117. #####################################
  118. sub
  119. OWFS_Define($$)
  120. {
  121. my ($hash, $def) = @_;
  122. # define <name> OWFS <owserver:port> <model> <id>
  123. # define foo OWFS 127.0.0.1:4304 DS1420 93302D000000
  124. my @a = split("[ \t][ \t]*", $def);
  125. return "wrong syntax: define <name> OWFS <owserver:port> <model> [<id>]"
  126. if (@a < 2 && int(@a) > 5);
  127. my $name = $a[0];
  128. my $dev = $a[2];
  129. # return "wrong device format: use ip:port"
  130. # if ($device !~ m/^(.+):(0-9)+$/);
  131. my $model = $a[3];
  132. return "Define $name: wrong model: specify one of " . join ",", sort keys %models
  133. if (!grep { $_ eq $model } keys %models);
  134. if (@a > 4) {
  135. my $id = $a[4];
  136. return "Define $name: wrong ID format: specify a 12 digit value"
  137. if (uc($id) !~ m/^[0-9|A-F]{12}$/);
  138. $hash->{FamilyCode} = \%fc;
  139. my $fc = $hash->{FamilyCode};
  140. if (defined ($fc)) {
  141. foreach my $c (sort keys %{$fc}) {
  142. if ($c =~ m/$model/) {
  143. $hash->{OW_FAMILY} = $fc->{$c};
  144. }
  145. }
  146. }
  147. delete ($hash->{FamilyCode});
  148. $hash->{OW_ID} = $id;
  149. $hash->{OW_PATH} = $hash->{OW_FAMILY}.".".$hash->{OW_ID};
  150. }
  151. $hash->{STATE} = "Defined";
  152. # default temperature-scale: C
  153. # C: Celsius, F: Fahrenheit, K: Kelvin, R: Rankine
  154. $attr{$name}{"temp-scale"} = "C";
  155. if ($dev eq "none") {
  156. $attr{$name}{dummy} = 1;
  157. Log 1, "OWFS device is none, commands will be echoed only";
  158. return undef;
  159. }
  160. Log 3, "OWFS opening OWFS device $dev";
  161. my $po;
  162. $po = OW::init($dev);
  163. return "Can't connect to $dev: $!" if(!$po);
  164. Log 3, "OWFS opened $dev for $name";
  165. Log 1, "OWFS ########################################";
  166. Log 1, "OWFS # IMPORTANT NOTE:";
  167. Log 1, "OWFS # This module is deprecated and will be removed in a future release!";
  168. Log 1, "OWFS # Please use OWServer / OWDevice.";
  169. Log 1, "OWFS ########################################";
  170. $hash->{DeviceName} = $dev;
  171. $hash->{STATE}="";
  172. my $ret = OWFS_DoInit($hash);
  173. return undef;
  174. }
  175. #####################################
  176. sub
  177. OWFS_Undef($$)
  178. {
  179. my ($hash, $arg) = @_;
  180. my $name = $hash->{NAME};
  181. foreach my $d (sort keys %defs) {
  182. if (defined($defs{$d}) && defined($defs{$d}{IODev}) && $defs{$d}{IODev} == $hash) {
  183. my $lev = ($reread_active ? 4 : 2);
  184. Log GetLogLevel($name,$lev), "deleting port for $d";
  185. delete $defs{$d}{IODev};
  186. }
  187. }
  188. return undef;
  189. }
  190. 1;
  191. =pod
  192. =begin html
  193. <a name="OWFS"></a>
  194. <h3>OWFS</h3>
  195. <ul>
  196. OWFS is a suite of programs that designed to make the 1-wire bus and its
  197. devices easily accessible. The underlying priciple is to create a virtual
  198. filesystem, with the unique ID being the directory, and the individual
  199. properties of the device are represented as simple files that can be read
  200. and written.<br><br>
  201. Note: You need the owperl module from
  202. <a href="http://owfs.org/index.php?page=owperl">http://owfs.org/</a>.
  203. <br><br>
  204. <a name="OWFSdefine"></a>
  205. <b>Define</b>
  206. <ul>
  207. <code>define &lt;name&gt; OWFS &lt;owserver-ip:port&gt; &lt;model&gt; [&lt;id&gt;]</code>
  208. <br><br>
  209. Define a 1-wire device to communicate with an OWFS-Server.<br><br>
  210. <code>&lt;owserver-ip:port&gt;</code>
  211. <ul>
  212. IP-address:port from OW-Server.
  213. </ul>
  214. <code>&lt;model&gt;</code>
  215. <ul>
  216. Define the <a href="#owfs_type">type</a> of the input device.
  217. Currently supportet: <code>DS1420, DS9097 (for passive Adapter)</code>
  218. </ul>
  219. <code>&lt;id&gt;</code>
  220. <ul>
  221. Corresponding to the <a href="#owfs_id">id</a> of the input device. Only for active Adapter.
  222. <br><br>
  223. </ul>
  224. Note:<br>
  225. If the <code>owserver-ip:port</code> is called <code>none</code>, then
  226. no device will be opened, so you can experiment without hardware attached.<br><br>
  227. Example:
  228. <ul>
  229. <code>#define an active Adapter:<br>
  230. define DS9490R OWFS 127.0.0.1:4304 DS1420 93302D000000</code><br>
  231. </ul>
  232. <br>
  233. <ul>
  234. <code>#define a passive Adapter:<br>
  235. define DS9097 OWFS 127.0.0.1:4304 DS9097</code><br>
  236. </ul>
  237. <br>
  238. </ul>
  239. <b>Set</b> <ul>N/A</ul><br>
  240. <a name="OWFSget"></a>
  241. <b>Get</b>
  242. <ul>
  243. <code>get &lt;name&gt; &lt;value&gt;</code>
  244. <br><br>
  245. where <code>value</code> is one of (not supported by passive Devices e.g. DS9097):<br>
  246. <ul>
  247. <li><a name="owfs_address"></a>
  248. <code>address</code> (read-only)<br>
  249. The entire 64-bit unique ID. address starts with the family code.<br>
  250. Given as upper case hexidecimal digits (0-9A-F).
  251. </li>
  252. <li><a name="owfs_crc8"></a>
  253. <code>crc8</code> (read-only)<br>
  254. The 8-bit error correction portion. Uses cyclic redundancy check. Computed
  255. from the preceeding 56 bits of the unique ID number.<br>
  256. Given as upper case hexidecimal digits (0-9A-F).
  257. </li>
  258. <li><a name="owfs_family"></a>
  259. <code>family</code> (read-only)<br>
  260. The 8-bit family code. Unique to each type of device.<br>
  261. Given as upper case hexidecimal digits (0-9A-F).
  262. </li>
  263. <li><a name="owfs_id"></a>
  264. <code>id</code> (read-only)<br>
  265. The 48-bit middle portion of the unique ID number. Does not include the
  266. family code or CRC.<br>
  267. Given as upper case hexidecimal digits (0-9A-F).
  268. </li>
  269. <li><a name="owfs_locator"></a>
  270. <code>locator</code> (read-only)<br>
  271. Uses an extension of the 1-wire design from iButtonLink company that
  272. associated 1-wire physical connections with a unique 1-wire code. If
  273. the connection is behind a Link Locator the locator will show a unique
  274. 8-byte number (16 character hexidecimal) starting with family code FE.<br>
  275. If no Link Locator is between the device and the master, the locator
  276. field will be all FF.
  277. </li>
  278. <li><a name="owfs_present"></a>
  279. <code>present</code> (read-only)<br>
  280. Is the device currently present on the 1-wire bus?
  281. </li>
  282. <li><a name="owfs_type"></a>
  283. <code>type</code> (read-only)<br>
  284. Part name assigned by Dallas Semi. E.g. DS2401 Alternative packaging
  285. (iButton vs chip) will not be distiguished.
  286. </li>
  287. <br>
  288. </ul>
  289. Examples:
  290. <ul>
  291. <code>get DS9490R type</code><br>
  292. <code>DS9490R type => DS1420</code><br><br>
  293. <code>get DS9490R address</code><br>
  294. <code>DS9490R address => 8193302D0000002B</code>
  295. </ul>
  296. <br>
  297. </ul>
  298. <a name="OWFSattr"></a>
  299. <b>Attributes</b>
  300. <ul>
  301. <li><a href="#attrdummy">dummy</a></li>
  302. <li><a href="#do_not_notify">do_not_notify</a></li>
  303. <li><a href="#loglevel">loglevel</a></li>
  304. <li><a href="#showtime">showtime</a></li>
  305. <li><a name="owfs_temp-scale"></a>
  306. temp-scale<br>
  307. Specifies the temperature-scale unit:
  308. <ul>
  309. <li><code>C</code><br>
  310. Celsius. This is the default.</li>
  311. <li><code>F</code><br>
  312. Fahrenheit</li>
  313. <li><code>K</code><br>
  314. Kelvin</li>
  315. <li><code>R</code><br>
  316. Rankine</li>
  317. </ul>
  318. </li>
  319. </ul>
  320. <br>
  321. </ul>
  322. =end html
  323. =cut