#lang scribble/doc

@(require scribble/manual)

@title{Live}
@author{@(author+email "jeeve" "jvjulien@free.fr")}

@defmodule[(planet jeeve/live)]{
                                
                                This basic library provided client web service and graphics to follow specifical values in web pages.}

@section{Values} 

@defproc[(live-web-number
          [url string?]
          [key-line string?]
          [regexp-pattern string?]
          [error-value number? 0]
          [delta-nb-lines number? 0])
         number?]

Extracts a value in a web page.

Returns error-value if value not found or internet connection failed.

Example to get wind velocity on a spot location (via @link["http://www.winds-up.com"]{winds-up} web page)

@itemlist[
          @item{Open the web site}
           
           @item{Inspect HTML code
                 
                 @image[#:scale 0.5 "./images/html.png"]}
                                                         ]
To find appropriate parameters, visualize position of searched value. 
Search a word to locate a reference line (key-line parameter).
In the example, we choose "Aujourd" for the key-line word with delta-nb-lines = 3 to jump to velocity wind value.
The value is an integer, therefore regexp-pattern parameter is "[0-9]+".

Which gives

@racketinput[(live-web-number "http://www.winds-up.com/index.php?p=spots&id=21"
                              "Aujourd"
                              "[0-9]+"
                              -1
                              3)] 

Returns wind velocity read as an integer on  winds-up web site at 3 lines after that containing "Aujourd" word. Otherwise returns -1.

Another examples:

Wind velocity at Belle-Ile, France via meteociel web site

@racketinput[(live-web-number "http://www.meteociel.fr/observations-meteo/vent.php" 
                   "Belle-Ile"  
                   "[0-9]+ km/h")]

Water level web service

@racketblock[
(define (water-level id-station)
  (lambda ()
    (live-web-number (string-append "http://www.vigicrues.gouv.fr/niveau3.php?idstation=" 
                                    (number->string id-station) 
                                    "&idspc=21&typegraphe=h&AffProfondeur=24"
                                    "&AffRef=auto&AffPrevi=non&nbrstations=3&ong=2") 
                     "<tr><th>Date</th><th>"  
                     "[0-9]+\\.[0-9]+")))]

@section{Graphics} 

@defproc[(live-graph
          [label string?]
          [function (-> number?)]
          [rate number?]
          [title string?])
         any/c]

Graphic evolution of value in web page.

An example to display water level at Cavaillon in France (id-station = 142)

@racketinput[(live-graph "Water level (m)"
              (water-level 142)
              (* 5 60) (code:comment "refresh each 5 minutes")
              "Cavaillon")]

An other example to obtain pressure level in Paris

@racketblock[
(define (pressure-paris)
  (live-web-number "http://www.station-meteo.com/historique-fr75020-paris/" 
                   "<td>Pression atmosphérique"  
                   "[0-9]+\\.[0-9]+"
                   -1
                   7))]

With axis scale parameterize

@racketblock[
(parameterize ([delta-x (* 12 3600)] (code:comment "12 hours")
               [delta-y 0.01])  (code:comment "1 %")
  (live-graph "Level pressure (hPa)"
              pressure-paris
              (* 5 60) 
              "Paris"))]

Use live-dashboard function to plot multiple web services

@defproc[(live-dashboard
          [labels (listof (listof string?))]
          [functions (listof (listof (-> number?)))]
          [rate number?]
          [title string?])
         any/c]

This function displays graphics in rows and columns disposition. Each sublist is a row.

@racketinput[(live-dashboard '(("Ners" "Besseges"))
                  (list (list (water-level 38) (water-level 31)))
                  (* 5 60) 
                  "Water level (m)")]

The same but with one function of label parameter  

@defproc[(live-dashboard-one-ft 
          [labels (listof (listof string?))]
          [function (-> string? number?)]  
          [rate number?] 
          [title string?])
         any/c]

Example:

@racketinput[
  (live-dashboard-one-ft '(("Paris" "Marseille"))
              pressure
              (* 15 60) 
              "Pressure level (hPa)")]

@racket[(pressure "Paris")] and @racket[(pressure "Marseille")] will be called every 15 minutes.