12_HMS.pm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. ##############################################
  2. # $Id: 12_HMS.pm 15027 2017-09-08 09:11:43Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. my %codes = (
  7. "0" => "HMS100TF",
  8. "1" => "HMS100T",
  9. "2" => "HMS100WD",
  10. "3" => "RM100-2",
  11. "4" => "HMS100TFK", # Depending on the onboard jumper it is 4 or 5
  12. "5" => "HMS100TFK",
  13. "6" => "HMS100MG",
  14. "8" => "HMS100CO",
  15. "e" => "HMS100FIT",
  16. );
  17. #####################################
  18. sub
  19. HMS_Initialize($)
  20. {
  21. my ($hash) = @_;
  22. # 810e047e0510a001473a000000120233 HMS100TF
  23. # 810e04b90511a0018e63000001100000 HMS100T
  24. # 810e04e80212a001ec46000001000000 HMS100WD
  25. # 810e04d70213a001b16d000003000000 RM100-2
  26. # 810e047f0214a001a81f000001000000 HMS100TFK
  27. # 810e048f0295a0010155000001000000 HMS100TFK (jumper)
  28. # 810e04330216a001b4c5000001000000 HMS100MG
  29. # 810e04210218a00186e0000000000000 HMS100CO
  30. # 810e0448029ea00132d5000000000000 FI-Trenner
  31. $hash->{Match} = "^810e04......a001";
  32. $hash->{DefFn} = "HMS_Define";
  33. $hash->{UndefFn} = "HMS_Undef";
  34. $hash->{ParseFn} = "HMS_Parse";
  35. $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model:hms100-t,hms100-tf,hms100-wd,hms100-mg,hms100-tfk,rm100-2,hms100-co,hms100-fit ignore:0,1 $readingFnAttributes";
  36. $hash->{AutoCreate}= {
  37. "HMS100TFK_.*" =>
  38. { GPLOT => "fht80tf:Contact,", FILTER => "%NAME" },
  39. "HMS100T[F]?_.*" =>
  40. { GPLOT => "temp4hum6:Temp/Hum,", FILTER => "%NAME:T:.*" }
  41. };
  42. }
  43. #####################################
  44. sub
  45. HMS_Define($$)
  46. {
  47. my ($hash, $def) = @_;
  48. my @a = split("[ \t][ \t]*", $def);
  49. return "wrong syntax: define <name> HMS CODE" if(int(@a) != 3);
  50. $a[2] = lc($a[2]);
  51. return "Define $a[0]: wrong CODE format: specify a 4 digit hex value"
  52. if($a[2] !~ m/^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/);
  53. $hash->{CODE} = $a[2];
  54. $modules{HMS}{defptr}{$a[2]} = $hash;
  55. AssignIoPort($hash);
  56. return undef;
  57. }
  58. #####################################
  59. sub
  60. HMS_Undef($$)
  61. {
  62. my ($hash, $name) = @_;
  63. delete($modules{HMS}{defptr}{$hash->{CODE}})
  64. if(defined($hash->{CODE}) &&
  65. defined($modules{HMS}{defptr}{$hash->{CODE}}));
  66. return undef;
  67. }
  68. #####################################
  69. sub
  70. HMS_Parse($$)
  71. {
  72. my ($hash, $msg) = @_;
  73. my $dev = substr($msg, 16, 4);
  74. my $cde = substr($msg, 11, 1);
  75. # 012345678901234567890123456789
  76. # 810e047f0214a001a81f000001000000 HMS100TFK
  77. my $val = substr($msg, 24, 8) if(length($msg) == 32);
  78. if(!defined($val)) {
  79. Log3 $hash, 3, "Strange HMS message $msg";
  80. return "";
  81. }
  82. my $type = "";
  83. foreach my $c (keys %codes) {
  84. if($cde =~ m/$c/) {
  85. $type = $codes{$c};
  86. last;
  87. }
  88. }
  89. # As the HMS devices change their id on each battery change, we offer
  90. # a wildcard too for each type: 100<device-code>,
  91. my $odev = $dev;
  92. if(!defined($modules{HMS}{defptr}{$dev})) {
  93. Log3 $hash, 4,
  94. "HMS device $dev not defined, using the wildcard device 100$cde";
  95. $dev = "100$cde";
  96. }
  97. if(!defined($modules{HMS}{defptr}{$dev})) {
  98. Log3 $hash, 3, "Unknown HMS device $dev/$odev, please define it";
  99. $type = "HMS" if(!$type);
  100. $type =~ s/-//; # RM100-2, - is special in fhem names
  101. return "UNDEFINED ${type}_$odev HMS $odev";
  102. }
  103. my $def = $modules{HMS}{defptr}{$dev};
  104. my $name = $def->{NAME};
  105. return "" if(IsIgnored($name));
  106. my (@v, @txt);
  107. # Used for HMS100TF & HMS100T
  108. my $batstr1 = "ok";
  109. my $status1 = hex(substr($val, 0, 1));
  110. $batstr1 = "empty" if( $status1 & 2 );
  111. $batstr1 = "replaced" if( $status1 & 4 );
  112. # Used for the other devices
  113. my $batstr2 = "ok";
  114. my $status = hex(substr($val, 1, 1));
  115. my $status2 = hex(substr($msg, 10, 1));
  116. $batstr2 = "empty" if( $status2 & 4 );
  117. $batstr2 = "replaced" if( $status2 & 8 );
  118. if($type eq "HMS100TF") {
  119. @txt = ( "temperature", "humidity", "battery");
  120. # Codierung <s1><s0><t1><t0><f0><t2><f2><f1>
  121. $v[0] = int(substr($val, 5, 1) . substr($val, 2, 2))/10;
  122. $v[0] = -$v[0] if($status1 & 8);
  123. $v[1] = int(substr($val, 6, 2) . substr($val, 4, 1))/10;
  124. $v[2] = $batstr1;
  125. $val = "T: $v[0] H: $v[1] Bat: $v[2]";
  126. #$v[0] = "$v[0] (Celsius)";
  127. #$v[1] = "$v[1] (%)";
  128. } elsif ($type eq "HMS100T") {
  129. @txt = ( "temperature", "battery");
  130. $v[0] = int(substr($val, 5, 1) . substr($val, 2, 2))/10;
  131. $v[0] = -$v[0] if($status1 & 8);
  132. $v[1] = $batstr1;
  133. $val = "T: $v[0] Bat: $v[1]";
  134. #$v[0] = "$v[0] (Celsius)";
  135. } elsif ($type eq "HMS100WD") {
  136. @txt = ( "water_detect", "battery");
  137. $v[0] = ($status ? "on" : "off");
  138. $v[1] = $batstr2;
  139. $val = "Water Detect: $v[0]";
  140. } elsif ($type eq "HMS100TFK") { # By Peter P.
  141. @txt = ( "switch_detect", "battery");
  142. $v[0] = ($status ? "on" : "off");
  143. $v[1] = $batstr2;
  144. $val = "Switch Detect: $v[0]";
  145. } elsif($type eq "RM100-2") {
  146. @txt = ( "smoke_detect", "battery");
  147. $v[0] = ($status ? "on" : "off");
  148. $v[1] = $batstr2;
  149. $val = "smoke_detect: $v[0]";
  150. } elsif ($type eq "HMS100MG") { # By Peter Stark
  151. @txt = ( "gas_detect", "battery");
  152. $v[0] = ($status ? "on" : "off");
  153. $v[1] = $batstr2; # Battery conditions not yet verified
  154. $val = "Gas Detect: $v[0]";
  155. } elsif ($type eq "HMS100CO") { # By PAN
  156. @txt = ( "gas_detect", "battery");
  157. $v[0] = ($status ? "on" : "off");
  158. $v[1] = $batstr2; # Battery conditions not yet verified
  159. $val = "CO Detect: $v[0]";
  160. } elsif ($type eq "HMS100FIT") { # By PAN
  161. @txt = ( "fi_triggered", "battery");
  162. $v[0] = ($status ? "on" : "off");
  163. $v[1] = $batstr2; # Battery conditions not yet verified
  164. $val = "FI triggered: $v[0]";
  165. } else {
  166. Log3 $name, 3, "HMS Device $dev (Unknown type: $type)";
  167. return "";
  168. }
  169. Log3 $name, 4, "HMS Device $dev ($type: $val)";
  170. readingsBeginUpdate($def);
  171. my $max = int(@txt);
  172. for( my $i = 0; $i < $max; $i++) {
  173. readingsBulkUpdate($def, $txt[$i], $v[$i]);
  174. }
  175. readingsBulkUpdate($def, "type", $type);
  176. readingsBulkUpdate($def, "state", $val);
  177. readingsBulkUpdate($def, "ExactId", $odev) if($odev ne $dev);
  178. readingsEndUpdate($def, 1);
  179. return $name;
  180. }
  181. 1;
  182. =pod
  183. =item summary devices communicating via the ELV HMS protocol
  184. =item summary_DE Anbindung von ELV HMS Ger&auml;ten
  185. =begin html
  186. <a name="HMS"></a>
  187. <h3>HMS</h3>
  188. <ul>
  189. <a name="HMSdefine"></a>
  190. <b>Define</b>
  191. <ul>
  192. <code>define &lt;name&gt; HMS &lt;housecode&gt;</code>
  193. <br><br>
  194. <code>&lt;housecode&gt;</code> is a four digit hex number,
  195. corresponding to the address of the HMS device.
  196. <br>
  197. Examples:
  198. <ul>
  199. <code>define temp HMS 1234</code><br>
  200. </ul>
  201. Notes:<br>
  202. <ul>
  203. <li>Currently supported devices are the HMS100-T HMS100-TF HMS100-WD
  204. HMS100-MG HMS100-TFK HMS100-CO HMS100-FIT RM100-2 RM100-3</li>
  205. <li>The housecode of the HMS devices may change if the battery is renewed.
  206. In order to make life easier, you can define a "wildcard" device for each
  207. type of HMS device. First the real device-id will be checked, then the
  208. wildcard device id. The wildcards are:
  209. <ul>
  210. <li>1000 for the HMS100-TF</li>
  211. <li>1001 for the HMS100-T</li>
  212. <li>1002 for the HMS100-WD</li>
  213. <li>1003 for the RM100-2</li>
  214. <li>1004 for the HMS100-TFK</li>
  215. <li>1006 for the HMS100-MG</li>
  216. <li>1008 for the HMS100-CO</li>
  217. <li>100e for the HMS100-FIT</li>
  218. </ul>
  219. </li>
  220. <li>Some battery low notifications are not yet implemented (RM100,
  221. HMS100WD).</li>
  222. <li>Please test your installation before relying on the
  223. functionality.</li>
  224. </ul>
  225. <br>
  226. </ul>
  227. <br>
  228. <a name="HMSset"></a>
  229. <b>Set</b> <ul>N/A</ul><br>
  230. <a name="HMSget"></a>
  231. <b>Get</b> <ul>N/A</ul><br>
  232. <a name="HMSattr"></a>
  233. <b>Attributes</b>
  234. <ul>
  235. <li><a href="#ignore">ignore</a></li>
  236. <li><a href="#do_not_notify">do_not_notify</a></li>
  237. <li><a href="#showtime">showtime</a></li>
  238. <li><a href="#IODev">IODev</a></li>
  239. <li><a href="#eventMap">eventMap</a></li>
  240. <li><a href="#model">model</a> (hms100-t hms100-tf hms100-wd hms100-mg
  241. hms100-co hms100-tfk hms100-fit rm100-2)</li>
  242. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  243. </ul>
  244. <br>
  245. </ul>
  246. =end html
  247. =begin html_DE
  248. <a name="HMS"></a>
  249. <h3>HMS</h3>
  250. <ul>
  251. <a name="HMSdefine"></a>
  252. <b>Define</b>
  253. <ul>
  254. <code>define &lt;name&gt; HMS &lt;housecode&gt;</code>
  255. <br><br>
  256. Der <code>&lt;housecode&gt;</code> ist eine vierstellige HEX-Zahl,
  257. entsprechend dem HMS Ger&auml;t.<br>
  258. Beispiel:
  259. <ul>
  260. <code>define temp HMS 1234</code><br>
  261. </ul>
  262. Hinweise:<br>
  263. <ul>
  264. <li>Derzeit werden folgende Komponenten Unterst&uuml;tzt: HMS100-T
  265. HMS100-TF HMS100-WD HMS100-MG HMS100-TFK HMS100-CO HMS100-FIT RM100-2
  266. RM100-3</li>
  267. <li>Der Hauscode kann sich &auml;ndern wenn die Batterie gewechselt wird.
  268. Um sich das Leben einfacher zu machen kann man ein "Wildcard"
  269. (Platzhalter) Device f&uuml;r jeden Typ von HMS Ger&auml;t anlegen.
  270. Zuerst wird die echte Device-ID gepr&uuml;ft, danach die Wildcard-ID.
  271. Wildcards sind:
  272. <ul>
  273. <li>1000 f&uuml;r das HMS100-TF</li>
  274. <li>1001 f&uuml;r das HMS100-T</li>
  275. <li>1002 f&uuml;r das HMS100-WD</li>
  276. <li>1003 f&uuml;r das RM100-2</li>
  277. <li>1004 f&uuml;r das HMS100-TFK</li>
  278. <li>1006 f&uuml;r das HMS100-MG</li>
  279. <li>1008 f&uuml;r das HMS100-CO</li>
  280. <li>100e f&uuml;r das HMS100-FIT</li>
  281. </ul>
  282. </li>
  283. <li>Einige "Batteriestand niedrig" Benachrichtigungen sind noch nicht
  284. implemeniert (RM100, HMS100WD).</li>
  285. <li>Die Installation ist zu testen bevor man sich auf die
  286. Funktionalit&auml;t verl&auml;sst.</li>
  287. </ul>
  288. <br>
  289. </ul>
  290. <br>
  291. <a name="HMSset"></a>
  292. <b>Set</b> <ul>N/A</ul><br>
  293. <a name="HMSget"></a>
  294. <b>Get</b> <ul>N/A</ul><br>
  295. <a name="HMSattr"></a>
  296. <b>Attributes</b>
  297. <ul>
  298. <li><a href="#ignore">ignore</a></li>
  299. <li><a href="#do_not_notify">do_not_notify</a></li>
  300. <li><a href="#showtime">showtime</a></li>
  301. <li><a href="#IODev">IODev</a></li>
  302. <li><a href="#eventMap">eventMap</a></li>
  303. <li><a href="#model">model</a> (hms100-t hms100-tf hms100-wd hms100-mg
  304. hms100-co hms100-tfk hms100-fit rm100-2)</li>
  305. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  306. </ul>
  307. <br>
  308. </ul>
  309. =end html_DE
  310. =cut