To use this file copy and paste this:
// #URL-lib "http://pin1.org/forthlib/flb/Miscl/HA Interface v1.0.fth" into BV Terminal 3
or here to download.
// Home Automation Project
// S. Clarkson
// 03-Feb-2009
//
// REQUIRES:
// #URL-lib "http://pin1.org/forthlib/flb/General/soft1.flb" sid=99
// #URL-lib "http://pin1.org/forthlib/flb/General/pinsel.flb" sid=100
Full Contents of File
variable  I_kWh-p
variable  I_alm-set
variable  I_intrude
variable  O_led
: init-io
 16  io1-in
 17  io1-in
 18  io1-in
 27  io1-in
 28  io1-in
 31  io0-out
;
: scan-in
 
 16  p1@  I_kwh-p  !
 17  p1@  I_alm-set  !
 18  p1@  I_intrude  !
;
: wr-out
 
 O_led  @  31  p0!
;
variable  kW
variable  kwh
variable  kwh-1000th
variable  osf
variable  a1 
variable  pr
variable  bpos
variable  prev-c
variable  inpkt   
variable  Address 
2  constant  STX
6  constant  ACK
21  constant  NAK
3  constant  ETX
16  constant  DLE
1  constant  SOH
27  constant  ESC
20  constant  SYNC-CLK
21  constant  RQ-KWH
22  constant  SD-KWH
23  constant  RQ-W
24  constant  SD-W
20  constant  BLEN 
BLEN  vspace$  d-buff 
BLEN  vspace$  s-buff 
: inpkt?
 inpkt  @  0  <>
;
: c-buf
 
 0  bpos  ! 
 BLEN  for  0  i  d-buff  +  c!  next
 0  inpkt  !
;
: dump-buf
INT:  k
 
 0  =>  k
 begin
   key1?  k  ETX  <>  and
 while
   key1  =>  k
   prev-c  @  ESC  =  if  0  =>  k  then 
   k  prev-c  !
 repeat
 
 c-buf
 0  prev-c  !
;
: stx?
 -1   
 inpkt?  0  =  if
   drop
   0
   key1?  if
     
     drop
     prev-c  @  ESC  <> 
     key1  dup  prev-c  ! 
     STX  =  and   
     dup  if  -1  inpkt  !  then   
   then 
 then
;
: get-buf
 
 
 -2 
 bpos  @  BLEN  <  if
   drop 
   -3 
   key1?  if
     drop
     prev-c  @  ESC  <>   
     key1  dup  prev-c  ! 
     dup  ESC  <>  if 
       dup  d-buff  bpos  @  +  c! 
       bpos  @  1  +  bpos  ! 
     then
     ETX  =  and 
   then
 then
;
: getall
 
 begin
   get-buf  dup  0  =
 while
   drop
 repeat
;
: send-data
 kwh  @  iu.
 46  emit1
 kwh-1000th  @  iu.
 32  emit1
 kw  @  iu.
 87  emit1
 13  emit1
 10  emit1
 10  emit1
;
: send-nak
 NAK  emit1
;
: send-ack
 ACK  emit1
;
: chk-len?
 
int:  len
 -1
 bpos  @  6  <  if
   drop
   send-nak
   0
 then
 
 
 d-buff  3  +  c@  =>  len   
 bpos  @  6  len  +  <>  if
   
   drop
   send-nak
   0
 then
 
;
: !sync-clk
 send-ack
;
: !send-kwh 
 send-ack
 STX  emit1
 Address  @  emit1
 src  emit1
 SD-KWH  emit1
 9  emit1
 kwh  @  <#  #  #  #  #  #  #>  stype1
 46  emit1
 kwh-1000th  @  <#  #  #  #  #>  stype1
 0  emit1 
 ETX  emit1
;
: !send-w
 send-ack
 STX  emit1
 Address  @  emit1
 src  emit1
 SD-W  emit1
 5  emit1
 kw  @  <#  #  #  #  #  #  #>  stype1
 0  emit1 
 ETX  emit1
;
: do-pkt
 
int:  src  cmd  len  crc
 
 chk-len?  if 
   
   
   d-buff  c@  =>  src
   d-buff  2  +  c@  =>  cmd
   d-buff  3  +  c@  =>  len
   d-buff  4  len  +  +  c@  =>  crc
   
   
   
   cmd  SYNC-CLK  =  if
     
     src  !sync-clk
   then
   cmd  RQ-KWH  =  if
     
     src  !send-kwh
     0  kwh  !  0  kwh-1000th  !
   then
   cmd  RQ-W  =  if
     
     src  !send-w
   then
 then
;
: parse-pkt
 
int#:  ourmsg  0   
 
 p-status  -3  <>  if
   
   
   bpos  1  >  if
     
     d-buff  1  +  c@  Address  @  =  =>  ourmsg
   then
   p-status  -2  =  if
     
     
     dump-buf
     ourmsg  if  send-nak  then
   then
   p-status  -1  =  if
     
     
     
     ourmsg  if
       do-pkt
     then
     
     c-buf
   then
 then
;
: do-comms
 
 stx?  if
   
   
   getall  parse-pkt
 then
 
;
: 1st-scan
 
 
 
 1000  set-t1
 1500  set-t2
 700  set-t3
 180000000  set-t4   
 1  O_led  !
 0  kW  !
 0  kwh  !
 0  kwh-1000th  !  
 0  osf  !
;
: ob1
 
 
 t4-dn  0  =  if  en-t4  then
 
 osf  @  1  =  I_kwh-p  @  0  <>  and  if
   en-t2
 then
 osf  @  1  =  t2-dn  and  if
   
   0  osf  !
   
   5  kwh-1000th  @  +  kwh-1000th  !
   
   kwh-1000th  @  999  >  if
     0  kwh-1000th  !
     1  kwh  @  +  kwh  !
   then
   
   kwh  @  0  <>  kwh-1000th  @  0  <>  or  if
     
     t4pre  @  dup  t4acc  @  - 
     
     t4pre  @  t4acc  !
   then
   1  pr  !
 then
 I_kwh-p  @  0  =  if 
   en-t1 
 then   
 
 t1-dn  if
   1  osf  !
 then
 
 
 t2-dn  t3-tt  or  if 
   en-t3
 then
 1  O_led  ! 
 t3-tt  if 
   0  O_led  ! 
 then
;
: ob1-test
 
 I_kwh-p  @  O_led  !
;
: sys-init
 init-io 
 65  Address  !
 c-buf 
 1st-scan 
 t-init
;
: sgl-step
   scan-in
   ob1
   wr-out
   do-comms
   
   TSTATS
;
: test-m
   scan-in
   ob1-test
   wr-out
   do-comms
   
   TSTATS
;
: run
 sys-init
 
 begin
   27  p1@  -1  =
 while
   
   28  p1@  -1  =  if
     sgl-step
   then
   
   28  p1@  0  =  if
     test-m
   then
 repeat
 drop  drop
 
 
 
 1  O_led  !
 
 wr-out
;