00_CUL.pm 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755
  1. ##############################################
  2. # $Id: 00_CUL.pm 12983 2017-01-06 13:53:27Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use Time::HiRes qw(gettimeofday);
  7. sub CUL_Attr(@);
  8. sub CUL_Clear($);
  9. sub CUL_HandleCurRequest($$);
  10. sub CUL_HandleWriteQueue($);
  11. sub CUL_Parse($$$$@);
  12. sub CUL_Read($);
  13. sub CUL_ReadAnswer($$$$);
  14. sub CUL_Ready($);
  15. sub CUL_Write($$$);
  16. sub CUL_SimpleWrite(@);
  17. sub CUL_WriteInit($);
  18. my %gets = ( # Name, Data to send to the CUL, Regexp for the answer
  19. "ccconf" => 1,
  20. "version" => ["V", '^V .*'],
  21. "raw" => ["", '.*'],
  22. "uptime" => ["t", '^[0-9A-F]{8}[\r\n]*$' ],
  23. "fhtbuf" => ["T03", '^[0-9A-F]+[\r\n]*$' ],
  24. "cmds" => ["?", '.*Use one of( .)*[\r\n]*$' ],
  25. "credit10ms" => [ "X", '^.. *\d*[\r\n]*$' ],
  26. );
  27. my %sets = (
  28. "reopen" => "",
  29. "hmPairForSec" => "HomeMatic",
  30. "hmPairSerial" => "HomeMatic",
  31. "raw" => "",
  32. "freq" => "SlowRF",
  33. "bWidth" => "SlowRF",
  34. "rAmpl" => "SlowRF",
  35. "sens" => "SlowRF",
  36. "led" => "",
  37. "patable" => "",
  38. "ITClock" => "SlowRF"
  39. );
  40. my @ampllist = (24, 27, 30, 33, 36, 38, 40, 42); # rAmpl(dB)
  41. my $sccMods = "STACKABLE_CC:TSSTACKED"; # for noansi
  42. my $culNameRe = "^(CUL|TSCUL)\$";
  43. my $clientsSlowRF = ":FS20:FHT.*:KS300:USF1000:BS:HMS: ".
  44. ":CUL_EM:CUL_WS:CUL_FHTTK:CUL_HOERMANN: ".
  45. ":ESA2000:CUL_IR:CUL_TX:Revolt:IT:UNIRoll:SOMFY: ".
  46. ":$sccMods:CUL_RFR::CUL_TCM97001:CUL_REDIRECT:";
  47. my $clientsHomeMatic = ":CUL_HM:HMS:CUL_IR:$sccMods:";
  48. my $clientsMAX = ":CUL_MAX:HMS:CUL_IR:$sccMods:";
  49. my $clientsWMBus = ":WMBUS:HMS:CUL_IR:$sccMods:";
  50. my $clientsKOPP_FC = ":KOPP_FC:HMS:CUL_IR:$sccMods:";
  51. my %matchListSlowRF = (
  52. "1:USF1000" => "^81..(04|0c)..0101a001a5ceaa00....",
  53. "2:BS" => "^81..(04|0c)..0101a001a5cf",
  54. "3:FS20" => "^81..(04|0c)..0101a001",
  55. "4:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..",
  56. "5:KS300" => "^810d04..4027a001",
  57. "6:CUL_WS" => "^K.....",
  58. "7:CUL_EM" => "^E0.................\$",
  59. "8:HMS" => "^810e04....(1|5|9).a001",
  60. "9:CUL_FHTTK" => "^T[A-F0-9]{8}",
  61. "A:CUL_RFR" => "^[0-9A-F]{4}U.",
  62. "B:CUL_HOERMANN"=> "^R..........",
  63. "C:ESA2000" => "^S................................\$",
  64. "D:CUL_IR" => "^I............",
  65. "E:CUL_TX" => "^TX[A-F0-9]{10}",
  66. "F:Revolt" => "^r......................\$",
  67. "G:IT" => "^i......",
  68. "H:STACKABLE_CC"=>"^\\*",
  69. "I:UNIRoll" => "^[0-9A-F]{5}(B|D|E)",
  70. "J:SOMFY" => "^Y[r|t|s]:?[A-F0-9]+",
  71. "K:CUL_TCM97001" => "^s[A-F0-9]+",
  72. "L:CUL_REDIRECT" => "^o+",
  73. "M:TSSTACKED"=>"^\\*",
  74. );
  75. my %matchListHomeMatic = (
  76. "1:CUL_HM" => "^A....................",
  77. "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation
  78. "D:CUL_IR" => "^I............",
  79. "H:STACKABLE_CC"=>"^\\*",
  80. "M:TSSTACKED"=>"^\\*",
  81. );
  82. my %matchListMAX = (
  83. "1:CUL_MAX" => "^Z........................",
  84. "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation
  85. "D:CUL_IR" => "^I............",
  86. "H:STACKABLE_CC"=>"^\\*",
  87. "M:TSSTACKED"=>"^\\*",
  88. );
  89. my %matchListWMBus = (
  90. "J:WMBUS" => "^b.*",
  91. "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation
  92. "D:CUL_IR" => "^I............",
  93. "H:STACKABLE_CC"=>"^\\*",
  94. "M:TSSTACKED"=>"^\\*",
  95. );
  96. my %matchListKOPP_FC = (
  97. "1:Kopp_FC" => "^kr..................",
  98. "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation
  99. "D:CUL_IR" => "^I............",
  100. "H:STACKABLE_CC"=>"^\\*",
  101. "M:TSSTACKED"=>"^\\*",
  102. );
  103. sub
  104. CUL_Initialize($)
  105. {
  106. my ($hash) = @_;
  107. require "$attr{global}{modpath}/FHEM/DevIo.pm";
  108. # Provider
  109. $hash->{ReadFn} = "CUL_Read";
  110. $hash->{WriteFn} = "CUL_Write";
  111. $hash->{ReadyFn} = "CUL_Ready";
  112. # Normal devices
  113. $hash->{DefFn} = "CUL_Define";
  114. $hash->{FingerprintFn} = "CUL_FingerprintFn";
  115. $hash->{UndefFn} = "CUL_Undef";
  116. $hash->{GetFn} = "CUL_Get";
  117. $hash->{SetFn} = "CUL_Set";
  118. $hash->{AttrFn} = "CUL_Attr";
  119. no warnings 'qw';
  120. my @attrList = qw(
  121. addvaltrigger
  122. connectCommand
  123. do_not_notify:1,0
  124. dummy:1,0
  125. hmId longids
  126. hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger
  127. model:CUL,CUN,CUNO,SCC,nanoCUL
  128. rfmode:SlowRF,HomeMatic,MAX,WMBus_T,WMBus_S,KOPP_FC
  129. sendpool
  130. showtime:1,0
  131. );
  132. use warnings 'qw';
  133. $hash->{AttrList} = join(" ", @attrList)." ".$readingFnAttributes;
  134. $hash->{ShutdownFn} = "CUL_Shutdown";
  135. }
  136. sub
  137. CUL_FingerprintFn($$)
  138. {
  139. my ($name, $msg) = @_;
  140. # Store only the "relevant" part, as the CUL won't compute the checksum
  141. $msg = substr($msg, 8) if($msg =~ m/^81/ && length($msg) > 8);
  142. return ($name, $msg);
  143. }
  144. #####################################
  145. sub
  146. CUL_Define($$)
  147. {
  148. my ($hash, $def) = @_;
  149. my @a = split("[ \t][ \t]*", $def);
  150. if(@a < 4 || @a > 5) {
  151. my $msg = "wrong syntax: define <name> CUL {none | devicename[\@baudrate] ".
  152. "| devicename\@directio | hostname:port} <FHTID>";
  153. Log3 undef, 2, $msg;
  154. return $msg;
  155. }
  156. DevIo_CloseDev($hash);
  157. my $name = $a[0];
  158. my $dev = $a[2];
  159. return "FHTID must be H1H2, with H1 and H2 hex and both smaller than 64"
  160. if(uc($a[3]) !~ m/^[0-6][0-9A-F][0-6][0-9A-F]$/);
  161. if(uc($a[3]) =~ m/^([0-6][0-9A-F])/ && $1 ne "00") {
  162. my $x = $1;
  163. foreach my $d (keys %defs) {
  164. next if($d eq $name);
  165. if($defs{$d}{TYPE} =~ m/$culNameRe/) {
  166. if(uc($defs{$d}{FHTID}) =~ m/^$x/) {
  167. my $m = "$name: Cannot define multiple CULs with identical ".
  168. "first two digits ($x)";
  169. Log3 $name, 1, $m;
  170. return $m;
  171. }
  172. }
  173. }
  174. }
  175. $hash->{FHTID} = uc($a[3]);
  176. $hash->{initString} = "X21";
  177. $hash->{CMDS} = "";
  178. $hash->{Clients} = $clientsSlowRF;
  179. $hash->{MatchList} = \%matchListSlowRF;
  180. if($dev eq "none") {
  181. Log3 $name, 1, "$name device is none, commands will be echoed only";
  182. $attr{$name}{dummy} = 1;
  183. return undef;
  184. }
  185. $hash->{DeviceName} = $dev;
  186. my $ret = DevIo_OpenDev($hash, 0, "CUL_DoInit");
  187. return $ret;
  188. }
  189. #####################################
  190. sub
  191. CUL_Undef($$)
  192. {
  193. my ($hash, $arg) = @_;
  194. my $name = $hash->{NAME};
  195. foreach my $d (sort keys %defs) {
  196. if(defined($defs{$d}) &&
  197. defined($defs{$d}{IODev}) &&
  198. $defs{$d}{IODev} == $hash)
  199. {
  200. my $lev = ($reread_active ? 4 : 2);
  201. Log3 $name, $lev, "deleting port for $d";
  202. delete $defs{$d}{IODev};
  203. }
  204. }
  205. CUL_SimpleWrite($hash, "X00"); # Switch reception off, it may hang up the CUL
  206. DevIo_CloseDev($hash);
  207. return undef;
  208. }
  209. #####################################
  210. sub
  211. CUL_Shutdown($)
  212. {
  213. my ($hash) = @_;
  214. CUL_SimpleWrite($hash, "X00");
  215. return undef;
  216. }
  217. sub
  218. CUL_RemoveHMPair($)
  219. {
  220. my $hash = shift;
  221. delete($hash->{hmPair});
  222. }
  223. #####################################
  224. sub
  225. CUL_Reopen($)
  226. {
  227. my ($hash) = @_;
  228. DevIo_CloseDev($hash);
  229. DevIo_OpenDev($hash, 1, "CUL_DoInit");
  230. }
  231. #####################################
  232. sub
  233. CUL_Set($@)
  234. {
  235. my ($hash, @a) = @_;
  236. return "\"set CUL\" needs at least one parameter" if(@a < 2);
  237. return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
  238. if(!defined($sets{$a[1]}));
  239. my $name = shift @a;
  240. my $type = shift @a;
  241. my $arg = join("", @a);
  242. return "This command is not valid in the current rfmode"
  243. if($sets{$type} && $sets{$type} ne AttrVal($name, "rfmode", "SlowRF"));
  244. if($type eq "reopen") {
  245. CUL_Reopen($hash);
  246. } elsif($type eq "hmPairForSec") {
  247. return "Usage: set $name hmPairForSec <seconds_active>"
  248. if(!$arg || $arg !~ m/^\d+$/);
  249. $hash->{hmPair} = 1;
  250. InternalTimer(gettimeofday()+$arg, "CUL_RemoveHMPair", $hash, 1);
  251. } elsif($type eq "hmPairSerial") {
  252. return "Usage: set $name hmPairSerial <10-character-serialnumber>"
  253. if(!$arg || $arg !~ m/^.{10}$/);
  254. my $id = AttrVal($hash->{NAME}, "hmId", "F1".$hash->{FHTID});
  255. $hash->{HM_CMDNR} = $hash->{HM_CMDNR} ? ($hash->{HM_CMDNR}+1)%256 : 1;
  256. CUL_SimpleWrite($hash, sprintf("As15%02x8401%s000000010A%s",
  257. $hash->{HM_CMDNR}, $id, unpack('H*', $arg)));
  258. $hash->{hmPairSerial} = $arg;
  259. } elsif($type eq "freq") {
  260. my $f = $arg/26*65536;
  261. my $f2 = sprintf("%02x", $f / 65536);
  262. my $f1 = sprintf("%02x", int($f % 65536) / 256);
  263. my $f0 = sprintf("%02x", $f % 256);
  264. $arg = sprintf("%.3f", (hex($f2)*65536+hex($f1)*256+hex($f0))/65536*26);
  265. Log3 $name, 3, "Setting FREQ2..0 (0D,0E,0F) to $f2 $f1 $f0 = $arg MHz";
  266. CUL_SimpleWrite($hash, "W0F$f2");
  267. CUL_SimpleWrite($hash, "W10$f1");
  268. CUL_SimpleWrite($hash, "W11$f0");
  269. CUL_WriteInit($hash); # Will reprogram the CC1101
  270. } elsif($type eq "bWidth") {
  271. my ($err, $ob);
  272. if(!IsDummy($hash->{NAME})) {
  273. CUL_SimpleWrite($hash, "C10");
  274. ($err, $ob) = CUL_ReadAnswer($hash, $type, 0, "^C10 = .*");
  275. return "Can't get old MDMCFG4 value" if($err || $ob !~ m,/ (.*)\r,);
  276. $ob = $1 & 0x0f;
  277. }
  278. my ($bits, $bw) = (0,0);
  279. for (my $e = 0; $e < 4; $e++) {
  280. for (my $m = 0; $m < 4; $m++) {
  281. $bits = ($e<<6)+($m<<4);
  282. $bw = int(26000/(8 * (4+$m) * (1 << $e))); # KHz
  283. goto GOTBW if($arg >= $bw);
  284. }
  285. }
  286. GOTBW:
  287. $ob = sprintf("%02x", $ob+$bits);
  288. Log3 $name, 3, "Setting MDMCFG4 (10) to $ob = $bw KHz";
  289. CUL_SimpleWrite($hash, "W12$ob");
  290. CUL_WriteInit($hash);
  291. } elsif($type eq "rAmpl") {
  292. return "a numerical value between 24 and 42 is expected"
  293. if($arg !~ m/^\d+$/ || $arg < 24 || $arg > 42);
  294. my ($v, $w);
  295. for($v = 0; $v < @ampllist; $v++) {
  296. last if($ampllist[$v] > $arg);
  297. }
  298. $v = sprintf("%02d", $v-1);
  299. $w = $ampllist[$v];
  300. Log3 $name, 3, "Setting AGCCTRL2 (1B) to $v / $w dB";
  301. CUL_SimpleWrite($hash, "W1D$v");
  302. CUL_WriteInit($hash);
  303. } elsif($type eq "sens") {
  304. return "a numerical value between 4 and 16 is expected"
  305. if($arg !~ m/^\d+$/ || $arg < 4 || $arg > 16);
  306. my $w = int($arg/4)*4;
  307. my $v = sprintf("9%d",$arg/4-1);
  308. Log3 $name, 3, "Setting AGCCTRL0 (1D) to $v / $w dB";
  309. CUL_SimpleWrite($hash, "W1F$v");
  310. CUL_WriteInit($hash);
  311. } elsif( $type eq "ITClock" ) {
  312. my $clock = shift @a;
  313. $clock=250 if($clock eq "");
  314. return "argument $arg is not numeric" if($clock !~ /^\d+$/);
  315. Log3 $name, 3, "set $name $type $clock";
  316. $arg="ic$clock";
  317. CUL_SimpleWrite($hash, $arg);
  318. } else {
  319. return "Expecting a 0-padded hex number"
  320. if((length($arg)&1) == 1 && $type ne "raw");
  321. Log3 $name, 3, "set $name $type $arg";
  322. $arg = "l$arg" if($type eq "led");
  323. $arg = "x$arg" if($type eq "patable");
  324. CUL_SimpleWrite($hash, $arg);
  325. }
  326. return undef;
  327. }
  328. #####################################
  329. sub
  330. CUL_Get($@)
  331. {
  332. my ($hash, @a) = @_;
  333. my $type = $hash->{TYPE};
  334. return "\"get $type\" needs at least one parameter" if(@a < 2);
  335. if(!defined($gets{$a[1]})) {
  336. my @cList = map { $_ =~ m/^(file|raw)$/ ? $_ : "$_:noArg" } sort keys %gets;
  337. return "Unknown argument $a[1], choose one of " . join(" ", @cList);
  338. }
  339. my $arg = ($a[2] ? $a[2] : "");
  340. my ($msg, $err);
  341. my $name = $a[0];
  342. return "No $a[1] for dummies" if(IsDummy($name));
  343. if($a[1] eq "ccconf") {
  344. my %r = ( "0D"=>1,"0E"=>1,"0F"=>1,"10"=>1,"1B"=>1,"1D"=>1 );
  345. foreach my $a (sort keys %r) {
  346. CUL_SimpleWrite($hash, "C$a");
  347. ($err, $msg) = CUL_ReadAnswer($hash, "C$a", 0, "^C.* = .*");
  348. return $err if($err);
  349. my @answ = split(" ", $msg);
  350. $r{$a} = $answ[4];
  351. }
  352. $msg = sprintf("freq:%.3fMHz bWidth:%dKHz rAmpl:%ddB sens:%ddB",
  353. 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq
  354. 26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw
  355. $ampllist[$r{"1B"}&7],
  356. 4+4*($r{"1D"}&3) #Sens
  357. );
  358. } else {
  359. CUL_SimpleWrite($hash, $gets{$a[1]}[0] . $arg);
  360. ($err, $msg) = CUL_ReadAnswer($hash, $a[1], 0, $gets{$a[1]}[1]);
  361. if(!defined($msg)) {
  362. DevIo_Disconnected($hash);
  363. $msg = "No answer";
  364. } elsif($a[1] eq "cmds") { # nice it up
  365. $msg =~ s/.*Use one of//g;
  366. } elsif($a[1] eq "uptime") { # decode it
  367. $msg =~ s/[\r\n]//g;
  368. $msg = hex($msg)/125;
  369. $msg = sprintf("%d %02d:%02d:%02d",
  370. $msg/86400, ($msg%86400)/3600, ($msg%3600)/60, $msg%60);
  371. } elsif($a[1] eq "credit10ms") {
  372. ($msg) = ($msg =~ /^.. *(\d*)[\r\n]*$/);
  373. }
  374. $msg =~ s/[\r\n]//g;
  375. }
  376. readingsSingleUpdate($hash, $a[1], $msg, 1);
  377. return "$a[0] $a[1] => $msg";
  378. }
  379. sub
  380. CUL_Clear($)
  381. {
  382. my $hash = shift;
  383. # Clear the pipe
  384. $hash->{RA_Timeout} = 0.1;
  385. for(;;) {
  386. my ($err, undef) = CUL_ReadAnswer($hash, "Clear", 0, "wontmatch");
  387. last if($err);
  388. }
  389. delete($hash->{RA_Timeout});
  390. $hash->{PARTIAL} = "";
  391. }
  392. #####################################
  393. sub
  394. CUL_DoInit($)
  395. {
  396. my $hash = shift;
  397. my $name = $hash->{NAME};
  398. my $err;
  399. my $msg = undef;
  400. CUL_Clear($hash);
  401. my ($ver, $try) = ("", 0);
  402. while($try++ < 3 && $ver !~ m/^V/) {
  403. CUL_SimpleWrite($hash, "V");
  404. ($err, $ver) = CUL_ReadAnswer($hash, "Version", 0, "^V");
  405. return "$name: $err" if($err && ($err !~ m/Timeout/ || $try == 3));
  406. $ver = "" if(!$ver);
  407. }
  408. if($ver !~ m/^V/) {
  409. $attr{$name}{dummy} = 1;
  410. $msg = "Not an CUL device, got for V: $ver";
  411. Log3 $name, 1, $msg;
  412. return $msg;
  413. }
  414. $ver =~ s/[\r\n]//g;
  415. $hash->{VERSION} = $ver;
  416. # Cmd-String feststellen
  417. my $cmds = CUL_Get($hash, $name, "cmds", 0);
  418. $cmds =~ s/$name cmds =>//g;
  419. $cmds =~ s/ //g;
  420. $hash->{CMDS} = $cmds;
  421. Log3 $name, 3, "$name: Possible commands: " . $hash->{CMDS};
  422. CUL_WriteInit($hash);
  423. # FHTID
  424. if(defined($hash->{FHTID})) {
  425. my $fhtid;
  426. CUL_SimpleWrite($hash, "T01");
  427. ($err, $fhtid) = CUL_ReadAnswer($hash, "FHTID", 0, undef);
  428. return "$name: $err" if($err);
  429. $fhtid =~ s/[\r\n]//g;
  430. Log3 $name, 5, "GOT CUL fhtid: $fhtid";
  431. if(!defined($fhtid) || $fhtid ne $hash->{FHTID}) {
  432. Log3 $name, 2, "Setting CUL fhtid from $fhtid to " . $hash->{FHTID};
  433. CUL_SimpleWrite($hash, "T01" . $hash->{FHTID});
  434. }
  435. }
  436. my $cc = AttrVal($name, "connectCommand", undef);
  437. CUL_SimpleWrite($hash, $cc) if($cc);
  438. readingsSingleUpdate($hash, "state", "Initialized", 1);
  439. # Reset the counter
  440. delete($hash->{XMIT_TIME});
  441. delete($hash->{NR_CMD_LAST_H});
  442. return undef;
  443. }
  444. #####################################
  445. # This is a direct read for commands like get
  446. # Anydata is used by read file to get the filesize
  447. sub
  448. CUL_ReadAnswer($$$$)
  449. {
  450. my ($hash, $arg, $anydata, $regexp) = @_;
  451. my $ohash = $hash;
  452. while($hash && $hash->{TYPE} !~ m/$culNameRe/) {
  453. $hash = $hash->{IODev};
  454. }
  455. return ("No FD", undef)
  456. if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD})));
  457. my ($mculdata, $rin) = ("", '');
  458. my $buf;
  459. my $to = 3; # 3 seconds timeout
  460. $mculdata = $hash->{PARTIAL} if(defined($hash->{PARTIAL}));
  461. $to = $ohash->{RA_Timeout} if($ohash->{RA_Timeout}); # ...or less
  462. for(;;) {
  463. if($^O =~ m/Win/ && $hash->{USBDev}) {
  464. $hash->{USBDev}->read_const_time($to*1000); # set timeout (ms)
  465. # Read anstatt input sonst funzt read_const_time nicht.
  466. $buf = $hash->{USBDev}->read(999);
  467. return ("Timeout reading answer for get $arg", undef)
  468. if(length($buf) == 0);
  469. } else {
  470. return ("Device lost when reading answer for get $arg", undef)
  471. if(!$hash->{FD});
  472. vec($rin, $hash->{FD}, 1) = 1;
  473. my $nfound = select($rin, undef, undef, $to);
  474. if($nfound < 0) {
  475. next if ($! == EAGAIN() || $! == EINTR() || $! == 0);
  476. my $err = $!;
  477. DevIo_Disconnected($hash);
  478. return("CUL_ReadAnswer $arg: $err", undef);
  479. }
  480. return ("Timeout reading answer for get $arg", undef)
  481. if($nfound == 0);
  482. $buf = DevIo_SimpleRead($hash);
  483. return ("No data", undef) if(!defined($buf));
  484. }
  485. if(defined($buf)) {
  486. Log3 $ohash->{NAME}, 5, "CUL/RAW (ReadAnswer): $buf";
  487. $mculdata .= $buf;
  488. }
  489. # Dispatch data in the buffer before the proper answer.
  490. while(($mculdata =~ m/^([^\n]*\n)(.*)/s) || $anydata) {
  491. my $line = ($anydata ? $mculdata : $1);
  492. $mculdata = $2;
  493. $hash->{PARTIAL} = $mculdata; # for recursive calls
  494. (undef, $line) = CUL_prefix(0, $ohash, $line); # Delete prefix
  495. if($regexp && $line !~ m/$regexp/) {
  496. $line =~ s/[\n\r]+//g;
  497. CUL_Parse($ohash, $hash, $ohash->{NAME}, $line) if($init_done);
  498. $mculdata = $hash->{PARTIAL};
  499. } else {
  500. return (undef, $line);
  501. }
  502. }
  503. }
  504. }
  505. #####################################
  506. # Check if the 1% limit is reached and trigger notifies
  507. sub
  508. CUL_XmitLimitCheck($$$)
  509. {
  510. my ($hash,$fn,$now) = @_;
  511. if(!$hash->{XMIT_TIME}) {
  512. $hash->{XMIT_TIME}[0] = $now;
  513. $hash->{NR_CMD_LAST_H} = 1;
  514. return;
  515. }
  516. my $nowM1h = $now-3600;
  517. my @b = grep { $_ > $nowM1h } @{$hash->{XMIT_TIME}};
  518. # Maximum nr of transmissions per hour, but not for HM and MAX
  519. if(@b > 163 && $fn !~ m/^[AZ]/) {
  520. my $name = $hash->{NAME};
  521. Log3 $name, 2, "CUL TRANSMIT LIMIT EXCEEDED";
  522. DoTrigger($name, "TRANSMIT LIMIT EXCEEDED");
  523. } else {
  524. push(@b, $now);
  525. }
  526. $hash->{XMIT_TIME} = \@b;
  527. $hash->{NR_CMD_LAST_H} = int(@b);
  528. }
  529. sub
  530. CUL_XmitDlyHM($$$)
  531. {
  532. my ($hash,$fn,$now) = @_;
  533. my (undef,$mTy,undef,$id) = unpack 'A8A2A6A6',$fn if(length($fn)>19);
  534. if($id &&
  535. $modules{CUL_HM}{defptr}{$id} &&
  536. $modules{CUL_HM}{defptr}{$id}{helper}{io} &&
  537. $modules{CUL_HM}{defptr}{$id}{helper}{io}{nextSend}) {
  538. my $dDly = $modules{CUL_HM}{defptr}{$id}{helper}{io}{nextSend} - $now;
  539. #$dDly -= 0.04 if ($mTy eq "02");# while HM devices need a rest there are
  540. # still some devices that need faster
  541. # reactionfor ack.
  542. # Mode needs to be determined
  543. if ($dDly > 0.01){# wait less then 10 ms will not work
  544. $dDly = 0.1 if($dDly > 0.1);
  545. Log3 $hash->{NAME}, 5, "CUL $id dly:".int($dDly*1000)."ms";
  546. select(undef, undef, undef, $dDly);
  547. }
  548. }
  549. shift(@{$hash->{helper}{$id}{QUEUE}});
  550. InternalTimer($now+0.1, "CUL_XmitDlyHMTo", "$hash->{NAME}:$id", 1)
  551. if (scalar(@{$hash->{helper}{$id}{QUEUE}}));
  552. return 0;
  553. }
  554. sub
  555. CUL_XmitDlyHMTo($)
  556. { # waited long enough - next send for this ID
  557. my ($name,$id) = split(":",$_[0]);
  558. CUL_SendFromQueue($defs{$name}, ${$defs{$name}{helper}{$id}{QUEUE}}[0]);
  559. }
  560. #####################################
  561. # Translate data prepared for an FHZ to CUL syntax, so we can reuse
  562. # the FS20 and FHZ modules.
  563. sub
  564. CUL_WriteTranslate($$$)
  565. {
  566. my ($hash,$fn,$msg) = @_;
  567. ###################
  568. # Rewrite message from FHZ -> CUL
  569. if(length($fn) <= 1) { # CUL Native
  570. ;
  571. } elsif($fn eq "04" && substr($msg,0,6) eq "010101") { # FS20
  572. $fn = "F";
  573. AddDuplicate($hash->{NAME},
  574. "0101a001" . substr($msg, 6, 6) . "00" . substr($msg, 12));
  575. $msg = substr($msg,6);
  576. } elsif($fn eq "04" && substr($msg,0,6) eq "020183") { # FHT
  577. $fn = "T";
  578. $msg = substr($msg,6,4) . substr($msg,10);
  579. } elsif($fn eq "cmd") { # internal command
  580. if($msg eq "speed100") {
  581. $fn = "AR";
  582. } elsif($msg eq "speed10") {
  583. $fn = "Ar";
  584. } else { # by default rewrite init
  585. $fn = $hash->{initString};
  586. }
  587. $msg = "";
  588. } else {
  589. Log3 $hash, 2, "CUL cannot translate $fn $msg";
  590. return (undef, undef);
  591. }
  592. return ($fn, $msg);
  593. }
  594. #####################################
  595. sub
  596. CUL_Write($$$)
  597. {
  598. my ($hash,$fn,$msg) = @_;
  599. ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg);
  600. return if(!defined($fn));
  601. my $name = $hash->{NAME};
  602. Log3 $name, 5, "$hash->{NAME} sending $fn$msg";
  603. my $bstring = "$fn$msg";
  604. if($fn eq "F" || # FS20 message
  605. $bstring =~ m/^u....F/ || # FS20 messages sent over an RFR
  606. ($fn eq "" && ($bstring =~ m/^A/ || $bstring =~ m/^Z/ ))) { # AskSin/BidCos/HomeMatic/MAX
  607. CUL_AddSendQueue($hash, $bstring);
  608. } else {
  609. CUL_SimpleWrite($hash, $bstring);
  610. }
  611. }
  612. sub
  613. CUL_SendFromQueue($$)
  614. {
  615. my ($hash, $bstring) = @_;
  616. my $name = $hash->{NAME};
  617. my $hm = ($bstring =~ m/^A/);
  618. my $to = ($hm ? 0.15 : 0.3);
  619. my $now = gettimeofday();
  620. if($bstring ne "") {
  621. my $sp = AttrVal($name, "sendpool", undef);
  622. if($sp) { # Is one of the CUL-fellows sending data?
  623. my @fellows = split(",", $sp);
  624. foreach my $f (@fellows) {
  625. if($f ne $name &&
  626. $defs{$f} &&
  627. $defs{$f}{QUEUE} &&
  628. $defs{$f}{QUEUE}->[0] ne ""){
  629. unshift(@{$hash->{QUEUE}}, "");
  630. InternalTimer($now+$to, "CUL_HandleWriteQueue", $hash, 1);
  631. return;
  632. }
  633. }
  634. }
  635. CUL_XmitLimitCheck($hash, $bstring, $now);
  636. if($hm) {
  637. CUL_SimpleWrite($hash, $bstring) if(!CUL_XmitDlyHM($hash,$bstring,$now));
  638. return;
  639. } else {
  640. CUL_SimpleWrite($hash, $bstring);
  641. }
  642. }
  643. ##############
  644. # Write the next buffer not earlier than 0.23 seconds
  645. # = 3* (12*0.8+1.2+1.0*5*9+0.8+10) = 226.8ms
  646. # else it will be sent too early by the CUL, resulting in a collision
  647. InternalTimer($now+$to, "CUL_HandleWriteQueue", $hash, 1);
  648. }
  649. sub
  650. CUL_AddSendQueue($$)
  651. {
  652. my ($hash, $bstring) = @_;
  653. my $qHash = $hash;
  654. if ($bstring =~ m/^A/){ # HM device
  655. my $id = substr($bstring,16,6);#get HMID destination
  656. $qHash = $hash->{helper}{$id};
  657. }
  658. if(!$qHash->{QUEUE} || 0 == scalar(@{$qHash->{QUEUE}})) {
  659. $qHash->{QUEUE} = [ $bstring ];
  660. CUL_SendFromQueue($hash, $bstring);
  661. } else {
  662. push(@{$qHash->{QUEUE}}, $bstring);
  663. }
  664. }
  665. #####################################
  666. sub
  667. CUL_HandleWriteQueue($)
  668. {
  669. my $hash = shift;
  670. my $arr = $hash->{QUEUE};
  671. if(defined($arr) && @{$arr} > 0) {
  672. shift(@{$arr});
  673. if(@{$arr} == 0) {
  674. delete($hash->{QUEUE});
  675. return;
  676. }
  677. my $bstring = $arr->[0];
  678. if($bstring eq "") {
  679. CUL_HandleWriteQueue($hash);
  680. } else {
  681. CUL_SendFromQueue($hash, $bstring);
  682. }
  683. }
  684. }
  685. #####################################
  686. # called from the global loop, when the select for hash->{FD} reports data
  687. sub
  688. CUL_Read($)
  689. {
  690. my ($hash) = @_;
  691. my $buf = DevIo_SimpleRead($hash);
  692. return "" if(!defined($buf));
  693. my $name = $hash->{NAME};
  694. my $culdata = $hash->{PARTIAL};
  695. Log3 $name, 5, "CUL/RAW: $culdata/$buf";
  696. $culdata .= $buf;
  697. while($culdata =~ m/\n/) {
  698. my $rmsg;
  699. ($rmsg,$culdata) = split("\n", $culdata, 2);
  700. $rmsg =~ s/\r//;
  701. $hash->{PARTIAL} = $culdata; # for recursive calls
  702. CUL_Parse($hash, $hash, $name, $rmsg) if($rmsg);
  703. $culdata = $hash->{PARTIAL};
  704. }
  705. $hash->{PARTIAL} = $culdata;
  706. }
  707. sub
  708. CUL_Parse($$$$@)
  709. {
  710. my ($hash, $iohash, $name, $rmsg, $initstr) = @_;
  711. if($rmsg =~ m/^\*/) { # STACKABLE_CC
  712. Dispatch($hash, $rmsg, undef);
  713. return;
  714. }
  715. if($rmsg =~ m/^V/) { # CUN* keepalive
  716. Log3 $name, 4, "CUL_Parse: $name $rmsg";
  717. return;
  718. }
  719. my $rssi;
  720. my $dmsg = $rmsg;
  721. my $dmsgLog = (AttrVal($name,"rfmode","") eq "HomeMatic")
  722. ? join(" ",(unpack'A1A2A2A4A6A6A*',$rmsg))
  723. :$dmsg;
  724. if($dmsg =~ m/^[AFTKEHRStZrib]([A-F0-9][A-F0-9])+$/) { # RSSI
  725. my $l = length($dmsg);
  726. $rssi = hex(substr($dmsg, $l-2, 2));
  727. $dmsg = substr($dmsg, 0, $l-2);
  728. $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74));
  729. Log3 $name, 4, "CUL_Parse: $name $dmsgLog $rssi";
  730. } else {
  731. Log3 $name, 4, "CUL_Parse: $name $dmsgLog";
  732. }
  733. ###########################################
  734. #Translate Message from CUL to FHZ
  735. next if(!$dmsg || length($dmsg) < 1); # Bogus messages
  736. if ($dmsg eq 'SMODE' || $dmsg eq 'TMODE') { # brs/brt returns SMODE/TMODE
  737. Log3 $name, 5, "CUL_Parse: switched to $dmsg";
  738. return;
  739. }
  740. if($dmsg =~ m/^[0-9A-F]{4}U./) { # RF_ROUTER
  741. Dispatch($hash, $dmsg, undef);
  742. return;
  743. }
  744. my $fn = substr($dmsg,0,1);
  745. my $len = length($dmsg);
  746. if($fn eq "F" && $len >= 9) { # Reformat for 10_FS20.pm
  747. CUL_AddSendQueue($iohash, ""); # Delay immediate replies
  748. $dmsg = sprintf("81%02x04xx0101a001%s00%s",
  749. $len/2+7, substr($dmsg,1,6), substr($dmsg,7));
  750. $dmsg = lc($dmsg);
  751. } elsif($fn eq "T") {
  752. if ($len >= 11) { # Reformat for 11_FHT.pm
  753. $dmsg = sprintf("81%02x04xx0909a001%s00%s",
  754. $len/2+7, substr($dmsg,1,6), substr($dmsg,7));
  755. $dmsg = lc($dmsg);
  756. } else {
  757. ; # => 09_CUL_FHTTK.pm
  758. }
  759. } elsif($fn eq "H" && $len >= 13) { # Reformat for 12_HMS.pm
  760. my $type = hex(substr($dmsg,6,1));
  761. my $stat = $type > 1 ? hex(substr($dmsg,7,2)) : hex(substr($dmsg,5,2));
  762. my $prf = $type > 1 ? "02" : "05";
  763. my $bat = $type > 1 ? hex(substr($dmsg,5,1))+1 : 1;
  764. my $HA = substr($dmsg,1,4);
  765. my $values = $type > 1 ? "000000" : substr($dmsg,7);
  766. $dmsg = sprintf("81%02x04xx%s%x%xa001%s0000%02x%s",
  767. $len/2+8, # Packet-Length
  768. $prf, $bat, $type,
  769. $HA, # House-Code
  770. $stat,
  771. $values); # Values
  772. $dmsg = lc($dmsg);
  773. } elsif($fn eq "K" && $len >= 5) {
  774. if($len == 15) { # Reformat for 13_KS300.pm
  775. my @a = split("", $dmsg);
  776. $dmsg = sprintf("81%02x04xx4027a001", $len/2+6);
  777. for(my $i = 1; $i < 14; $i+=2) { # Swap nibbles.
  778. $dmsg .= $a[$i+1] . $a[$i];
  779. }
  780. $dmsg = lc($dmsg);
  781. }
  782. # Other K... Messages ar sent to CUL_WS
  783. } elsif($fn eq "r" && $len >= 23) { # Revolt
  784. $dmsg = lc($dmsg);
  785. } elsif($fn eq "i" && $len >= 7) { # IT
  786. $dmsg = lc($dmsg);
  787. } elsif($fn eq "Y" && $len >= 3) { # SOMFY RTS
  788. ;
  789. } elsif($fn eq "S" && $len >= 33) { # CUL_ESA / ESA2000 / Native
  790. ;
  791. } elsif($fn eq "E" && $len >= 11) { # CUL_EM / Native
  792. ;
  793. } elsif($fn eq "R" && $len >= 11) { # CUL_HOERMANN / Native
  794. ;
  795. } elsif($fn eq "I" && $len >= 12) { # IR-CUL/CUN/CUNO
  796. ;
  797. } elsif($fn eq "A" && $len >= 20) { # AskSin/BidCos/HomeMatic
  798. my $src = substr($dmsg,9,6);
  799. if($modules{CUL_HM}{defptr}{$src}){
  800. $modules{CUL_HM}{defptr}{$src}{helper}{io}{nextSend} =
  801. gettimeofday() + 0.100;
  802. }
  803. $dmsg .= "::$rssi:$name" if(defined($rssi));
  804. } elsif($fn eq "Z" && $len >= 21) { # Moritz/Max
  805. ;
  806. } elsif($fn eq "b" && $len >= 24) { # Wireless M-Bus
  807. $dmsg .= "::$rssi" if (defined($rssi));
  808. } elsif($fn eq "t" && $len >= 5) { # TX3
  809. $dmsg = "TX".substr($dmsg,1); # t.* is occupied by FHTTK
  810. } elsif($fn eq "s" && $len >= 5) { # CUL_TCM97001
  811. ;
  812. } elsif($fn eq "o" && $len >= 5) { # CUL_REDIRECT
  813. ;
  814. } elsif($fn eq "k" && $len >= 20) { # KOPP_FC
  815. ;
  816. } else {
  817. DoTrigger($name, "UNKNOWNCODE $dmsg");
  818. Log3 $name, 2, "$name: unknown message $dmsg";
  819. return;
  820. }
  821. $hash->{"${name}_MSGCNT"}++;
  822. $hash->{"${name}_TIME"} = TimeNow();
  823. # showtime attribute
  824. readingsSingleUpdate($hash, "state", $hash->{READINGS}{state}{VAL}, 0);
  825. $hash->{RAWMSG} = $rmsg;
  826. my %addvals = (RAWMSG => $dmsg);
  827. if(defined($rssi)) {
  828. $hash->{RSSI} = $rssi;
  829. $addvals{RSSI} = $rssi;
  830. }
  831. Dispatch($hash, $dmsg, \%addvals);
  832. }
  833. #####################################
  834. sub
  835. CUL_Ready($)
  836. {
  837. my ($hash) = @_;
  838. return DevIo_OpenDev($hash, 1, "CUL_DoInit")
  839. if($hash->{STATE} eq "disconnected");
  840. # This is relevant for windows/USB only
  841. my $po = $hash->{USBDev};
  842. my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags);
  843. if($po) {
  844. ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
  845. }
  846. return ($InBytes && $InBytes>0);
  847. }
  848. ########################
  849. # Needed for STACKABLE_CC
  850. sub
  851. CUL_WriteInit($)
  852. {
  853. my ($hash) = @_;
  854. foreach my $is (split("\n", $hash->{initString})) {
  855. CUL_SimpleWrite($hash, $is);
  856. }
  857. }
  858. sub
  859. CUL_SimpleWrite(@)
  860. {
  861. my ($hash, $msg, $nonl) = @_;
  862. return if(!$hash);
  863. ($hash, $msg) = CUL_prefix(1, $hash, $msg);
  864. my $name = $hash->{NAME};
  865. if (AttrVal($name,"rfmode","") eq "HomeMatic"){
  866. Log3 $name, 4, "CUL_send: $name".join(" ",unpack('A2A2A2A4A6A6A*',$msg));
  867. }
  868. else{
  869. Log3 $name, 5, "SW: $msg";
  870. }
  871. $msg .= "\n" unless($nonl);
  872. $hash->{USBDev}->write($msg) if($hash->{USBDev});
  873. syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev});
  874. syswrite($hash->{DIODev}, $msg) if($hash->{DIODev});
  875. # Some linux installations are broken with 0.001, T01 returns no answer
  876. select(undef, undef, undef, 0.01);
  877. }
  878. sub
  879. CUL_Attr(@)
  880. {
  881. my ($cmd,$name,$aName,$aVal) = @_;
  882. my $hash = $defs{$name};
  883. if($aName eq "rfmode") {
  884. $aVal = "SlowRF" if(!$aVal ||
  885. ($aVal ne "HomeMatic"
  886. && $aVal ne "MAX"
  887. && $aVal ne "WMBus_T"
  888. && $aVal ne "WMBus_S"
  889. && $aVal ne "KOPP_FC"));
  890. my $msg = $hash->{NAME} . ": Mode $aVal not supported";
  891. if($aVal eq "HomeMatic") {
  892. return if($hash->{initString} =~ m/Ar/);
  893. if($hash->{CMDS} =~ m/A/ || IsDummy($hash->{NAME}) || !$hash->{FD}) {
  894. $hash->{Clients} = $clientsHomeMatic;
  895. $hash->{MatchList} = \%matchListHomeMatic;
  896. CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz
  897. $hash->{initString} = "X21\nAr"; # X21 is needed for RSSI reporting
  898. CUL_WriteInit($hash);
  899. } else {
  900. Log3 $name, 2, $msg;
  901. return $msg;
  902. }
  903. } elsif($aVal eq "MAX") {
  904. return if($hash->{initString} =~ m/Zr/);
  905. if($hash->{CMDS} =~ m/Z/ || IsDummy($hash->{NAME}) || !$hash->{FD}) {
  906. $hash->{Clients} = $clientsMAX;
  907. $hash->{MatchList} = \%matchListMAX;
  908. CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin
  909. $hash->{initString} = "X21\nZr"; # X21 is needed for RSSI reporting
  910. CUL_WriteInit($hash);
  911. } else {
  912. Log3 $name, 2, $msg;
  913. return $msg;
  914. }
  915. } elsif($aVal eq "WMBus_S") {
  916. return if($hash->{initString} =~ m/brs/);
  917. if($hash->{CMDS} =~ m/b/ || IsDummy($hash->{NAME}) || !$hash->{FD}) {
  918. $hash->{Clients} = $clientsWMBus;
  919. $hash->{MatchList} = \%matchListWMBus;
  920. $hash->{initString} = "X21\nbrs"; # Use S-Mode
  921. CUL_WriteInit($hash);
  922. } else {
  923. Log3 $name, 2, $msg;
  924. return $msg;
  925. }
  926. } elsif($aVal eq "WMBus_T") {
  927. return if($hash->{initString} =~ m/brt/);
  928. if($hash->{CMDS} =~ m/b/ || IsDummy($hash->{NAME}) || !$hash->{FD}) {
  929. $hash->{Clients} = $clientsWMBus;
  930. $hash->{MatchList} = \%matchListWMBus;
  931. $hash->{initString} = "X21\nbrt"; # Use T-Mode
  932. CUL_WriteInit($hash);
  933. } else {
  934. Log3 $name, 2, $msg;
  935. return $msg;
  936. }
  937. } elsif($aVal eq "KOPP_FC") {
  938. if($hash->{CMDS} =~ m/k/ || IsDummy($hash->{NAME}) || !$hash->{FD}) {
  939. $hash->{Clients} = $clientsKOPP_FC;
  940. $hash->{MatchList} = \%matchListKOPP_FC;
  941. $hash->{initString} = "krS"; # krS: start Kopp receive Mode
  942. CUL_WriteInit($hash);
  943. } else {
  944. Log3 $name, 2, $msg;
  945. return $msg;
  946. }
  947. } else {
  948. return if($hash->{initString} eq "X21");
  949. $hash->{Clients} = $clientsSlowRF;
  950. $hash->{MatchList} = \%matchListSlowRF;
  951. $hash->{initString} = "X21";
  952. CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin
  953. CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz
  954. CUL_SimpleWrite($hash, "brx") if ($hash->{CMDS} =~ m/b/); # reset WMBus
  955. CUL_WriteInit($hash);
  956. }
  957. Log3 $name, 2, "Switched $name rfmode to $aVal";
  958. delete $hash->{".clientArray"};
  959. } elsif($aName eq "hmId"){
  960. if($cmd eq "set") {
  961. return "wrong syntax: hmId must be 6-digit-hex-code (3 byte)"
  962. if($aVal !~ m/^[A-F0-9]{6}$/i);
  963. }
  964. } elsif($aName eq "connectCommand"){
  965. CUL_SimpleWrite($hash, $aVal) if($cmd eq "set");
  966. }
  967. return undef;
  968. }
  969. sub
  970. CUL_prefix($$$)
  971. {
  972. my ($isadd, $hash, $msg) = @_;
  973. while($hash && $hash->{TYPE} !~ m/$culNameRe/) {
  974. $msg = CallFn($hash->{NAME}, $isadd ? "AddPrefix":"DelPrefix", $hash, $msg);
  975. $hash = $hash->{IODev};
  976. last if(!$hash);
  977. }
  978. return ($hash, $msg);
  979. }
  980. 1;
  981. =pod
  982. =item summary connect devices with the culfw Firmware, e.g. Busware CUL
  983. =item summary_DE Anbindung von Geraeten mit dem culfw Firmware, z.Bsp. Busware CUL
  984. =begin html
  985. <a name="CUL"></a>
  986. <h3>CUL</h3>
  987. <ul>
  988. <table>
  989. <tr><td>
  990. The CUL/CUN(O) is a family of RF devices sold by <a
  991. href="http://www.busware.de">busware.de</a>.
  992. With the opensource firmware
  993. <a href="http://culfw.de/culfw.html">culfw</a> they are capable
  994. to receive and send different 433/868 MHz protocols (FS20/FHT/S300/EM/HMS/MAX!).
  995. It is even possible to use these devices as range extenders/routers, see the
  996. <a href="#CUL_RFR">CUL_RFR</a> module for details.
  997. <br> <br>
  998. Some protocols (FS20, FHT and KS300) are converted by this module so that
  999. the same logical device can be used, irrespective if the radio telegram is
  1000. received by a CUL or an FHZ device.<br>
  1001. Other protocols (S300/EM) need their
  1002. own modules. E.g. S300 devices are processed by the CUL_WS module if the
  1003. signals are received by the CUL, similarly EMWZ/EMGZ/EMEM is handled by the
  1004. CUL_EM module.<br><br>
  1005. It is possible to attach more than one device in order to get better
  1006. reception, FHEM will filter out duplicate messages.<br><br>
  1007. Note: This module may require the <code>Device::SerialPort</code> or
  1008. <code>Win32::SerialPort</code> module if you attach the device via USB
  1009. and the OS sets strange default parameters for serial devices.<br><br>
  1010. </td><td>
  1011. <img src="ccc.jpg"/>
  1012. </td></tr>
  1013. </table>
  1014. <a name="CULdefine"></a>
  1015. <b>Define</b>
  1016. <ul>
  1017. <code>define &lt;name&gt; CUL &lt;device&gt; &lt;FHTID&gt;</code> <br>
  1018. <br>
  1019. USB-connected devices (CUL/CUN):<br><ul>
  1020. &lt;device&gt; specifies the serial port to communicate with the CUL.
  1021. The name of the serial-device depends on your distribution, under
  1022. linux the cdc_acm kernel module is responsible, and usually a
  1023. /dev/ttyACM0 device will be created. If your distribution does not have a
  1024. cdc_acm module, you can force usbserial to handle the CUL by the
  1025. following command:
  1026. <ul><code>
  1027. modprobe usbserial vendor=0x03eb product=0x204b
  1028. </code></ul>
  1029. In this case the device is most probably /dev/ttyUSB0.<br><br>
  1030. You can also specify a baudrate if the device name contains the @
  1031. character, e.g.: /dev/ttyACM0@38400<br><br>
  1032. If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the
  1033. perl module <code>Device::SerialPort</code> is not needed, and FHEM
  1034. opens the device with simple file io. This might work if the operating
  1035. system uses sane defaults for the serial parameters, e.g. some Linux
  1036. distributions and OSX.<br><br>
  1037. </ul>
  1038. Network-connected devices (CUN(O)):<br><ul>
  1039. &lt;device&gt; specifies the host:port of the device, e.g.
  1040. 192.168.0.244:2323
  1041. </ul>
  1042. <br>
  1043. If the device is called none, then no device will be opened, so you
  1044. can experiment without hardware attached.<br>
  1045. The FHTID is a 4 digit hex number, and it is used when the CUL talks to
  1046. FHT devices or when CUL requests data. Set it to 0000 to avoid answering
  1047. any FHT80b request by the CUL.
  1048. </ul>
  1049. <br>
  1050. <a name="CULset"></a>
  1051. <b>Set </b>
  1052. <ul>
  1053. <li>reopen<br>
  1054. Reopens the connection to the device and reinitializes it.
  1055. </li><br>
  1056. <li>raw<br>
  1057. Issue a CUL firmware command. See the <a
  1058. href="http://culfw.de/commandref.html">this</a> document
  1059. for details on CUL commands.
  1060. </li><br>
  1061. <li>freq / bWidth / rAmpl / sens<br>
  1062. <a href="#rfmode">SlowRF</a> mode only.<br>
  1063. Set the CUL frequency / bandwidth / receiver-amplitude / sensitivity<br>
  1064. Use it with care, it may destroy your hardware and it even may be
  1065. illegal to do so. Note: The parameters used for RFR transmission are
  1066. not affected.<br>
  1067. <ul>
  1068. <li>freq sets both the reception and transmission frequency. Note:
  1069. Although the CC1101 can be set to frequencies between 315 and 915
  1070. MHz, the antenna interface and the antenna of the CUL is tuned for
  1071. exactly one frequency. Default is 868.3 MHz (or 433 MHz)</li>
  1072. <li>bWidth can be set to values between 58 kHz and 812 kHz. Large values
  1073. are susceptible to interference, but make possible to receive
  1074. inaccurately calibrated transmitters. It affects tranmission too.
  1075. Default is 325 kHz.</li>
  1076. <li>rAmpl is receiver amplification, with values between 24 and 42 dB.
  1077. Bigger values allow reception of weak signals. Default is 42.
  1078. </li>
  1079. <li>sens is the decision boundary between the on and off values, and it
  1080. is 4, 8, 12 or 16 dB. Smaller values allow reception of less clear
  1081. signals. Default is 4 dB.</li>
  1082. </ul>
  1083. </li><br>
  1084. <a name="hmPairForSec"></a>
  1085. <li>hmPairForSec<br>
  1086. <a href="#rfmode">HomeMatic</a> mode only.<br>
  1087. Set the CUL in Pairing-Mode for the given seconds. Any HM device set into
  1088. pairing mode in this time will be paired with FHEM.
  1089. </li><br>
  1090. <a name="hmPairSerial"></a>
  1091. <li>hmPairSerial<br>
  1092. <a href="#rfmode">HomeMatic</a> mode only.<br>
  1093. Try to pair with the given device. The argument is a 10 character
  1094. string, usually starting with letters and ending with digits, printed on
  1095. the backside of the device. It is not necessary to put the given device
  1096. in learning mode if it is a receiver.
  1097. </li><br>
  1098. <a name="hmPairForSec"></a>
  1099. <li>led<br>
  1100. Set the CUL led off (00), on (01) or blinking (02).
  1101. </li><br>
  1102. <li>ITClock</br>
  1103. Set the IT clock for Intertechno V1 protocol. Default 250.
  1104. </li><br>
  1105. </ul>
  1106. <a name="CULget"></a>
  1107. <b>Get</b>
  1108. <ul>
  1109. <li>version<br>
  1110. returns the CUL firmware version
  1111. </li><br>
  1112. <li>uptime<br>
  1113. returns the CUL uptime (time since CUL reset)
  1114. </li><br>
  1115. <li>raw<br>
  1116. Issues a CUL firmware command, and waits for one line of data returned by
  1117. the CUL. See the CUL firmware README document for details on CUL
  1118. commands.
  1119. </li><br>
  1120. <li>fhtbuf<br>
  1121. CUL has a message buffer for the FHT. If the buffer is full, then newly
  1122. issued commands will be dropped, and an "EOB" message is issued to the
  1123. FHEM log.
  1124. <code>fhtbuf</code> returns the free memory in this buffer (in hex),
  1125. an empty buffer in the CUL V2 is 74 bytes, in CUL V3/CUN(O) 200 Bytes.
  1126. A message occupies 3 + 2x(number of FHT commands) bytes,
  1127. this is the second reason why sending multiple FHT commands with one
  1128. <a href="#set">set</a> is a good idea. The first reason is, that
  1129. these FHT commands are sent at once to the FHT.
  1130. </li> <br>
  1131. <li>ccconf<br>
  1132. Read some CUL radio-chip (cc1101) registers (frequency, bandwidth, etc.),
  1133. and display them in human readable form.
  1134. </li><br>
  1135. <li>cmds<br>
  1136. Depending on the firmware installed, CULs have a different set of
  1137. possible commands. Please refer to the README of the firmware of your
  1138. CUL to interpret the response of this command. See also the raw command.
  1139. </li><br>
  1140. <li>credit10ms<br>
  1141. One may send for a duration of credit10ms*10 ms before the send limit
  1142. is reached and a LOVF is generated.
  1143. </li><br>
  1144. </ul>
  1145. <a name="CULattr"></a>
  1146. <b>Attributes</b>
  1147. <ul>
  1148. <li><a name="addvaltrigger">addvaltrigger</a><br>
  1149. Create triggers for additional device values. Right now these are RSSI
  1150. and RAWMSG for the CUL family and RAWMSG for the FHZ.
  1151. </li><br>
  1152. <li><a name="connectCommand">connectCommand</a><br>
  1153. raw culfw command sent to the CUL after a (re-)connect of the USB device,
  1154. and sending the usual initialization needed for the configured rfmode.
  1155. </li>
  1156. <li><a href="#do_not_notify">do_not_notify</a></li>
  1157. <li><a href="#attrdummy">dummy</a></li>
  1158. <li><a name="hmId">hmId</a><br>
  1159. Set the HomeMatic ID of this device. If this attribute is absent, the
  1160. ID will be F1&lt;FHTID&gt;. Note 1: After setting or changing this
  1161. attribute you have to relearn all your HomeMatic devices. Note 2: The
  1162. value <b>must</b> be a 6 digit hex number, and 000000 is not valid. FHEM
  1163. won't complain if it is not correct, but the communication won't work.
  1164. </li><br>
  1165. <li><a name="hmProtocolEvents">hmProtocolEvents</a><br>
  1166. Generate events for HomeMatic protocol messages. These are normally
  1167. used for debugging, by activating "inform timer" in a telnet session,
  1168. or looking at the Event Monitor window in the FHEMWEB frontend.<br>
  1169. Example:
  1170. <ul>
  1171. <code>
  1172. 2012-05-17 09:44:22.515 CUL CULHM RCV L:0B N:81 CMD:A258 SRC:......
  1173. DST:...... 0000 (TYPE=88,WAKEMEUP,BIDI,RPTEN)
  1174. </code>
  1175. </ul>
  1176. </li><br>
  1177. <li><a name="longids">longids</a><br>
  1178. Comma separated list of device-types for CUL that should be handled
  1179. using long IDs. This additional ID allows it to differentiate some
  1180. weather sensors, if they are sending on the same channel.
  1181. Therefore a random generated id is added. If you choose to use longids,
  1182. then you'll have to define a different device after battery change.
  1183. Default is not to use long IDs.<br>
  1184. Modules which are using this functionality are for e.g. :
  1185. 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.<br>
  1186. Examples:<br>
  1187. <ul><code>
  1188. # Do not use any long IDs for any devices (this is default):<br>
  1189. attr cul longids 0<br>
  1190. # Use long IDs for all devices:<br>
  1191. attr cul longids 1<br>
  1192. # Use longids for SD_WS07 devices.<br>
  1193. # Will generate devices names like SD_WS07_TH_3 for channel 3.<br>
  1194. attr cul longids SD_WS07
  1195. </code></ul>
  1196. </li><br>
  1197. <li><a href="#model">model</a> (CUL,CUN,etc)</li>
  1198. <li><a name="sendpool">sendpool</a><br>
  1199. If using more than one CUL for covering a large area, sending
  1200. different events by the different CUL's might disturb each other. This
  1201. phenomenon is also known as the Palm-Beach-Resort effect.
  1202. Putting them in a common sendpool will serialize sending the events.
  1203. E.g. if you have three CUN's, you have to specify following
  1204. attributes:<br>
  1205. <code>attr CUN1 sendpool CUN1,CUN2,CUN3<br>
  1206. attr CUN2 sendpool CUN1,CUN2,CUN3<br>
  1207. attr CUN3 sendpool CUN1,CUN2,CUN3</code><br>
  1208. </li><br>
  1209. <li><a name="rfmode">rfmode</a><br>
  1210. Configure the RF Transceiver of the CUL (the CC1101). Available
  1211. arguments are:
  1212. <ul>
  1213. <li>SlowRF<br>
  1214. To communicate with FS20/FHT/HMS/EM1010/S300/Hoermann devices @1 kHz
  1215. datarate. This is the default.</li>
  1216. <li>HomeMatic<br>
  1217. To communicate with HomeMatic type of devices @10 kHz datarate.</li>
  1218. <li>MAX<br>
  1219. To communicate with MAX! type of devices @10 kHz datarate.</li>
  1220. <li>WMBus_S</li>
  1221. <li>WMBus_T<br>
  1222. To communicate with Wireless M-Bus devices like water, gas or
  1223. electrical meters. Wireless M-Bus uses two different communication
  1224. modes, S-Mode and T-Mode. While in this mode, no reception of other
  1225. protocols like SlowRF or HomeMatic is possible. See also the WMBUS
  1226. FHEM Module.
  1227. </li>
  1228. </ul>
  1229. </li><br>
  1230. <li><a href="#showtime">showtime</a></li>
  1231. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  1232. </ul>
  1233. <br>
  1234. </ul>
  1235. =end html
  1236. =begin html_DE
  1237. <a name="CUL"></a>
  1238. <h3>CUL</h3>
  1239. <ul>
  1240. <table>
  1241. <tr><td>
  1242. Der CUL/CUN(O) ist eine Familie von Funkempf&auml;ngern, die von der Firma
  1243. <a href="http://www.busware.de">Busware</a> verkauft wird.
  1244. Mit der OpenSource Firmware
  1245. <a href="http://culfw.de/culfw.html">culfw</a> k&ouml;nnen sie verschiedene
  1246. 868 MHz Funkprotokolle empfangen bzw. senden (FS20/FHT/S300/EM/HMS/MAX!).
  1247. Man kann diese Ger&auml;te auch zur Reichweitenverl&auml;ngerung, siehe
  1248. <a href="#CUL_RFR">CUL_RFR</a> einsetzen.
  1249. <br> <br>
  1250. Einige Protokolle (FS20, FHT und KS300) werden von diesem Modul in das FHZ
  1251. Format konvertiert, daher kann dasselbe logische Ger&auml;t verwendet werden,
  1252. egal ob das Funktelegramm von einem CUL oder einem FHZ Ger&auml;t empfangen
  1253. wird.<br>
  1254. Andere Protokolle (S300/EM) ben&ouml;tigen ihre eigenen Module. S300
  1255. Ger&auml;te werden vom Modul CUL_WS verarbeitet, wenn das Signal von einem
  1256. CUL empfangen wurde, &auml;hnliches gilt f&uuml;r EMWZ/EMGZ/EMEM: diese
  1257. werden vom CUL_EM Modul verarbeitet.<br><br>
  1258. Es ist m&ouml;glich mehr als ein Ger&auml;t zu verwenden, um einen besseren
  1259. Empfang zu erhalten, FHEM filtert doppelte Funktelegramme aus.<br><br>
  1260. Bemerkung: Dieses Modul ben&ouml;tigt unter Umst&auml;nden das
  1261. <code>Device::SerialPort</code> bzw. <code>Win32::SerialPort</code> Modul,
  1262. wenn Sie das Ger&auml;t &uuml;ber USB anschlie&szlig;en und das
  1263. Betriebssystem un&uuml;bliche Parameter f&uuml;r serielle Schnittstellen
  1264. setzt.<br><br>
  1265. </td><td>
  1266. <img src="ccc.jpg"/>
  1267. </td></tr>
  1268. </table>
  1269. <a name="CULdefine"></a>
  1270. <b>Define</b>
  1271. <ul>
  1272. <code>define &lt;name&gt; CUL &lt;device&gt; &lt;FHTID&gt;</code> <br>
  1273. <br>
  1274. Ger&auml;te, die an USB angeschlossen sind (CUL/CUN):<br>
  1275. <ul>
  1276. &lt;device&gt; gibt die serielle Schnittstelle an, mit der der CUL
  1277. kommuniziert. Der Name der seriellen Schnittstelle h&auml;ngt von der
  1278. gew&auml;hlten Distribution und USB-Treiber ab, unter Linux ist dies das
  1279. Kernel Modul cdc_acm und &uuml;blicherweise wird die Schnittstelle
  1280. /dev/ttyACM0 genannt. Wenn die Linux Distribution &uuml;ber kein Kernel
  1281. Modul cdc_acm verf&uuml;gt, dann kann die Schnittstelle &uuml;ber
  1282. usbserial mit dem folgenden Befehl erzeugt werden:
  1283. <ul><code>
  1284. modprobe usbserial vendor=0x03eb product=0x204b
  1285. </code></ul>
  1286. In diesem Fall ist diese Schnittstelle dann wahrscheinlich
  1287. /dev/ttyUSB0.<br><br>
  1288. Wenn der Name der Schnittstelle ein @ enth&auml;lt, kann nachfolgend die
  1289. verwendete Baudrate angegeben werden, z.B.: /dev/ttyACM0@38400.<br><br>
  1290. Wenn die Baudrate mit "directio" angegeben wird (z.B.:
  1291. /dev/ttyACM0@directio), wird das Perl Modul
  1292. <code>Device::SerialPort</code> nicht ben&ouml;tigt und FHEM &ouml;ffnet
  1293. die Schnittstelle mit einfachem Dateizugriff. Dies sollte dann
  1294. funktionieren, wenn das Betriebssystem vern&uuml;nftige Standardwerte
  1295. f&uuml;r die serielle Schnittstelle verwendet, wie z.B. einige Linux
  1296. Distributionen oder OSX.<br><br>
  1297. </ul>
  1298. Ger&auml;te, die mit dem Netzwerk verbunden sind (CUN(O)):<br>
  1299. <ul>
  1300. &lt;device&gt; gibt die Hostadresse:Port des Ger&auml;tes an, z.B.
  1301. 192.168.0.244:2323
  1302. </ul>
  1303. <br>
  1304. Wenn das Ger&auml;t mit none bezeichnet wird, wird keine Schnittstelle
  1305. ge&ouml;ffnet und man kann ohne angeschlossene Hardware
  1306. experimentieren.<br>
  1307. Die FHTID ist eine 4-stellige hexadezimale Zahl und wird verwendet, wenn
  1308. der CUL FHT Telegramme sendet bzw. Daten anfragt. Diese sollte als 0000
  1309. gew&auml;hlt werden, wenn man FHT80b Anfragen durch den CUL vermeiden will.
  1310. </ul>
  1311. <br>
  1312. <a name="CULset"></a>
  1313. <b>Set </b>
  1314. <ul>
  1315. <li>reopen<br>
  1316. &Ouml;ffnet die Verbindung zum Ger&auml;t neu und initialisiert es.
  1317. </li><br>
  1318. <li>raw<br>
  1319. Sendet einen CUL Firmware Befehl. Siehe auch
  1320. <a href="http://culfw.de/commandref.html">hier</a> f&uuml;r
  1321. n&auml;here Erl&auml;uterungen der CUL Befehle.
  1322. </li><br>
  1323. <li>freq / bWidth / rAmpl / sens<br>
  1324. Nur in der Betriebsart <a href="#rfmode">SlowRF</a>.<br> Bestimmt die
  1325. CUL Frequenz / Bandbreite / Empf&auml;nger Amplitude /
  1326. Empfindlichkeit<br>
  1327. Bitte mit Vorsicht verwenden, da es die verwendete Hardware
  1328. zerst&ouml;ren kann bzw. es zu illegalen Funkzust&auml;nden kommen
  1329. kann. <br> Bemerkung: Die Parameter f&uuml;r die RFR &Uuml;bermittlung
  1330. werden hierdurch nicht beeinflu&szlig;t.<br>
  1331. <ul>
  1332. <li>freq bestimmt sowohl die Empfangs- als auch die Sendefrequenz.<br>
  1333. Bemerkung: Auch wenn der CC1101 zwischen den Frequenzen 315 und 915
  1334. MHz eingestellt werden kann, ist die Antennenanbindung bzw. die
  1335. Antenne des CUL exakt auf eine Frequenz eingestellt. Standard ist
  1336. 868.3 MHz (bzw. 433 MHz).</li>
  1337. <li>bWidth kann zwischen 58 kHz und 812 kHz variiert werden.
  1338. Gro&szlig;e Werte sind empfindlicher gegen Interferencen, aber
  1339. machen es m&ouml;glich, nicht genau kalbrierte Signale zu
  1340. empfangen. Die Einstellung beeinflusst ebenso die &Uuml;bertragung.
  1341. Standardwert ist 325 kHz.</li>
  1342. <li>rAmpl ist die Verst&auml;rkung des Empf&auml;ngers mit Werten
  1343. zwischen 24 and 42 dB. Gr&ouml;&szlig;ere Werte erlauben den
  1344. Empfang von schwachen Signalen. Standardwert ist 42.</li>
  1345. <li>sens ist die Entscheidungsgrenze zwischen "on" und "off"
  1346. Zust&auml;nden und kann 4, 8, 12 oder 16 dB sein. Kleinere Werte
  1347. erlauben den Empfang von undeutlicheren Signalen. Standard ist 4
  1348. dB.</li>
  1349. </ul>
  1350. </li><br>
  1351. <a name="hmPairForSec"></a>
  1352. <li>hmPairForSec<br>
  1353. Nur in der Betriebsart <a href="#rfmode">HomeMatic</a>.<br> Versetzt den
  1354. CUL f&uuml;r die angegebene Zeit in Sekunden in den Anlern-Modus. Jedes
  1355. HM Ger&auml;t, das sich im Anlern-Modus befindet, wird an FHEM
  1356. angelernt. </li><br>
  1357. <a name="hmPairSerial"></a>
  1358. <li>hmPairSerial<br>
  1359. Nur in der Betriebsart <a href="#rfmode">HomeMatic</a>.<br>
  1360. Versucht, das angegebene Ger&auml;t anzulernen (zu "pairen"). Der
  1361. Parameter ist eine 10-stellige Zeichenfolge, die normalerweise mit
  1362. Buchstaben beginnt und mit Ziffern endet; diese sind auf der
  1363. R&uuml;ckseite der Ger&auml;te aufgedruckt. Wenn das Ger&auml;t ein
  1364. Empf&auml;nger ist, ist es nicht notwendig, das angegebene Ger&auml;t in
  1365. den Anlern-Modus zu versetzen. </li><br>
  1366. <a name="hmPairForSec"></a>
  1367. <li>led<br>
  1368. Schaltet die LED des CUL: aus (00), an (01) oder blinkend (02).
  1369. </li><br>
  1370. <li>ITClock</br>
  1371. Setzt die IT clock f&uuml; Intertechno V1 Protokoll. Default 250.
  1372. </li><br>
  1373. </ul>
  1374. <a name="CULget"></a>
  1375. <b>Get</b>
  1376. <ul>
  1377. <li>version<br>
  1378. gibt die Version der CUL Firmware zur&uuml;ck
  1379. </li><br>
  1380. <li>uptime<br>
  1381. gibt die Betriebszeit des CULs zur&uuml;ck (Zeit seit dem letzten Reset
  1382. des CULs) </li><br>
  1383. <li>raw<br>
  1384. Sendet einen CUL Firmware Befehl und wartet auf eine R&uuml;ckgabe des
  1385. CULs. Siehe auch README der Firmware f&uuml;r n&auml;here
  1386. Erl&auml;uterungen zu den CUL Befehlen. </li><br>
  1387. <li>fhtbuf<br>
  1388. Der CUL hat einen Puffer f&uuml;r Nachrichten f&uuml;r FHT. Wenn der
  1389. Puffer voll ist, werden neu empfangene Telegramme ignoriert und eine
  1390. "EOB" Meldung wird in die FHEM Logdatei geschrieben.
  1391. <code>fhtbuf</code> gibt den freien Speicher dieses Puffers (in hex)
  1392. zur&uuml;ck, ein leerer Puffer im CUL V2 hat 74 Byte, im CUL V3/CUN(O)
  1393. hat 200 Byte. Eine Telegramm ben&ouml;tigt 3 + 2x(Anzahl der FHT
  1394. Befehle) Byte, dies ist ein Grund, warum man mehrere FHT Befehle mit
  1395. einem <a href="#set">set</a> senden sollte. Ein weiterer Grund ist,
  1396. dass diese FHT Befehle in einem "Paket" zum FHT Ger&auml;t gesendet werden.
  1397. </li> <br>
  1398. <li>ccconf<br>
  1399. Liest einige CUL Register des CC1101 (Sende- und Empf&auml;ngerchips)
  1400. aus (Frequenz, Bandbreite, etc.) und stellt diese in lesbarer Form dar.
  1401. </li><br>
  1402. <li>cmds<br>
  1403. In abh&auml;gigkeit der installierten Firmware hat der CUL/CUN(O)
  1404. unterschiedliche Befehlss&auml;tze. N&auml;here Informationen &uuml;ber
  1405. die Befehle bzw. deren Interpretation siehe README Datei der
  1406. verwendeten CUL Firmware. Siehe auch Anmerkungen beim raw Befehl.
  1407. </li><br>
  1408. <li>credit10ms<br>
  1409. Der Funkraum darf f&uuml;r eine Dauer von credit10ms*10 ms belegt
  1410. werden, bevor die gesetzliche 1% Grenze erreicht ist und eine
  1411. LOVF Meldung ausgegeben wird. </li><br> </ul>
  1412. <a name="CULattr"></a>
  1413. <b>Attribute</b>
  1414. <ul>
  1415. <li><a name="addvaltrigger">addvaltrigger</a><br>
  1416. Generiert Trigger f&uuml;r zus&auml;tzliche Werte. Momentan sind dies
  1417. RSSI und RAWMSG f&uuml;r die CUL Familie und RAWMSG f&uuml;r FHZ.
  1418. </li><br>
  1419. <li><a name="connectCommand">connectCommand</a><br>
  1420. culfw Befehl, was nach dem Verbindungsaufbau mit dem USB-Ger&auml;t, nach
  1421. Senden der zum Initialisieren der konfigurierten rfmode ben&ouml;tigten
  1422. Befehle gesendet wird.
  1423. </li>
  1424. <li><a href="#do_not_notify">do_not_notify</a></li>
  1425. <li><a href="#attrdummy">dummy</a></li>
  1426. <li><a name="hmId">hmId</a><br>
  1427. Setzt die HomeMatic ID des Ger&auml;tes. Wenn dieses Attribut fehlt,
  1428. wird die ID zu F1&lt;FHTID&gt; gesetzt. Bemerkung 1: Nach dem Setzen
  1429. bzw. Ver&auml;ndern dieses Attributes m&uuml;ssen alle HomeMatic
  1430. Ger&auml;te neu angelernt werden. Bemerkung 2: Der Wert <b>muss</b>
  1431. eine 6-stellige Hexadezimalzahl sein, 000000 ist ung&uuml;ltig. FHEM
  1432. &uuml;berpr&uuml;ft nicht, ob die ID korrekt ist, im Zweifelsfall
  1433. funktioniert die Kommunikation nicht. </li><br>
  1434. <li><a name="hmProtocolEvents">hmProtocolEvents</a><br>
  1435. Generiert Ereignisse f&uuml;r HomeMatic Telegramme. Diese werden
  1436. normalerweise f&uuml;r die Fehlersuche verwendet, z.B. durch Aktivieren
  1437. von <code>inform timer</code> in einer telnet Sitzung bzw. im
  1438. <code>Event Monitor</code> Fenster im FHEMWEB Frontend.<br>
  1439. Beispiel:
  1440. <ul>
  1441. <code>
  1442. 2012-05-17 09:44:22.515 CUL CULHM RCV L:0B N:81 CMD:A258 SRC:......
  1443. DST:...... 0000 (TYPE=88,WAKEMEUP,BIDI,RPTEN)
  1444. </code>
  1445. </ul>
  1446. </li><br>
  1447. <li><a name="longids">longids</a><br>
  1448. Durch Kommata getrennte Liste von Device-Typen f&uuml;r Empfang von
  1449. langen IDs mit den CUL. Diese zus&auml;tzliche ID erlaubt es
  1450. Wettersensoren, welche auf dem gleichen Kanal senden zu unterscheiden.
  1451. Hierzu wird eine zuf&auml;llig generierte ID hinzugef&uuml;gt. Wenn Sie
  1452. longids verwenden, dann wird in den meisten F&auml;llen nach einem
  1453. Batteriewechsel ein neuer Sensor angelegt.
  1454. Standardm&auml;&szlig;ig werden keine langen IDs verwendet.<br>
  1455. Folgende Module verwenden diese Funktionalit&auml;t:
  1456. 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.<br>
  1457. Beispiele:
  1458. <ul><code>
  1459. # Keine langen IDs verwenden (Default Einstellung):<br>
  1460. attr cul longids 0<br>
  1461. # Immer lange IDs verwenden:<br>
  1462. attr cul longids 1<br>
  1463. # Verwende lange IDs f&uuml;r SD_WS07 Devices.<br>
  1464. # Device Namen sehen z.B. so aus: SD_WS07_TH_3 for channel 3.<br>
  1465. attr cul longids SD_WS07
  1466. </code></ul>
  1467. </li><br>
  1468. <li><a href="#model">model</a> (CUL,CUN)</li><br>
  1469. <li><a name="rfmode">rfmode</a><br>
  1470. Konfiguriert den RF Transceiver des CULs (CC1101). Verf&uuml;gbare
  1471. Argumente sind:
  1472. <ul>
  1473. <li>SlowRF<br>
  1474. F&uuml;r die Kommunikation mit FS20/FHT/HMS/EM1010/S300/Hoermann
  1475. Ger&auml;ten @1 kHz Datenrate (Standardeinstellung).</li>
  1476. <li>HomeMatic<br>
  1477. F&uuml;r die Kommunikation mit HomeMatic Ger&auml;ten @10 kHz
  1478. Datenrate.</li>
  1479. <li>MAX<br>
  1480. F&uuml;r die Kommunikation mit MAX! Ger&auml;ten @10 kHz
  1481. Datenrate.</li>
  1482. <li>WMBus_S</li>
  1483. <li>WMBus_T<br>
  1484. F&uuml;r die Kommunikation mit Wireless M-Bus Ger&auml;ten wie
  1485. Wasser-, Gas- oder Elektroz&auml;hlern. Wireless M-Bus verwendet
  1486. zwei unterschiedliche Kommunikationsarten, S-Mode und T-Mode. In
  1487. diesem Modus ist der Empfang von anderen Protokollen wie SlowRF
  1488. oder HomeMatic nicht m&ouml;glich.</li>
  1489. </ul>
  1490. </li><br>
  1491. <li><a name="sendpool">sendpool</a><br>
  1492. Wenn mehr als ein CUL verwendet wird, um einen gr&ouml;&szlig;eren
  1493. Bereich abzudecken, k&ouml;nnen diese sich gegenseitig
  1494. beeinflussen. Dieses Ph&auml;nomen wird auch Palm-Beach-Resort Effekt
  1495. genannt. Wenn man diese zu einen gemeinsamen Sende"pool"
  1496. zusammenschlie&szlig;t, wird das Senden der einzelnen Telegramme
  1497. seriell (d.h. hintereinander) durchgef&uuml;hrt.
  1498. Wenn z.B. drei CUN's zur
  1499. Verf&uuml;gung stehen, werden folgende Attribute gesetzt:<br>
  1500. <code>attr CUN1 sendpool CUN1,CUN2,CUN3<br>
  1501. attr CUN2 sendpool CUN1,CUN2,CUN3<br>
  1502. attr CUN3 sendpool CUN1,CUN2,CUN3</code><br>
  1503. </li><br>
  1504. <li><a href="#showtime">showtime</a></li>
  1505. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  1506. </ul>
  1507. <br>
  1508. </ul>
  1509. =end html_DE
  1510. =cut