45_TRX.pm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #################################################################################
  2. # 45_TRX.pm
  3. #
  4. # FHEM Module for RFXtrx433
  5. #
  6. # Derived from 00_CUL.pm: Copyright (C) Rudolf Koenig"
  7. #
  8. # Copyright (C) 2012-2016 Willi Herzig
  9. #
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU General Public License
  12. # as published by the Free Software Foundation; either version 2
  13. # of the License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program; if not, write to the Free Software
  22. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  23. #
  24. # The GNU General Public License may also be found at http://www.gnu.org/licenses/gpl-2.0.html .
  25. #
  26. ###########################
  27. # $Id: 45_TRX.pm 11456 2016-05-15 20:19:24Z wherzig $
  28. package main;
  29. use strict;
  30. use warnings;
  31. use Time::HiRes qw(gettimeofday usleep);
  32. my $last_rmsg = "abcd";
  33. my $last_time = 1;
  34. my $trx_rssi = 0;
  35. sub TRX_Clear($);
  36. sub TRX_Read($@);
  37. sub TRX_Ready($);
  38. sub TRX_Parse($$$$);
  39. my %sets = (
  40. "reopen" => ""
  41. );
  42. sub
  43. TRX_Initialize($)
  44. {
  45. my ($hash) = @_;
  46. require "$attr{global}{modpath}/FHEM/DevIo.pm";
  47. # Provider
  48. $hash->{ReadFn} = "TRX_Read";
  49. $hash->{WriteFn} = "TRX_Write";
  50. $hash->{Clients} =
  51. ":TRX_WEATHER:TRX_SECURITY:TRX_LIGHT:TRX_ELSE:";
  52. my %mc = (
  53. "1:TRX_WEATHER" => "^..(40|4e|50|51|52|54|55|56|57|58|5a|5b|5c|5d).*",
  54. "2:TRX_SECURITY" => "^..(20).*",
  55. "3:TRX_LIGHT" => "^..(10|11|12|13|14|15|16|17|18|19).*",
  56. "4:TRX_ELSE" => "^..(0[0-9a-f]|1[a-f]|2[1-9a-f]|3[0-9a-f]|4[1-9a-d]|4f|53|59|5e|5f|[6-9a-f][0-9a-f]).*",
  57. );
  58. $hash->{MatchList} = \%mc;
  59. $hash->{ReadyFn} = "TRX_Ready";
  60. $hash->{ReadAnswerFn} = "TRX_ReadAnswer";
  61. # Normal devices
  62. $hash->{DefFn} = "TRX_Define";
  63. $hash->{UndefFn} = "TRX_Undef";
  64. $hash->{GetFn} = "TRX_Get";
  65. $hash->{SetFn} = "TRX_Set";
  66. $hash->{StateFn} = "TRX_SetState";
  67. $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 do_not_init:1,0 addvaltrigger:1,0 longids rssi:1,0";
  68. $hash->{ShutdownFn} = "TRX_Shutdown";
  69. }
  70. #####################################
  71. sub
  72. TRX_Define($$)
  73. {
  74. my ($hash, $def) = @_;
  75. my @a = split("[ \t][ \t]*", $def);
  76. if (@a != 3 && @a != 4) {
  77. my $msg = "wrong syntax: define <name> TRX devicename [noinit]";
  78. Log3 undef, 2, $msg;
  79. return $msg;
  80. }
  81. DevIo_CloseDev($hash);
  82. my $name = $a[0];
  83. my $dev = $a[2];
  84. my $opt = $a[3] if(@a == 4);;
  85. if($dev eq "none") {
  86. Log3 $name, 1, "TRX: $name device is none, commands will be echoed only";
  87. $attr{$name}{dummy} = 1;
  88. return undef;
  89. }
  90. if(defined($opt)) {
  91. if($opt eq "noinit") {
  92. Log3 $name, 1 , "TRX: $name no init is done";
  93. $attr{$name}{do_not_init} = 1;
  94. } else {
  95. return "wrong syntax: define <name> TRX devicename [noinit]"
  96. }
  97. }
  98. $hash->{DeviceName} = $dev;
  99. my $ret = DevIo_OpenDev($hash, 0, "TRX_DoInit");
  100. return $ret;
  101. }
  102. #####################################
  103. # Input is hexstring
  104. sub
  105. TRX_Write($$)
  106. {
  107. my ($hash,$fn,$msg) = @_;
  108. my $name = $hash->{NAME};
  109. return if(!defined($fn));
  110. my $bstring;
  111. $bstring = "$fn$msg";
  112. Log3 $name, 5, "$hash->{NAME} sending $bstring";
  113. DevIo_SimpleWrite($hash, $bstring, 1);
  114. }
  115. #####################################
  116. sub
  117. TRX_Undef($$)
  118. {
  119. my ($hash, $arg) = @_;
  120. my $name = $hash->{NAME};
  121. foreach my $d (sort keys %defs) {
  122. if(defined($defs{$d}) &&
  123. defined($defs{$d}{IODev}) &&
  124. $defs{$d}{IODev} == $hash)
  125. {
  126. my $lev = ($reread_active ? 4 : 2);
  127. Log3 $name, $lev, "deleting port for $d";
  128. delete $defs{$d}{IODev};
  129. }
  130. }
  131. DevIo_CloseDev($hash);
  132. return undef;
  133. }
  134. #####################################
  135. sub
  136. TRX_Shutdown($)
  137. {
  138. my ($hash) = @_;
  139. return undef;
  140. }
  141. #####################################
  142. sub
  143. TRX_Reopen($)
  144. {
  145. my ($hash) = @_;
  146. DevIo_CloseDev($hash);
  147. sleep(1);
  148. DevIo_OpenDev($hash, 0, "TRX_DoInit");
  149. }
  150. #####################################
  151. sub
  152. TRX_Get($@)
  153. {
  154. my ($hash, @a) = @_;
  155. my $msg;
  156. my $name=$a[0];
  157. my $reading= $a[1];
  158. $msg="$name => No Get function ($reading) implemented";
  159. Log3 $name, 1, $msg if ($reading ne "?");
  160. return $msg;
  161. }
  162. #####################################
  163. sub
  164. TRX_Set($@)
  165. {
  166. my ($hash, @a) = @_;
  167. return "\"set TRX\" needs at least one parameter" if(@a < 1);
  168. return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
  169. if(!defined($sets{$a[1]}));
  170. my $name = shift @a;
  171. my $type = shift @a;
  172. if($type eq "reopen") { ####################################
  173. TRX_Reopen($hash);
  174. }
  175. return undef;
  176. }
  177. #####################################
  178. sub
  179. TRX_SetState($$$$)
  180. {
  181. my ($hash, $tim, $vt, $val) = @_;
  182. return undef;
  183. }
  184. sub
  185. TRX_Clear($)
  186. {
  187. my $hash = shift;
  188. # Clear the pipe
  189. $hash->{RA_Timeout} = 0.1;
  190. for(;;) {
  191. my ($err, undef) = TRX_ReadAnswer($hash, "Clear");
  192. last if($err);
  193. }
  194. delete($hash->{RA_Timeout});
  195. $hash->{PARTIAL} = "";
  196. }
  197. #####################################
  198. sub
  199. TRX_DoInit($)
  200. {
  201. my $hash = shift;
  202. my $name = $hash->{NAME};
  203. my $err;
  204. my $msg = undef;
  205. my $buf;
  206. my $char = undef ;
  207. if(defined($attr{$name}) && defined($attr{$name}{"do_not_init"})) {
  208. Log3 $name, 1, "TRX: defined with noinit. Do not send init string to device.";
  209. }
  210. else
  211. {
  212. # Reset
  213. my $init = pack('H*', "0D00000000000000000000000000");
  214. DevIo_SimpleWrite($hash, $init, 0);
  215. DevIo_TimeoutRead($hash, 0.5);
  216. sleep(1);
  217. TRX_Clear($hash);
  218. sleep(1);
  219. #
  220. # Get Status
  221. $init = pack('H*', "0D00000102000000000000000000");
  222. DevIo_SimpleWrite($hash, $init, 0);
  223. usleep(50000); # wait 50 ms
  224. $buf = unpack('H*',DevIo_TimeoutRead($hash, 0.2));
  225. if (! $buf) {
  226. Log3 $name, 1, "TRX: Initialization Error: No character read";
  227. return "TRX: Initialization Error $name: no char read";
  228. } elsif ($buf !~ m/0d0100....................../ && $buf !~ m/140100..................................../) {
  229. Log3 $name, 1, "TRX: Initialization Error hexline='$buf', expected 0d0100......................";
  230. return "TRX: Initialization Error %name expected 0D010, but buf=$buf received.";
  231. } else {
  232. Log3 $name,1, "TRX: Init OK";
  233. # Analyse result and display it:
  234. if ($buf =~ m/0d0100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/) {
  235. my $status = "";
  236. my $seqnbr = $1;
  237. my $cmnd = $2;
  238. my $msg1 = $3;
  239. my $msg2 = ord(pack('H*', $4));
  240. my $msg3 = ord(pack('H*', $5));
  241. my $msg4 = ord(pack('H*', $6));
  242. my $msg5 = ord(pack('H*', $7));
  243. my $freq = {
  244. '50' => '310MHz',
  245. '51' => '315MHz',
  246. '52' => '433.92MHz receiver only',
  247. '53' => '433.92MHz transceiver',
  248. '55' => '868.00MHz',
  249. '56' => '868.00MHz FSK',
  250. '57' => '868.30MHz',
  251. '58' => '868.30MHz FSK',
  252. '59' => '868.35MHz',
  253. '5a' => '868.35MHz FSK',
  254. '5b' => '868.95MHz'
  255. }->{$msg1} || 'unknown Mhz';
  256. $status .= $freq;
  257. $status .= ", " . sprintf "firmware=%d",$msg2;
  258. $status .= ", protocols enabled: ";
  259. $status .= "undecoded " if ($msg3 & 0x80);
  260. $status .= "RFU " if ($msg3 & 0x40);
  261. $status .= "ByronSX " if ($msg3 & 0x20);
  262. $status .= "RSL " if ($msg3 & 0x10);
  263. $status .= "Lighting4 " if ($msg3 & 0x08);
  264. $status .= "FineOffset/Viking " if ($msg3 & 0x04);
  265. $status .= "Rubicson " if ($msg3 & 0x02);
  266. $status .= "AE/Blyss " if ($msg3 & 0x01);
  267. $status .= "BlindsT1/T2/T3/T4 " if ($msg4 & 0x80);
  268. $status .= "BlindsT0 " if ($msg4 & 0x40);
  269. $status .= "ProGuard " if ($msg4 & 0x20);
  270. $status .= "FS20 " if ($msg4 & 0x10);
  271. $status .= "LaCrosse " if ($msg4 & 0x08);
  272. $status .= "Hideki " if ($msg4 & 0x04);
  273. $status .= "LightwaveRF " if ($msg4 & 0x02);
  274. $status .= "Mertik " if ($msg4 & 0x01);
  275. $status .= "Visonic " if ($msg5 & 0x80);
  276. $status .= "ATI " if ($msg5 & 0x40);
  277. $status .= "OREGON " if ($msg5 & 0x20);
  278. $status .= "KOPPLA " if ($msg5 & 0x10);
  279. $status .= "HOMEEASY " if ($msg5 & 0x08);
  280. $status .= "AC " if ($msg5 & 0x04);
  281. $status .= "ARC " if ($msg5 & 0x02);
  282. $status .= "X10 " if ($msg5 & 0x01);
  283. my $hexline = unpack('H*', $buf);
  284. Log3 $name, 4, "TRX: Init status hexline='$hexline'";
  285. Log3 $name, 1, "TRX: Init status: '$status'";
  286. }
  287. # Since 1001
  288. if ($buf =~ m/140100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/) {
  289. my $status = "";
  290. my $seqnbr = $1;
  291. my $cmnd = $2;
  292. my $msg1 = $3;
  293. my $msg2 = ord(pack('H*', $4));
  294. my $msg3 = ord(pack('H*', $5));
  295. my $msg4 = ord(pack('H*', $6));
  296. my $msg5 = ord(pack('H*', $7));
  297. my $msg6 = ord(pack('H*', $8));
  298. my $freq = {
  299. '50' => '310MHz',
  300. '51' => '315MHz',
  301. '52' => '433.92MHz receiver only',
  302. '53' => '433.92MHz transceiver',
  303. '55' => '868.00MHz',
  304. '56' => '868.00MHz FSK',
  305. '57' => '868.30MHz',
  306. '58' => '868.30MHz FSK',
  307. '59' => '868.35MHz',
  308. '5a' => '868.35MHz FSK',
  309. '5b' => '868.95MHz'
  310. }->{$msg1} || 'unknown Mhz';
  311. $status .= $freq;
  312. $status .= ", " . sprintf "firmware=%d",$msg2+1000;
  313. $status .= ", protocols enabled: ";
  314. $status .= "undecoded " if ($msg3 & 0x80);
  315. $status .= "RFU " if ($msg3 & 0x40);
  316. $status .= "ByronSX " if ($msg3 & 0x20);
  317. $status .= "RSL " if ($msg3 & 0x10);
  318. $status .= "Lighting4 " if ($msg3 & 0x08);
  319. $status .= "FineOffset/Viking " if ($msg3 & 0x04);
  320. $status .= "Rubicson " if ($msg3 & 0x02);
  321. $status .= "AE/Blyss " if ($msg3 & 0x01);
  322. $status .= "BlindsT1/T2/T3/T4 " if ($msg4 & 0x80);
  323. $status .= "BlindsT0 " if ($msg4 & 0x40);
  324. $status .= "ProGuard " if ($msg4 & 0x20);
  325. $status .= "FS20 " if ($msg4 & 0x10);
  326. $status .= "LaCrosse " if ($msg4 & 0x08);
  327. $status .= "Hideki " if ($msg4 & 0x04);
  328. $status .= "LightwaveRF " if ($msg4 & 0x02);
  329. $status .= "Mertik " if ($msg4 & 0x01);
  330. $status .= "Visonic " if ($msg5 & 0x80);
  331. $status .= "ATI " if ($msg5 & 0x40);
  332. $status .= "OREGON " if ($msg5 & 0x20);
  333. $status .= "KOPPLA " if ($msg5 & 0x10);
  334. $status .= "HOMEEASY " if ($msg5 & 0x08);
  335. $status .= "AC " if ($msg5 & 0x04);
  336. $status .= "ARC " if ($msg5 & 0x02);
  337. $status .= "X10 " if ($msg5 & 0x01);
  338. $status .= "HomeComfort " if ($msg6 & 0x02);
  339. $status .= "KEELOQ " if ($msg6 & 0x01);
  340. my $hexline = unpack('H*', $buf);
  341. Log3 $name, 4, "TRX: Init status hexline='$hexline'";
  342. Log3 $name, 1, "TRX: Init status: '$status'";
  343. }
  344. }
  345. }
  346. # Reset the counter
  347. delete($hash->{XMIT_TIME});
  348. delete($hash->{NR_CMD_LAST_H});
  349. readingsSingleUpdate($hash, "state", "Initialized", 1);
  350. return undef;
  351. }
  352. #####################################
  353. # This is a direct read for commands like get
  354. sub
  355. TRX_ReadAnswer($$)
  356. {
  357. my ($hash, $arg) = @_;
  358. return ("No FD (dummy device?)", undef)
  359. if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD})));
  360. # my $to = ($hash->{RA_Timeout} ? $hash->{RA_Timeout} : 3);
  361. my $to = ($hash->{RA_Timeout} ? $hash->{RA_Timeout} : 9);
  362. Log3 $hash, 4, "TRX_ReadAnswer arg:$arg";
  363. for(;;) {
  364. my $buf;
  365. if($^O =~ m/Win/ && $hash->{USBDev}) {
  366. $hash->{USBDev}->read_const_time($to*1000); # set timeout (ms)
  367. # Read anstatt input sonst funzt read_const_time nicht.
  368. $buf = $hash->{USBDev}->read(999);
  369. return ("Timeout reading answer for get $arg", undef)
  370. if(length($buf) == 0);
  371. } else {
  372. if(!$hash->{FD}) {
  373. Log3 $hash, 1, "TRX_ReadAnswer: device lost";
  374. return ("Device lost when reading answer for get $arg", undef);
  375. }
  376. my $rin = '';
  377. vec($rin, $hash->{FD}, 1) = 1;
  378. my $nfound = select($rin, undef, undef, $to);
  379. if($nfound < 0) {
  380. my $err = $!;
  381. Log3 $hash, 5, "TRX_ReadAnswer: nfound < 0 / err:$err";
  382. next if ($err == EAGAIN() || $err == EINTR() || $err == 0);
  383. DevIo_Disconnected($hash);
  384. return("TRX_ReadAnswer $arg: $err", undef);
  385. }
  386. if($nfound == 0){
  387. Log3 $hash, 5, "TRX_ReadAnswer: select timeout";
  388. return ("Timeout reading answer for get $arg", undef);
  389. }
  390. $buf = DevIo_SimpleRead($hash);
  391. if(!defined($buf)){
  392. Log3 $hash, 1,"TRX_ReadAnswer: no data read";
  393. return ("No data", undef);
  394. }
  395. }
  396. my $ret = TRX_Read($hash, $buf);
  397. if(defined($ret)){
  398. Log3 $hash, 4, "TRX_ReadAnswer for $arg: $ret";
  399. return (undef, $ret);
  400. }
  401. }
  402. }
  403. #####################################
  404. # called from the global loop, when the select for hash->{FD} reports data
  405. sub
  406. TRX_Read($@)
  407. {
  408. my ($hash, $local) = @_;
  409. my $mybuf = (defined($local) ? $local : DevIo_SimpleRead($hash));
  410. return "" if(!defined($mybuf));
  411. my $name = $hash->{NAME};
  412. my $TRX_data = $hash->{PARTIAL};
  413. Log3 $name, 5, "TRX/RAW: $TRX_data/$mybuf";
  414. $TRX_data .= $mybuf;
  415. my $hexline = unpack('H*', $TRX_data);
  416. Log3 $name, 5, "TRX: TRX_Read '$hexline'";
  417. # first char as byte represents number of bytes of the message
  418. my $num_bytes = ord(substr($TRX_data,0,1));
  419. while(length($TRX_data) > $num_bytes) {
  420. # the buffer contains at least the number of bytes we need
  421. my $rmsg;
  422. $rmsg = substr($TRX_data, 0, $num_bytes+1);
  423. #my $hexline = unpack('H*', $rmsg);
  424. Log3 $name, 5, "TRX_Read rmsg '$hexline'";
  425. $TRX_data = substr($TRX_data, $num_bytes+1);;
  426. #$hexline = unpack('H*', $TRX_data);
  427. Log3 $name, 5, "TRX_Read TRX_data '$hexline'";
  428. #
  429. TRX_Parse($hash, $hash, $name, unpack('H*', $rmsg));
  430. $num_bytes = ord(substr($TRX_data,0,1));
  431. }
  432. Log3 $name, 5, "TRX_Read END";
  433. $hash->{PARTIAL} = $TRX_data;
  434. }
  435. sub
  436. TRX_Parse($$$$)
  437. {
  438. my ($hash, $iohash, $name, $rmsg) = @_;
  439. #Log3 $hash, 5, "TRX_Parse() '$rmsg'";
  440. if(!defined($hash->{STATE}) || $hash->{STATE} ne "Initialized"){
  441. Log3 $hash, 4,"TRX_Parse $rmsg: dongle not yet initialized";
  442. return;
  443. }
  444. my %addvals;
  445. # Parse only if message is different within 2 seconds
  446. # (some Oregon sensors always sends the message twice, X10 security sensors even sends the message five times)
  447. if (("$last_rmsg" ne "$rmsg") || (time() - $last_time) > 1) {
  448. Log3 $hash, 5, "TRX_Parse() '$rmsg'";
  449. %addvals = (RAWMSG => $rmsg);
  450. Dispatch($hash, $rmsg, \%addvals);
  451. $hash->{"${name}_MSGCNT"}++;
  452. $hash->{"${name}_TIME"} = TimeNow();
  453. $hash->{RAWMSG} = $rmsg;
  454. readingsSingleUpdate($hash, "state", $hash->{READINGS}{state}{VAL}, 0);
  455. } else {
  456. Log3 $hash, 5, "TRX_Parse() '$rmsg' dup";
  457. }
  458. $last_rmsg = $rmsg;
  459. $last_time = time();
  460. }
  461. #####################################
  462. sub
  463. TRX_Ready($)
  464. {
  465. my ($hash) = @_;
  466. return DevIo_OpenDev($hash, 1, "TRX_DoInit")
  467. if($hash->{STATE} eq "disconnected");
  468. # This is relevant for windows/USB only
  469. my $po = $hash->{USBDev};
  470. my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
  471. return ($InBytes>0);
  472. }
  473. 1;
  474. =pod
  475. =begin html
  476. <a name="TRX"></a>
  477. <h3>TRX</h3>
  478. <ul>
  479. <table>
  480. This module is for the <a href="http://www.rfxcom.com">RFXCOM</a> RFXtrx433 USB based 433 Mhz RF transmitters.
  481. This USB based transmitter is able to receive and transmit many protocols like Oregon Scientific weather sensors, X10 security and lighting devices, ARC ((address code wheels) HomeEasy, KlikAanKlikUit, ByeByeStandBy, Intertechno, ELRO,
  482. AB600, Duewi, DomiaLite, COCO) and others. <br>
  483. Currently the following parser modules are implemented: <br>
  484. <ul>
  485. <li> 46_TRX_WEATHER.pm (see device <a href="#TRX">TRX</a>): Process messages Oregon Scientific weather sensors.
  486. See <a href="http://www.rfxcom.com/oregon.htm">http://www.rfxcom.com/oregon.htm</a> for a list of
  487. Oregon Scientific weather sensors that could be received by the RFXtrx433 tranmitter.
  488. Until now the following Oregon Scientific weather sensors have been tested successfully: BTHR918, BTHR918N, PCR800, RGR918, THGR228N, THGR810, THR128, THWR288A, WTGR800, WGR918. It will also work with many other Oregon sensors supported by RFXtrx433. Please give feedback if you use other sensors.<br>
  489. </li>
  490. <li> 46_TRX_SECURITY.pm (see device <a href="#TRX_SECURITY">TRX_SECURITY</a>): Receive X10, KD101 and Visonic security sensors.</li>
  491. <li> 46_TRX_LIGHT.pm (see device <a href="#RFXX10REC">RFXX10REC</a>): Process X10, ARC, ELRO AB400D, Waveman, Chacon EMW200, IMPULS, RisingSun, Philips SBC, AC, HomeEasy EU and ANSLUT lighting devices (switches and remote control). ARC is a protocol used by devices from HomeEasy, KlikAanKlikUit, ByeByeStandBy, Intertechno, ELRO, AB600, Duewi, DomiaLite and COCO with address code wheels. AC is the protocol used by different brands with units having a learning mode button:
  492. KlikAanKlikUit, NEXA, CHACON, HomeEasy UK.</li>
  493. </ul>
  494. <br>
  495. Note: this module requires the Device::SerialPort or Win32::SerialPort module
  496. if the devices is connected via USB or a serial port.
  497. <br><br>
  498. <a name="TRXdefine"></a>
  499. <b>Define</b>
  500. <ul>
  501. <code>define &lt;name&gt; TRX &lt;device&gt; [noinit] </code><br>
  502. </ul>
  503. <br>
  504. USB-connected:<br><ul>
  505. &lt;device&gt; specifies the USB port to communicate with the RFXtrx433 receiver.
  506. Normally on Linux the device will be named /dev/ttyUSBx, where x is a number.
  507. For example /dev/ttyUSB0. Please note that RFXtrx433 normally operates at 38400 baud. You may specify the baudrate used after the @ char.<br>
  508. <br>
  509. Example: <br>
  510. <code>define RFXTRXUSB TRX /dev/ttyUSB0@38400</code>
  511. <br>
  512. </ul>
  513. <br>
  514. Network-connected devices:
  515. <br><ul>
  516. &lt;device&gt; specifies the host:port of the device. E.g.
  517. 192.168.1.5:10001
  518. </ul>
  519. <ul>
  520. noninit is optional and issues that the RFXtrx433 device should not be
  521. initialized. This is useful if you share a RFXtrx433 device via LAN. It is
  522. also useful for testing to simulate a RFXtrx433 receiver via netcat or via
  523. FHEM2FHEM.
  524. <br>
  525. <br>
  526. Example: <br>
  527. <code>define RFXTRXTCP TRX 192.168.1.5:10001</code>
  528. <br>
  529. <code>define RFXTRXTCP2 TRX 192.168.1.121:10001 noinit</code>
  530. <br>
  531. </ul>
  532. <br>
  533. </table>
  534. <a name="TRXattr"></a>
  535. <b>Attributes</b>
  536. <ul>
  537. <li><a href="#attrdummy">dummy</a></li><br>
  538. <li>longids<br>
  539. Comma separated list of device-types for TRX_WEATHER that should be handled using long IDs. This additional ID is a one byte hex string and is generated by the Oregon sensor when is it powered on. The value seems to be randomly generated. This has the advantage that you may use more than one Oregon sensor of the same type even if it has no switch to set a sensor id. For example the author uses two BTHR918N sensors at the same time. All have different deviceids. The drawback is that the deviceid changes after changing batteries. All devices listed as longids will get an additional one byte hex string appended to the device name.<br>
  540. Default is to use no long IDs.
  541. <br><br>
  542. Examples:<PRE>
  543. # Do not use any long IDs for any devices (this is default):
  544. attr RFXCOMUSB longids 0
  545. # Use long IDs for all devices:
  546. attr RFXCOMUSB longids 1
  547. # Use longids for BTHR918N devices.
  548. # Will generate devices names like BTHR918N_f3.
  549. attr RFXTRXUSB longids BTHR918N
  550. # Use longids for TX3_T and TX3_H devices.
  551. # Will generate devices names like TX3_T_07, TX3_T_01 ,TX3_H_07.
  552. attr RFXTRXUSB longids TX3_T,TX3_H</PRE>
  553. </li><br>
  554. <li>rssi<br>
  555. 1: enable RSSI logging, 0: disable RSSI logging<br>
  556. Default is no RSSI logging.
  557. <br><br>
  558. Examples:<PRE>
  559. # Do log rssi values (this is default):
  560. attr RFXCOMUSB rssi 0
  561. # Enable rssi logging for devices:
  562. attr RFXCOMUSB rssi 1
  563. </li><br>
  564. </ul>
  565. <br>
  566. </ul>
  567. =end html
  568. =cut