70_USBWX.pm 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. #################################################################################
  2. # 70_USBWX.pm
  3. # Module for FHEM to receive sensors via ELV USB-WDE1
  4. #
  5. # derived from previous 70_USBWX.pm version written by "Peter from Vienna"
  6. #
  7. # Willi Herzig, 2011-2013
  8. #
  9. # This script is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################
  14. # $Id: 70_USBWX.pm 3011 2013-04-01 11:35:04Z wherzig $
  15. package main;
  16. use strict;
  17. use warnings;
  18. use Device::SerialPort;
  19. #####################################
  20. sub
  21. USBWX_Initialize($)
  22. {
  23. my ($hash) = @_;
  24. $hash->{ReadFn} = "USBWX_Read";
  25. $hash->{ReadyFn} = "USBWX_Ready";
  26. # Normal devices
  27. $hash->{DefFn} = "USBWX_Define";
  28. $hash->{UndefFn} = "USBWX_Undef";
  29. $hash->{GetFn} = "USBWX_Get";
  30. $hash->{ParseFn} = "USBWX_Parse";
  31. $hash->{StateFn} = "USBWX_SetState";
  32. $hash->{Match} = ".*";
  33. #$hash->{AttrList}= "model:USB-WDE1 loglevel:0,1,2,3,4,5,6";
  34. $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6";
  35. $hash->{ShutdownFn} = "USBWX_Shutdown";
  36. }
  37. #####################################
  38. sub
  39. USBWX_Define($$)
  40. {
  41. my ($hash, $def) = @_;
  42. my @a = split("[ \t][ \t]*", $def);
  43. return "wrong syntax: 'define <name> USBWX <devicename>' or define <name> USBWX <code> [<corr1>...<corr4>]"
  44. if(@a < 3);
  45. if ($a[2] =~/^[0-9].*/) {
  46. # define <name> USBWX <code> [<corr1>...<corr4>]
  47. return "wrong syntax: define <name> USBWX <code> [corr1...corr4]"
  48. if(int(@a) < 3 || int(@a) > 7);
  49. return "Define $a[0]: wrong CODE format: valid is 1-8"
  50. if($a[2] !~ m/^[1-9]$/);
  51. #Log 1,"USBWX_Define def=$def";
  52. my $name = $a[0];
  53. my $code = $a[2];
  54. $hash->{CODE} = $code;
  55. $hash->{corr1} = ((int(@a) > 3) ? $a[3] : 0);
  56. $hash->{corr2} = ((int(@a) > 4) ? $a[4] : 0);
  57. $hash->{corr3} = ((int(@a) > 5) ? $a[5] : 0);
  58. $hash->{corr4} = ((int(@a) > 6) ? $a[6] : 0);
  59. $modules{USBWX}{defptr}{$code} = $hash;
  60. #AssignIoPort($hash);
  61. } else {
  62. # define <name> USBWX <devicename>
  63. return "wrong syntax: define <name> USBWX <devicename>"
  64. if(@a != 3);
  65. USBWX_CloseDev($hash);
  66. my $name = $a[0];
  67. my $dev = $a[2];
  68. if($dev eq "none") {
  69. Log 1, "USBWX $name device is none, commands will be echoed only";
  70. $attr{$name}{dummy} = 1;
  71. return undef;
  72. }
  73. $hash->{DeviceName} = $dev;
  74. my $ret = USBWX_OpenDev($hash, 0);
  75. return $ret;
  76. }
  77. return undef;
  78. }
  79. #####################################
  80. sub
  81. USBWX_OpenDev($$)
  82. {
  83. my ($hash, $reopen) = @_;
  84. my $dev = $hash->{DeviceName};
  85. my $name = $hash->{NAME};
  86. my $po;
  87. #Log 1, "USBWX opening $name device $dev reopen = $reopen";
  88. $hash->{PARTIAL} = "";
  89. Log 3, "USBWX opening $name device $dev"
  90. if(!$reopen);
  91. if ($^O=~/Win/) {
  92. require Win32::SerialPort;
  93. $po = new Win32::SerialPort ($dev);
  94. } else {
  95. require Device::SerialPort;
  96. $po = new Device::SerialPort ($dev);
  97. }
  98. if(!$po) {
  99. return undef if($reopen);
  100. Log(2, "USBWX Can't open $dev: $!");
  101. $readyfnlist{"$name.$dev"} = $hash;
  102. $hash->{STATE} = "disconnected";
  103. return "";
  104. }
  105. $hash->{USBWX} = $po;
  106. if( $^O =~ /Win/ ) {
  107. $readyfnlist{"$name.$dev"} = $hash;
  108. } else {
  109. $hash->{FD} = $po->FILENO;
  110. delete($readyfnlist{"$name.$dev"});
  111. $selectlist{"$name.$dev"} = $hash;
  112. }
  113. $po->baudrate(9600) || Log 1, "USBWX could not set baudrate";
  114. $po->databits(8) || Log 1, "USBWX could not set databits";
  115. $po->parity('none') || Log 1, "USBWX could not set parity";
  116. $po->stopbits(1) || Log 1, "USBWX could not set stopbits";
  117. $po->handshake('none') || Log 1, "USBWX could not set handshake";
  118. #$po->reset_error() || Log 1, "USBWX reset_error";
  119. $po->lookclear || Log 1, "USBWX could not set lookclear";
  120. $po->write_settings || Log 1, "USBWX could not write_settings $dev";
  121. if($reopen) {
  122. Log 1, "USBWX $dev reappeared ($name)";
  123. } else {
  124. Log 2, "USBWX opened device $dev";
  125. }
  126. $hash->{po} = $po;
  127. $hash->{socket} = 0;
  128. $hash->{STATE}=""; # Allow InitDev to set the state
  129. my $ret = USBWX_DoInit($hash);
  130. if($ret) {
  131. # try again
  132. Log 1, "USBWX Cannot init $dev, at first try. Trying again.";
  133. my $ret = USBWX_DoInit($hash);
  134. if($ret) {
  135. USBWX_CloseDev($hash);
  136. Log 1, "USBWX Cannot init $dev, ignoring it";
  137. return "USBWX Error Init string.";
  138. }
  139. }
  140. DoTrigger($name, "CONNECTED") if($reopen);
  141. #return undef;
  142. return $ret;
  143. }
  144. ########################
  145. sub
  146. USBWX_CloseDev($)
  147. {
  148. my ($hash) = @_;
  149. my $name = $hash->{NAME};
  150. my $dev = $hash->{DeviceName};
  151. return if(!$dev);
  152. Log 1, "USBWX: closing $dev";
  153. $hash->{USBWX}->close() ;
  154. delete($hash->{USBWX});
  155. delete($selectlist{"$name.$dev"});
  156. delete($readyfnlist{"$name.$dev"});
  157. delete($hash->{FD});
  158. }
  159. #####################################
  160. sub
  161. USBWX_Ready($)
  162. {
  163. my ($hash) = @_;
  164. return USBWX_OpenDev($hash, 1)
  165. if($hash->{STATE} eq "disconnected");
  166. # This is relevant for windows/USB only
  167. my $po = $hash->{USBWX};
  168. my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
  169. return ($InBytes>0);
  170. }
  171. #####################################
  172. sub
  173. USBWX_SetState($$$$)
  174. {
  175. my ($hash, $tim, $vt, $val) = @_;
  176. return undef;
  177. }
  178. #####################################
  179. sub
  180. USBWX_Clear($)
  181. {
  182. my $hash = shift;
  183. my $buf;
  184. # clear buffer:
  185. if($hash->{USBWX})
  186. {
  187. while ($hash->{USBWX}->lookfor())
  188. {
  189. $buf = USBWX_SimpleRead($hash);
  190. }
  191. }
  192. return $buf;
  193. }
  194. #####################################
  195. sub
  196. USBWX_DoInit($)
  197. {
  198. my $hash = shift;
  199. my $name = $hash->{NAME};
  200. my $init ="?";
  201. my $buf;
  202. USBWX_Clear($hash);
  203. USBWX_SimpleWrite($hash, $init);
  204. return undef;
  205. }
  206. #####################################
  207. sub USBWX_Undef($$)
  208. {
  209. my ($hash, $arg) = @_;
  210. my $name = $hash->{NAME};
  211. delete $hash->{FD};
  212. $hash->{STATE}='close';
  213. $hash->{USBWX}->close() if($hash->{USBWX});
  214. Log 2, "$name shutdown complete";
  215. return undef;
  216. }
  217. #####################################
  218. # called from the global loop, when the select for hash->{FD} reports data
  219. sub
  220. USBWX_Read($)
  221. {
  222. my ($hash) = @_;
  223. my $name = $hash->{NAME};
  224. my $char;
  225. #Log 4, "USBWX Read State:$hash->{STATE}";
  226. my $mybuf = USBWX_SimpleRead($hash);
  227. my $usbwx_data = $hash->{PARTIAL};
  228. #Log 1, "USBWX usbwxdata='$usbwx_data' $mybuf='$mybuf'";
  229. if(!defined($mybuf) || length($mybuf) == 0) {
  230. USBWX_Disconnected($hash);
  231. return "";
  232. }
  233. if ( ( length($usbwx_data) > 1) && ($mybuf eq "\n") ) {
  234. Log 4, "USBWX/RAW line: '$usbwx_data'";
  235. #Log 1, "USBWX/RAW line='$usbwx_data'";
  236. }
  237. if ($mybuf eq "\n") {
  238. USBWX_Parse($hash, $usbwx_data);
  239. $hash->{PARTIAL} = "";
  240. } else {
  241. $usbwx_data .= $mybuf;
  242. $hash->{PARTIAL} = $usbwx_data;
  243. }
  244. }
  245. #####################################
  246. sub
  247. USBWX_Shutdown($)
  248. {
  249. my ($hash) = @_;
  250. return undef;
  251. }
  252. #####################################
  253. sub
  254. USBWX_Get($@)
  255. {
  256. my ($hash, @a) = @_;
  257. my $msg;
  258. my $name=$a[0];
  259. my $reading= $a[1];
  260. $msg="$name => No Get function ($reading) implemented";
  261. Log 1,$msg;
  262. return $msg;
  263. }
  264. ########################
  265. sub
  266. USBWX_SimpleRead($)
  267. {
  268. my ($hash) = @_;
  269. my $buf;
  270. if($hash->{USBWX})
  271. {
  272. $buf = $hash->{USBWX}->read(1) ;
  273. if (!defined($buf) || length($buf) == 0)
  274. {
  275. $buf = $hash->{USBWX}->read(1) ;
  276. }
  277. # Log 4, "USBWX SimpleRead=>$buf";
  278. return $buf;
  279. }
  280. return undef;
  281. }
  282. ########################
  283. sub
  284. USBWX_SimpleWrite(@)
  285. {
  286. my ($hash, $msg) = @_;
  287. return if(!$hash);
  288. $hash->{USBWX}->write($msg) if($hash->{USBWX});
  289. Log 4, "USBWX SimpleWrite $msg";
  290. select(undef, undef, undef, 0.001);
  291. }
  292. # -----------------------------
  293. # Dewpoint calculation.
  294. # see http://www.faqs.org/faqs/meteorology/temp-dewpoint/ "5. EXAMPLE"
  295. sub
  296. dewpoint($$)
  297. {
  298. my ($temperature, $humidity) = @_;
  299. my $dp;
  300. my $A = 17.2694;
  301. my $B = ($temperature > 0) ? 237.3 : 265.5;
  302. my $es = 610.78 * exp( $A * $temperature / ($temperature + $B) );
  303. my $e = $humidity/ 100 * $es;
  304. if ($e == 0) {
  305. Log 1, "Error: dewpoint() e==0: temp=$temperature, hum=$humidity";
  306. return 0;
  307. }
  308. my $e1 = $e / 610.78;
  309. my $f = log( $e1 ) / $A;
  310. my $f1 = 1 - $f;
  311. if ($f1 == 0) {
  312. Log 1, "Error: dewpoint() (1-f)==0: temp=$temperature, hum=$humidity";
  313. return 0;
  314. }
  315. $dp = $B * $f / $f1 ;
  316. return($dp);
  317. }
  318. #####################################
  319. sub
  320. USBWX_Parse($$)
  321. {
  322. my ($hash,$rmsg) = @_;
  323. $rmsg =~ s/[\r\n]//g;
  324. #Log 4, "USBWX Parse Msg:$rmsg, State:$hash->{STATE}";
  325. # Testmessages
  326. #$rmsg = "\$1;1;;;;;;;23,5;21,0;24,2;;;;;;36;42;;16,8;39;6,1;5;0;0";
  327. if ($rmsg =~ /^\$1;.*/) {
  328. #$1;1;;23,9;;23,6;24,3;;;26,0;;56;;59;58;;;54;;;;;;;0
  329. #$1;1;;;;;;;;;;;;;;;;;;;;;;;0
  330. Log 4, "USBWX Parse Msg:'$rmsg', State:$hash->{STATE}";
  331. # Reset to clear data already read. Otherwise data will be read multiple times.
  332. USBWX_SimpleWrite($hash, "RESET");
  333. my @c = split(";", $rmsg);
  334. #Log 4, "USBWX T1:$c[3] T2:$c[4] T3:$c[5] T4:$c[6] T5:$c[7] T6:$c[8] T7:$c[9] T8:$c[10]";
  335. $rmsg =~ s/,/./g; # format for FHEM
  336. my @data = split(";", $rmsg);
  337. my @names = ("1", "2", "3", "4", "5", "6", "7", "8");
  338. my $tm = TimeNow();
  339. # perform sensors with ID 1 up to 8
  340. for(my $i = 0; $i < int(@names); $i++) {
  341. my $sensor = "";
  342. my $val = "";
  343. my $current;
  344. if ($data[$i+3] ne "") { # only for existing sensors
  345. my $n = 0;
  346. my $device_name = $names[$i];
  347. my $code = $i+1;
  348. #Log 1, "i=$i, device_name=$device_name code=$code";
  349. my $def = $modules{USBWX}{defptr}{"$device_name"};
  350. if(!$def) {
  351. Log 3, "USBWX: Unknown device USBWX_$device_name, please define it";
  352. #Log 1, "USBWX: Unknown device USBWX_$device_name, please define it";
  353. my $ret = "UNDEFINED USBWX_$device_name USBWX $device_name";
  354. DoTrigger("global", $ret);
  355. return undef;
  356. }
  357. my $name = $def->{NAME};
  358. my $temperature = $data[$i+3] + $def->{corr1};;
  359. $current = $temperature;
  360. $val .= "T: ".$current." ";
  361. $sensor = "temperature";
  362. $def->{READINGS}{$sensor}{TIME} = $tm;
  363. $def->{READINGS}{$sensor}{VAL} = $current;
  364. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  365. if ($data[$i+11] ne "") {
  366. my $humidity = $data[$i+11] + $def->{corr2};;
  367. $current = $humidity;
  368. $val .= "H: ".$current." ";
  369. $sensor = "humidity";
  370. $def->{READINGS}{$sensor}{TIME} = $tm;
  371. $def->{READINGS}{$sensor}{VAL} = $current;
  372. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  373. my $dewpoint = sprintf("%.1f", dewpoint($temperature,$humidity));
  374. $current = $dewpoint;
  375. $sensor = "dewpoint";
  376. $def->{READINGS}{$sensor}{TIME} = $tm;
  377. $def->{READINGS}{$sensor}{VAL} = $current;
  378. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  379. }
  380. #Log 1, "i=$i, device_name=$device_name temp=$temperature, hum=$humidity";
  381. if ("$val" ne "") {
  382. $def->{STATE} = $val;
  383. $def->{TIME} = $tm;
  384. $def->{CHANGED}[$n++] = $val;
  385. }
  386. DoTrigger($name, undef);
  387. }
  388. }
  389. # Look for KS300 data:
  390. if ($data[19] ne "") {
  391. my $n = 0;
  392. my $sensor = "";
  393. my $val = "";
  394. my $current;
  395. my $ks300_temperature = $data[19]; # KS300 temperature
  396. my $ks300_humidity = $data[20]; # KS300 humidity
  397. my $ks300_windspeed = $data[21]; # KS300 windspeed km/h
  398. my $ks300_rain = $data[22]; # KS300 rain (units)
  399. my $ks300_israining = $data[23]; # KS300 rain indicator 1=yes, 0=no
  400. Log 4, "USBWX Parse KS300 data found $ks300_temperature, $ks300_humidity, $ks300_windspeed, $ks300_rain, $ks300_israining ";
  401. my $device_name = "9";
  402. my $def = $modules{USBWX}{defptr}{"$device_name"};
  403. if(!$def) {
  404. Log 3, "USBWX: Unknown device USBWX_ks300, please define it";
  405. #Log 1, "USBWX: Unknown device USBWX_ks300, please define it";
  406. my $ret = "UNDEFINED USBWX_ks300 USBWX $device_name";
  407. DoTrigger("global", $ret);
  408. return undef;
  409. }
  410. my $name = $def->{NAME};
  411. $current = $ks300_temperature;
  412. $val .= "T: ".$current." ";
  413. $sensor = "temperature";
  414. $def->{READINGS}{$sensor}{TIME} = $tm;
  415. $def->{READINGS}{$sensor}{VAL} = $current;
  416. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  417. $current = $ks300_humidity;
  418. $val .= "H: ".$current." ";
  419. $sensor = "humidity";
  420. $def->{READINGS}{$sensor}{TIME} = $tm;
  421. $def->{READINGS}{$sensor}{VAL} = $current;
  422. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  423. my $dewpoint = sprintf("%.1f", dewpoint($ks300_temperature,$ks300_humidity));
  424. $current = $dewpoint;
  425. $sensor = "dewpoint";
  426. $def->{READINGS}{$sensor}{TIME} = $tm;
  427. $def->{READINGS}{$sensor}{VAL} = $current;
  428. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  429. $current = $ks300_windspeed;
  430. $val .= "W: ".$current." ";
  431. $sensor = "wind";
  432. $def->{READINGS}{$sensor}{TIME} = $tm;
  433. $def->{READINGS}{$sensor}{VAL} = $current;
  434. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  435. $current = $ks300_rain;
  436. $sensor = "rain_raw";
  437. $def->{READINGS}{$sensor}{TIME} = $tm;
  438. $def->{READINGS}{$sensor}{VAL} = $current;
  439. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  440. $current = $ks300_rain * 255 / 1000;
  441. $val .= "R: ".$current." ";
  442. $sensor = "rain";
  443. $def->{READINGS}{$sensor}{TIME} = $tm;
  444. $def->{READINGS}{$sensor}{VAL} = $current;
  445. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  446. $current = $ks300_israining ? "yes" : "no";
  447. $val .= "IR: ".$current." ";
  448. $sensor = "israining";
  449. $def->{READINGS}{$sensor}{TIME} = $tm;
  450. $def->{READINGS}{$sensor}{VAL} = $current;
  451. $def->{CHANGED}[$n++] = $sensor . ": " . $current;
  452. $def->{STATE} = $val;
  453. $def->{TIME} = $tm;
  454. $def->{CHANGED}[$n++] = $val;
  455. DoTrigger($name, undef);
  456. }
  457. } elsif ($rmsg =~ /^ELV.*/) {
  458. #ELV USB-WDE1 v1.1
  459. #Baud:9600bit/s
  460. #Mode:LogView
  461. Log 4, "USBWX Parse ID";
  462. my @c = split(" ", $rmsg);
  463. if ($c[1] eq "USB-WDE1") {
  464. Log 4, "USBWX $c[1] $c[2] found";
  465. $rmsg =~ s/[\r\n]/ /g;
  466. $hash->{READINGS}{"status"}{VAL} = $rmsg;
  467. $hash->{READINGS}{"status"}{TIME} = TimeNow();
  468. }
  469. } elsif ($rmsg =~ /^Mod.*/) {
  470. Log 4, "USBWX Parse mode $rmsg";
  471. my @c = split(":", $rmsg);
  472. my @d = split("\n", $c[1]);
  473. $d[0] =~ s/[\r\n]//g; # Delete the NewLine
  474. Log 4, "USBWX Parse mode >$d[0]<";
  475. if ($d[0] eq "LogView") {
  476. Log 2, "USBWX in $c[0] $d[0] found. rmsg=$rmsg";
  477. #Log 2, "USBWX in $c[0] $d[0] found";
  478. $hash->{STATE} = "Initialized";
  479. $hash->{READINGS}{"mode"}{VAL} = $d[0];
  480. $hash->{READINGS}{"mode"}{TIME} = TimeNow();
  481. }
  482. } elsif ($rmsg =~ /^Baud.*/) {
  483. Log 4, "USBWX BAUD rmsg='$rmsg'";
  484. } elsif ($rmsg =~ /^OK.*/) {
  485. Log 4, "USBWX EMPTY rmsg='$rmsg'";
  486. } elsif ($rmsg =~ /^FullBuff/) {
  487. Log 1, "USBWX Fullbuf-Error rmsg='$rmsg'";
  488. Log 1, "USBWX closing device";
  489. USBWX_Disconnected($hash);
  490. Log 1, "USBWX opening device";
  491. my $ret = USBWX_OpenDev($hash, 0);
  492. } elsif ($rmsg eq "") {
  493. Log 4, "USBWX OK rmsg='$rmsg'";
  494. } else {
  495. Log 2, "USBWX unknown: '$rmsg'";
  496. }
  497. return undef;
  498. }
  499. #####################################
  500. sub
  501. USBWX_Disconnected($)
  502. {
  503. my $hash = shift;
  504. my $dev = $hash->{DeviceName};
  505. my $name = $hash->{NAME};
  506. return if(!defined($hash->{FD})); # Already deleted
  507. Log 1, "USBWX dev='$dev' name='$name' disconnected, waiting to reappear";
  508. USBWX_CloseDev($hash);
  509. $readyfnlist{"$name.$dev"} = $hash; # Start polling
  510. $hash->{STATE} = "disconnected";
  511. # Without the following sleep the open of the device causes a SIGSEGV,
  512. # and following opens block infinitely. Only a reboot helps.
  513. sleep(5);
  514. DoTrigger($name, "DISCONNECTED");
  515. }
  516. 1;
  517. =pod
  518. =begin html
  519. <a name="USBWX"></a>
  520. <h3>USBWX</h3>
  521. <ul>
  522. The USBWX module interprets the messages received by the ELV <a
  523. href="http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=29870">USB-WDE1</a>
  524. weather receiver. This receiver is compaptible with the following ELV sensors:
  525. KS200/KS300, S300IA, S300TH, ASH2200, PS50. It also known to work with Conrad
  526. weather sensors KS555, S555TH and ASH555.<br> This module was tested with ELV
  527. S300TH, ELV ASH2200, ELV KS300, Conrad S555TH and Conrad KS555. <br> Readings
  528. and STATE of temperature/humidity sensors are compatible with the CUL_WS
  529. module. For KS300/KS555 sensors STATE is compatible with the KS300 module. The
  530. module is integrated into autocreate to generate the appropriate filelogs and
  531. weblinks automatically.
  532. <br><br>
  533. Note: this module requires the Device::SerialPort or Win32::SerialPort module
  534. if the devices is connected via USB or a serial port.
  535. <br><br>
  536. <a name="USBWXdefine"></a>
  537. <b>Define</b>
  538. <ul>
  539. <code>define &lt;name&gt; USBWX &lt;serial device&gt;</code>
  540. <br>
  541. <br>Defines USB-WDE1 attached via usb.<br>
  542. <br>
  543. <code>define &lt;name&gt; USBWX &lt;code&gt; [corr1...corr4]</code> <br>
  544. <br>
  545. &lt;code&gt; is the code which must be set on the sensor. Valid values
  546. are 1 through 8. <br> 9 is used as the sensor id of the ks300 sensor.<br>
  547. corr1..corr4 are up to 4 numerical correction factors, which will be added
  548. to the respective value to calibrate the device. Note: rain-values will be
  549. multiplied and not added to the correction factor.
  550. <br>
  551. <br>
  552. Example:<pre>
  553. define USBWDE1 USBWX /dev/ttyUSB0
  554. define USBWX_1 USBWX 1
  555. define USBWX_livingroom USBWX 2
  556. define USBWX_ks300 USBWX 9
  557. </pre>
  558. </ul>
  559. <a name="USBWXset"></a>
  560. <b>Set</b> <ul>N/A</ul><br>
  561. <a name="USBWXget"></a>
  562. <b>Get</b> <ul>N/A</ul><br>
  563. <a name="USBWXattr"></a>
  564. <b>Attributes</b>
  565. <ul>
  566. <li><a href="#model">model</a></li>
  567. <li><a href="#loglevel">loglevel</a></li>
  568. </ul>
  569. <br>
  570. </ul>
  571. =end html
  572. =cut