16_CUL_RFR.pm 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ##############################################
  2. # $Id: 16_CUL_RFR.pm 15341 2017-10-29 14:24:51Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. #####################################
  7. sub
  8. CUL_RFR_Initialize($)
  9. {
  10. my ($hash) = @_;
  11. # Message is like
  12. # K41350270
  13. $hash->{Match} = "^[0-9A-F]{4}U.";
  14. $hash->{DefFn} = "CUL_RFR_Define";
  15. $hash->{FingerprintFn} = "RFR_FingerprintFn";
  16. $hash->{UndefFn} = "CUL_RFR_Undef";
  17. $hash->{ParseFn} = "CUL_RFR_Parse";
  18. $hash->{AttrList} = "IODev do_not_notify:0,1 model:CUL,CUN,CUR " .
  19. "ignore:0,1 addvaltrigger";
  20. $hash->{WriteFn} = "CUL_RFR_Write";
  21. $hash->{GetFn} = "CUL_Get";
  22. $hash->{SetFn} = "CUL_Set";
  23. $hash->{noRawInform} = 1; # Our message was already sent as raw.
  24. $hash->{AddPrefix} = "CUL_RFR_AddPrefix";
  25. $hash->{DelPrefix} = "CUL_RFR_DelPrefix";
  26. $hash->{noAutocreatedFilelog} = 1;
  27. }
  28. sub
  29. RFR_FingerprintFn($$)
  30. {
  31. my ($name, $msg) = @_;
  32. # Store only the "relevant" part, as the CUL won't compute the checksum
  33. $msg = substr($msg, 8) if($msg =~ m/^81/ && length($msg) > 8);
  34. return ($name, $msg);
  35. }
  36. #####################################
  37. sub
  38. CUL_RFR_Define($$)
  39. {
  40. my ($hash, $def) = @_;
  41. my @a = split("[ \t][ \t]*", $def);
  42. return "wrong syntax: define <name> CUL_RFR <id> <routerid>"
  43. if(int(@a) != 4 ||
  44. $a[2] !~ m/[0-9A-F]{2}/i ||
  45. $a[3] !~ m/[0-9A-F]{2}/i);
  46. $hash->{ID} = $a[2];
  47. $hash->{ROUTERID} = $a[3];
  48. $modules{CUL_RFR}{defptr}{"$a[2]$a[3]"} = $hash;
  49. $hash->{STATE} = "Defined";
  50. AssignIoPort($hash);
  51. return undef;
  52. }
  53. #####################################
  54. sub
  55. CUL_RFR_Write($$)
  56. {
  57. my ($hash,$fn,$msg) = @_;
  58. ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg);
  59. return if(!defined($fn));
  60. $msg = $hash->{ID} . $hash->{ROUTERID} . $fn . $msg;
  61. IOWrite($hash, "u", $msg);
  62. }
  63. #####################################
  64. sub
  65. CUL_RFR_Undef($$)
  66. {
  67. my ($hash, $name) = @_;
  68. delete($modules{CUL_RFR}{defptr}{$hash->{ID} . $hash->{ROUTERID}});
  69. return undef;
  70. }
  71. #####################################
  72. sub
  73. CUL_RFR_Parse($$)
  74. {
  75. my ($iohash,$msg) = @_;
  76. # 0123456789012345678
  77. # E01012471B80100B80B -> Type 01, Code 01, Cnt 10
  78. $msg =~ m/^([0-9AF]{2})([0-9AF]{2})U(.*)/;
  79. my ($rid, $id, $smsg) = ($1,$2,$3);
  80. my $cde = "${id}${rid}";
  81. if(!$modules{CUL_RFR}{defptr}{$cde}) {
  82. Log3 $iohash, 1, "CUL_RFR detected, Id $id, Router $rid, MSG $smsg";
  83. return "UNDEFINED CUL_RFR_$id CUL_RFR $id $rid";
  84. }
  85. my $hash = $modules{CUL_RFR}{defptr}{$cde};
  86. my $name = $hash->{NAME};
  87. return "" if(IsIgnored($name));
  88. $hash->{Clients} = $iohash->{Clients};
  89. $hash->{MatchList} = $iohash->{MatchList};
  90. my @m = split(";", $smsg, -1); # process only messages terminated with ;
  91. for(my $i = 0; $i < $#m; $i++) {
  92. my $m = $m[$i];
  93. # Compressed FHT messages
  94. while($m =~ m/^T(....)(..)(..)(..)(..)(..)(.*)(..)$/) {
  95. my ($fhtid, $cmd, $source, $val, $cmd2, $val2, $rest, $rssi) =
  96. ($1, $2, $3, $4, $5, $6, $7, $8);
  97. my $firstmsg = "T$fhtid$cmd$source$val$rssi";
  98. $m = "T$fhtid$cmd2$source$val2$rest$rssi";
  99. CUL_Parse($hash, $iohash, $hash->{NAME}, $firstmsg);
  100. }
  101. CUL_Parse($hash, $iohash, $hash->{NAME}, $m);
  102. if($m =~ m/^T/) { $hash->{NR_TMSG}++ }
  103. elsif($m =~ m/^F/) { $hash->{NR_FMSG}++ }
  104. elsif($m =~ m/^E/) { $hash->{NR_EMSG}++ }
  105. elsif($m =~ m/^K/) { $hash->{NR_KMSG}++ }
  106. else { $hash->{NR_RMSG}++ }
  107. }
  108. return "";
  109. }
  110. sub
  111. CUL_RFR_DelPrefix($$)
  112. {
  113. my ($hash, $msg) = @_;
  114. $msg = $1 if($msg =~ m/^\d{4}U(.*)$/);
  115. $msg =~ s/;([\r\n]*)$/$1/; # ???
  116. return $msg;
  117. }
  118. sub
  119. CUL_RFR_AddPrefix($$)
  120. {
  121. my ($hash, $msg) = @_;
  122. return "u" . $hash->{ID} . $hash->{ROUTERID} . $msg;
  123. }
  124. 1;
  125. =pod
  126. =item summary devices communicating over culfw RFR (SlowRF repeater)
  127. =item summary_DE Anbindung von Ger&auml;ten &uuml;ber ein culfw RFR (SlowRF repeater)
  128. =begin html
  129. <a name="CUL_RFR"></a>
  130. <h3>CUL_RFR</h3>
  131. <ul>
  132. <table>
  133. <tr><td>
  134. The CUL_RFR module is used to "attach" a second CUL to your base CUL, and
  135. use it as a repeater / range extender. RFR is shorthand for RF_ROUTER.
  136. Transmission of the data uses the CC1101 packet capabilities with GFSK
  137. modulation at 250kBaud after pinging the base CUL at the usual 1kBaud. After
  138. configured, the RFR device can be used like another CUL connected directly to
  139. FHEM.<br>
  140. In theory every SlowRF protocol should work, as the hook is implemented in
  141. the culfw output routine: instead of sending the data to the USB-Interface it
  142. is transmitted via radio to the base CUL. There are still some restrictions:
  143. <ul>
  144. <li>due to the ping both CULs have to be in SlowRF mode, and use the same
  145. parameters (freq, bwidth, etc).</li>
  146. <li>the logical module handling the protocol is not allowed to access the
  147. routines of the IODev (i.e. CUL) directly.</li>
  148. </ul>
  149. Tested protocols are FHT, FS20, EM, HMS, S300.<br>
  150. Since there is no ack or a resend mechanism, it should be primarily used to
  151. forward "unimportant" data, it was developed for forwading KS300 packets.
  152. <br><br>
  153. Before you can use this feature in fhem, you have to enable/configure RF
  154. ROUTING in both CUL's:
  155. <ul>
  156. <li>First give your base CUL (which remains connected to the PC) an RFR ID
  157. by issuing the fhem command "set MyCUL raw ui0100". With this command
  158. the base CUL will get the ID 01, and it will not relay messages to other
  159. CUL's (as the second number is 00).</li>
  160. <li>Now replace the base CUL with the RFR CUL, and set its id by issuing
  161. the fhem command "set MyCUL raw ui0201". Now remove this CUL and attach the
  162. original, base CUL again. The RFR CUL got the id 02, and will relay every
  163. message to the base CUL with id 01.</li>
  164. <li>Take the RFR CUL, and attach it to an USB power supply, as seen on
  165. the image. As the configured base id is not 00, it will activate RF
  166. reception on boot, and will start sending messages to the base CUL.</li>
  167. <li>Now you have to define this RFR cul as a fhem device:</li>
  168. </ul>
  169. </td><td>
  170. <img src="cul_rfr.jpg"/>
  171. </td></tr>
  172. </table>
  173. <br>
  174. <a name="CUL_RFRdefine"></a>
  175. <b>Define</b>
  176. <ul>
  177. <code>define &lt;name&gt; CUL_RFR &lt;own-id&gt; &lt;base-id&gt;</code> <br>
  178. <br>
  179. &lt;own-id&gt; is the id of the RFR CUL <b>not</b> connected to the PC,
  180. &lt;base-id&gt; is the id of the CUL connected to the PC. Both parameters
  181. have two characters, each representing a one byte hex number.<br>
  182. Example:
  183. <ul>
  184. <code>set MyCUL raw ui0100</code><br>
  185. # Now replace the base CUL with the RFR CUL<br>
  186. <code>set MyCUL raw ui0201</code><br>
  187. # Reattach the base CUL to the PC and attach the RFR CUL to a
  188. USB power supply<br>
  189. <code>define MyRFR CUL_RFR 02 01</code><br>
  190. </ul>
  191. </ul> <br>
  192. <a name="CUL_RFRset"></a>
  193. <b>Set</b> <ul>Same as for the <a href="#CULset">CUL</a>.</ul><br>
  194. <a name="CUL_RFRget"></a>
  195. <b>Get</b> <ul>Same as for the <a href="#CULget">CUL</a>.</ul><br>
  196. <a name="CUL_RFRattr"></a>
  197. <b>Attributes</b>
  198. <ul>
  199. <li><a href="#ignore">ignore</a></li><br>
  200. <li><a href="#IODev">IODev</a></li><br>
  201. The rest of the attributes is the same as for the <a href="#CUL">CUL</a>.</ul><br>
  202. </ul>
  203. <br>
  204. =end html
  205. =cut