forked from HeyuX10Automation/heyu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmd.c
6334 lines (5453 loc) · 217 KB
/
cmd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*----------------------------------------------------------------------------+
| |
| Enhanced HEYU Functionality |
| Copyright 2002-2008 Charles W. Sullivan |
| |
| |
| As used herein, HEYU is a trademark of Daniel B. Suthers. |
| X10, CM11A, and ActiveHome are trademarks of X-10 (USA) Inc. |
| The author is not affiliated with either entity. |
| |
| Charles W. Sullivan |
| Co-author and Maintainer |
| Greensboro, North Carolina |
| Email ID: cwsulliv01 |
| Email domain: -at- heyu -dot- org |
| |
+----------------------------------------------------------------------------*/
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <ctype.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <syslog.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include "x10.h"
#include "process.h"
#include "x10state.h"
#if defined(RAND_MAX)
#define RandMax RAND_MAX
#elif defined(RANDOM_MAX)
#define RandMax RANDOM_MAX
#else
#define RandMax LONG_MAX
#endif
extern int tty, tty_aux;
extern int line_no;
extern int sptty, i_am_relay, i_am_aux, i_am_state;
extern int heyu_parent;
extern int verbose;
extern int xwrite(), xread(), exread(), sxread(), check4poll();
extern int is_modem_support(void);
extern CONFIG config;
extern CONFIG *configp;
extern struct x10global_st x10global;
extern x10hcode_t *x10state;
unsigned char alert_cmd[6];
unsigned char alert_ack[3];
int special_func = 0;
char *typename[] = {"???", "Scene", "Usersyn"};
#if 0 /* Reference - Flags for parse_addr() function */
#define A_VALID 1
#define A_HCODE 2
#define A_BMAP 4
#define A_PLUS 8
#define A_MINUS 16
#define A_ALIAS 32
#define A_DUMMY 64
#define A_MULT 128
#define A_STAR 256
#endif /* Reference */
/* Arguments for the various commands */
static char *helparg[] = {
"[H]", /* 0 HC optional */
"H", /* 1 HC only */
"Hu", /* 2 HC | single unit */
"HU", /* 3 HC | unit string */
"HU <level>", /* 4 Dim/Bright level*/
"HU <level>", /* 5 Preset dim level*/
"<level>", /* 6 Preset dim level only */
"HU <level>", /* 7 Extended Preset level*/
"<T/F> HU <Data>", /* 8 Arbitrary extended code command (hex)*/
"<command ...>", /* 9 Send HC|Funct only, no address */
"xx xx xx ...", /* 10 Arbitrary hex bytes */
"H <\"text\">", /* 11 Arbitrary quoted text message */
"", /* 12 No arguments */
"[<command>]", /* 13 For help command */
"N.NNN", /* 14 Pause delay */
"HU [HU [...]]", /* 15 Multiple addresses */
"HU <command>", /* 16 For Turn command */
"<query_command>", /* 17 Special functions */
"HU <linked>", /* 18 Preset for macros */
"H <mode 0-3>", /* 19 Ext status_ack mode */
"<\"text\">", /* 20 Message to log file */
"NNN", /* 21 Delay in minutes */
"H[U] <count>", /* 22 RF Dim/Bright */
"xx xx <count>", /* 23 Two hex bytes */
"HU <count>", /* 24 RF Dimbo */
"H[u]", /* 25 State commands */
"n[,n...]", /* 26 Flag set/clear commands */
"H[U]", /* 27 Status flag clear command */
"HU <byte>", /* 28 Virtual data */
"N <hh:mm:ss>", /* 29 Countdown timer */
"xxxx xxxx ...", /* 30 Multiple 16-bit hex words */
"<parameters>", /* 31 Special for UX17/23 command */
"HU g <level>", /* 32 Include in group at level*/
"HU g[,g,...]", /* 33 Delete from group(s) */
"H G", /* 34 Execute group[.subgroup] functions */
"HU G", /* 35 Include in group[.subgroup] */
"H g[,g,...]", /* 36 Delete from group(s) */
"HU <level> <ramp>", /* 37 Extended Preset level with ramp */
"N <count>", /* 38 Set counter */
"N", /* 39 Increment or Decrement counter */
"[parameters]", /* 40 Arm system */
"N [MIN] MAX", /* 41 Random countdown timer */
"[MIN] MAX", /* 42 Random delay */
};
static char *options[] = {
"Usage: heyu [options] <command> (Run 'heyu help' for commands)\n",
" [Options]",
" -v Enable verbose mode",
" -c <pathname> Specify full configuration file pathname",
" -s <pathname> Specify full schedule file pathname",
" -0 ... -9 Config file is in subdirectory /0 ... /9",
" of standard location, e.g., $HOME/.heyu/3/x10config",
#ifdef HAVE_LIBXPL
" -interface <if> Change the default interface xPLLib uses",
" -xpldebug Enable xPLLib debugging",
#endif
};
/* Descriptions of "administrative" commands */
static char *helpadmin[][3] = {
{"info","","Display CM11A registers, clock, and upload status"},
{"help","[category|command]","This screen [category or command]"},
{"help","help","Explain help usage"},
{"start","","Start Heyu background processes (daemons)"},
{"stop","","Stop Heyu background processes"},
{"restart","","Reconfigure running Heyu background processes"},
{"engine","","Start the (optional) Heyu state engine daemon"},
{"aux","","Start the (optional) Heyu auxiliary RF input daemon"},
{"monitor","","Monitor X10 activity (end with <BREAK>)"},
{"date","","Return date in date(1) input format"},
{"erase","","Zero CM11A EEPROM, erasing all events and macros"},
{"syn","","Display built-in synonyms for direct commands"},
{"<label>","","Execute a scene or usersyn defined in the config file"},
{"show","<option>","(Enter 'heyu show' to see options)"},
{"script_ctrl","<option>","Launch scripts disable|enable"},
{"initstate","[H[U]]","Zero entire state table or just for address H[U]"},
{"initothers","","Zero cumulative address table"},
{"reset","[H]","Reset interface to housecode H or default"},
{"setclock","","Set CM11A clock to system clock (per schedule)"},
{"readclock","","Display CM11A and system clocks (per schedule)"},
{"newbattery","","Reset CM11A battery timer to zero"},
{"purge","","Cancel pending CM11A delayed macros"},
{"clear","","Clear CM11A registers"},
{"list","","Display Lock, Spool, and System base directory names"},
{"upload","[check|croncheck]","Upload schedule to CM11A or check schedule file"},
{"upload","status|cronstatus","Display status of uploaded schedule"},
{"catchup","","Emulate uploaded Timers from 0:00 to current time today"},
{"trigger","Hu on|off","Emulate Trigger in uploaded schedule"},
{"macro","<label>","Emulate Macro in uploaded schedule"},
{"utility","<option>","(Enter 'heyu utility' to see options)"},
{"logmsg","<\"text\">","Display text message in log file and/or monitor"},
{"wait","[timeout]","Wait until macro execution is completed"},
{"cm10a_init","","Initialize CM10A interface. (For CM10A only!)"},
{"restore_groups","","Restore extended group and xconfig settings"},
{"logtail","[N]","Display tail [N lines] of log file"},
{"sec_emu","Hu <func> <flags>","Emulate an X10 Security signal"},
{"launch","<parameters>","Launch script. Enter 'heyu launch' for usage"},
{"conflist","","Display list of all configuration directives"},
{"modlist","","Display list of all module types"},
{"stateflaglist","","Display list of all state flags"},
{"masklist","","Display lists of all environment variable masks"},
{"webhook","<parameters>","Enter 'heyu webhook' for usage"},
{"version","","Display the Heyu version and exit"},
{NULL, NULL, NULL}
};
static char *helpstate[][3] = {
{"enginestate","","Display 1 if state engine is running, else 0"},
{"armedstate","","Bitmap: 1 = armed, 2 = home, 4 = armpending, 8 = tamper"},
{"sensorfault","","Bitmap: 1 = low battery, 2 = inactive, 8 = tamper"},
{"flagstate","n","Boolean state of flag n"},
{"nightstate","","Boolean state of night flag"},
{"darkstate","","Boolean state of dark flag"},
{"sunstate","","Bitmap: 1 = night, 2 = dark"},
{"spendstate","H[u]","Status-pending bitmap of H or Boolean Hu"},
{"onstate","H[u]","On-state bitmap of H or Boolean Hu"},
{"offstate","H[u]","On-state complement bitmap of H or Boolean Hu"},
{"dimstate","H[u]","Dim-state bitmap of H or Boolean Hu"},
{"fullonstate","H[u]","FullOn-state bitmap of H or Boolean Hu"},
{"chgstate","H[u]","Changed-state bitmap of H or Boolean Hu"},
{"alertstate","H[u]","Alert-state bitmap of H or Boolean Hu"},
{"clearstate","H[u]","Clear-state bitmap of H or Boolean Hu"},
{"auxalertstate","H[u]","AuxAlert-state bitmap of H or Boolean Hu"},
{"auxclearstate","H[u]","AuxClear-state bitmap of H or Boolean Hu"},
{"addrstate","H[u]","Addressed-state bitmap of H or Boolean Hu"},
{"activestate","H[u]","Active-state bitmap of H or Boolean Hu"},
{"inactivestate","H[u]","Inactive-state bitmap of H or Boolean Hu"},
{"lobatstate","H[u]","Low_Battery-state bitmap of H or Boolean Hu"},
{"validstate","H[u]","Valid function state bitmap of H or Boolean Hu"},
{"statestr","H","State mini-bitmaps of all units as ASCII string"},
{"dimlevel","Hu","Brighness level of module Hu as 0-100%"},
{"rawlevel","Hu","Native level (0-210, 1-32, or 0-63) of module Hu"},
{"memlevel","Hu","Stored level 0-100% for module Hu with memory"},
{"rawmemlevel","Hu","Stored native level for module Hu with memory"},
{"heyu_state","Hu","Heyu script environment state bitmap (as integer)"},
{"heyu_rawstate","Hu","Heyu script raw environment state bitmap (as integer)"},
{"heyu_vflagstate","Hu","Heyu script vFlag environment state bitmap (as integer)"},
#if 0
#if defined(HAVE_FEATURE_RFXS) || defined(HAVE_FEATURE_RFXM)
{"rfxflag_state","Hu","RFXsensor/RFXmeter flag state bitmap (as integer)"},
#endif
#ifdef HAVE_FEATURE_ORE
{"oreflag_state","Hu","Oregon (Electrisave, Owl) flag state bitmap (as integer)"},
#endif
#ifdef HAVE_FEATURE_DMX
{"dmxflag_state","Hu","Digimax flag state bitmap (as integer)"},
#endif
#endif
{"xtend_state","Hu","Xtend script environment state bitmap (as integer)"},
{"rcstemp","H","RCS compatible temperature (stored value)"},
{"fetchstate","","See man page heyu(1)"},
{NULL, NULL, NULL}
};
#ifdef HAVE_FEATURE_RFXS
static char *helprfxsensor[][3] = {
{"rfxtemp","Hu","Temperature"},
{"rfxrh","Hu","Relative Humidity"},
{"rfxbp","Hu","Barometric Pressure"},
{"rfxpot","Hu","Potentiometer setting"},
{"rfxvs","Hu","Supply Voltage"},
{"rfxvad","Hu","A/D Voltage"},
{"rfxvadi","Hu","Internal A/D Voltage"},
{"rfxlobat","Hu","Low Battery state (Boolean)"},
{"rfxtemp2","Hu","Second Temperature"},
{NULL, NULL, NULL}
};
#endif /* HAVE_FEATURE_RFXS */
#ifdef HAVE_FEATURE_RFXM
static char *helprfxmeter[][3] = {
{"rfxpower","Hu","Watt-Hour meter reading"},
{"rfxpanel","[n]","Total Watt-Hours for Power Panel [n]"},
{"rfxwater","Hu","Water meter reading"},
{"rfxgas","Hu","Gas meter reading"},
{"rfxpulse","Hu","Pulse meter reading"},
{"rfxcount","Hu","Raw counter of any meter"},
{NULL, NULL, NULL}
};
#endif /* HAVE_FEATURE_RFXM */
#ifdef HAVE_FEATURE_DMX
static char *helpdigimax[][3] = {
{"dmxtemp","Hu","DigiMax current temperature (C)"},
{"dmxsetpoint","Hu","DigiMax setpoint temperature (C)"},
{"dmxstatus","Hu","DigiMax On/Off status (1 = On)"},
{"dmxmode","Hu","DigiMax Heat/Cool mode (1 = Heat)"},
{NULL, NULL, NULL}
};
#endif /* HAVE_FEATURE_DMX */
#ifdef HAVE_FEATURE_ORE
static char *helporegon[][3] = {
{"oretemp","Hu","Oregon sensor Temperature"},
{"orerh","Hu","Oregon sensor Relative Humidity"},
{"orebp","Hu","Oregon sensor Barometric Pressure"},
{"oredt","Hu","Oregon radio clock Date and Time"},
{"orewindavsp","Hu","Oregon sensor Wind Average Speed"},
{"orewindsp","Hu","Oregon sensor Wind Instantaneous Speed"},
{"orewinddir","Hu","Oregon sensor Wind Direction"},
{"orerainrate","Hu","Oregon sensor Rainfall Rate"},
{"oreraintot","Hu","Oregon sensor Total Rainfall"},
{"ore_emu","Hu <func> <data>","Enter data in Oregon emulation module"},
{"elscurr","Hu","Electrisave CM113 Current"},
{"owlpower","Hu","Owl CM119 Power"},
{"owlenergy","Hu","Owl CM119 Energy"},
{NULL, NULL, NULL}
};
#endif /* HAVE_FEATURE_ORE */
/* Descriptions of direct and uploaded macro commands */
static char *helpdirect[] = {
/* 0 */ "Turn units ON",
/* 1 */ "Turn units OFF",
/* 2 */ "Turn All Lights ON",
/* 3 */ "Turn All Lights OFF (**)",
/* 4 */ "Turn All Units OFF",
/* 5 */ "Dim units by <level> (1-22)",
/* 6 */ "Dim units by <level> (1-22) after full bright",
/* 7 */ "Brighten units by <level> (1-22)",
/* 8 */ "Brighten units by <level> (1-22) after full bright",
/* 9 */ "Request ON/OFF status (two-way modules)",
/* 10 */ "Status Acknowledge ON",
/* 11 */ "Status Acknowledge OFF",
/* 12 */ "Preset units to <level> (1-32)",
/* 13 */ "Preset to <level> (1-32) (function only)",
/* 14 */ "Extended Preset <level> (0-63) (LM14A)",
/* 15 */ "Extended All Units ON (LM14A)",
/* 16 */ "Extended All Units OFF (LM14A)",
/* 17 */ "Extended Status Request (LM14A)",
/* 18 */ "Extended Status Acknowledge",
/* 19 */ "Extended command - general",
/* 20 */ "Extended command - general, await ack",
/* 21 */ "Send arbitrary hex bytes as addresses",
/* 22 */ "Send Housecode|Units addresses only",
/* 23 */ "Send command function only",
/* 24 */ "Hail other devices",
/* 25 */ "Hail Acknowledge",
/* 26 */ "Send quoted text (special protocol)",
/* 27 */ "Data Transfer (function code 0xC)",
/* 28 */ "Send All_Units_Off to All Housecodes",
/* 29 */ "Extended Turn Units Full ON (LM14A)",
/* 30 */ "Extended Turn Units Full OFF (LM14A)",
/* 31 */ "This screen, or specific command help",
/* 32 */ "Display synonyms for direct commands",
/* 33 */ "Hail other devices, await ack",
/* 34 */ "Legacy status command as above",
/* 35 */ "Legacy preset command as above",
/* 36 */ "Pause for N.NNN seconds",
/* 37 */ "Turn Units 1-16 ON",
/* 38 */ "Change state on|off|up|down [vv]",
/* 39 */ "Legacy turn command as above",
/* 40 */ "Request temperature (RCS compatible)",
/* 41 */ "Send bytes directly to interface",
/* 42 */ "Limited Preset for macros - see manpage",
/* 43 */ "Extended config auto status mode (LM14A)",
/* 44 */ "Request RCS compatible status",
/* 45 */ "Delay for NNN minutes, NNN = 0-240",
/* 46 */ "Pause until next tick of system clock",
/* 47 */ "Transmit RF On",
/* 48 */ "Transmit RF Off",
/* 49 */ "Transmit RF Dims [after On]",
/* 50 */ "Transmit RF Brights [after On]",
/* 51 */ "Transmit RF All Lights On",
/* 51 */ "Transmit RF All Lights Off (**)",
/* 53 */ "Transmit RF All Units Off",
/* 54 */ "Transmit RF Arbitrary 2-byte hex code",
/* 55 */ "Reset CM17A device",
/* 56 */ "Transmit RF Dims after Off",
/* 57 */ "Transmit RF Dims [after On] (#)",
/* 58 */ "Transmit RF Brights [after On] (#)",
/* 59 */ "Transmit RF Dims after Off (#)",
/* 60 */ "Transmit RF Arbitrary 2-byte hex code (#)",
/* 61 */ "Open shutter to level (0-25), enforce limit",
/* 62 */ "Set limit (0-25) and open shutter to limit",
/* 63 */ "Open shutter to level (0-25) and cancel limit",
/* 64 */ "Open all shutters fully and cancel limit",
/* 65 */ "Close all shutters fully",
/* 66 */ "Extended module power-up signal (LM14A)",
/* 67 */ "Set one or more flags (@)",
/* 68 */ "Clear one or more flags (@)",
/* 69 */ "Clear status-pending flags (@)",
/* 70 */ "Write data (0-255) to virtual module (@)",
/* 71 */ "Set countdown timer N to hh:mm:ss (@)",
/* 72 */ "Reset all countdown timers to zero (@)",
/* 73 */ "Transmit RF multiple 16-bit hex words",
/* 74 */ "Clear security tamper flags (@)",
/* 75 */ "Transmit RF multiple 16-bit hex words (#)",
/* 76 */ "Special for UX23A/UX17A - see manpage",
/* 77 */ "Special for UX23A/UX17A - see manpage (#)",
/* 78 */ "Sleep for N.NNN seconds",
/* 79 */ "Include in Group (G = 0-3) at current level",
/* 80 */ "Remove HU from one or more Groups (g = 0-3)",
/* 81 */ "Execute extended Group G function (LM14A)",
/* 82 */ "Extended Group G Status Request (LM14A)",
/* 83 */ "Remove H from one or more Groups (g = 0-3)",
/* 84 */ "Include in Group (g = 0-3) at <level>",
/* 85 */ "Extended Group G Off (**)",
/* 86 */ "Extended Group G Dim one level (**)",
/* 87 */ "Extended Group G Bright one level (**)",
/* 88 */ "Extended Preset <level> (0-63) <ramp> (0-3)",
/* 89 */ "Set counter N to <count> (0-64K) (@)",
/* 90 */ "Increment counter N by 1 (@)",
/* 91 */ "Decrement counter N by 1 (@)",
/* 92 */ "Decrement counter N and skip if Zero (@)",
/* 93 */ "Decrement counter N and skip if Greater than Zero (@)",
/* 94 */ "Arm system [home|away] [min|max] (@)",
/* 95 */ "Disarm system (@)",
/* 96 */ "Delay random time [MIN-]MAX minutes (0-240)",
/* 97 */ "Set timer N to random [MIN-]MAX hh:mm:ss (@)",
/* 98 */ "Write mem data (0-255) to virtual module (@)",
/* 99 */ "Null command - does nothing (@)",
/*100 */ "Dec counter N and skip if Non-Zero or Initial Zero (@)",
/*101 */ "Null command - does nothing",
/*102 */ "Emulate Status Acknowledge for 1-way modules",
};
void display_helpnotes ( void )
{
printf("\n (*) Not available for use in uploaded macros.\n");
printf(" (**) Many lamp modules do NOT support this command.\n");
#ifdef HAVE_FEATURE_CM17A
printf(" (#) Fast CM17A command - see man x10cm17a(5) for configuration.\n");
#endif
printf(" (@) Ignored unless state engine is running.\n");
return;
}
void display_manpage_list ( void )
{
printf("\n Man pages:\n heyu(1), x10config(5), x10sched(5), x10scripts(5), x10aux(5)");
#ifdef HAVE_FEATURE_CM17A
printf(", x10cm17a(5)");
#endif
#ifdef HAVE_FEATURE_RFXS
printf(", x10rfxsensors(5)");
#endif
#ifdef HAVE_FEATURE_RFXM
printf(", x10rfxmeters(5)");
#endif
#ifdef HAVE_FEATURE_DMX
printf(", x10digimax(5)");
#endif
#ifdef HAVE_FEATURE_ORE
printf(", x10oregon(5)");
#endif
#ifdef HAVE_FEATURE_KAKU
printf(", x10kaku(5)");
#endif
printf(".\n\n");
return;
}
/* Flags for x10command table below */
#define F_ALL 0x00000001 /* "All" command; no unit code required on input */
#define F_DED 0x00000002 /* Display extended code data byte in report */
#define F_NOA 0x00000004 /* Suppress HC|Unit address byte transmission */
#define F_BRI 0x00000008 /* Brighten before dimming */
#define F_FAD 0x00000010 /* Force HC|Unit address byte(s) transmission */
#define F_ARB 0x00000020 /* Use special format for arbitrary extended code */
#define F_NMA 0x00000040 /* Unavailable as an uploadable macro */
#define F_HID 0x00000080 /* Hidden command */
#define F_STA 0x00000100 /* Status/xStatus Request (await status) */
#define F_NUM 0x00000200 /* Arguments are all numbers */
#define F_HLP 0x00000400 /* For help menu only - not a CM11A command */
#define F_NMAI 0x00000800 /* Unavailable and ignored for uploaded macro */
#define F_TRN 0x00001000 /* For Turn command */
#define F_SPF 0x00002000 /* For special function processing */
#define F_MAC 0x00004000 /* Special version for uploaded macros */
#define F_FIR 0x00008000 /* CM17A (Firecracker) command */
#define F_FFM 0x00010000 /* CM17A "fast" mode */
#define F_SHU 0x00020000 /* Extended Type 0 (Marmitek SW10) shutter commands */
#define F_EXT 0x00040000 /* Extended Type 3 (LM14A, AM14A) commands */
#define F_FLSC 0x00080000 /* Flag set and clear commands */
#define F_GRP 0x00100000 /* Extended code group commands */
#define F_ONN 0x00200000 /* On required before brightening */
#define F_INT 0x00400000 /* Internal - no PLC interface required */
#define F_DUM 0x00800000 /* No PLC interface required */
#define F_RFS (F_FIR | F_NMA)
#define F_RFF (F_FIR | F_NMA | F_FFM)
#define F_FLG (F_FLSC | F_NMA | F_NUM)
#define F_XGP (F_GRP | F_EXT)
/*---------------------------------------------------------------------+
| Master table of commands and synonyms. The first of any grouping |
| having all fields identical except for the label is considered the |
| command; subsequent entries in the grouping are treated as built-in |
| synonyms. |
+---------------------------------------------------------------------*/
/* Names for arbitrary extended code functions */
#define XARBNAME "xfunc"
#define XARBNAMEW "xfuncw"
static struct cmd_list {
char *label;
unsigned char code;
int length; /* Length as a macro */
int minargs;
int maxargs;
unsigned long flags;
unsigned char subcode; /* Type|command for extended code commands */
unsigned char subsubcode;
unsigned char argtype;
unsigned char help;
} x10command[] = {
{"on", 2, 3, 1, 1, 0, 0, 0, 3, 0 }, /* Simple ON command */
{"turnon", 2, 3, 1, 1, 0, 0, 0, 3, 0 }, /* Simple ON command */
{"off", 3, 3, 1, 1, 0, 0, 0, 3, 1 }, /* Simple OFF command */
{"turnoff", 3, 3, 1, 1, 0, 0, 0, 3, 1 }, /* Simple OFF command */
{"bright", 5, 4, 2, 2, 0, 0, 0, 4, 7 }, /* Brighten command */
{"turnup", 5, 4, 2, 2, 0, 0, 0, 4, 7 }, /* Brighten command */
{"up", 5, 4, 2, 2, 0, 0, 0, 4, 7 }, /* Brighten command */
{"brighten", 5, 4, 2, 2, 0, 0, 0, 4, 7 }, /* Brighten command */
{"tbright", 5, 4, 2, 2, F_NMA | F_HID, 1, 0, 4, 7 }, /* Brighten command - triggered */
{"brightb", 5, 4, 2, 2, F_BRI, 0, 0, 4, 8 }, /* Brighten command with brighten first */
{"bbright", 5, 4, 2, 2, F_BRI, 0, 0, 4, 8 }, /* Brighten command with brighten first */
{"dim", 4, 4, 2, 2, 0, 0, 0, 4, 5 }, /* Dim command without brighten first */
{"turndown", 4, 4, 2, 2, 0, 0, 0, 4, 5 }, /* Dim command without brighten first */
{"down", 4, 4, 2, 2, 0, 0, 0, 4, 5 }, /* Dim command without brighten first */
{"dimb", 4, 4, 2, 2, F_BRI, 0, 0, 4, 6 }, /* Dim command with brighten first */
{"bdim", 4, 4, 2, 2, F_BRI, 0, 0, 4, 6 }, /* Dim command with brighten first */
{"obdim", 4, 4, 2, 2, F_BRI | F_ONN, 0, 0, 4, 6 }, /* Dim command with on, brighten first */
{"tdim", 4, 4, 2, 2, F_NMA | F_HID, 1, 0, 4, 5 }, /* Dim command - triggered */
{"lightson", 1, 3, 1, 1, F_ALL, 0, 0, 1, 2 }, /* All_Lights_On */
{"lights_on", 1, 3, 1, 1, F_ALL, 0, 0, 1, 2 }, /* All_Lights_On */
{"all_lights_on", 1, 3, 1, 1, F_ALL, 0, 0, 1, 2 }, /* All_Lights_On */
{"alllightson", 1, 3, 1, 1, F_ALL, 0, 0, 1, 2 }, /* All_Lights_On */
{"lightsoff", 6, 3, 1, 1, F_ALL, 0, 0, 1, 3 }, /* All_Lights_Off */
{"lights_off", 6, 3, 1, 1, F_ALL, 0, 0, 1, 3 }, /* All_Lights_Off */
{"all_lights_off", 6, 3, 1, 1, F_ALL, 0, 0, 1, 3 }, /* All_Lights_Off */
{"alllightsoff", 6, 3, 1, 1, F_ALL, 0, 0, 1, 3 }, /* All_Lights_Off */
{"allon", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"all_on", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"all_units_on", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"allunitson", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"units_on", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"unitson", 26,-1, 1, 1, F_ALL, 0, 0, 1,37 }, /* Units 1-16 On */
{"alloff", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"all_off", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"all_units_off", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"allunitsoff", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"units_off", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"unitsoff", 0, 3, 1, 1, F_ALL, 0, 0, 1, 4 }, /* All_Units_Off */
{"turn", 27,-1, 1,-1, F_TRN, 0, 0,16,38 }, /* Turn command */
{"preset", 10, 3, 2, 2, F_NMA, 0, 0, 5,12 }, /* Old Preset (not for macro) */
{"preset_dim", 10, 3, 2, 2, F_NMA, 0, 0, 5,12 }, /* Old Preset (not for macro) */
{"preset", 11, 3, 2, 2, F_NMA | F_HID, 0, 0, 5,12 }, /* Old Preset (not for macro) */
{"preset_dim", 11, 3, 2, 2, F_NMA | F_HID, 0, 0, 5,12 }, /* Old Preset (not for macro) */
{"mpreset", 10, 3, 2, 2, F_MAC, 0, 0,18,42 }, /* Limited old Preset for macros */
{"macro_preset", 10, 3, 2, 2, F_MAC, 0, 0,18,42 }, /* Limited old Preset for macros */
{"mpreset", 11, 3, 2, 2, F_MAC | F_HID, 0, 0,18,42 }, /* Limited old Preset for macros */
{"macro_preset", 11, 3, 2, 2, F_MAC | F_HID, 0, 0,18,42 }, /* Limited old Preset for macros */
{"preset_level", 10, 3, 1, 1, F_NOA | F_NUM, 0, 0, 6,13 }, /* Old Preset with no address byte */
{"presetlevel", 10, 3, 1, 1, F_NOA | F_NUM, 0, 0, 6,13 }, /* Old Preset with no address byte */
{"preset_level", 11, 3, 1, 1, F_NOA|F_NUM|F_HID, 0, 0, 6,13 }, /* Old Preset with no address byte */
{"presetlevel", 11, 3, 1, 1, F_NOA|F_NUM|F_HID, 0, 0, 6,13 }, /* Old Preset with no address byte */
{"status", 15, 3, 1, 1, F_STA, 0, 0, 3, 9 }, /* Status Request */
{"status_req", 15, 3, 1, 1, F_STA, 0, 0, 3, 9 }, /* Status Request */
{"statusreq", 15, 3, 1, 1, F_STA, 0, 0, 3, 9 }, /* Status Request */
{"status_on", 13, 3, 1, 1, F_ALL, 0, 0, 3,10 }, /* Status On */
{"statuson", 13, 3, 1, 1, F_ALL, 0, 0, 3,10 }, /* Status On */
{"status_off", 14, 3, 1, 1, F_ALL, 0, 0, 3,11 }, /* Status Off */
{"statusoff", 14, 3, 1, 1, F_ALL, 0, 0, 3,11 }, /* Status Off */
{"status_emu", 48,-1, 1, 1, F_NMA|F_HID, 0, 0, 2,102}, /* Emulate Status Ack */
{"hail", 8, 3, 0, 1, F_ALL, 0, 0, 0,24 }, /* Hail Request */
{"hail_req", 8, 3, 0, 1, F_ALL, 0, 0, 0,24 }, /* Hail Request */
{"hailw", 8, 3, 0, 1, F_ALL|F_STA|F_NMA, 0, 0, 0,33 }, /* Hail Request, wait for ack */
{"hail_ack", 9, 3, 0, 1, F_ALL, 0, 0, 0,25 }, /* Hail Acknowledge */
{"hailack", 9, 3, 0, 1, F_ALL, 0, 0, 0,25 }, /* Hail Acknowledge */
{"data_xfer", 12, 3, 1, 1, F_ALL, 0, 0, 1,27 }, /* Extended data transfer (0xC) */
{"dataxfer", 12, 3, 1, 1, F_ALL, 0, 0, 1,27 }, /* Extended data transfer (0xC) */
{"xon", 7, 6, 1, 1, F_EXT | F_DED, 0xfe, 0, 3,29 }, /* Extended Full ON (LM14A) */
{"xoff", 7, 6, 1, 1, F_EXT | F_DED, 0xfd, 0, 3,30 }, /* Extended Full OFF (LM14A) */
{"xpreset", 7, 6, 2, 2, F_EXT | F_DED, 0x31, 0, 7,14 }, /* Extended Preset Dim (LM14A) */
{"ext_preset", 7, 6, 2, 2, F_EXT | F_DED, 0x31, 0, 7,14 }, /* Extended Preset Dim (LM14A) */
{"xdim", 7, 6, 2, 2, F_EXT | F_DED, 0x31, 0, 7,14 }, /* Extended Preset Dim (LM14A) */
{"xpresetramp", 7, 6, 3, 3, F_EXT|F_DED|F_HID|F_NMA, 0x31, 0,37,88 }, /* Extended Preset Dim with ramp */
{"xallon", 7, 6, 1, 1, F_EXT | F_ALL, 0x33, 0, 1,15 }, /* Extended All Units On */
{"xall_on", 7, 6, 1, 1, F_EXT | F_ALL, 0x33, 0, 1,15 }, /* Extended All Units On */
{"ext_all_on", 7, 6, 1, 1, F_EXT | F_ALL, 0x33, 0, 1,15 }, /* Extended All Units On */
{"xalloff", 7, 6, 1, 1, F_EXT | F_ALL, 0x34, 0, 1,16 }, /* Extended All Units Off */
{"xall_off", 7, 6, 1, 1, F_EXT | F_ALL, 0x34, 0, 1,16 }, /* Extended All Units Off */
{"ext_all_off", 7, 6, 1, 1, F_EXT | F_ALL, 0x34, 0, 1,16 }, /* Extended All Units Off */
{"xstatus", 7, 6, 1, 1, F_EXT | F_STA, 0x37, 0, 3,17 }, /* Extended Status Request */
{"ext_status", 7, 6, 1, 1, F_EXT | F_STA, 0x37, 0, 3,17 }, /* Extended Status Request */
{"ext_status_req", 7, 6, 1, 1, F_EXT | F_STA, 0x37, 0, 3,17 }, /* Extended Status Request */
{"xconfig", 7, 6, 2, 2, F_EXT|F_ALL|F_DED, 0x3b, 0,19,43 }, /* Extended Auto Status Mode */
{"xpowerup", 7, 6, 1, 1, F_EXT, 0x37, 1, 3,66 }, /* Extended Module PowerUp */
{"xpup", 7, 6, 1, 1, F_EXT, 0x37, 1, 3,66 }, /* Extended Module PowerUp */
{"xgrpadd", 7, 6, 2, 2, F_XGP, 0x30, 0,35,79 }, /* Extended add to group */
{"xga", 7, 6, 2, 2, F_XGP, 0x30, 0,35,79 }, /* Extended add to group */
{"xgrpaddlvl", 7, 6, 3, 3, F_XGP, 0x32, 0,32,84 }, /* Extended add to group at level */
{"xgal", 7, 6, 3, 3, F_XGP, 0x32, 0,32,84 }, /* Extended add to group at level */
{"xgrprem", 7, 6, 2, 2, F_XGP, 0x35, 0,33,80 }, /* Extended remove from group(s) */
{"xgr", 7, 6, 2, 2, F_XGP, 0x35, 0,33,80 }, /* Extended remove from group(s) */
{"xgrpremall", 7, 6, 2, 2, F_XGP | F_ALL, 0x35, 3,36,83 }, /* Extended delete from group(s) */
{"xgra", 7, 6, 2, 2, F_XGP | F_ALL, 0x35, 3,36,83 }, /* Extended delete from group(s) */
{"xgrpexec", 7, 6, 2, 2, F_XGP | F_ALL, 0x36, 0,34,81 }, /* Extended delete from group */
{"xgx", 7, 6, 2, 2, F_XGP | F_ALL, 0x36, 0,34,81 }, /* Extended delete from group */
{"xgrpexec", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x36, 2,34,81 }, /* (Needed for report.txt) */
{"xgrpstatus", 7, 6, 2, 2, F_XGP | F_STA, 0x37, 2,35,82 }, /* Extended group status request */
{"xgs", 7, 6, 2, 2, F_XGP | F_STA, 0x37, 2,35,82 }, /* Extended group status request */
{"xgrpstatusreq", 7, 6, 2, 2, F_XGP | F_STA, 0x37, 2,35,82 }, /* Extended group status request */
{"xgrpstatus", 7, 6, 2, 2, F_XGP|F_STA|F_HID, 0x37, 3,35,82 }, /* (Needed for report.txt) */
{"xgrpoff", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x36, 1,34,85 }, /* Ext group Off - maybe!!!*/
{"xgrpdim", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x3c, 0,34,86 }, /* Ext group Dim */
{"xgrpdim", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x3c, 2,34,86 }, /* (Needed for report.txt) */
{"xgrpbright", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x3c, 1,34,87 }, /* Ext group Bright */
{"xgrpbright", 7, 6, 2, 2, F_XGP|F_ALL|F_HID, 0x3c, 3,34,87 }, /* (Needed for report.txt) */
{ XARBNAME, 7, 6, 3, 3, F_ARB, 0xff, 0, 8,19 }, /* Extended code - arbitrary */
{ XARBNAMEW, 7, 6, 3, 3, F_ARB|F_STA|F_NMA, 0xff, 0,8,20 }, /* Extended Status Req - arbitrary */
{"address", 20,-1, 1,-1, F_NMA, 0, 0,15,22 }, /* Address bytes only (*)*/
{"function", 21,-1, 1,-1, F_NOA, 0, 0, 9,23 }, /* HC|Func byte only */
{"kill_all_hc", 24,-1, 0, 0, 0, 0, 0,12,28 }, /* Send All_Units_Off to all housecodes */
{"pause", 25,-1, 1, 1, F_NMA|F_NUM|F_DUM, 0, 0,14,36 }, /* Pause seconds (locked) */
{"sleep", 41,-1, 1, 1, F_NMA|F_NUM|F_DUM, 0, 0,14,78 }, /* Sleep seconds (unlocked) */
{"delay", 32,-1, 1, 1, F_NMA|F_NUM|F_DUM, 0, 0,21,45 }, /* Delay minutes (unlocked) */
{"rdelay", 45,-1, 1, 2, F_NMA|F_NUM|F_DUM, 0, 0,42,96 }, /* Random delay minutes (unlocked) */
{"rcs_req", 28,-1, 1,-1, F_SPF | F_NMA, 0, 0,17,44 }, /* RCS-compatible general status query */
{"temp_req", 28,-1, 1,-1, F_SPF | F_NMA, 0, 0,17,40 }, /* RCS-compatible temperature query */
{"vdata", 37,-1, 2, 2, F_NMA|F_DUM, 0, 0,28,70 }, /* Virtual data */
{"vdatam", 37,-1, 2, 2, F_NMA|F_DUM, 1, 0,28,98 }, /* Virtual memory data */
{"command2cm11a", 31,-1, 1,-1, F_NMA|F_NUM|F_HID, 0, 0,10,41 }, /* Send bytes directly to interface */
{"bytes2cm11a", 29,-1, 1,-1, F_NMA|F_NUM|F_HID, 0, 0,10,41 }, /* Send bytes directly to interface */
{"sendbytes", 22,-1, 1,-1, F_NMA|F_NUM|F_HID, 0, 0,10,21 }, /* Send arbitrary hex bytes (*)*/
{"sendtext", 23,-1, 2, 2, F_NMA|F_ALL|F_HID, 0, 0,11,26 }, /* Send (quoted) text message (*)*/
{"pausetick", 33,-1, 0, 0, F_NMA|F_HID|F_DUM, 0, 0,12,46 }, /* Pause until next tick of sys clock */
{"arm", 43,-1, 0, 4, F_NMA|F_NUM|F_DUM, SETFLAG, 0,40,94 }, /* Arm system */
{"disarm", 43,-1, 0, 0, F_NMA|F_NUM|F_DUM, CLRFLAG, 0,12,95 }, /* Disarm system */
{"setflag", 35,-1, 1, 1, F_FLG|F_DUM, SETFLAG, 0,26,67 }, /* Set software flags */
{"setflags", 35,-1, 1, 1, F_FLG|F_DUM, SETFLAG, 0,26,67 }, /* Set software flags */
{"clrflag", 35,-1, 1, 1, F_FLG|F_DUM, CLRFLAG, 0,26,68 }, /* Clear software flags */
{"clrflags", 35,-1, 1, 1, F_FLG|F_DUM, CLRFLAG, 0,26,68 }, /* Clear software flags */
{"settimer", 38,-1, 2, 2, F_NMA|F_NUM|F_DUM, 0, 0,29,71 }, /* Set countdown timer */
{"setrtimer", 46,-1, 2, 3, F_NMA|F_NUM|F_DUM, 0, 0,41,97 }, /* Set random countdown timer */
{"clrtimers", 39,-1, 0, 0, F_NMA|F_NUM|F_DUM, 0, 0,12,72 }, /* Reset all timers to zero */
{"clrspend", 36,-1, 1, 1, F_NMA|F_DUM, 0, 0,27,69 }, /* Clear status flags */
{"clrstatus", 36,-1, 1, 1, F_NMA|F_DUM, 0, 0,27,69 }, /* Clear status flags */
{"clrtamper", 40,-1, 0, 0, F_NMA|F_NUM|F_DUM, 0, 0,12,74 }, /* Clear tamper flags */
{"setcount", 42,-1, 2, 2, F_NMA|F_NUM|F_DUM, CNT_SET, 0,38,89 }, /* Set counter value */
{"setc", 42,-1, 2, 2, F_NMA|F_NUM|F_DUM, CNT_SET, 0,38,89 }, /* Set counter value */
{"inccount", 42,-1, 1, 1, F_NMA|F_NUM|F_DUM, CNT_INC, 0,39,90 }, /* Increment counter value */
{"incc", 42,-1, 1, 1, F_NMA|F_NUM|F_DUM, CNT_INC, 0,39,90 }, /* Increment counter value */
{"deccount", 42,-1, 1, 1, F_NMA|F_NUM|F_DUM, CNT_DEC, 0,39,91 }, /* Decrement counter value */
{"decc", 42,-1, 1, 1, F_NMA|F_NUM|F_DUM, CNT_DEC, 0,39,91 }, /* Decrement counter value */
{"null", 47,-1, 0, 0, F_NMA|F_DUM, 0, 0, 12,101 }, /* Null, does nothing */
{"@arm", 43,-1, 0, 4, F_FLG|F_INT, SETFLAG, 0,40,94 }, /* Arm system */
{"@disarm", 43,-1, 0, 0, F_FLG|F_INT, CLRFLAG, 0,12,95 }, /* Disarm system */
{"@setflag", 35,-1, 1, 1, F_FLG|F_INT, SETFLAG, 0,26,67 }, /* Set software flags */
{"@setflags", 35,-1, 1, 1, F_FLG|F_INT, SETFLAG, 0,26,67 }, /* Set software flags */
{"@setf", 35,-1, 1, 1, F_FLG|F_INT, SETFLAG, 0,26,67 }, /* Set software flags */
{"@clrflag", 35,-1, 1, 1, F_FLG|F_INT, CLRFLAG, 0,26,68 }, /* Clear software flags */
{"@clrflags", 35,-1, 1, 1, F_FLG|F_INT, CLRFLAG, 0,26,68 }, /* Clear software flags */
{"@clrf", 35,-1, 1, 1, F_FLG|F_INT, CLRFLAG, 0,26,68 }, /* Clear software flags */
{"@settimer", 38,-1, 2, 2, F_NMA|F_NUM|F_INT, 0, 0,29,71 }, /* Set countdown timer */
{"@sett", 38,-1, 2, 2, F_NMA|F_NUM|F_INT, 0, 0,29,71 }, /* Set countdown timer */
{"@setrtimer", 46,-1, 2, 3, F_NMA|F_NUM|F_INT, 0, 0,41,97 }, /* Set random countdown timer */
{"@clrtimers", 39,-1, 0, 0, F_NMA|F_NUM|F_INT, 0, 0,12,72 }, /* Reset all timers to zero */
{"@clrt", 39,-1, 0, 0, F_NMA|F_NUM|F_INT, 0, 0,12,72 }, /* Reset all timers to zero */
{"@clrspend", 36,-1, 1, 1, F_NMA|F_INT, 0, 0,27,69 }, /* Clear status pending flags */
{"@clrstatus", 36,-1, 1, 1, F_NMA|F_INT, 0, 0,27,69 }, /* Clear status pending flags */
{"@clrs", 36,-1, 1, 1, F_NMA|F_INT, 0, 0,27,69 }, /* Clear status pending flags */
{"@vdata", 37,-1, 2, 2, F_NMA|F_INT, 0, 0,28,70 }, /* Virtual data */
{"@vdatam", 37,-1, 2, 2, F_NMA|F_INT, 1, 0,28,98 }, /* Virtual memory data */
{"@setcount", 42,-1, 2, 2, F_NMA|F_NUM|F_INT, CNT_SET, 0,38,89 }, /* Set counter value */
{"@setc", 42,-1, 2, 2, F_NMA|F_NUM|F_INT, CNT_SET, 0,38,89 }, /* Set counter value */
{"@inccount", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_INC, 0,39,90 }, /* Increment counter value */
{"@incc", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_INC, 0,39,90 }, /* Increment counter value */
{"@deccount", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DEC, 0,39,91 }, /* Decrement counter value */
{"@decc", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DEC, 0,39,91 }, /* Decrement counter value */
{"@decskpz", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DSKPZ, 0,39,92 }, /* Dec Skip Z */
{"@decskpgz", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DSKPNZ, 0,39,93 }, /* Dec Skip GTZ */
{"@decskpnziz", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DSKPNZIZ, 0,39,100 }, /* Dec Skip NZ or Init Z */
{"@decskpnz", 42,-1, 1, 1, F_NMA|F_NUM|F_INT, CNT_DSKPNZIZ, 0,39,100 }, /* Dec Skip NZ or Init Z */
{"@null", 44,-1, 0, 0, F_NMA|F_INT, 0, 0,12,99 }, /* Null command */
#ifdef HAVE_FEATURE_EXT0 /* Extended Type 0 (SW10 shutter controller) commands */
{"shopen", 7, 6, 2, 2, F_DED | F_SHU, 0x03, 0, 7,63 }, /* Shutter open, ignore limit */
{"shopenlim", 7, 6, 2, 2, F_DED | F_SHU, 0x01, 0, 7,61 }, /* Shutter open, enforce limit */
{"shsetlim", 7, 6, 2, 2, F_DED | F_SHU, 0x02, 0, 7,62 }, /* Shutter set limit */
{"shopenall", 7, 6, 1, 1, F_ALL | F_SHU, 0x04, 0, 1,64 }, /* Shutter all full open */
{"shcloseall", 7, 6, 1, 1, F_ALL | F_SHU, 0x0B, 0, 1,65 }, /* Shutter all full close */
#endif
#ifdef HAVE_FEATURE_CM17A /* CM17A ("Firecracker") commands */
{"freset", 34,-1, 0, 0, F_RFS, 8, 0,12,55 }, /* CM17A Reset */
{"fon", 34,-1, 1, 1, F_RFS, 2, 0, 3,47 }, /* CM17A On RF command */
{"foff", 34,-1, 1, 1, F_RFS, 3, 0, 3,48 }, /* CM17A Off RF command */
{"fbright", 34,-1, 2, 2, F_RFS, 5, 0,22,50 }, /* CM17A Bright RF command */
{"fdim", 34,-1, 2, 2, F_RFS, 4, 0,22,49 }, /* CM17A Dim RF command */
{"fdimbo", 34,-1, 2, 2, F_RFS, 7, 0,24,56 }, /* CM17A Dimb RF command */
{"flightson", 34,-1, 1, 1, F_RFS | F_ALL, 1, 0, 1,51 }, /* CM17A AllLightsOn RF command */
{"flightsoff", 34,-1, 1, 1, F_RFS | F_ALL, 6, 0, 1,52 }, /* CM17A AllLightsOff RF command */
{"falloff", 34,-1, 1, 1, F_RFS | F_ALL, 0, 0, 1,53 }, /* CM17A AllUnitsOff RF command */
{"farb", 34,-1, 3, 3, F_RFS | F_NUM, 9, 0,23,54 }, /* CM17A Arbitrary RF command */
{"farw", 34,-1, 1,-1, F_RFS | F_NUM, 10, 0,30,73 }, /* CM17A Arbit 16 bit RF command */
{"flux", 34,-1, 3,-1, F_RFS | F_NUM, 11, 0,31,76 }, /* CM17A Arbit UX17/23 RF command */
{"ffbright", 34,-1, 2, 2, F_RFF, 5, 0,22,58 }, /* CM17A Fast Bright RF command */
{"ffdim", 34,-1, 2, 2, F_RFF, 4, 0,22,57 }, /* CM17A Fast Dim RF command */
{"ffdimbo", 34,-1, 2, 2, F_RFF, 7, 0,24,59 }, /* CM17A Dimb RF command */
{"ffarb", 34,-1, 3, 3, F_RFF | F_NUM, 9, 0,23,60 }, /* CM17A Fast Arbit RF command */
{"ffarw", 34,-1, 1,-1, F_RFF | F_NUM, 10, 0,30,75 }, /* CM17A Arbit 16 bit RF command */
{"fflux", 34,-1, 3,-1, F_RFF | F_NUM, 11, 0,31,77 }, /* CM17A Arbit UX17/23 RF command */
#endif
};
int nx10cmds = sizeof(x10command)/sizeof(struct cmd_list);
/* Function labels for monitor display (must align with enum in process.h) */
/* (with fake add-on function "AllOn") */
char *funclabel[77] = {
"AllOff", "LightsOn", "On", "Off", "Dim", "Bright", "LightsOff",
"Extended", "Hail", "HailAck", "Preset", "Preset",
"DataXfer", "StatusOn", "StatusOff", "StatusReq", "AllOn",
"xPowerUp", "vData", "vDataM", "Panic", "Arm", "Disarm",
"Alert", "Clear", "Test", "sLightsOn", "sLightsOff", "secTamper",
"sDusk", "sDawn", "AkeyOn", "AkeyOff", "BkeyOn", "BkeyOff",
"rfxTemp", "rfxTemp2", "rfxRH", "rfxBP", "rfxVad", "rfxPot", "rfxVs",
"rfxLoBat", "rfxOther", "rfxPulse", "rfxPower", "rfxWater", "rfxGas",
"rfxCount", "dmxTemp", "dmxOn", "dmxOff", "dmxSetpoint",
"oreTemp", "oreRH", "oreBP", "oreWgt",
"oreWindSp", "oreWindAvSp", "oreWindDir",
"oreRainRate", "oreRainTot", "elsCurr", "oreUV",
"kOff", "kOn", "kGrpOff", "kGrpOn", "kUnkFunc", "kPreset", "kGrpPreset", "kUnkPresetFunc",
"owlPower", "owlEnergy", "Inactive", "oreDT",
"_Invalid_",
};
char *ext3funclabel[17] = {
"", "xPreset", "", "xAllOn", "xAllOff", "", "", "xStatusReq", "xStatusAck",
"", "", "xConfig", "", "", "", "", "xPowerUp",
};
char *rfxfunclabel[8] = {
"rfxTemp", "rfxTemp2", "rfxHumidity", "rfxPressure", "rfxVad",
"rfxVs", "rfxLoBat", "rfxOther",
};
char *rcs_temp ( int function, int predim, char hc, int unit )
{
static char buffer[80];
int temp;
if ( (function != 10 && function != 11) || unit < 11 ) {
buffer[0] = '\0';
return (char *)NULL;
}
temp = -60 + (predim - 1) + 32 * (unit - 11);
sprintf(buffer, " Temperature =%3d : Location %c\n",
temp, toupper((int)hc));
return buffer;
}
/*---------------------------------------------------------------------+
| Return the length of a macro element corresponding to the |
| argument command code. |
+---------------------------------------------------------------------*/
int macro_element_length ( unsigned char cmdcode )
{
int j, length = -1;
for ( j = 0; j < nx10cmds; j++ ) {
if ( x10command[j].code == cmdcode && x10command[j].length > 0 ) {
length = x10command[j].length;
break;
}
}
return length;
}
/*---------------------------------------------------------------------+
| Return 1 if argument command label is in the administrative command |
| (help) table, otherwise return 0. |
+---------------------------------------------------------------------*/
int is_admin_cmd ( char *label )
{
int j;
j = 0;
while ( helpadmin[j][0] != NULL ) {
if ( strcmp(label, helpadmin[j][0]) == 0 )
return 1;
j++;
}
return 0;
}
/*---------------------------------------------------------------------+
| Return 1 if argument command label is in the x10command[] table, |
| otherwise return 0. |
+---------------------------------------------------------------------*/
int is_direct_cmd ( char *label )
{
int j;
for ( j = 0; j < nx10cmds; j++ ) {
if ( strcmp(label, x10command[j].label) == 0 &&
!(x10command[j].flags & F_HLP) )
return 1;
}
return 0;
}
/*---------------------------------------------------------------------+
| Return 1 if argument command label is a scene or is in the |
| x10command[] table, otherwise return 0. |
+---------------------------------------------------------------------*/
int is_heyu_cmd ( char *label )
{
if ( strchr(label, ';') || strchr(label, ' ') || strchr(label, '\t') ) {
/* Possible compound command */
return 1;
}
if ( lookup_scene(configp->scenep, label) >= 0 ) {
return 1;
}
if ( is_direct_cmd(label) ) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------+
| Return a double random number between 0.0 and 1.0 |
+---------------------------------------------------------------------*/
double random_float ( void )
{
static int is_seeded;
unsigned int seed;
struct timeval tvstruct, *tv = &tvstruct;
if ( !is_seeded ) {
gettimeofday(tv, NULL);
seed = (unsigned long)tv->tv_sec + (unsigned long)tv->tv_usec;
srandom(seed);
is_seeded = 1;
}
return (double)random() / (double)RandMax;
}
/*---------------------------------------------------------------------+
| Sleep for argument milliseconds. |
+---------------------------------------------------------------------*/
void millisleep( long millisec )
{
#ifdef HAVE_NSLEEP
struct timestruc_t tspec;
if ( millisec == 0 )
return;
tspec.tv_sec = millisec / 1000;
tspec.tv_nsec = 1000000L * (millisec % 1000);
while ( nsleep( &tspec, &tspec ) == -1 );
#else
#ifndef HAVE_NANOSLEEP
struct timeval tspec;
#else
struct timespec tspec;
#endif /* HAVE_NANOSLEEP */
if ( millisec == 0 )
return;
#ifndef HAVE_NANOSLEEP
tspec.tv_sec = millisec / 1000;
tspec.tv_usec = 1000 * (millisec % 1000);
while ( usleep(tspec.tv_usec) == -1 );
#else
tspec.tv_sec = millisec / 1000;
tspec.tv_nsec = 1000000L * (millisec % 1000);
while ( nanosleep( &tspec, &tspec ) == -1 );
#endif /* HAVE_NANOSLEEP */
#endif /* HAVE_NSLEEP */
return;
}
/*---------------------------------------------------------------------+
| Sleep for argument microseconds. |
+---------------------------------------------------------------------*/
void microsleep( long microsec )
{
#ifdef HAVE_NSLEEP
struct timestruc_t tspec;
if ( microsec == 0 )
return;
tspec.tv_sec = microsec / 1000000L;
tspec.tv_nsec = 1000L * (microsec % 1000000L);
while ( nsleep( &tspec, &tspec ) == -1 );
#else
#ifndef HAVE_NANOSLEEP
struct timeval tspec;
#else
struct timespec tspec;
#endif
if ( microsec == 0 )
return;
#ifndef HAVE_NANOSLEEP
tspec.tv_sec = microsec / 1000000;
tspec.tv_usec = microsec % 1000000;
while ( usleep(tspec.tv_usec) == -1 );
#else
tspec.tv_sec = microsec / 1000000L;
tspec.tv_nsec = 1000L * (microsec % 1000000L);
while ( nanosleep( &tspec, &tspec ) == -1 );
#endif /* HAVE_NANOSLEEP */
#endif /* HAVE_NSLEEP */
return;
}
/*---------------------------------------------------------------------+
| Compare two commands. Return 0 if identical except for label. |
+---------------------------------------------------------------------*/
static int cmp_commands( struct cmd_list *one, struct cmd_list *two )
{
if ( !one || !two ||
one->flags != two->flags ||
one->code != two->code ||
one->subcode != two->subcode ||
one->length != two->length ||
one->minargs != two->minargs ||
one->maxargs != two->maxargs ||
one->argtype != two->argtype ||
one->help != two->help )
return 1;
return 0;
}
/*---------------------------------------------------------------------+
| Parse the units string. Pass back the X10 units bitmap through the |
| argument list. Return 0 if valid bitmap, otherwise write error msg |
| to error handler and return 1. Unit 0 is considered a valid unit |
| number but doesn't appear in the bitmap unless it's the only unit, |
| whereupon the bitmap will be 0. |
+---------------------------------------------------------------------*/
int parse_units ( char *str, unsigned int *bitmap )
{
static int umap[] = {6,14,2,10,1,9,5,13,7,15,3,11,0,8,4,12};
char buffer[256];