20_X10.pm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. ################################################################
  2. #
  3. # Copyright notice
  4. #
  5. # (c) 2008 Dr. Boris Neubert (omega@online.de)
  6. #
  7. # This script is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # The GNU General Public License can be found at
  13. # http://www.gnu.org/copyleft/gpl.html.
  14. # A copy is found in the textfile GPL.txt and important notices to the license
  15. # from the author is found in LICENSE.txt distributed with these scripts.
  16. #
  17. # This script is distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. # GNU General Public License for more details.
  21. #
  22. # This copyright notice MUST APPEAR in all copies of the script!
  23. #
  24. ################################################################
  25. # $Id: 20_X10.pm 16375 2018-03-10 15:40:02Z neubert $
  26. #
  27. # Internals introduced in this module:
  28. # MODEL distinguish between different X10 device types
  29. # BRIGHT brightness level of dimmer devices in units of microdims (0..210)
  30. #
  31. # Readings introduced in this module:
  32. # state function and argument of last command
  33. # onoff inherited from switch interface (0= on, 1= off)
  34. # dimmer inherited from dimmer interface (0= dark, 100= bright)
  35. #
  36. # Setters introduced in this module:
  37. # on inherited from switch interface
  38. # off inherited from switch interface
  39. # dimmer inherited from dimmer interface (0= dark, 100= bright)
  40. # dimdown inherited from dimmer interface
  41. # dimup inherited from dimmer interface
  42. #
  43. package main;
  44. use strict;
  45. use warnings;
  46. my %functions = ( ALL_UNITS_OFF => "all_units_off",
  47. ALL_LIGHTS_ON => "all_lights_on",
  48. ON => "on",
  49. OFF => "off",
  50. DIM => "dimdown",
  51. BRIGHT => "dimup",
  52. ALL_LIGHTS_OFF => "all_lights_off",
  53. EXTENDED_CODE => "",
  54. HAIL_REQUEST => "",
  55. HAIL_ACK => "",
  56. PRESET_DIM1 => "",
  57. PRESET_DIM2 => "",
  58. EXTENDED_DATA_TRANSFER => "",
  59. STATUS_ON => "",
  60. STATUS_OFF => "",
  61. STATUS_REQUEST => "",
  62. );
  63. my %snoitcnuf; # the reverse of the above
  64. my %functions_rewrite = ( "all_units_off" => "off",
  65. "all_lights_on" => "on",
  66. "all_lights_off" => "off",
  67. );
  68. my %functions_snd = qw( ON 0010
  69. OFF 0011
  70. DIM 0100
  71. BRIGHT 0101 );
  72. my %housecodes_snd = qw(A 0110 B 1110 C 0010 D 1010
  73. E 0001 F 1001 G 0101 H 1101
  74. I 0111 J 1111 K 0011 L 1011
  75. M 0000 N 1000 O 0100 P 1100);
  76. my %unitcodes_snd = qw( 1 0110 2 1110 3 0010 4 1010
  77. 5 0001 6 1001 7 0101 8 1101
  78. 9 0111 10 1111 11 0011 12 1011
  79. 13 0000 14 1000 15 0100 16 1100);
  80. my %functions_set = ( "on" => 0,
  81. "off" => 0,
  82. "dimup" => 1,
  83. "dimdown" => 1,
  84. "dimto" => 1,
  85. "on-till" => 1,
  86. "on-for-timer" => 1,
  87. );
  88. my %models = (
  89. lm12 => 'dimmer',
  90. lm15 => 'switch',
  91. am12 => 'switch',
  92. tm13 => 'switch',
  93. );
  94. my %interfaces = (
  95. lm12 => 'dimmer',
  96. lm15 => 'switch_passive',
  97. am12 => 'switch_passive',
  98. tm13 => 'switch_passive',
  99. );
  100. my @lampmodules = ('lm12','lm15'); # lamp modules
  101. sub
  102. X10_Initialize($)
  103. {
  104. my ($hash) = @_;
  105. foreach my $k (keys %functions) {
  106. $snoitcnuf{$functions{$k}}= $k;
  107. }
  108. $hash->{Match} = "^X10:[A-P];";
  109. $hash->{SetFn} = "X10_Set";
  110. $hash->{StateFn} = "X10_SetState";
  111. $hash->{DefFn} = "X10_Define";
  112. $hash->{UndefFn} = "X10_Undef";
  113. $hash->{ParseFn} = "X10_Parse";
  114. $hash->{AttrList} = "IODev do_not_notify:1,0 " .
  115. "dummy:1,0 showtime:1,0 model:lm12,lm15,am12,tm13";
  116. }
  117. #####################################
  118. sub
  119. X10_SetState($$$$)
  120. {
  121. my ($hash, $tim, $vt, $val) = @_;
  122. return undef;
  123. }
  124. #############################
  125. sub
  126. X10_StateMachine($$$$)
  127. {
  128. my($hash, $time, $function, $argument)= @_;
  129. # the following changes between (onoff,bright) states were
  130. # experimentally observed for a Busch Timac Ferndimmer 2265
  131. # bright and argument are measured in brightness steps
  132. # from 0 (0%) to 210 (100%).
  133. # for convenience, we connect the off state with a 210 bright state
  134. #
  135. # initial on off dimup d dimdown d
  136. # -------------------------------------------------------------------------
  137. # (on,x) -> (on,x) (off,210) (on,x+d) (on,x-d)
  138. # (off,210) -> (on,210) (off,210) (on,210) (on,210-d)
  139. my $onoff;
  140. my $bright;
  141. if(defined($hash->{ONOFF})) {
  142. $onoff= $hash->{ONOFF};
  143. } else {
  144. $onoff= 0; }
  145. if(defined($hash->{BRIGHT})) {
  146. $bright= $hash->{BRIGHT};
  147. } else {
  148. $bright= 0; }
  149. #Log3 $hash, 1, $hash->{NAME} . " initial state ($onoff,$bright)";
  150. if($onoff) {
  151. # initial state (on,bright)
  152. if($function eq "on") {
  153. } elsif($function eq "off") {
  154. $onoff= 0; $bright= 210;
  155. } elsif($function eq "dimup") {
  156. $bright+= $argument;
  157. if($bright> 210) { $bright= 210 };
  158. } elsif($function eq "dimdown") {
  159. $bright-= $argument;
  160. if($bright< 0) { $bright= 0 };
  161. }
  162. } else {
  163. # initial state (off,bright)
  164. if($function eq "on") {
  165. $onoff= 1; $bright= 210;
  166. } elsif($function eq "off") {
  167. $onoff= 0; $bright= 210;
  168. } elsif($function eq "dimup") {
  169. $onoff= 1; $bright= 210;
  170. } elsif($function eq "dimdown") {
  171. $onoff= 1;
  172. $bright= 210-$argument;
  173. if($bright< 0) { $bright= 0 };
  174. }
  175. }
  176. #Log3 $hash, 1, $hash->{NAME} . " final state ($onoff,$bright)";
  177. $hash->{ONOFF}= $onoff;
  178. $hash->{BRIGHT}= $bright;
  179. $hash->{READINGS}{onoff}{TIME}= $time;
  180. $hash->{READINGS}{onoff}{VAL}= $onoff;
  181. $hash->{READINGS}{dimmer}{TIME}= $time;
  182. $hash->{READINGS}{dimmer}{VAL}= int(1000.0*$bright/210.0+0.5)/10.0;
  183. }
  184. #############################
  185. sub
  186. X10_LevelToDims($)
  187. {
  188. # 22= 100%
  189. my ($level)= @_;
  190. my $dim= int(22*$level/100.0+0.5);
  191. return $dim;
  192. }
  193. #############################
  194. sub
  195. X10_Do_On_Till($@)
  196. {
  197. my ($hash, @a) = @_;
  198. return "Timespec (HH:MM[:SS]) needed for the on-till command" if(@a != 3);
  199. my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($a[2]);
  200. return $err if($err);
  201. my @lt = localtime;
  202. my $hms_till = sprintf("%02d:%02d:%02d", $hr, $min, $sec);
  203. my $hms_now = sprintf("%02d:%02d:%02d", $lt[2], $lt[1], $lt[0]);
  204. if($hms_now ge $hms_till) {
  205. Log3 $hash, 4, "on-till: won't switch as now ($hms_now) is later than $hms_till";
  206. return "";
  207. }
  208. if($modules{X10}{ldata}{$a[0]}) {
  209. CommandDelete(undef, $a[0] . "_timer");
  210. delete $modules{FS20}{ldata}{$a[0]};
  211. }
  212. $modules{X10}{ldata}{$a[0]} = "$hms_till";
  213. my @b = ($a[0], "on");
  214. X10_Set($hash, @b);
  215. CommandDefine(undef, $hash->{NAME} . "_timer at $hms_till set $a[0] off");
  216. }
  217. #############################
  218. sub
  219. X10_Do_On_For_Timer($@)
  220. {
  221. my ($hash, @a) = @_;
  222. return "Timespec (HH:MM[:SS]) needed for the on-for-timer command" if(@a != 3);
  223. my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($a[2]);
  224. return $err if($err);
  225. my $hms_for_timer = sprintf("+%02d:%02d:%02d", $hr, $min, $sec);
  226. if($modules{X10}{ldata}{$a[0]}) {
  227. CommandDelete(undef, $a[0] . "_timer");
  228. delete $modules{FS20}{ldata}{$a[0]};
  229. }
  230. $modules{X10}{ldata}{$a[0]} = "$hms_for_timer";
  231. my @b = ($a[0], "on");
  232. X10_Set($hash, @b);
  233. CommandDefine(undef, $hash->{NAME} . "_timer at $hms_for_timer set $a[0] off");
  234. }
  235. ###################################
  236. sub
  237. X11_Write($$$)
  238. {
  239. my ($hash, $function, $dim)= @_;
  240. my $name = $hash->{NAME};
  241. my $housecode= $hash->{HOUSE};
  242. my $unitcode = $hash->{UNIT};
  243. my $x10func = $snoitcnuf{$function};
  244. undef $function; # do not use after this point
  245. my $prefix= "X10 device $name:";
  246. Log3 $name, 5, "$prefix sending X10:$housecode;$unitcode;$x10func $dim";
  247. my ($hc_b, $hu_b, $hf_b);
  248. my ($hc, $hu, $hf);
  249. # Header:Code, Address
  250. $hc_b = "00000100"; # 0x04
  251. $hc = pack("B8", $hc_b);
  252. $hu_b = $housecodes_snd{$housecode} . $unitcodes_snd{$unitcode};
  253. $hu = pack("B8", $hu_b);
  254. IOWrite($hash, $hc, $hu);
  255. # Header:Code, Function
  256. $hc_b = substr(unpack('B8', pack('C', $dim)), 3) . # dim, 0..22
  257. "110"; # always 110
  258. $hc = pack("B8", $hc_b);
  259. $hf_b = $housecodes_snd{$housecode} . $functions_snd{$x10func};
  260. $hf = pack("B8", $hf_b);
  261. IOWrite($hash, $hc, $hf);
  262. }
  263. ###################################
  264. sub
  265. X10_Set($@)
  266. {
  267. my ($hash, @a) = @_;
  268. my $ret = undef;
  269. my $na = int(@a);
  270. # initialization and sanity checks
  271. return "no set value specified" if($na < 2);
  272. my $name= $hash->{NAME};
  273. my $function= $a[1];
  274. my $nrparams= $functions_set{$function};
  275. return "Unknown argument $function, choose one of " .
  276. join(" ", sort keys %functions_set) if(!defined($nrparams));
  277. return "Wrong number of parameters" if($na != 2+$nrparams);
  278. # special for on-till
  279. return X10_Do_On_Till($hash, @a) if($function eq "on-till");
  280. # special for on-for-timer
  281. return X10_Do_On_For_Timer($hash, @a) if($function eq "on-for-timer");
  282. # argument evaluation
  283. my $model= $hash->{MODEL};
  284. my $dim= 0;
  285. if($function =~ m/^dim/) {
  286. return "Cannot dim $name (model $model)" if($models{$model} ne "dimmer");
  287. my $arg= $a[2];
  288. return "Wrong argument $arg, use 0..100" if($arg !~ m/^[0-9]{1,3}$/);
  289. return "Wrong argument $arg, use 0..100" if($arg>100);
  290. if($function eq "dimto") {
  291. # translate dimmer command to dimup/dimdown command
  292. my $bright= 210;
  293. if(defined($hash->{BRIGHT})) { $bright= $hash->{BRIGHT} };
  294. $arg= $arg-100.0*$bright/210.0;
  295. if($arg> 0) {
  296. $function= "dimup";
  297. $dim= X10_LevelToDims($arg);
  298. } else {
  299. $function= "dimdown";
  300. $dim= X10_LevelToDims(-$arg);
  301. }
  302. } else {
  303. $dim= X10_LevelToDims($arg);
  304. }
  305. # the meaning of $dim= 0, 1 is unclear
  306. # if we encounter the need for dimming by such a small amount, we
  307. # ignore it
  308. if($dim< 2) { return "Dim amount too small" };
  309. };
  310. # send command to CM11
  311. X11_Write($hash, $function, $dim) if(!IsDummy($a[0]));
  312. my $v = join(" ", @a);
  313. Log3 $a[0], 2, "X10 set $v";
  314. (undef, $v) = split(" ", $v, 2); # Not interested in the name...
  315. my $tn = TimeNow();
  316. $hash->{CHANGED}[0] = $v;
  317. $hash->{STATE} = $v;
  318. $hash->{READINGS}{state}{TIME} = $tn;
  319. $hash->{READINGS}{state}{VAL} = $v;
  320. X10_StateMachine($hash, $tn, $function, int(210.0*$dim/22.0+0.5));
  321. return undef;
  322. }
  323. #############################
  324. sub
  325. X10_Define($$)
  326. {
  327. my ($hash, $def) = @_;
  328. my @a = split("[ \t][ \t]*", $def);
  329. return "wrong syntax: define <name> X10 model housecode unitcode"
  330. if(int(@a)!= 5);
  331. my $model= $a[2];
  332. return "Define $a[0]: wrong model: specify one of " .
  333. join ",", sort keys %models
  334. if(!grep { $_ eq $model} keys %models);
  335. my $housecode = $a[3];
  336. return "Define $a[0]: wrong housecode format: specify a value ".
  337. "from A to P"
  338. if($housecode !~ m/^[A-P]$/i);
  339. my $unitcode = $a[4];
  340. return "Define $a[0]: wrong unitcode format: specify a value " .
  341. "from 1 to 16"
  342. if( ($unitcode<1) || ($unitcode>16) );
  343. $hash->{MODEL} = $model;
  344. $hash->{HOUSE} = $housecode;
  345. $hash->{UNIT} = $unitcode;
  346. $hash->{internals}{interfaces}= $interfaces{$model};
  347. if(defined($modules{X10}{defptr}{$housecode}{$unitcode})) {
  348. return "Error: duplicate X10 device $housecode $unitcode definition " .
  349. $hash->{NAME} . " (previous: " .
  350. $modules{X10}{defptr}{$housecode}{$unitcode}->{NAME} .")";
  351. }
  352. $modules{X10}{defptr}{$housecode}{$unitcode}= $hash;
  353. AssignIoPort($hash);
  354. }
  355. #############################
  356. sub
  357. X10_Undef($$)
  358. {
  359. my ($hash, $name) = @_;
  360. if( defined($hash->{HOUSE}) && defined($hash->{UNIT}) ) {
  361. delete($modules{X10}{defptr}{$hash->{HOUSE}}{$hash->{UNIT}});
  362. }
  363. return undef;
  364. }
  365. #############################
  366. sub
  367. X10_Parse($$)
  368. {
  369. my ($hash, $msg) = @_;
  370. # message example: X10:N;1 12;OFF
  371. (undef, $msg)= split /:/, $msg, 2; # strip off "X10"
  372. my ($housecode,$unitcodes,$command)= split /;/, $msg, 4;
  373. my @list; # list of selected devices
  374. #
  375. # command evaluation
  376. #
  377. my ($x10func,$arg)= split / /, $command, 2;
  378. my $function= $functions{$x10func}; # translate, eg BRIGHT -> dimup
  379. undef $x10func; # do not use after this point
  380. # the following code sequence converts an all on/off command into
  381. # a sequence of simple on/off commands for all defined devices
  382. my $all_lights= ($function=~ m/^all_lights_/);
  383. my $all_units= ($function=~ m/^all_units_/);
  384. if($all_lights || $all_units) {
  385. $function= $functions_rewrite{$function}; # translate, all_lights_on -> on
  386. $unitcodes= "";
  387. foreach my $unitcode (keys %{ $modules{X10}{defptr}{$housecode} } ) {
  388. my $h= $modules{X10}{defptr}{$housecode}{$unitcode};
  389. my $islampmodule= grep { $_ eq $h->{MODEL} } @lampmodules;
  390. if($all_units || $islampmodule ) {
  391. $unitcodes.= " " if($unitcodes ne "");
  392. $unitcodes.= $h->{UNIT};
  393. }
  394. }
  395. # no units for that housecode
  396. if($unitcodes eq "") {
  397. Log3 $hash, 3, "X10 No units with housecode $housecode, command $command, " .
  398. "please define one";
  399. push(@list,
  400. "UNDEFINED X10_$housecode X10 lm15 $housecode ?");
  401. return @list;
  402. }
  403. }
  404. # apply to each unit in turn
  405. my @unitcodes= split / /, $unitcodes;
  406. if(!int(@unitcodes)) {
  407. # command without unitcodes, this happens when a single on/off is sent
  408. # but no unit was previously selected
  409. Log3 $hash, 3, "X10 No unit selected for housecode $housecode, command $command";
  410. push(@list,
  411. "UNDEFINED X10_$housecode X10 lm15 $housecode ?");
  412. return @list;
  413. }
  414. # function rewriting
  415. my $value= $function;
  416. return @list if($value eq ""); # function not evaluated
  417. # function determined, add argument
  418. if( defined($arg) ) {
  419. # received dims from 0..210
  420. my $dim= $arg;
  421. $value = "$value $dim" ;
  422. }
  423. my $unknown_unitcodes= '';
  424. my $tn= TimeNow();
  425. foreach my $unitcode (@unitcodes) {
  426. my $h= $modules{X10}{defptr}{$housecode}{$unitcode};
  427. if($h) {
  428. my $name= $h->{NAME};
  429. $h->{CHANGED}[0] = $value;
  430. $h->{STATE} = $value;
  431. $h->{READINGS}{state}{TIME} = $tn;
  432. $h->{READINGS}{state}{VAL} = $value;
  433. X10_StateMachine($h, $tn, $function, $arg);
  434. Log3 $hash, 2, "X10 $name $value";
  435. push(@list, $name);
  436. } else {
  437. Log3 $hash, 3, "X10 Unknown device $housecode $unitcode, command $command, " .
  438. "please define it";
  439. push(@list,
  440. "UNDEFINED X10_$housecode X10 lm15 $housecode $unitcode");
  441. }
  442. }
  443. return @list;
  444. }
  445. 1;
  446. =pod
  447. =item summary devices communicating via the X10 protocol
  448. =item summary_DE Anbindung von X10-Ger&auml;ten
  449. =begin html
  450. <a name="X10"></a>
  451. <h3>X10</h3>
  452. <ul>
  453. <a name="X10define"></a>
  454. <b>Define</b>
  455. <ul>
  456. <code>define &lt;name&gt; X10 &lt;model&gt; &lt;housecode&gt;
  457. &lt;unitcode&gt;</code>
  458. <br><br>
  459. Defines an X10 device via its model, housecode and unitcode.<br><br>
  460. Notes:
  461. <ul>
  462. <li><code>&lt;model&gt;</code> is one of
  463. <ul>
  464. <li><code>lm12</code>: lamp module, dimmable</li>
  465. <li><code>lm15</code>: lamp module, not dimmable</li>
  466. <li><code>am12</code>: appliance module, not dimmable</li>
  467. <li><code>tm12</code>: tranceiver module, not dimmable. Its
  468. unitcode is 1.</li>
  469. </ul>
  470. Model determines whether a dim command is reasonable to be sent
  471. or not.</li>
  472. <li><code>&lt;housecode&gt;</code> ranges from A to P.</li>
  473. <li><code>&lt;unitcode&gt;</code> ranges from 1 to 16.</li>
  474. </ul>
  475. <br>
  476. Examples:
  477. <ul>
  478. <code>define lamp1 X10 lm12 N 10</code><br>
  479. <code>define pump X10 am12 B 7</code><br>
  480. <code>define lamp2 X10 lm15 N 11</code><br>
  481. </ul>
  482. </ul>
  483. <br>
  484. <a name="X10set"></a>
  485. <b>Set </b>
  486. <ul>
  487. <code>set &lt;name&gt; &lt;value&gt; [&lt;argument&gt]</code>
  488. <br><br>
  489. where <code>value</code> is one of:<br>
  490. <pre>
  491. dimdown # requires argument, see the note
  492. dimup # requires argument, see the note
  493. off
  494. on
  495. on-till # Special, see the note
  496. on-for-timer # Special, see the note
  497. </pre>
  498. Examples:
  499. <ul>
  500. <code>set lamp1 dimup 10</code><br>
  501. <code>set lamp1,lamp2 off</code><br>
  502. <code>set pump off</code><br>
  503. <code>set lamp2 on-till 19:59</code><br>
  504. <code>set lamp2 on-for-timer 00:02:30</code><br>
  505. </ul>
  506. <br>
  507. Notes:
  508. <ul>
  509. <li>Only switching and dimming are supported by now.</li>
  510. <li>Dimming is valid only for a dimmable device as specified by
  511. the <code>model</code> argument in its <code>define</code>
  512. statement.</li>
  513. <li>An X10 device has 210 discrete brightness levels. If you use a
  514. X10 sender, e.g. a remote control or a wall switch to dim, a
  515. brightness step is 100%/210.</li>
  516. <li><code>dimdown</code> and <code>dimup</code> take a number in the
  517. range from 0 to 22 as argument. It is assumed that argument 1 is
  518. a 1% brightness change (microdim) and arguments 2 to 22 are
  519. 10%..100% brightness changes. The meaning of argument 0 is
  520. unclear.</li>
  521. <li>This currently leads to some confusion in the logs as the
  522. <code>dimdown</code> and <code>dimup</code> codes are logged with
  523. different meaning of the arguments depending on whether the commands
  524. were sent from the PC or from a remote control or a wall switch.</li>
  525. <li><code>dimdown</code> and <code>dimup</code> from on and off states may
  526. have unexpected results. This seems to be a feature of the X10
  527. devices.</li>
  528. <li><code>on-till</code> requires an absolute time in the "at" format
  529. (HH:MM:SS, HH:MM) or { &lt;perl code&gt; }, where the perl code
  530. returns a time specification).
  531. If the current time is greater than the specified time, then the
  532. command is ignored, else an "on" command is generated, and for the
  533. given "till-time" an off command is scheduleld via the at command.
  534. </li>
  535. <li><code>on-for-timer</code> requires a relative time in the "at" format
  536. (HH:MM:SS, HH:MM) or { &lt;perl code&gt; }, where the perl code
  537. returns a time specification).
  538. </li>
  539. </ul>
  540. </ul>
  541. <br>
  542. <a name="X10get"></a>
  543. <b>Get</b> <ul>N/A</ul><br>
  544. <a name="X10attr"></a>
  545. <b>Attributes</b>
  546. <ul>
  547. <li><a href="#do_not_notify">do_not_notify</a></li>
  548. <li><a href="#attrdummy">dummy</a></li>
  549. <li><a href="#showtime">showtime</a></li>
  550. <li><a href="#model">model</a> (lm12,lm15,am12,tm13)</li>
  551. <li><a href="#IODev">IODev</a></li><br>
  552. <li><a href="#eventMap">eventMap</a></li><br>
  553. </ul>
  554. <br>
  555. </ul>
  556. =end html
  557. =cut