Ecco come promesso una miniguida per importare i dati di WeatherLink in un database MySQL in modo semplice e veloce.
E' una guida di livello medio, cioè considera tutto il software richiesto già installato e configurato correttamente e che l'utente sia abbastanza esperto in sviluppo di web-applications.
In questa guida è presente anche un sistema per l'integrazione dei dati passati (esportando manualmente tutto il database da Weatherlink)
Cominciamo!
In questa guida useremo:1) Creiamo il database
- Il compilatore PHP (dalla 5.x in su)
- Il server MySQL attivo e funzionante
- WeatherLink (5.7 in su)
- Un sistema di cron (cron su linux o pycron su windows)
Creiamoci il database (via terminale o via phpmyadmin). In questa guida la chiamiamo "meteo".
Creiamo una tabella con i seguenti campi, tipo di dato e grandezza del dato. In questa guida viene chiamata "data":
Per rendervi la vita più facile vi incollo lo script SQL che ve la crea...Campo Tipo Null Predefinito
datetime datetime No
temp decimal(4,1) Sì NULL
tempmax decimal(4,1) Sì NULL
tempmin decimal(4,1) Sì NULL
hum decimal(3,0) Sì NULL
dp decimal(4,1) Sì NULL
wspeed decimal(5,1) Sì NULL
wdir varchar(3) Sì NULL
wrun decimal(6,2) Sì NULL
whi decimal(5,1) Sì NULL
whidir varchar(3) Sì NULL
wchill decimal(4,1) Sì NULL
heati decimal(4,1) Sì NULL
thwi decimal(4,1) Sì NULL
bar decimal(6,1) Sì NULL
rain decimal(7,2) Sì NULL
rr decimal(7,2) Sì NULL
cooldd decimal(8,3) Sì NULL
Impostiamo infine datetime come chiave primaria. Ho integrato tutti i dati utili, escludendo i sensori interni, la ricezione della console e i campi dell'UV (in quando non dispongo dei sensoriCodice:CREATE TABLE `data` ( `datetime` datetime NOT NULL, `temp` decimal(4,1) default NULL, `tempmax` decimal(4,1) default NULL, `tempmin` decimal(4,1) default NULL, `hum` decimal(3,0) default NULL, `dp` decimal(4,1) default NULL, `wspeed` decimal(5,1) default NULL, `wdir` varchar(3) default NULL, `wrun` decimal(6,2) default NULL, `whi` decimal(5,1) default NULL, `whidir` varchar(3) default NULL, `wchill` decimal(4,1) default NULL, `heati` decimal(4,1) default NULL, `thwi` decimal(4,1) default NULL, `bar` decimal(6,1) default NULL, `rain` decimal(7,2) default NULL, `rr` decimal(7,2) default NULL, `cooldd` decimal(8,3) default NULL, PRIMARY KEY (`datetime`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;)
2) Scriviamo lo script php di prelievo ed elaborazione dati.
Salviamolo e mettiamolo nella stessa cartella dove viene prodotto il file dei dati di WeatherLink.Codice PHP:
<?php
// Definizioni utente per la connessione a MySQL
$dbUser = "miousername";
$dbPwd = "miapassword";
$conn_my = mysql_connect("localhost", $dbUser, $dbPwd) ;
mysql_select_db ("meteo");
//Nome del file di weatherlink
$file='downld02.txt';
//Apro il file
$handle = fopen("$file", 'r');
if (!$handle) die ('Impossibile aprire il file di testo!');
//Indice che mi indica la riga
$i = 1;
while ( !feof ($handle) ) {
$riga = fgets($handle,4096);
//Condizione che esclude dalle operazioni seguenti le tot righe d'intestazione eventualmente iniziali presenti nel file
$riga = trim(preg_replace("/[\s,]+/", " ", $riga));
//Escludo le prime 3 righe
if($i > 3):
// Le variabili della lista seguente devono rispecchiare i campi che compaiono nel file di testo
list($date, $time, $temp, $tempmax, $tempmin, $hum, $dp, $wspeed, $wdir, $wrun, $whi, $whidir, $wchill, $heati, $thwi, $bar, $rain, $rr, $inutile1, $cooldd) = explode(" ",$riga);
//Formattazione e validazione dati
//Cambio la data in formato americano
list($giorno, $mese, $anno) = explode("/",$date);
//Aggiungo all'anno il '20' -> 2007
$anno = '20' . $anno;
//Ricompongo la data
$date = $anno . "/" . $mese . "/" . $giorno;
//Raggruppo la data e l'orario in quanto il campo nel db è datetime
$datetime = $date . ' ' . $time;
//Escludo eventualmente il campo della dir del vento se non soffia vento ('---' -> NULL)
if($wdir == '---'):
$wdir = '';
endif;
if($whidir == '---'):
$whidir = '';
endif;
// Archiviazione di $riga su DB
$queryi= "insert into data values ('$datetime', $temp, $tempmax, $tempmin, $hum, $dp, $wspeed, '$wdir', $wrun, $whi, '$whidir', $wchill, $heati, $thwi, $bar, $rain, $rr, $cooldd)";
$resulti = mysql_query($queryi);
if($resulti == 1):
echo "Inserito il valore del $datetime con la query $queryi\n";
else:
echo("La query $queryi non è andata a buon fine!!!");
endif;
endif;
//Incremento l'indice della riga
$i++;
}
//Chiudo il file
fclose ($handle);
//Chiudo il db
mysql_close ($conn_my);
?>
3) Aprimo il terminale e scriviamo:
Se abbiamo configurato correttamente il php e lo script, dovrebbe darci come output una serie di "Inserito il valore del ********"Codice:$ cd /mia/dir/di/weatherlink/stazione $ php mioscript.php
Su windows è possibile avere dei problemi, proviamo quindi con:
(dove " > miolog.log" ci crea un file di log che possiamo leggere tranquillamente se ci verificano errori).Codice:$ cd C:\mia\dir\di\weatherlink\stazione $ C:\php\php mioscript.php > miolog.log
4) Verifichiamo l'inserimento corretto dei dati con un SELECT (o più comodamente da phpmyadmin)
5) Se sono presenti i dati, tutto è andato a buon fine, altrimenti abbiamo sbagliato qualcosa.....Codice:SELECT * FROM data ORDER BY datetime DESC LIMIT 50
6) Possiamo inserire il tutto nel cron.
Creiamo un bat (o script sh su linux)
7) Aggiungiamo questa riga con un crontabCodice:cd C:\Weatherlink\stazione\ php mioscript.php
8) Riavviamo il servizio di cron e ogni 5 minuti vedremo il nostro script che inserisce i dati da solo!!!!!Codice:0,5,10,15,20,25,30,35,40,45,50,55 * * * * "C:\percorso_allo_script\meteo_data.bat"
Inserimento dei dati antecedenti
Possiamo inserire i dati meno recenti con una piccola modifica allo script.
1) Andiamo in WeatherLink e esportiamo tutti i dati desiderati (andando nell'elenco dei dati ed esportando dal menu)
2) Salviamo tutto in un file (utile metterlo nella cartella di prima
3) Salviamo (con lo stesso metodo di prima) questo codice:
Il nome del file che abbiamo salvato da weatherlink è modificabile, in questo caso lo abbiamo chiamato data1.txtCodice PHP:
<?php
// Definizioni utente per la connessione a MySQL
$dbUser = "miauser";
$dbPwd = "miapassword";
$conn_my = mysql_connect("localhost", $dbUser, $dbPwd) ;
mysql_select_db ("meteo");
//Nome del file di weatherlink
$file='data1.txt';
//Apro il file
$handle = fopen("$file", 'r');
if (!$handle) die ('Impossibile aprire il file di testo!');
//Indice che mi indica la riga
$i = 1;
while ( !feof ($handle) ) {
$riga = fgets($handle,4096);
//Condizione che esclude dalle operazioni seguenti le tot righe d'intestazione eventualmente iniziali presenti nel file
$riga = trim(preg_replace("/[\s,]+/", "\t", $riga));
//Escludo le prime 3 righe
if($i > 2):
// Le variabili della lista seguente devono rispecchiare i campi che compaiono nel file di testo
list($date, $time, $temp, $tempmax, $tempmin, $hum, $dp, $wspeed, $wdir, $wrun, $whi, $whidir, $wchill, $heati, $thwi, $bar, $rain, $rr, $inutile1, $cooldd) = explode("\t",$riga);
//Formattazione e validazione dati
//Cambio la data in formato americano
list($giorno, $mese, $anno) = explode("/",$date);
//Aggiungo all'anno il '20' -> 2007
$anno = '20' . $anno;
//Ricompongo la data
$date = $anno . "/" . $mese . "/" . $giorno;
//Raggruppo la data e l'orario in quanto il campo nel db è datetime
$datetime = $date . ' ' . $time;
//Escludo eventualmente il campo della dir del vento se non soffia vento ('---' -> NULL)
if($wdir == '---'):
$wdir = '';
endif;
if($whidir == '---'):
$whidir = '';
endif;
// Archiviazione di $riga su DB
$queryi= "insert into data values ('$datetime', $temp, $tempmax, $tempmin, $hum, $dp, $wspeed, '$wdir', $wrun, $whi, '$whidir', $wchill, $heati, $thwi, $bar, $rain, $rr, $cooldd)";
$resulti = mysql_query($queryi);
if($resulti == 1):
echo "Inserito il valore del $datetime con la query $queryi\n";
else:
echo("La query $queryi non è andata a buon fine!!!\n");
endif;
endif;
//Incremento l'indice della riga
$i++;
}
//Chiudo il file
fclose ($handle);
//Chiudo il db
mysql_close ($conn_my);
?>
L'inserimento di un file di testo annuale (circa 14 mega per dati ogni 5 minuti) comporta una elaborazione di circa 3 minuti su un server a 800 mhz e 320 mb di ram.
L'elaborazione del file giornaliero invece dura circa 3 o 4 secondi
NOTE:
Se un certo dato è già stato inserito, la query di inserimento fallisce (trovando giustamente una chiave primaria doppia). E' così possibile inserire i dati senza preoccuparsi di doppioni).
Il database (con DBMS di tipo MyISAM), contenente circa 185.000 righe di dati (circa 2 anni) occupa 13 mb.
Ringrazio Bio per lo spunto del codice, senza di lui non ce l'avrei mai fatta![]()
Una guida ben fatta e sicuramente assai utile a tutti i possessori di una DAVIS
NOTA 1: per coloro che hanno il pluviometro che scatta con un accumulo di pioggia equivalente pari a 0.254 mm.
WeatherLink scrive nello storico esportato in formato .txt valori di pioggia arrotondati al secondo decimale. Ad es. 0.25 anziché 0.254.
Se inseriamo questi valori pari pari nel DB e se non ci ricordiamo di questo arrotondamento, quando andiamo a fare una query che calcola l'accumulo su un certo arco temporale, avremo un certo errore.
Il risultato della query perciò va corretto a posteriori. Oppure, ancora meglio, inseriamo nel DB i valori di pioggia corretti, cioè senza arrotondamento.
NOTA 2: pochi hanno la versione 5.x di PHP. Per fortuna gira perfettamente anche sulla 4.x
Grandi complimenti a merto che ha voluto condividere con tutti una "piccola grande utilità" che alcuni di noi... custodiscono gelosamente da tempo
![]()
Ultima modifica di bio; 20/07/2007 alle 09:57
Centro Meteorologico Sammarinese - meteo.sm
Rete di rilevamento ~ Previsioni ~ Modello numerico ad alta risoluzione San Marino NEMS - NMMB
That is incredible!
Who would be so kind and translate this guide into English? Unfortunatelly I don't understand it in Italian language..
Thank you if its possible!![]()
Marko Korosec, Slovenia
Severe Weather Europe - http://www.severe-weather.EU
www.Weather-Photos.NET | http://www.facebook.com/WeatherPhotos.NET
It works also with WeatherLink 5.6.![]()
Nell'avatar: io, come mi vede Francesco.
ottima guida!
sarebbe bello integrare tutto in un modulo di drupal, cos' ogni persona che vuole farsi un sitino meteo avrà la stazione online gratis e senza sbattimenti.
se qualcuno è interessato possiamo iniziare a buttare giù un modulino, fatemi sapere!
ho provato a buttare giu un install per il modulo
ho pensato di gestire più stazioni in modo poi da poter implementare logiche più carine.
quindi una tabella con le stazioni e i loro dati ed un altra con i dati meteo con l'id della stazione a fare da collegamento
ecco lo script che crea le tabelle nel db di drupal
il risultato è questoCodice PHP:
// database structure
function meteo_install()
{
drupal_install_schema('meteo');
}
function meteo_uninstall()
{
drupal_uninstall_schema('meteo');
}
function meteo_schema()
{
return array
(
/* first table: collects stations data */
'stations' => array(
'fields' => array
(
'id' => array( // station ID
'type' => 'serial', // auto increment
'not null' => TRUE,
'size' => 'normal'
),
'name' => array( // station NAME
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'description' => array( // station Description
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'default' => '',
),
'latitude' => array( // latitude
'type' => 'numeric',
'precision' => 10,
'scale' => 6,
'not null' => TRUE,
'default' => 0.0,
),
'longitude' => array( // longitude
'type' => 'numeric',
'precision' => 10,
'scale' => 6,
'not null' => TRUE,
'default' => 0.0,
),
'altitude' => array( // station ALTITUDE
'type' => 'int',
'size' => 'normal',
'not null' => TRUE,
'default' => 0,
),
'nation' => array( // station NATION
'type' => 'varchar',
'not null' => TRUE,
'length' => 255,
'default' => '',
),
'city' => array( // station CITY
'type' => 'varchar',
'not null' => TRUE,
'length' => 255,
),
'image' => array( // station image filepath
'type' => 'varchar',
'not null' => FALSE,
'length' => 255,
'default' => '',
),
),
'primary key' => array('id')
),
/* second table: collects weather data */
'weatherdata' => array(
'fields' => array
(
'id' => array( // station id
'type' => 'int',
'not null' => TRUE,
'size' => 'normal'
),
'datetime' => array( // station id
'type' => 'datetime',
'not null' => TRUE,
'size' => 'normal'
),
'temp' => array( // temperature
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'tempmax' => array( // temperature max
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0
),
'tempmin' => array( // temperature min
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'hum' => array( // humidity
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 3,
'scale' => 0,
'default' => 0.0,
),
'dp' => array( // dew point
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'wspeed' => array( // wind speed
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 5,
'scale' => 1,
'default' => 0.0,
),
'wdir' => array( // wind direction
'type' => 'varchar',
'length' => 3,
'not null' => FALSE,
'default' => ''
),
'wrun' => array( // wind run
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 6,
'scale' => 2,
'default' => 0.00,
),
'whi' => array( // wind hi value
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 5,
'scale' => 1,
'default' => 0.0,
),
'whdir' => array( // wind hi value direction
'type' => 'varchar',
'length' => 3,
'not null' => FALSE,
'default' => ''
),
'wchill' => array( // wind chill
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'heati' => array( // heat index
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'thwi' => array( // THWI index
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 4,
'scale' => 1,
'default' => 0.0,
),
'bar' => array( // Pressure
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 6,
'scale' => 1,
'default' => 0.0,
),
'rain' => array( // Rain
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 7,
'scale' => 2,
'default' => 0.00,
),
'rr' => array( // Rain rate
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 7,
'scale' => 2,
'default' => 0.00,
),
'cooldd' => array(
'type' => 'numeric',
'not null' => TRUE,
'size' => 'normal',
'precision' => 8,
'scale' => 3,
'default' => 0.000,
),
),
'primary key' => array('id,datetime')
),
);
}
?>
CREATE TABLE IF NOT EXISTS `stations` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL default '',
`description` longtext NOT NULL,
`latitude` decimal(10,6) NOT NULL default '0.000000',
`longitude` decimal(10,6) NOT NULL default '0.000000',
`altitude` int(11) NOT NULL default '0',
`nation` varchar(255) NOT NULL default '',
`city` varchar(255) NOT NULL,
`image` varchar(255) default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `weatherdata` (
`id` int(11) NOT NULL,
`datetime` datetime NOT NULL,
`temp` decimal(4,1) NOT NULL default '0.0',
`tempmax` decimal(4,1) NOT NULL default '0.0',
`tempmin` decimal(4,1) NOT NULL default '0.0',
`hum` decimal(3,0) NOT NULL default '0',
`dp` decimal(4,1) NOT NULL default '0.0',
`wspeed` decimal(5,1) NOT NULL default '0.0',
`wdir` varchar(3) default '',
`wrun` decimal(6,2) NOT NULL default '0.00',
`whi` decimal(5,1) NOT NULL default '0.0',
`whdir` varchar(3) default '',
`wchill` decimal(4,1) NOT NULL default '0.0',
`heati` decimal(4,1) NOT NULL default '0.0',
`thwi` decimal(4,1) NOT NULL default '0.0',
`bar` decimal(6,1) NOT NULL default '0.0',
`rain` decimal(7,2) NOT NULL default '0.00',
`rr` decimal(7,2) NOT NULL default '0.00',
`cooldd` decimal(8,3) NOT NULL default '0.000',
PRIMARY KEY (`id`,`datetime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
che ne pensate?
utilissimo sto 3D...sto provando in questi giorni a capirci qualcosa di PHP...speriamo bene!
...vabbhè, tanto la davis la prendo verso l'autunno prossimo, quindi di tempo ne ho!![]()
dai dai secondo me è un progettino interessante!
anch'io pensavo di usare il cron di drupal per importare tutto
un cms cosi valido con integrazione automatica dei dati sarebbe una carta vincente
poi chiaramente possiamo anche agganciarci l'invio automatico dei dati nella rete
apri tu?
ho portato avanti un po il modulino
basta copiarlo nella cartella moduli di drupal e attivarlo
per ora ho implementato queste funzioni
1) creazione automatica delle tabelle stazioni
2) creazione, modifica, cancellazione di una stazione meteo
prossimi step
1) realizzare la funzione di import
2) generare la pagina della singola stazione con magari un blocchetto laerale
3) generare la mappa di google con le stazioni
c'è qualcuno che vuole darmi una mano?
lo potete scaricare da qui
http://www.signalkuppe.com/meteo.zip
Segnalibri