DECUServe VMS Conference 3064.7 [Next-Reply] [Prev-Reply] [Next-Topic] [Prev-Topic] [ConfDir-Paged-New>Old] [ConfDir-Paged-Old>New] [ConfDir-All-New>Old][ConfDir-All-Old>New] Directory of conferences This topic directory --------------------------------------------------------------------------- Note 3064.7 X10 / X-10 / BSR / Home Automation 7 of 15 EISNER::COVERT "John.Covert@Compaq.com" 130 lines 10-JAN-2000 09:51 -< Now VMS responds to X10 events and runs DCL procedures as macros >- -------------------------------------------------------------------------------- I wrote a little bit of code to deal with processing received X10 signals (from the various hand-held remotes around the house, the motion detectors, any 2-way modules I might possibly buy, etc.). I used what I consider an interesting technique, that may be applicable to things you might want to do in other situations. There is a fairly simple program (next reply) which reads the data from the CM11 and passes it to DCL through a pipe. The DCL code can process the incoming data, maintaining context from one call to the next because even though repeatedly invoked (possibly with a newer version of the procedure each time) it runs in the same DCL PIPE subprocess, and any global symbols are maintained. It uses GROUP logicals to communicate with the outside world, in particular, to see if any of the remote buttons have been assigned to macros -- which are other DCL procedures. The procedure name and its arguments are named in the macro definition. I only defined a few before I decided to call it a night: "CM11_MACRO B8 Off" = "firewrapper!indoor off" "CM11_MACRO B8 On" = "firewrapper!indoor on" "CM11_MACRO D2 On" = "firewrapper!b12 off c16 on" At system startup, the following runs from my account: $ run/detach/input=cm11_daemon.com/out=cm11.log/auth sys$system:dcl This is cm11_daemon.com; note the PIPE command. CM11.EXE shouldn't ever exit, but in case it does, it's started again. $! $! CM11 daemon $! $ allocate tta3 $ define term_dev tta3 $ set proc/name="CM11 Daemon" $ set noon $ set ter tta3/nottsy/nohostsy/pasthru/typeahead/eight $ set nover $loop: $ pipe run cm11 | @cm11pipe $ goto loop This is cm11pipe.com: $ set noon $loop: $ read sys$pipe/end=endloop linen $ write sys$output linen $ @cm11.com "''linen'" $ goto loop $endloop: $ exit And this is CM11.com: $! $! This command procedure gets every output line from cm11.exe $! $! Because of the way it is invoked, global symbols are persistent. $! $ count = %x'f$extract(24,2,p1)' $ if count .eq. 0 .or. count .gt. 10 then exit $ if f$length(p1) .le. 26 then exit ! no actual data $ datetime=f$extract(0,24,p1) $ mask = " " $ mask[0,8] = %x'f$extract(26,2,p1)' $ i=0 $ count=count-1 $ text="" $interploop: $ if i .eq. count then goto endinterploop $ nibblehigh=%x'f$extract(i*2+28,1,p1)' $ nibblelow=%x'f$extract(i*2+29,1,p1)' $ housecode=f$extract(nibblehigh,1,"MECKOGAINFDLPHBJ") $ if f$cvui(i,1,mask) ! Bit set means function $ then $ function=f$element(nibblelow,"/","All Units Off/All Lights On/On/Off/Dim/Bright/All Lights Off/Extended Code/Hail Request/Hail Acknowledge/Pre-set Dim (1)/Pre-set Dim (2)/Extended Data Transfer/Status On/Status Off/Status Request") $ if nibblelow .eq. 4 .or. nibblelow .eq. 5 ! Dim or Bright $ then $ i=i+1 $ dimamount=%x'f$extract(i*2+28,2,p1)' $ function=housecode+" "+function+" ''dimamount'" $ endif $ if nibblelow .eq. 7 ! Extended Code $ then $ i=i+2 $ extdata=%x'f$extract(i*2+26,2,p1)' $ extcommand=%x'f$extract(i*2+28,2,p1)' $ function=function+" ''extdata' ''extcommand'" $ endif $ macro=f$logical("CM11_MACRO ''lastaddress' ''function'") $ if macro .nes. "" then submit/nolog 'f$element(0,"!",macro)'/par="''f$element(1,"!",macro)'" $ text=text+function+" " $ else ! Bit not set means address $ unit=f$cvsi(0,8,f$extract(nibblelow,1,"MECKOGAINFDLPHBJ"))-f$cvsi(0,8,"A")+1 $ lastaddress==housecode+"''unit'" $ text=text+housecode+"''unit' " $ endif $ i=i+1 $ goto interploop $endinterploop: $ write sys$output datetime," ",text $ if f$logical("cm11_speak") then submit/nolog/que:serial_jobs script /par=(say,"''text'") $ nml $ if .not. f$logical("cm11_noreply") then repl/ter='f$logical("john_main_term")' "''p1' ''text'" $ nor $ exit And this is the one procedure I'm using so far as a macro (firewrapper). It "unwraps" p1 into multiple arguments for firecracker.com (enhanced since I originally posted it to loop through multiple arguments) or can do other things. Of course, "indoor" could have been a completely separate procedure, and it will soon be modified to get its units from a configuration file; this example was written at quarter of two, and it was time to do something quick and quit for the night. $if f$extract(0,6,p1) .eqs. "indoor" then goto indoor $@firecracker 'p1' $exit: $indoor: $ onoff=f$extract(7,3,p1) $@firecracker b1 'onoff' b2 'onoff' b3 'onoff' b4 'onoff' $@firecracker b5 'onoff' b6 'onoff' b12 'onoff' b13 'onoff' $@firecracker b15 'onoff' b16 'onoff' c1 'onoff' c2 'onoff' $@firecracker c7 'onoff' c15 'onoff' c16 'onoff' d5 'onoff' $@firecracker d6 'onoff' d7 'onoff' $ exit /john --------------------------------------------------------------------------- [Next-Reply] [Prev-Reply] [Next-Topic] [Prev-Topic] [ConfDir-Paged-New>Old] [ConfDir-Paged-Old>New] [ConfDir-All-New>Old][ConfDir-All-Old>New] Directory of conferences This topic directory --------------------------------------------------------------------------- DECUServe on-line conferencing system - consulting for peanuts DECnotes Script provided by Roland Kessi, 21 February 1996