#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")
"
Date | "
"[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/"
" | 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.
@section{Database}
Data displayed in graphs can be saved in real time in a database.
For this you can use @racket[new-value-event] parameter with @racket[insert-into-db] procedure.
First, describe your dabatase schema in a db-struct structure
@defstruct*[db-struct
([connection connection?]
[table-name string?]
[field-label string?]
[field-date-time string?]
[field-value string?])]
Then, use this function in @racket[new-value-event] handler
@defproc[(insert-into-db
[db db-struct?]
[label string?]
[seconds exact-integer?]
[value string?])
void?]
Example with a table named T_Data containing 3 fields F_Label, F_DateTime and F_Value:
@racketblock[
(define my-db (db-struct (odbc-connect #:dsn "BdLive" #:user "" #:password "")
"T_Data" "F_Label" "F_DateTime" "F_Value"))
(parameterize ([new-value-event (lambda (label seconds value)
(insert-into-db my-db label seconds value))])
(live-graph "test" (lambda () 10) 2 "demo"))] |
---|