home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / aprs72a.zip / NWSPARSE.BAS < prev    next >
BASIC Source File  |  1995-01-17  |  10KB  |  222 lines

  1. Init: 'First set up the constants
  2.       DTG$ = "131218z"'a test time
  3.       Period = 30'seconds (real world should be 30 or more)
  4.       MaxNum = 18 'Max number of OBJects (max of 18 or screen scrolls!)
  5.                   'Make this smaller to limit the QRM you are transmitting
  6.                   'and accumulating on everyone's screen!
  7.       UNvia$ = "APRS VIA WIDE"
  8.       MyPOS$ = "!0000.00N/00000.00W!Automatic NWS bulletin Parser"
  9.                REM Put your POSIT in this string so that U show on the map!
  10.       DIM P$(MaxNum + 1)'Make room for MaxNum different objects
  11.       DIM Count(MaxNum + 1)
  12.  
  13. CLS : PRINT "                           APRS NWS PARSER": PRINT
  14. PRINT "This program will parse incomming NWS bulletins on COM1 and output APRS"
  15. PRINT "OBJECTS and BULLETINS via a TNC connected to COM2. (or also COM1 !)"
  16. PRINT ""
  17. PRINT "The overall objective is to convert all available information on a tropical"
  18. PRINT "storm into a plottable APRS storm object, and all of its forcast  future "
  19. PRINT "positions.  So far, the following syntax is parsed, where ... is any length,"
  20. PRINT "and ___ means exact spaces.  Lower case are data fields extracted:"
  21. REM    Programmers, please keep this list updated as you add more parsing!
  22. PRINT
  23. PRINT "... NNNN                             (indicates start of a new message"
  24. PRINT "... xxxxZ .... dd_1995               (message date/time. Change this in 96..."
  25. PRINT "... TROPICAL STORM_name.... ADVISORY NUMBER"
  26. PRINT "... TROPICAL STORM .... LOCATED NEAR__lattN_longW"
  27. PRINT "... CENTRAL PRESSURE_pres"
  28. PRINT "... MOVEMENT TOWARD .....xxx_DEGREES.... xx_KT"
  29. PRINT "... FORCAST VALID_datetime_lattN_longW"
  30. PRINT "... OUTLOOK VALID_datetime_lattN_longW"
  31. PRINT "... MAX SUSTAINED... xx_KT_comments"
  32. PRINT "... MAX WINDS... xx_KT_comments"; ""
  33. PRINT
  34. PRINT "Enter the period between packets ("; Period; ")"; : INPUT a$
  35.        IF a$ <> "" THEN Period = VAL(a$)
  36. CLS
  37. PRINT "This is just a beginning of this capability.  I am making this program"
  38. PRINT "available as source code, so that others can add additional NWS parsing."
  39. PRINT "You will need to manually modify portions of the code to match your needs."
  40. PRINT
  41. PRINT "Since the program only listens to incomming messages and only outputs packets"
  42. PRINT "to a TNC, a single COM port can be used for both functions!  Just connect the"
  43. PRINT "incomming data to the COM1 RXD, and the TNC to TXD.  Be sure the TNC is at"
  44. PRINT "9600 baud (or whatever you have in this program).  The program will set the"
  45. PRINT "TNC to CONV mode so that it will transmit all packets over the air."
  46. PRINT
  47. PRINT "Other programmers, add instructions here..."
  48. PRINT
  49. PRINT "As distributed, this program has a TEST line in the GETMORE subroutine at"
  50. PRINT "the end of the program, to simulate serial data input.  To begin parsing"
  51. PRINT "REAL serial data, simply REM out that statement."
  52. PRINT
  53.  OPEN "COM1:9600,N,8,1,CD0,CS0,DS0" FOR RANDOM AS #1  'For NWS messages
  54. PRINT "Enter UNPROTO path to be used by TNC ("; UNvia$; ")"; : INPUT a$
  55.        IF a$ <> "" THEN UNvia$ = a$
  56.  
  57.  REM   OPEN "COM2:9600,N,8,1,CD0,CS0,DS0" FOR RANDOM AS #2 'For TNC output
  58.  REM to use separate COM ports for input and output, remove the REM in the
  59.  REM above line to activate COM2, and scan the program for "OUTPORT" and
  60.  REM change the port numbers there to #2....
  61.  
  62. InitTNC: T = TIMER: PRINT #1, CHR$(3); CHR$(3); CHR$(3);
  63.          DO UNTIL TIMER - T > 1: LOOP
  64.          PRINT #1, "UNPROTO "; UNvia$; CHR$(13);
  65.          DO UNTIL TIMER - T > 2: LOOP
  66.          PRINT #1, "CONV"; CHR$(13);
  67. CLS
  68. PRINT "The following is a list of the packets currently in the transmit queue."
  69. PRINT "The number indicates how many more times the particular packet will be sent."
  70. PRINT
  71. PRINT "NUM OBJECT   DA-TIME LAT      LONG      CSE SPD COMMENTS.... "
  72. PRINT "--- -------- ------- -------- ---------$--- --- -------------"
  73. Main: REM Scan the text comming in COM1 forever, and each time you see a key
  74.       REM word, try to build a position report out of it.  Once a complete
  75.       REM position report or object report is put together, add it to the
  76.       REM P$() array.  Then send out these OBJECTS from the P$() array at
  77.       REM regular intervals.  Decrement the COUNT() counter, and stop sending
  78.       REM when the COUNT for each object gets to 0.
  79.       REM TO TEST THIS THING, PUT THINGS IN a$ in the GETMORE subroutine
  80.   DO
  81.      GOSUB Getmore 'Get next line of message from serial port #1
  82.      LOCATE 25, 1: PRINT "Parsing: "; LEFT$(a$ + SPACE$(70), 70);
  83.      a = INSTR(a$, "NNNN"): IF a > 0 THEN GOSUB BeginNEW
  84.      a = INSTR(a$, "1995"): IF a > 0 THEN GOSUB GetDate
  85.      a = INSTR(a$, "TROPICAL STORM"): IF a > 0 THEN GOSUB Tropical
  86.      a = INSTR(a$, "MOVEMENT TOWARD"): IF a > 0 THEN GOSUB Movement
  87.      a = INSTR(a$, "CENTRAL PRESSURE"): IF a > 0 THEN GOSUB Pressure
  88.      a = INSTR(a$, "MAX SUSTAINED"): IF a > 0 THEN GOSUB Winds
  89.      a = INSTR(a$, "FORECAST VALID"): IF a > 0 THEN GOSUB Forecast
  90.      a = INSTR(a$, "MAX WIND"): IF a > 0 THEN GOSUB Winds
  91.      a = INSTR(a$, "OUTLOOK VALID"): IF a > 0 THEN GOSUB Forecast
  92.      IF Pos$ <> "" AND CSpd$ <> "" AND Cmts$ <> "" THEN GOSUB BuildPOS
  93.      IF TIMER - LastPkt > Period THEN GOSUB SendNext
  94.      IF TIMER - LastPOS > 600 THEN GOSUB SendMyPos
  95.      LOCATE 4, 68: PRINT "ToGo:"; Period - INT(TIMER - LastPkt);
  96.   LOOP
  97.   END
  98. '********************** SUBROUTINES FOLLOW ***************************
  99.  
  100. BeginNEW: REM Clear everything to get ready for new message
  101.           Pos$ = "": CSpd$ = "": Name$ = ""
  102.           TropStrm = 0
  103.           RETURN
  104.  
  105. GetDate:  DTG$ = "******/": IF a > 3 THEN Day$ = MID$(a$, a - 3, 2)
  106.           b = INSTR(a$, "Z"): IF b > 4 THEN DTG$ = Day$ + MID$(a$, b - 4, 5)
  107.           RETURN
  108.  
  109.  
  110. Tropical: sym$ = "@": REM symbol for a Hurricane
  111.           b = INSTR(a$, "ADVISORY NUMBER")
  112.           IF b > 0 THEN  ' Get the storm NAME
  113.              Num$ = MID$(a$, b + 17)
  114.              c = INSTR(a + 18, a$, " ")' Find ending space of name
  115.              Name$ = MID$(a$, a + 16, c - 16) + Num$
  116.              Name$ = LEFT$(Name$ + "         ", 9)
  117.           END IF
  118.           b = INSTR(a$, "LOCATED NEAR") ' Get the POSIT
  119.           IF b > 0 THEN L = b + 13: T = 0: TropStrm = 1: GOSUB ParsePos
  120.           RETURN
  121.  
  122. ParsePos: REM Parse out LAT/LONG beginning at location L and TIME at T
  123.           REM also find TIME if after L
  124.     LAT = VAL(MID$(a$, L, 4)): LATd = INT(LAT): LATm = LAT - LATd
  125.     LON = VAL(MID$(a$, L + 6, 5)): LONd = INT(LON): LONm = LON - LONd
  126.     LAT$ = MID$(STR$(LATd), 2, 2) + MID$(STR$(INT(LATm * 60)), 2, 2) + ".00N"
  127.     LON$ = "0" + MID$(STR$(LONd), 2, 2) + RIGHT$("0" + MID$(STR$(INT(LONm * 60)), 2), 2) + ".00W"
  128.     c = INSTR(a$, " AT "): IF c > L THEN T = c + 4
  129.     IF T > 0 THEN TIM$ = MID$(a$, T, 2) + MID$(a$, T + 3, 5) ELSE TIM$ = "******/"
  130.     Pos$ = LAT$ + "/" + LON$ + sym$
  131.     RETURN
  132.  
  133. Pressure: Pres$ = "/" + MID$(a$, a + 17, 4) + "mb "
  134.           RETURN
  135.  
  136. Movement: b = INSTR(a$, "DEGREES")  'Get the direction
  137.           IF b > 4 THEN CSpd$ = MID$(a$, b - 4, 3)
  138.           c = INSTR(a$, " KT")
  139.           IF c > b + 10 THEN CSpd$ = CSpd$ + MID$(a$, c - 3, 3)
  140.           RETURN
  141.  
  142. Winds:    b = INSTR(a$, " KT")
  143.           IF b > 4 THEN Cmts$ = Pres$ + MID$(a$, b - 4)
  144.           RETURN
  145.  
  146. Forecast: b = INSTR(a$, "Z")
  147.           IF b > 20 AND TropStrm THEN
  148.              L = b + 2: T = b - 7: GOSUB ParsePos
  149.              Name$ = MID$(a$, T, 8) + " "' Use the Forecast TIME as the NAME
  150.              CSpd$ = "MaxWind "
  151.              TIM$ = DTG$' Insert Date/Time of the message
  152.           END IF
  153.           RETURN
  154.  
  155.  
  156. BuildPOS: REM Assemble the pieces into a complete OBJECT report and
  157.           REM add this completed POSIT to the PACKET array for transmission
  158.    P$ = LEFT$(Name$ + "*" + TIM$ + Pos$ + CSpd$ + Cmts$, 72)
  159.    
  160.    Dupe = 0: REM First check to see if the posit is already in the queue
  161.    FOR i = 1 TO NumP
  162.        IF P$(i) = P$ THEN Dupe = 1
  163.    NEXT i
  164.    IF Dupe = 0 THEN
  165.       IF NumP < MaxNum THEN
  166.          NumP = NumP + 1
  167.       ELSE
  168.          FOR i = 1 TO NumP   ' Throw away oldest one...
  169.              P$(i) = P$(i + 1): Count(i) = Count(i + 1)
  170.          NEXT
  171.       END IF
  172.       
  173.       P$(NumP) = P$
  174.       Count(NumP) = 10 ' initialize to number of times to xmt
  175.    END IF
  176.    Pos$ = "": CSpd$ = "": Cmts$ = "": REM Clear out the data
  177.    RETURN
  178.  
  179. SendNext: REM send the next available packet
  180.    NxtP = NxtP + 1: IF NxtP > NumP THEN NxtP = 1
  181.    PRINT #1, P$(NxtP) 'OUTPORT. Set to #2 if two ports used...
  182.    REM PRINT P$(NxtP)
  183.    Count(NxtP) = Count(NxtP) - 1
  184.    IF Count(NxtP) < 1 THEN 'remove this item from the list
  185.       FOR i = NxtP TO NumP
  186.           P$(i) = P$(i + 1)
  187.           Count(i) = Count(i + 1)
  188.       NEXT i
  189.    END IF
  190.    LastPkt = TIMER: SOUND 3000, 3
  191.    LOCATE 6, 1
  192.    FOR i = 1 TO MaxNum
  193.        PRINT Count(i); TAB(5); LEFT$(P$(i) + SPACE$(79), 74)
  194.    NEXT i
  195.    RETURN
  196.  
  197. Pause: LOCATE 25, 1: PRINT "Hit ENTER to continue...";
  198.        INPUT a$
  199.        RETURN
  200.  
  201. SendMyPos: PRINT #1, MyPOS$; CHR$(13); 'OUTPORT. Set to #2 if two ports used
  202.            LastPOS = TIMER
  203.            RETURN
  204.  
  205. Getmore: Tsec = 1
  206.          j = 1: a = 0: Strtime = TIMER
  207.    
  208.     TEST$ = "FORECAST VALID 19/0600Z 17.6N  51.9W": sym$ = "@": Cmts$ = "comments!"
  209.     a$ = TEST$: TropStrm = 1: RETURN  '******* REM OUT THIS LINE for REAL DATA
  210.  
  211.     DO WHILE j > 0 AND a = 0
  212.        IF ABS(TIMER - Strtime) >= Tsec THEN j = 0: a$ = Astr$: Astr$ = "": EXIT DO
  213.        a = INSTR(Astr$, CHR$(13))
  214.        IF a > 0 THEN a$ = LEFT$(Astr$, a - 1): Astr$ = MID$(Astr$, a + 1): EXIT DO
  215.        IF LOC(1) > 0 THEN Astr$ = Astr$ + INPUT$(LOC(1), 1)
  216.        LOOP
  217.     WHILE LEFT$(a$, 1) < " " AND LEN(a$) > 0
  218.        LET a$ = MID$(a$, 2)
  219.        WEND
  220.     RETURN
  221.  
  222.