Questo documento tratta la personalizzazione di Weewx. Si presuppone che l'utente abbia letto e conosca ragionevolmente la Guida per l'utente.
L'introduzione contiene una panoramica dell'architettura. Se sei interessato solo alla personalizzazione dei report generati, probabilmente puoi saltare l'introduzione e procedere direttamente alla sezione Personalizzazione dei report . Con questo approccio è possibile aggiungere facilmente nuove immagini di grafici, modificare i titoli delle immagini, modificare le unità utilizzate nei rapporti e così via.
Tuttavia, se il tuo obiettivo è un'applicazione specializzata, come l'aggiunta di allarmi, feed RSS, ecc ., allora varrebbe la pena leggere l'architettura interna.
La maggior parte della guida si applica a qualsiasi hardware, ma i tipi di dati esatti sono specifici dell'hardware. Consulta la Guida hardware di Weewx per i dettagli su come diversi tipi di osservazione vengono gestiti da diversi tipi di hardware.
Weewx è ancora un sistema sperimentale e, come tale, il suo design interno è soggetto a modifiche. Gli aggiornamenti futuri potrebbero interrompere qualsiasi personalizzazione che hai fatto, in particolare se coinvolgono l'API (le personalizzazioni della skin tendono ad essere più stabili).
INTRODUZIONE
Architettura complessiva del sistema
Di seguito è riportata una breve panoramica dell'architettura del sistema Weewx, trattata in modo molto più dettagliato nel resto di questo documento.
- • Un processo Weewx normalmente gestisce il monitoraggio di una stazione, ad esempio una stazione meteorologica. Il processo viene configurato utilizzando le opzioni in un file di configurazione, generalmente chiamato weewx.conf .
- • Un processo Weewx ha al massimo un "driver" per comunicare con l'hardware della stazione e ricevere dati di misurazione "ad alta risoluzione" ( cioè ogni pochi secondi) sotto forma di pacchetti LOOP. Il driver è a thread singolo e bloccante, quindi non più di un driver può essere eseguito in un processo Weewx.
- • I pacchetti LOOP possono contenere dati arbitrari dalla stazione/driver sotto forma di un dizionario Python. Ogni pacchetto LOOP deve contenere un timestamp e un sistema di unità, oltre a qualsiasi numero di osservazioni, come temperatura o umidità. Per i tipi estensivi, come la pioggia, il pacchetto contiene la quantità totale di pioggia caduta durante il periodo di osservazione.
- • Weewx quindi compila questi pacchetti LOOP in "record di archivio" con spaziatura regolare. Per la maggior parte dei tipi, il record di archivio contiene il valore medio visto in tutti i pacchetti LOOP nell'intervallo di archiviazione (in genere 5 minuti). Per i tipi estesi, come la pioggia, è la somma di tutti i valori nell'intervallo di archiviazione.
- • Internamente, il motore di Weewx utilizza un'architettura a pipeline , composta da molti servizi . I servizi si legano a eventi di interesse, come nuovi pacchetti LOOP o nuovi record di archivio. Gli eventi vengono quindi eseguiti lungo la pipeline in ordine: i servizi nella parte superiore della pipeline agiscono sui dati prima dei servizi più in basso nella pipeline.
- • I servizi possono eseguire operazioni come controllare la qualità dei dati, applicare correzioni o salvare i dati in un database. Gli utenti possono facilmente aggiungere nuovi servizi.
- • Weewx include la possibilità di personalizzare il comportamento installando estensioni . Le estensioni possono consistere in uno o più driver, servizi e/o skin, il tutto in un pacchetto facile da installare.
Architettura dei dati
Weewx è basato sui dati. Quando i sensori emettono dei dati, Weewx fa qualcosa. Il "qualcosa" potrebbe essere stampare i dati, o generare un rapporto HTML, o usare FTP per copiare un rapporto su un server web, o eseguire alcuni calcoli usando i dati.
Un driver è codice Python che comunica con l'hardware. Il driver legge i dati da una porta seriale o da un dispositivo sull'interfaccia USB o di rete. Gestisce qualsiasi decodifica di bit e byte grezzi e inserisce i dati risultanti in pacchetti LOOP. Anche i driver per alcuni tipi di hardware (in particolare, Davis Vantage) sono in grado di emettere record di archivio.
Oltre ai tipi di osservazione primari come temperatura, umidità o radiazione solare, ci sono anche molti tipi dipendenti utili, come wind chill, indice di calore o ET, che vengono calcolati dai dati primari. Il firmware di alcune stazioni meteorologiche è in grado di eseguire autonomamente molti di questi calcoli. Per il resto, se scegli di farlo, il servizio Weewx StdWXCalculate può colmare le lacune. A volte il firmware lo fa semplicemente in modo sbagliato e potresti scegliere di far eseguire il calcolo a Weewx, nonostante la presenza del tipo nei pacchetti LOOP.
Pacchetti LOOP vs. record di archivio
Generalmente, ci sono due tipi di dati che passano attraverso Weewx: pacchetti LOOP e record di archivio. Entrambi sono rappresentati come dizionari Python.
Pacchetti LOOP
I pacchetti LOOP sono i dati grezzi generati dal driver del dispositivo. Prendono il loro nome dalla documentazione di Davis Instruments. Per alcuni dispositivi vengono generati a intervalli rigidi, come ogni 2 secondi per la serie Davis Vantage, per altri, in modo irregolare, ogni 20 o 30 secondi circa. I pacchetti LOOP possono contenere o meno tutti i tipi di dati. Ad esempio, un pacchetto può contenere solo dati di temperatura, un altro solo dati barometrici, ecc . Questi tipi di pacchetti sono chiamati pacchetti di record parziali . Al contrario, altri tipi di hardware (in particolare la serie Vantage), ogni pacchetto LOOP contiene ogni tipo di dati.
In sintesi, i pacchetti LOOP possono essere molto irregolari, ma arrivano frequentemente.
Record d'archivio
Al contrario, i record d'archivio sono molto regolari. Vengono generati a intervalli regolari (generalmente ogni 5-30 minuti) e contengono tutti gli stessi tipi di dati. Rappresentano un'aggregazione dei pacchetti LOOP nell'intervallo di archiviazione. Il tipo esatto di aggregazione dipende dal tipo di dati. Ad esempio, per la temperatura, è generalmente la temperatura media nell'intervallo. Per la pioggia, è la somma della pioggia nell'intervallo. Per lo stato della batteria è l'ultimo valore nell'intervallo.
Alcuni hardware sono in grado di generare i propri record di archivio (il Davis Vantage e l'Oregon Scientific WMR200, per esempio), ma per l'hardware che non può, Weewx li genera.
Sono i dati di archivio che vengono inseriti nel database SQL, anche se, occasionalmente, i pacchetti LOOP possono essere utili (come per la modalità "Rapidfire" di Weather Underground).
Cosa personalizzare
Per modifiche alla configurazione, ad esempio quali skin utilizzare o per abilitare i post su Weather Underground, è sufficiente modificare il file di configurazione di Weewx weewx.conf . Tutte le modifiche apportate verranno mantenute durante l'aggiornamento.
La personalizzazione dei rapporti può richiedere modifiche al file di configurazione della skin skin.conf o ai file modello che terminano con .tmpl o .inc . Tutto ciò che si trova nella sottodirectory skin viene conservato anche durante gli aggiornamenti.
Puoi scegliere di installare una delle tante estensioni di terze parti disponibili per Weewx. Questi sono in genere installati nelle skin o nelle sottodirectory dell'utente , entrambe conservate durante gli aggiornamenti.
Personalizzazioni più avanzate potrebbero richiedere nuovo codice Python o modifiche al codice di esempio. Questi dovrebbero essere inseriti nella directory utente , dove verranno conservati durante gli aggiornamenti. Ad esempio, se desideri modificare uno degli esempi forniti con Weewx, copialo dalla directory examples alla directory user , quindi modificalo lì. In questo modo, le tue modifiche non verranno toccate se esegui l'upgrade.
Per il codice che deve essere eseguito prima di qualsiasi altra cosa in Weewx (ad esempio, per impostare un ambiente), inseriscilo nel file extensions.py nella directory dell'utente . Viene sempre eseguito prima dell'avvio del motore di Weewx. Poiché si trova nella sottodirectory utente , viene conservato tra gli aggiornamenti.
Devo riavviare Weewx?
Se apporti una modifica a weewx.conf , dovrai riavviare Weewx.
Se modifichi il codice Python nella directory utente o altrove, dovrai riavviare Weewx.
Se installi un'estensione, dovrai riavviare Weewx.
Se apporti una modifica a un template o a un file skin.conf , non è necessario riavviare Weewx. La modifica verrà adottata al successivo ciclo di reporting, in genere al termine di un intervallo di archiviazione.
L'utilità wee_reports
Se apporti modifiche, come fai a sapere quali saranno i risultati? Potresti semplicemente eseguire Weewx e attendere fino all'inizio del successivo ciclo di report ma, a seconda dell'intervallo di archiviazione, potrebbe essere un'attesa di 30 minuti o più.
L'utility wee_reports ti permette di eseguire un report quando vuoi. Per usarlo, basta eseguirlo da una riga di comando, con la posizione del file di configurazione weewx.conf come primo argomento. Facoltativamente, se includi un timestamp epoch unix come secondo argomento, il report lo utilizzerà come ora "Corrente"; in caso contrario verrà utilizzata l'ora dell'ultimo record nel database di archivio. Ecco un esempio, utilizzando il 1 maggio 2014 00:00 PDT come ora "Corrente".
wee_reports weewx.conf 1398927600
Per ulteriori informazioni su wee_reports , consultare la Guida alle utilità
L'architettura del servizio Weewx
Ad alto livello, Weewx consiste in una classe di motori chiamata StdEngine . È responsabile del caricamento dei servizi , quindi predispone che vengano richiamati quando si verificano eventi chiave, come l'arrivo di LOOP o l'archiviazione dei dati. L'installazione predefinita di Weewx include i seguenti servizi:
SERVIZIO | FUNZIONE |
weewx.engine.StdTimeSynch | Fare in modo che l'orologio della stazione sia sincronizzato a intervalli regolari. |
weewx.engine.StdConvert | Converte le unità dell'input in un sistema di unità di destinazione (come US o Metric). |
weewx.engine.StdCalibrate | Regola il nuovo LOOP e archivia i pacchetti utilizzando le espressioni di calibrazione. |
weewx.engine.StdQC | Controlla la qualità dei dati in entrata, assicurandoti che i valori rientrino in un intervallo specificato. |
weewx.wxservices.StdWXCalculate | Calcola qualsiasi tipo di osservazione meteorologica derivata mancante, come il punto di rugiada, il windchill o la pressione corretta dall'altimetro. |
weewx.engine.StdArchive | Archivia tutti i nuovi dati nei database SQL. |
weewx.restx.StdStationRegistry weewx.restx.StdWunderground weewx.restx.StdPWSWeather weewx.restx.StdCWOP weewx.restx.StdWOW weewx.restx.StdAWEKAS |
Vari servizi RESTful (semplici protocolli client-server senza stato), come Weather Underground, CWOP, ecc. Ciascuno lancia il proprio thread indipendente, che gestisce il post. |
weewx.engine.StdPrint | Stampa il nuovo LOOP e archivia i pacchetti sulla console. |
weewx.engine.StdReport | Avvia un nuovo thread per eseguire l'elaborazione dei report dopo l'arrivo di un nuovo record di archivio. I rapporti eseguono operazioni come la generazione di file HTML o CSV, la generazione di immagini o il trasferimento di file tramite FTP/rsync. |
È facile estendere i vecchi servizi o aggiungerne di nuovi. La distribuzione di origine include un nuovo servizio di esempio chiamato MyAlarm , che invia un'e-mail quando un'espressione arbitraria restituisce True . Questi argomenti avanzati sono trattati più avanti nella sezione Personalizzare il motore di servizio di Weewx .
Il servizio di report standard, StdReport
Per il momento concentriamoci sull'ultimo servizio, weewx.engine.StdReport , il servizio standard per la creazione di report. Questo sarà ciò che la maggior parte degli utenti vorrà personalizzare, anche se ciò significa solo modificare alcune opzioni.
Rapporti
Il servizio di reportistica standard, StdReport , esegue zero o più report . I report specifici che vengono eseguiti sono impostati nel file di configurazione weewx.conf , nella sezione [StdReport] .
La distribuzione predefinita di Weewx include sei report:
RAPPORTO | FUNZIONALITÀ PREDEFINITA |
SeasonsReport | Introdotto con Weewx V3.9, questo report genera un singolo file HTML con i riepiloghi "aggiornati" di giorno, settimana, mese e anno, nonché le immagini dei grafici che li accompagnano. I pulsanti selezionano la scala temporale desiderata dall'utente. Genera anche file HTML con maggiori dettagli sui corpi celesti e statistiche. Genera anche riepiloghi mensili e annuali NOAA. |
SmartphoneReport | Un semplice report che genera un file HTML, che permette "drill down" per mostrare maggiori dettagli sulle osservazioni. Adatto per dispositivi più piccoli, come gli smartphone. |
MobileReport | Un file HTML super semplice che mostra solo le basi. Adatto per dispositivi a bassa potenza o con limiti di larghezza di banda. |
StandardReport | Questo è un vecchio report che è stato usato per molti anni in Weewx. Genera riepiloghi "aggiornati" di giorno, settimana, mese e anno in HTML, nonché le immagini dei grafici che li accompagnano. Genera anche riepiloghi mensili e annuali NOAA. In genere si carica più velocemente del SeasonsReport . |
FTP | Trasferisci tutto nella directory HTML_ROOT su un server remoto usando ftp. |
RSYNC | Trasferisci tutto nella directory HTML_ROOT su un server remoto utilizzando l'utilità rsync . |
Si noti che i "rapporti" FTP e RSYNC sono un tipo di rapporto divertente in quanto in realtà non generano nulla. Utilizzano invece il motore del servizio di reportistica per trasferire file e cartelle a un server remoto.
Skin
A ogni report è associata una skin . Per la maggior parte dei report, la relazione con la skin è ovvia: la skin contiene i modelli, eventuali file ausiliari come GIF di sfondo o fogli di stile CSS, file con dati di localizzazione e un file di configurazione della skin , skin.conf . Per intenderci, la skin controlla l' aspetto del report. Si noti che più di un report può utilizzare lo stesso skin. Ad esempio, potresti voler eseguire un report che utilizza le unità consuetudinarie statunitensi, quindi eseguire un altro report sullo stesso skin, ma utilizzando le unità metriche e inserire i risultati in una posizione diversa. Tutto questo è possibile sovrascrivendo le opzioni di configurazione nel file di configurazione di Weewx o nel file di configurazione della skin.
Come tutti i report, anche i "report" FTP e RSYNC utilizzano uno skin e includono un file di configurazione dello skin, sebbene siano piuttosto minimi.
Le skin sono nella loro directory chiamata skins , la cui posizione è indicata come SKIN_ROOT .
Generatori
Per creare il loro output, gli skin si affidano a uno o più generatori , che sono quelli che svolgono il lavoro effettivo, come la creazione di file HTML o immagini di grafici. I generatori possono anche copiare i file o sincronizzarli tramite FTP/rsync in posizioni remote. L'installazione predefinita di Weewx include i seguenti generatori:
GENERATORE | FUNZIONE |
weewx.cheetahgenerator.CheetahGenerator | Genera file da modelli, utilizzando il motore di modelli Cheetah. Utilizzato per generare file HTML e di testo. |
weewx.imagegenerator.ImageGenerator | Genera grafici. |
weewx.reportengine.FtpGenerator | Carica i dati su un server remoto tramite FTP. |
weewx.reportengine.RsyncGenerator | Carica i dati su un server remoto utilizzando rsync. |
weewx.reportengine.CopyGenerator | Copia i file localmente. |
Si noti che i tre generatori FtpGenerator , RsyncGenerator e CopyGenerator in realtà non generano nulla che abbia a che fare con il livello di presentazione. Invece, spostano semplicemente i file.
Quali generatori devono essere eseguiti per una data skin è specificato nel file di configurazione della skin skin.conf , nella sezione [Generators] .
Modelli
Un modello è un file di testo che viene elaborato da un motore di modelli per creare un nuovo file. Weewx utilizza il motore di template Cheetah. Il generatore weewx.cheetahgenerator.CheetahGenerator è responsabile dell'esecuzione di Cheetah nei momenti appropriati.
Un modello può essere utilizzato per generare HTML, XML, CSV, Javascript o qualsiasi altro tipo di file di testo. Un modello in genere contiene variabili che vengono sostituite durante la creazione del nuovo file. I modelli possono anche contenere una semplice logica di programmazione.
Ogni file modello risiede nella directory della skin della skin che lo utilizza. Per convenzione, un file modello termina con l' estensione .tmpl . Esistono anche file modello che terminano con l' estensione .inc . Questi modelli sono inclusi in altri modelli.
Il database
Weewx utilizza un singolo database per archiviare e recuperare i record di cui ha bisogno. Può essere implementato utilizzando SQLITE3 , un database SQL leggero e open source, o MySQL , un server di database completo e open source.
Struttura
All'interno di questo database ci sono diverse tabelle. La più importante è la tabella di archiviazione , una grande tabella, contenente un record per ogni intervallo di archiviazione, codificato da dateTime , l'ora alla fine dell'intervallo di archiviazione. Assomiglia a questo:
dateTime | usUnits | interval | barometer | pressure | altimeter | inTemp | outTemp | ... |
1413937800 | 1 | 5 | 29.938 | null | null | 71.2 | 56.0 | ... |
1413938100 | 1 | 5 | 29.941 | null | null | 71.2 | 55.9 | ... |
... | ... | ... | ... | ... | ... | ... | ... | ... |
Le prime tre colonne sono obbligatorie. Ecco cosa significano:
NOME | DESCRIZIONE |
dateTime | L'ora alla fine dell'intervallo di archiviazione in unix epoch time . Questa è la chiave primaria nel database. Deve essere univoco e non può essere nullo. |
usUnits | Il sistema di unità in cui si trova il record. Non può essere nullo. Vedere l' Appendice: Unità per come questi sistemi sono codificati. |
interval | La lunghezza dell'intervallo di archiviazione in minuti . Non può essere nullo. |
Oltre alla tabella dell'archivio principale, all'interno del database sono presenti una serie di tabelle più piccole, una per ogni tipo di osservazione, che contengono riepiloghi giornalieri del tipo, come il valore minimo e massimo visti durante la giornata e a che ora. Queste tabelle hanno nomi come archive_day_outTemp o archive_day_barometer . La loro esistenza è generalmente trasparente per l'utente. Per maggiori dettagli, consulta la sezione Riepiloghi giornalieri nel documento Note dello sviluppatore .
Nomi vincolanti
Mentre la maggior parte degli utenti avrà bisogno solo dell'unico database meteorologico fornito con Weewx, il motore di report ti consente di utilizzare più database nello stesso report. Ad esempio, se hai installato il pacchetto di monitoraggio del computer cmon , che utilizza il proprio database, potresti voler includere alcune statistiche o grafici sul tuo server nei tuoi rapporti, utilizzando quel database.
Un'ulteriore complicazione è che Weewx può utilizzare più di un'implementazione di database: SQLite o MySQL. Fare in modo che gli utenti specifichino nei modelli non solo quale database utilizzare, ma anche quale implementazione sarebbe irragionevole.
La soluzione, come tanti altri problemi nell'informatica, è introdurre un altro livello di indiretto, un database binding . Anziché specificare quale database utilizzare, specificare quale associazione utilizzare. I collegamenti non cambiano con l'implementazione del database, quindi, ad esempio, sai che wx_binding punterà sempre al database meteo, indipendentemente dal fatto che la sua implementazione sia un database sqlite o un database MySQL. I collegamenti sono elencati nella sezione [DataBindings] in weewx.conf .
Il binding del database meteorologico standard utilizzato da Weewx è wx_binding . Questa è l'associazione che utilizzerai la maggior parte del tempo e, in effetti, è l'impostazione predefinita. Raramente è necessario specificarlo esplicitamente.
Interfaccia di programmazione
Weewx include un modulo chiamato weedb che fornisce un'unica interfaccia per molte delle differenze tra implementazioni di database come SQLite e MySQL. Tuttavia, non è raro eseguire query SQL dirette all'interno di servizi o estensioni di elenchi di ricerca. In tali casi, l'SQL dovrebbe essere generico in modo che funzioni con ogni tipo di database.
La classe del gestore database fornisce i metodi per creare, aprire e interrogare un database. Queste sono le forme canoniche per ottenere un gestore di database.
Se stai aprendo un database dall'interno di un servizio Weewx:
db_manager = self.engine.db_binder.get_manager(data_binding='name_of_binding', initialize=True) # Query di esempio: db_manager.getSql("SELECT SUM(rain) FROM %s "\ "WHERE dateTime>? AND dateTime<=?" % db_manager.table_name, (start_ts, stop_ts))
Se stai aprendo un database dall'interno di un'estensione dell'elenco di ricerca di Weewx, ti verrà passata una funzione db_lookup() come parametro, che può essere utilizzato per collegarsi a un database. Per impostazione predefinita, restituisce un gestore associato a wx_binding :
wx_manager = db_lookup() # Ottieni il binding predefinito other_manager = db_lookup(data_binding='some_other_binding') # Ottieni un binding esplicito # Query di esempio: wx_manager.getSql("SELECT SUM(rain) FROM %s "\ "WHERE dateTime>? AND dateTime<=?" % wx_manager.table_name, (start_ts, stop_ts)) other_manager.getSql("SELECT SUM(power) FROM %s"\ "WHERE dateTime>? AND dateTime<=?" % other_manager.table_name, (start_ts, stop_ts))
Se si apre un database da un luogo diverso da un servizio e non è disponibile DBBinder :
db_manager = weewx.manager.open_manager_with_config(config_dict, data_binding='name_of_binding') # Query di esempio: db_manager.getSql("SELECT SUM(rain) FROM %s "\ "WHERE dateTime>? AND dateTime<=?" % db_manager.table_name , (start_ts, stop_ts))
DBBinder memorizza nella cache i gestori e quindi le connessioni al database. Non può essere condiviso tra thread.
Unità
L'architettura delle unità in Weewx è progettata per semplificare le conversioni di unità di base e la visualizzazione delle unità. Non è progettato per fornire analisi dimensionali, conversioni arbitrarie e indicazioni di compatibilità.
Il driver legge le osservazioni da uno strumento e le converte, se necessario, in un insieme standard di unità. Le unità effettive utilizzate da ciascuno strumento variano ampiamente; alcuni strumenti usano unità metriche, altri usano unità consuetudinarie statunitensi e molti usano una combinazione. Il driver assicura che le unità siano coerenti per l'archiviazione nel database Weewx. Per impostazione predefinita, e per mantenere la compatibilità con wview , le unità predefinite del database sono le consuetudini statunitensi, sebbene ciò possa essere modificato.
Si noti che qualunque sia il sistema di unità utilizzato nel database, i dati possono essere visualizzati utilizzando qualsiasi sistema di unità. Quindi, in pratica, non importa quale sistema di unità viene utilizzato nel database.
Ciascun tipo di osservazione , ad esempio outTemp o pressure , è associato a un gruppo di unità , ad esempio group_temperature o group_pressure . Ogni gruppo di unità è associato a un tipo di unità come degree_F o mbar . Il servizio di reportistica utilizza questa architettura per convertire le osservazioni in un sistema di unità target, da visualizzare nei report.
Con questa architettura è possibile creare facilmente rapporti con, diciamo, vento misurato in nodi, pioggia misurata in mm e temperature in gradi Celsius. Oppure si può creare un singolo set di modelli, ma visualizzare i dati in diversi sistemi di unità con solo poche stanze in un file di configurazione.
PERSONALIZZAZIONE DEI REPORT
Esistono due meccanismi generali per personalizzare i report: modificare le opzioni in uno o più file di configurazione o modificare i file modello. Il primo è generalmente più facile, ma occasionalmente il secondo è necessario.
Opzioni
Le opzioni vengono utilizzate per specificare come appariranno i report e cosa conterranno. Ad esempio, controllano quali unità utilizzare, come formattare date e orari, quali dati devono essere presenti in ogni grafico, i colori degli elementi del grafico, ecc .
Per un elenco completo delle opzioni del rapporto, vedere la sezione Riferimento: opzioni del rapporto .
Le opzioni vengono lette da tre diversi tipi di file di configurazione:
FILE | DESCRIZIONE |
weewx.conf | Questo è il file di configurazione dell'applicazione. Contiene informazioni generali sulla configurazione, ad esempio quali driver e servizi caricare, nonché quali report eseguire. Le opzioni del rapporto possono anche essere specificate in questo file. |
skin.conf | Questo è il file di configurazione della skin. Contiene informazioni specifiche per uno skin , in particolare quali file modello elaborare e quali grafici generare. Tipicamente questo file è fornito dall'autore della skin. |
en.conf de.conf fr.conf ecc. |
Questi sono file di internazionalizzazione. Contengono informazioni sulla lingua e sulle impostazioni locali per uno skin specifico . |
I file di configurazione vengono letti ed elaborati utilizzando l'utility Python ConfigObj , utilizzando un formato simile al formato "INI" di MS-DOS . Ecco un semplice esempio:
[Section1] # Un commento key1 = value1 [[SubSectionA]] key2 = value2 [Section2] key3=value3
Questo esempio utilizza due sezioni a livello di radice (sezioni Section1 e Section2 ) e una sottosezione ( SubSectionA ), nidificata in Section1 . L'opzione key1 è nidificata in Section1 , l'opzione key3 è nidificata in Section2 , mentre l'opzione key2 è nidificata nella sottosezione SubSectionA .
Nota che mentre questo esempio fa rientrare le sottosezioni e le opzioni, questo è strettamente per la leggibilità - questo non è Python! È il numero di parentesi che conta per determinare l'annidamento, non il rientro!
I file di configurazione sfruttano la capacità di ConfigObj di organizzare le opzioni gerarchicamente in stanze . Ad esempio, la stanza [Labels] contiene il testo che deve essere visualizzato per ciascuna osservazione. La stanza [Units] contiene altre stanze, ognuna delle quali contiene parametri che controllano la visualizzazione delle unità.
Ordine di elaborazione
I file di configurazione e le relative sezioni vengono elaborati in un ordine specifico. Generalmente, i valori del file di configurazione della skin ( skin.conf ) vengono elaborati per primi, quindi le opzioni nel file di configurazione di Weewx (nominalmente weewx.conf ) vengono applicate per ultime. Questo ordine consente agli autori di skin di specificare l'aspetto di base di un report, garantendo al tempo stesso che gli utenti della skin abbiano l'ultima parola.
Per illustrare l'ordine di elaborazione, ecco i passaggi per la skin Seasons :
- • Innanzitutto, un insieme di opzioni definite nel modulo Python weewx.defaults serve come punto di partenza.
- • Successivamente, le opzioni del file di configurazione per Seasons , che si trova in skins/Seasons/skin.conf , vengono unite.
- • Successivamente, tutte le opzioni che si applicano a tutte le skin, specificate nella sezione [StdReport] / [[Defaults]] del file di configurazione di Weewx, vengono unite.
- • Infine, tutte le opzioni specifiche della skin, specificate nella sezione [StdReport] / [[Seasons]] della configurazione di Weewx, vengono unite. Queste opzioni hanno l'ultima parola.
In tutti e quattro i passaggi, se viene rilevata una specifica della lingua (opzione lang ), il file della lingua corrispondente verrà letto e unito. Se viene rilevata una specifica di unità (opzione unit_system ), vengono impostati i gruppi di unità appropriati. Ad esempio, se unit_system=metricwx , l'unità per la pressione di gruppo sarà impostata su mbar , ecc.
Il risultato è la seguente gerarchia di opzioni, elencate in ordine crescente di precedenza.
FILE | ESEMPIO | DESCRIZIONE |
weewx/defaults.py | [Units] [[Labels]] mbar=" mbar" |
Questi sono i valori predefiniti codificati per ogni opzione. Vengono utilizzati quando un'opzione non è specificata da nessun'altra parte. Questi non dovrebbero essere modificati a meno che tu non proponga una modifica al codice di Weewx; eventuali modifiche apportate qui andranno perse quando il software viene aggiornato. |
skin.conf | [Units] [[Labels]] mbar=" hPa" |
Fornito dall'autore della skin, il file di configurazione della skin, skin.conf , contiene opzioni che definiscono il comportamento di base della skin. In questo esempio, per qualsiasi motivo, l'autore della skin ha deciso che l'etichetta per le unità in millibar dovrebbe essere "hPa" (che è equivalente). |
weewx.conf | [StdReport] [[Defaults]] [[[Labels]]] [[[[Generic]]]] rain=Precipitazioni |
Le opzioni specificate in [[Defaults]] si applicano a tutti i report. Questo esempio indica che l'etichetta Rainfall deve essere utilizzata per l'osservazione della pioggia in tutti i report. |
weewx.conf | [StdReport] [[SeasonsReport]] [[[Labels]]] [[[[Generic]]]] inTemp=Temperatura cucina |
Massima precedenza. Ha l'ultima parola. Le opzioni qui specificate si applicano a un singolo rapporto. Questo esempio indica che l'etichetta Kitchen temperature deve essere utilizzata per l'osservazione inTemp , ma solo per il report SeasonsReport . |
Quando si specificano le opzioni, è necessario prestare attenzione al numero di parentesi! Nella tabella sopra, sono utilizzate due diverse profondità di nidificazione: una per weewx.conf e una per weewx/defaults.py e skin.conf . Questo perché le stanze definite in weewx.conf iniziano due livelli più in basso nella gerarchia [StdReport] , mentre le stanze definite in skin.conf e defaults.py sono al livello root. Pertanto, le opzioni specificate in weewx.conf devono utilizzare due set aggiuntivi di parentesi.
Altre skin vengono elaborate in modo simile anche se, ovviamente, il loro nome sarà qualcosa di diverso da Seasons .
Sebbene sia possibile modificare le opzioni a qualsiasi livello, come utente di una skin, di solito è meglio mantenere le modifiche nel file di configurazione di Weewx ( weewx.conf ) se possibile. In questo modo puoi applicare eventuali correzioni o modifiche quando l'autore della skin aggiorna la skin e le tue personalizzazioni non verranno sovrascritte.
Se sei un autore di skin, dovresti fornire il file di configurazione della skin ( skin.conf ) e inserirvi solo le opzioni necessarie per rendere la skin nel modo in cui la intendi. Tutte le opzioni che potrebbero essere localizzate per una lingua specifica (in particolare il testo) devono essere inserite nel file della lingua appropriato.
Cambiare lingua
Per impostazione predefinita, le skin fornite con Weewx sono impostate per la lingua inglese, ma supponiamo che tu voglia passare a un'altra lingua. Il modo in cui lo fai dipenderà dal fatto che la skin che stai utilizzando sia stata internazionalizzata e, in tal caso, se offra la tua lingua locale.
Skin internazionalizzate
Tutte le skin incluse in Weewx sono state internazionalizzate, quindi se stai lavorando con una di esse, questa è la sezione che fa per te. Successivamente, è necessario verificare se esiste un file di localizzazione per la propria lingua specifica. Per verificare, guarda nel contenuto della sottodirectory lang nella directory della skin. Ad esempio, se hai utilizzato un programma di installazione del pacchetto e stai utilizzando la skin Seasons , vorrai cercare in /etc/weewx/skins/Seasons/lang . All'interno, vedrai qualcosa di simile a questo:
ls -l /etc/weewx/skins/Seasons/lang totale 136 -rw-rw-r-- 1 tkeffer tkeffer 9447 1 luglio 11:11 cn.conf -rw-rw-r-- 1 tkeffer tkeffer 9844 13 marzo 12 :31 cz.conf -rw-rw-r-- 1 tkeffer tkeffer 9745 Mar 13 12:31 de.conf -rw-rw-r-- 1 tkeffer tkeffer 9459 Mar 13 12:31 en.conf -rw-rw- r-- 1 tkeffer tkeffer 10702 Mar 13 12:31 es.conf -rw-rw-r-- 1 tkeffer tkeffer 10673 Mag 31 07:50 fr.conf -rw-rw-r-- 1 tkeffer tkeffer 11838 Mar 13 12 :31 gr.conf -rw-rw-r-- 1 tkeffer tkeffer 9947 Mar 13 12:31 it.conf -rw-rw-r-- 1 tkeffer tkeffer 9548 Mar 13 12:31 nl.conf -rw-rw- r-- 1 tkeffer tkeffer 10722 15 aprile 14:52 no.conf -rw-rw-r-- 1 tkeffer tkeffer 15356 13 marzo 12:31 th.conf
Ciò significa che la skin Seasons è stata localizzata per le seguenti lingue:
FILE | LINGUA |
cn.conf | Cinese tradizionale |
cz.conf | Ceco |
de.conf | Tedesco |
it.conf | Inglese |
es.conf | Spagnolo |
fr.conf | Francese |
it.conf | Italiano |
gr.conf | Greco |
nl.conf | Olandese |
th.conf | Tailandese |
Se vuoi usare la skin Seasons e stai lavorando con una di queste lingue, allora sei fortunato: puoi semplicemente sovrascrivere l' opzione lang . Ad esempio, per cambiare la lingua visualizzata dalla skin Seasons dall'inglese al tedesco, modifica weewx.conf e cambia la sezione evidenziata:
[StdReport] ... [[SeasonsReport]] # Il SeasonsReport utilizza la skin 'Seasons', che contiene # immagini, modelli e grafici per il report. skin = Seasons enable = true lang = de
Al contrario, se la skin è stata internazionalizzata, ma non esiste un file di localizzazione per la tua lingua, dovrai fornirne uno. Consulta la sezione Internazionalizzato, ma manca la tua lingua .
Modifica dei formati di data e ora
I formati di data e ora vengono specificati utilizzando le stesse stringhe di formato utilizzate da strftime() . Ad esempio, %Y indica l'anno a 4 cifre e %H:%M indica l'ora in ore:minuti. I valori predefiniti per i formati di data e ora sono generalmente %x %X , che indica "usa il formato per le impostazioni locali del computer".
Poiché i formati di data sono predefiniti per le impostazioni locali del computer, una data potrebbe apparire con il formato "mese/giorno/anno". E se preferisci che le date abbiano il formato "anno.mese.giorno"? Come si indica il formato dell'ora di 24 ore rispetto a quello di 12 ore?
Le date e le ore generalmente compaiono in due posti: nei grafici e nei tag.
Formati di data e ora nelle immagini
La maggior parte dei grafici ha un'etichetta sull'asse orizzontale che indica quando è stato generato il grafico. Per impostazione predefinita, il formato per questa etichetta utilizza la locale del computer su cui è in esecuzione Weewx, ma puoi modificare il formato specificando l'opzione bottom_label_format .
Ad esempio, ciò comporterebbe una stringa di data/ora come "2021.12.13 12:45" indipendentemente dalle impostazioni locali del computer:
[StdReport] ... [[Defaults]] [[[ImageGenerator]]] [[[[day_images]]]] bottom_label_format = %Y.%m.%d %H:%M [[[[week_images]]] ] bottom_label_format = %Y.%m.%d %H:%M [[[[month_images]]]] bottom_label_format = %Y.%m.%d %H:%M [[[[year_images]]]] bottom_label_format = %Y.%m.%d %H:%M
Formati di data e ora per i tag
Ogni periodo di aggregazione ha un formato per gli orari associati a tale periodo. Questi formati sono definiti nella sezione TimeFormats . Il formato predefinito per ciascuno utilizza la data e/o l'ora del computer della locale su cui è in esecuzione Weewx.
Ad esempio, ciò comporterebbe una stringa di data/ora come "2021.12.13 12:45" indipendentemente dalle impostazioni locali del computer:
[StdReport] ... [[Defaults]] [[[Units]]] [[[[TimeFormats]]]] hour = %H:%M day = %Y.%m.%d week = %Y.%m.%d (%A) month = %Y.%m.%d %H:%M year = %Y.%m.%d %H:%M rainyear = %Y.%m.%d %H:%M current = %Y.%m.%d %H:%M ephem_day = %H:%M ephem_year = %Y.%m.%d %H:%M
Modifica dei sistemi di unità
Ogni sistema di unità è un insieme di unità. Ad esempio, il sistema di unità METRIC utilizza i centimetri per la pioggia, i chilometri all'ora per la velocità del vento e i gradi Celsius per la temperatura. L'opzione unit_system controlla quale sistema di unità verrà utilizzato nei report. Le scelte disponibili sono US , METRIC o METRICWX . L'opzione non fa distinzione tra maiuscole e minuscole. Vedere l' Appendice Unità per l'unità definita in ciascuno di questi sistemi di unità.
Per impostazione predefinita, Weewx utilizza il sistema statunitense (consuetudine statunitense). Supponiamo che preferiresti utilizzare il sistema METRICWX per tutti i tuoi rapporti? Quindi cambia questo
[StdReport] ... [[Defaults]] # Quale sistema di unità utilizzare per tutti i report. Le scelte sono 'us', 'metric' o 'metricwx'. # È possibile eseguire l'override di questo per i singoli rapporti. unit_system = US
in questo
[StdReport] ... [[Defaults]] # Quale sistema di unità utilizzare per tutti i report. Le scelte sono 'us', 'metric' o 'metricwx'. # È possibile eseguire l'override di questo per i singoli rapporti. unit_system = metricwx
Unità miste
Tuttavia, cosa succede se si desidera un mix? Ad esempio, supponi di voler generalmente le unità consuetudinarie statunitensi, ma desideri che le pressioni barometriche siano espresse in millibar? Questo può essere fatto sovrascrivendo il gruppo di unità appropriato.
[StdReport] ... [[Defaults]] # Quale sistema di unità utilizzare per tutti i report. Le scelte sono 'us', 'metric' o 'metricwx'. # È possibile eseguire l'override di questo per i singoli rapporti. unit_system = us # Sovrascrivi le unità utilizzate per la pressione: [[[Units]]] [[[[Groups]]]] group_pressure = mbar
Questo dice che generalmente vuoi i sistemi di unità statunitensi per tutti i rapporti, ma vuoi che la pressione sia riportata in millibar . Altre unità possono essere sostituite in modo simile.
Sistemi a più unità
Un altro esempio. Supponiamo di voler generare due report, uno nel sistema consuetudinario statunitense, l'altro utilizzando il sistema METRICWX . Il primo, chiamalo SeasonsUSReport , andrà nella normale directory HTML_ROOT . Tuttavia, quest'ultimo, chiamalo SeasonsMetricReport , andrà in una sottodirectory, HTML_ROOT /metric:
[StdReport] # Dove risiedono le skin, relativo a WEEWX_ROOT SKIN_ROOT = skin # Dove dovrebbero andare i report generati, relativo a WEEWX_ROOT HTML_ROOT = public_html # Il binding del database indica quali dati devono essere utilizzati nei report. data_binding = wx_binding [[SeasonsUSReport]] skin = Seasons unit_system = us enable = true [[SeasonsMetricReport]] skin = Seasons unit_system = metricwx HTML_ROOT = public_html/metric enable = true
Si noti come entrambi i rapporti utilizzino la stessa skin (ovvero skin Seasons ), ma diversi sistemi di unità e destinazioni diverse. Il primo, SeasonsUSReport, imposta l'opzione unit_system su us e utilizza la destinazione predefinita. Al contrario, il secondo, SeasonsMetricReport , utilizza il sistema di unità metricwx e una destinazione diversa, public_html/metric .
Cambiare etichette
Ogni tipo di osservazione è associato a un'etichetta predefinita . Ad esempio, in lingua inglese, l'etichetta predefinita per il tipo di osservazione outTemp è generalmente Outside Temperature . È possibile modificare questa etichetta ignorando l'impostazione predefinita. Il modo in cui lo fai dipenderà dal fatto che la skin che stai utilizzando sia stata internazionalizzata e, in tal caso, se offra la tua lingua locale.
Diamo un'occhiata a un esempio. Se dai un'occhiata all'interno del file skins/Seasons/lang/en.conf , vedrai che contiene quello che sembra un grosso file di configurazione. Tra le altre cose, ha due voci che assomigliano a questa:
... [Labels] ... [[Generic]] ... inTemp = Inside Temperature outTemp = Outside Temperature ...
Questo indica ai generatori di report che quando arriva il momento di etichettare le variabili di osservazione inTemp e outTemp , utilizzare rispettivamente le stringhe Inside Temperature e Outside Temperature.
Tuttavia, diciamo che abbiamo effettivamente posizionato il nostro sensore di temperatura esterna nella stalla e desideriamo etichettarlo di conseguenza. Dobbiamo sovrascrivere l'etichetta fornita nel file di localizzazione. Potremmo semplicemente cambiare il file di localizzazione en.conf , ma poi se l'autore della skin facesse una nuova versione, la nostra modifica potrebbe andare persa. Meglio sovrascrivere l'impostazione predefinita apportando la modifica in weewx.conf . Per fare ciò, apportare le seguenti modifiche in weewx.conf :
[[SeasonsReport]] # The SeasonsReport uses the 'Seasons' skin, which contains the # images, templates and plots for the report. skin = Seasons lang = en unit_system = US enable = true [[[Labels]]] [[[[Generic]]]] outTemp = Barn Temperature
Ciò causerà la sostituzione dell'etichetta predefinita Temperatura esterna con la nuova etichetta Temperatura stalla ovunque nel rapporto. L'etichetta per il tipo inTemp non verrà modificata.
Pianificazione generazione report
La normale operazione di Weewx consiste nell'eseguire ogni report definito in weewx.conf ogni periodo di archiviazione. Anche se questo può essere adatto alla maggior parte delle situazioni, ci possono essere occasioni in cui è desiderabile eseguire un rapporto meno frequentemente di ogni periodo di archiviazione. Ad esempio, l'intervallo di archiviazione potrebbe essere di 5 minuti, ma si desidera eseguire l'FTP dei file solo ogni 30 minuti, una volta al giorno o ogni giorno a un'ora prestabilita. Weewx ha due meccanismi che forniscono la possibilità di controllare quando i file vengono generati. L' opzione stale_age consente di controllare l'età di un file prima che venga rigenerato e l' opzione report_timing consente un controllo preciso su quando vengono eseguiti i singoli report.
Mentre report_timing specifica quando deve essere generato un dato report, la generazione dei report è ancora controllata dal ciclo di report di Weewx, quindi i report non possono mai essere generati più frequentemente di una volta per periodo di archiviazione.
L' opzione report_timing
L' opzione report_timing utilizza un formato simile a CRON per controllare quando deve essere eseguito un report. Sebbene venga utilizzato un formato simile a CRON, il controllo della generazione di report Weewx utilizzando l' opzione report_timing è limitato completamente a Weewx e non ha alcuna interazione con il servizio CRON di sistema.
L' opzione report_timing è composta da cinque parametri separati da spazi bianchi:
report_timing = minutes hours day_of_month months day_of_week
I parametri report_timing sono riassunti nella seguente tabella:
PARAMETRO | FUNZIONE | VALORI CONSENTITI |
minutes | Specifica i minuti dell'ora in cui verrà eseguito il rapporto | * o numeri compresi tra 0 e 59 inclusi |
hours | Specifica le ore del giorno in cui verrà eseguito il report | * , o numeri compresi tra 0 e 23 inclusi |
day_of_month | Specifica i giorni del mese in cui verrà eseguito il rapporto | * , o numeri compresi nell'intervallo 1..31 inclusi |
months | Specifica i mesi dell'anno in cui verrà eseguito il report | * , o numeri nell'intervallo 1..12 inclusi, o nomi abbreviati nell'intervallo jan..dec inclusi |
day_of_week | Specifica i giorni della settimana in cui verrà eseguito il rapporto | * , o numeri nell'intervallo 0..7 inclusi (0,7 = domenica, 1 = lunedì ecc.), o nomi abbreviati nell'intervallo sun..sat inclusi |
L' opzione report_timing può essere utilizzata solo in weewx.conf . Se impostata nella sezione [StdReport] di weewx.conf, l'opzione verrà applicata a tutti i report elencati in [StdReport] . Se specificata all'interno di una sezione del report, l'opzione sostituirà qualsiasi impostazione in [StdReport] per tale report. In questo modo è possibile avere diversi report eseguiti in momenti diversi. Il seguente estratto weewx.conf di esempio lo illustra:
[StdReport] # Dove risiedono le skin, relativo a WEEWX_ROOT SKIN_ROOT = skin # Dove dovrebbero andare i report generati, relativo a WEEWX_ROOT HTML_ROOT = public_html # Il binding del database indica quali dati devono essere utilizzati nei report. data_binding = wx_binding # Parametro di temporizzazione report report_timing = 0 * * * * # Ognuna delle seguenti sottosezioni definisce un report che verrà eseguito. [[AReport]] skin = SomeSkin [[AnotherReport]] skin = SomeOtherSkin report_timing = */10 * * * *
In questo caso, il report [[AReport]] verrebbe eseguito sotto il controllo dell'impostazione 0 * * * * (sull'ora) in [StdReport] e il report [[AnotherReport]] verrebbe eseguito sotto il controllo di * /10 * * * * impostazione (ogni 10 minuti) che ha sostituito l' impostazione [StdReport] .
In che modo report_timing controlla i rapporti
La sintassi e l'interpretazione dei parametri report_timing sono sostanzialmente le stesse del servizio CRON in molti sistemi operativi Unix e simili a Unix. La sintassi e l'interpretazione sono descritte di seguito.
Quando l' opzione report_timing è in uso, Weewx eseguirà un report quando i parametri minuto, ora e mese dell'anno corrispondono all'ora del report e almeno uno dei due parametri del giorno (giorno del mese o giorno della settimana) corrisponde all'ora del report. Ciò significa che gli orari inesistenti, come le "ore mancanti" durante il passaggio all'ora legale, non corrisponderanno mai, causando la mancata esecuzione dei report pianificati durante gli "orari mancanti". Allo stesso modo, gli orari che si verificano più di una volta (di nuovo, durante il passaggio all'ora solare) causeranno l'esecuzione più di una volta dei rapporti corrispondenti.
L'ora del report non si riferisce all'ora in cui viene eseguito il report, ma piuttosto alla data e all'ora degli ultimi dati su cui si basa il report. Se lo desideri, è la data e l'ora effettiva del rapporto. Per il normale funzionamento di Weewx, l'ora del report si allinea con la data e l'ora del record di archivio più recente. Quando i rapporti vengono eseguiti utilizzando l' utilità wee_reports , l'ora del rapporto è la dateTime del record di archivio più recente (impostazione predefinita) o l'argomento facoltativo della riga di comando timestamp.
Il giorno in cui deve essere eseguito un rapporto può essere specificato da due parametri; giorno del mese e/o giorno della settimana. Se entrambi i parametri sono limitati (vale a dire, non un asterisco), il report verrà eseguito quando uno dei due campi corrisponde all'ora corrente. Ad esempio,
report_timing = 30 4 1,15 * 5
fa sì che il rapporto venga eseguito alle 4:30 del 1° e del 15 di ogni mese e alle 4:30 di ogni venerdì.
La relazione tra report_timing e periodo di archiviazione
Un servizio CRON tradizionale ha una risoluzione di un minuto, il che significa che il servizio CRON controlla ogni minuto se eseguire comandi. D'altra parte, il sistema di report di Weewx controlla quali report devono essere eseguiti una volta per periodo di archiviazione, dove il periodo di archiviazione può essere di un minuto, cinque minuti o un altro periodo definito dall'utente. Di conseguenza, l' opzione report_timing può specificare un rapporto da eseguire in un momento che non è in linea con il periodo di archiviazione di Weewx. In tali casi l' opzione report_timing non causa l'esecuzione di un report al di fuori del normale ciclo di report di Weewx, piuttosto farà in modo che il report venga eseguito durante il successivo ciclo di report. All'inizio di ogni ciclo di report e fornito un report_timing l'opzione è impostata, Weewx controllerà ogni limite di minuti dall'ora del report corrente fino all'ora del report del ciclo di report precedente. Se viene trovata una corrispondenza in uno di questi limiti di un minuto, il rapporto verrà eseguito durante il ciclo del rapporto. Questo può essere meglio descritto attraverso alcuni esempi:
REPORT_TIMING | PERIODO DI ARCHIVIO | QUANDO VERRÀ ESEGUITO IL RAPPORTO |
0 * * * * | 5 minuti | Il report verrà eseguito solo durante il ciclo di report che inizia all'ora. |
5 * * * * | 5 minuti | Il report verrà eseguito solo durante il ciclo di report che inizia 5 minuti dopo l'ora. |
3 * * * * | 5 minuti | Il report verrà eseguito solo durante il ciclo di report che inizia 5 minuti dopo l'ora. |
10 * * * * | 15 minuti | Il report verrà eseguito solo durante il ciclo di report che inizia 15 minuti dopo l'ora |
10,40 * * * * | 15 minuti | Il report verrà eseguito solo durante i cicli di report che iniziano 15 minuti dopo l'ora e 45 minuti dopo l'ora. |
5,10 * * * * | 15 minuti | Il report verrà eseguito una sola volta durante il ciclo di report che inizia 15 minuti dopo l'ora. |
Liste, intervalli e passi
L' opzione report_timing supporta elenchi, intervalli e passaggi per tutti i parametri. Elenchi, intervalli e passaggi possono essere utilizzati come segue:
- • Liste . Un elenco è un insieme di numeri (o intervalli) separati da virgole, ad esempio 1, 2, 5, 9 o 0-4, 8-12 . Una corrispondenza con uno qualsiasi degli elementi dell'elenco risulterà in una corrispondenza per quel particolare parametro. Se gli esempi fossero applicati al parametro minutes e soggetti ad altri parametri nell'opzione report_timing , il report verrebbe eseguito ai minuti 1, 2, 5 e 9 e 0, 1, 2, 3, 4, 8, 9, 10, 11 e 12 rispettivamente. I nomi abbreviati di mese e giorno non possono essere utilizzati in un elenco.
- • Intervalli . Gli intervalli sono due numeri separati da un trattino, ad esempio 8-11 . L'intervallo specificato è inclusivo. Una corrispondenza con uno qualsiasi dei valori inclusi nell'intervallo risulterà in una corrispondenza per quel particolare parametro. Se l'esempio è stato applicato al parametro hours e soggetto ad altri parametri nell'opzione report_timing , il report verrebbe eseguito alle ore 8, 9, 10 e 11. Un intervallo può essere incluso come elemento di un elenco. I nomi abbreviati di mese e giorno non possono essere utilizzati in un intervallo.
- • Passi . Un passaggio può essere utilizzato in combinazione con un intervallo o un asterisco e sono indicati da un ' / ' seguito da un numero. Seguire un intervallo con un passaggio specifica i salti del valore del numero del passaggio nell'intervallo. Ad esempio, 0-12/2 utilizzato nel parametro hours, soggetto ad altro parametro nell'opzione report_timing , eseguirà il report alle ore 0, 2, 4, 6, 8 e 12. I passaggi sono consentiti anche dopo un asterisco in in tal caso i salti del valore del numero di passo avvengono attraverso tutti i possibili valori del parametro. Ad esempio, */3 può essere utilizzato nel parametro hours per, soggetto ad altro parametro nell'opzione report_timing , eseguire il report alle ore 0, 3, 6, 9, 12, 15, 18 e 21.
Nicknames
L' opzione report_timing supporta una serie di 'nickname' di specificazione dell'ora. Questi soprannomi sono preceduti dal carattere ' @ ' e sostituiscono i cinque parametri nell'opzione report_timing . I nickname supportati sono:
NICKNAME | IMPOSTAZIONE EQUIVALENTE | QUANDO VERRÀ ESEGUITO IL RAPPORTO |
@yearly @annually |
0 0 1 1 * | Una volta all'anno alla mezzanotte del 1° gennaio. |
@monthly | 0 0 1 * * | Ogni mese alla mezzanotte del 1° del mese. |
@weekly | 0 0 * * 0 | Ogni settimana a mezzanotte la domenica. |
@daily | 0 0 * * * | Tutti i giorni a mezzanotte. |
@hourly | 0 * * * * | Ogni ora allo scoccare dell'ora. |
Esempi di report_timing
Le impostazioni numeriche per report_timing a volte possono essere difficili da comprendere a causa delle complesse combinazioni di parametri. La tabella seguente mostra una serie di opzioni report_timing di esempio e gli orari corrispondenti in cui il report verrà eseguito.
REPORT_TIMING | QUANDO VERRÀ ESEGUITO IL RAPPORTO |
* * * * * | Ogni periodo di archivio. Questa impostazione è effettivamente il metodo operativo predefinito di Weewx. |
25 * * * * | 25 minuti dopo ogni ora. |
0 * * * * | Ogni ora allo scoccare dell'ora. |
5 0 * * * | 00:05 tutti i giorni. |
25 16 * * * | 16:25 tutti i giorni. |
25 16 1 * * | 16:25 il 1° di ogni mese. |
25 16 1 2 * | 16:25 del 1° febbraio. |
25 16 * * 0 | 16:25 ogni domenica. |
*/10 * * * * | Ogni ora e 10, 20, 30, 40 e 50 minuti dopo l'ora. |
*/9 * * * * | Ogni ora e 9, 18, 27, 36, 45 e 54 minuti dopo l'ora. |
*/10 */2 * * * | 0, 10, 20, 30, 40 e 50 minuti dopo l'ora pari. |
* 6-17 * * * | Ogni periodo di archiviazione dalle 06:00 (incluse) fino alle 18:00 escluse. |
* 1,4,14 * * * | Ogni periodo di archiviazione nell'ora che inizia dalle 01:00 alle 01:59, dalle 04:00 alle 04:59 e dalle 14:00 alle 14:59 (la nota esclude gli orari dei report alle 02:00, 05:00 e 15:00). |
0*1*0,3 | Ogni ora il primo del mese e ogni ora ogni domenica e mercoledì. |
* * 21,1-10/3 6 * | Ogni periodo di archiviazione nei giorni 1, 4, 7, 10 e 21 giugno. |
@monthly | Mezzanotte del 1° del mese. |
L' utility wee_reports e l' opzione report_timing
L' opzione report_timing viene ignorata quando si utilizza l' utilità wee_reports.
CHEETAH GENERATOR
Questa sezione offre una panoramica del generatore Cheetah. Per i dettagli su ciascuna delle sue varie opzioni, vedere la sezione [CheetahGenerator] in Riferimento: opzioni di report .
La generazione del file viene eseguita utilizzando il motore di template Cheetah , che elabora un template , sostituendo eventuali tag simbolici , quindi produce un file di output. In genere, viene eseguito dopo ogni nuovo record di archivio (di solito circa ogni cinque minuti), ma può anche essere eseguito su richiesta utilizzando l' utilità wee_reports .
Il motore Cheetah è molto potente, essenzialmente ti consente di avere la semantica completa di Python disponibile nei tuoi modelli. Poiché ciò renderebbe i modelli incomprensibili a chiunque tranne che a un programmatore Python, Weewx adotta un sottoinsieme molto piccolo della sua potenza.
Il generatore Cheetah è controllato dalla sezione [CheetahGenerator] . Diamo un'occhiata a come funziona.
Quali file vengono elaborati?
Ogni file modello ha un nome simile a D/F.E.tmpl , dove D è la directory (facoltativa) in cui si trova il modello e sarà anche la directory in cui verranno inseriti i risultati e F.E è il nome del file generato. Quindi, dato un file modello con nome Acme/index.html.tmpl , i risultati verranno inseriti in HTML_ROOT /Acme/index.html .
La configurazione per un gruppo di modelli sarà simile a questa:
[CheetahGenerator] [[index]] template = index.html.tmpl [[textfile]] template = filename.txt.tmpl [[xmlfile]] template = filename.xml.tmpl
Può esserci un solo modello in ogni blocco. Nella maggior parte dei casi, il nome del blocco non ha importanza: viene utilizzato solo per isolare ciascun modello. Tuttavia, esistono quattro nomi di blocco con un significato speciale: SummaryByDay , SummaryByMonth , SummaryByYear e ToDate .
Specifica dei file modello
A titolo di esempio, ecco la sezione [CheetahGenerator] da skin.conf per la skin Seasons .
[CheetahGenerator] # CheetahGenerator crea file da modelli. Questa sezione # specifica quali file verranno generati da quale modello. # Le possibili codifiche includono 'html_entities', 'strict_ascii', 'normalized_ascii', # così come quelle elencate in https://docs.python.org/3/library/codecs.html#standard-encodings encoding = html_entities [[SummaryByMonth]] # Report che riepilogano "per mese" [[[NOAA_month]]] encoding = normalized_ascii template = NOAA/NOAA-%Y-%m.txt.tmpl [[SummaryByYear]] # Report che riepilogano "per anno" [[ [NOAA_year]]] encoding = normalized_ascii template = NOAA/NOAA-%Y.txt.tmpl [[ToDate]] # Report che mostrano le statistiche "to date", come day-to-date, # week-to-date, month-to-date , ecc. [[[index]]] template = index.html.tmpl [[[statistics]]] template = statistics.html.tmpl [[[telemetry]]] template = telemetry.html.tmpl [[[tabular] ]] template = tabular.html.tmpl [[[celestial]]] template = celestial.html.tmpl # Decommenta quanto segue per fare in modo che Weewx generi una pagina celestial solo una volta all'ora: # stale_age = 3600 [[[RSS]]] template = rss.xml.tmpl
La skin contiene tre diversi tipi di output generato:
- • Riepilogo per mese. La skin utilizza SummaryByMonth per produrre riepiloghi NOAA, uno per ogni mese, come un semplice file di testo.
- • Riepilogo per anno. La skin utilizza SummaryByYear per produrre riepiloghi NOAA, uno per ogni anno, come un semplice file di testo.
- • Sommario "ToDate". La skin produce una pagina HTML index.html , oltre a file HTML per statistiche dettagliate, telemetria e informazioni celesti. Include anche una pagina master ( tabular.html ) in cui vengono visualizzate le informazioni NOAA. Tutti questi file sono HTML.
Perché l'opzione
encoding = html_entities
appare direttamente sotto [StdReport] , questa sarà la codifica predefinita dei file generati a meno che non venga sovrascritta in modo esplicito. Ne vediamo un esempio in [SummaryByMonth] e [SummaryByYear] , che usano invece l'opzione normalized_ascii (sostituisce i caratteri accentati con un analogo non accentato).
A parte SummaryByMonth e SummaryByYear , i nomi delle sezioni sono arbitrari. ToDate avrebbe potuto benissimo chiamarsi files_to_date , e le sezioni index , statistics e telemetry avrebbero potuto benissimo chiamarsi tom , dick e harry .
[[SummaryByYear]]
Utilizzare SummaryByYear per generare una serie di file, un file all'anno. Il nome del file modello dovrebbe contenere un codice strftime() per l'anno; questo verrà sostituito con l'anno dei dati nel file.
[CheetahGenerator] [[SummaryByYear]] # Rapporti che riassumono "per anno" [[[NOAA_year]]] encoding = normalized_ascii template = NOAA/NOAA-%Y.txt.tmpl
Il modello NOAA/NOAA-%Y.txt.tmpl potrebbe essere simile a questo:
RIEPILOGO PER ANNO $year.dateTime TEMPERATURE E UMIDITÀ MENSILI: #for $record in $year.records $record.dateTime $record.outTemp $record.outHumidity #end for
[[SummaryByMonth]]
Utilizzare SummaryByMonth per generare una serie di file, un file al mese. Il nome del file modello dovrebbe contenere un codice strftime() per anno e mese; questi verranno sostituiti con l'anno e il mese dei dati presenti nel file.
[CheetahGenerator] [[SummaryByMonth]] # Rapporti che riassumono "per mese" [[[NOAA_month]]] encoding = normalized_ascii template = NOAA/NOAA-%Y-%m.txt.tmpl
Il modello NOAA/NOAA-%Y-%m.txt.tmpl potrebbe essere simile a questo:
RIEPILOGO DEL MESE $month.dateTime TEMPERATURE E UMIDITÀ GIORNALIERE: #for $record in $month.records $record.dateTime $record.outTemp $record.outHumidity #end for
[[SummaryByDay]]
Sebbene la skin Seasons non ne faccia uso, esiste anche una funzionalità SummaryByDay . Come suggerisce il nome, questo si traduce in un file al giorno. Il nome del file modello dovrebbe contenere un codice strftime() per l'anno, il mese e il giorno; questi verranno sostituiti con l'anno, il mese e il giorno dei dati nel file.
[CheetahGenerator] [[SummaryByDay]] # Rapporti che riassumono "per giorno" [[[NOAA_day]]]
encoding= normalized_ascii
template = NOAA/NOAA-%Y-%m-%d.txt.tmpl
Il modello NOAA/NOAA-%Y-%m-%d.txt.tmpl potrebbe essere simile a questo:
RIEPILOGO PER GIORNO $day.dateTime TEMPERATURE E UMIDITÀ ORARIE: #for $record in $day.records $record.dateTime $record.outTemp $record.outHumidity #end for
Questo può creare molti file, uno al giorno. Se hai 3 anni di record, sarebbero più di 1.000 file!
Tag
Se guardi all'interno di un modello, vedrai che fa un uso massiccio di tag . Quando il generatore Cheetah elabora il modello, sostituisce ogni tag con un valore appropriato e, a volte, un'etichetta. Questa sezione discute i dettagli di come ciò accade.
Se si verifica un errore di tag durante la generazione del modello, l'errore verrà visualizzato nel file di registro. Molti errori sono evidenti: Cheetah visualizzerà un numero di riga ed elencherà il file modello in cui si è verificato l'errore. Sfortunatamente, in altri casi, il messaggio di errore può essere molto criptico e poco utile. Quindi apporta piccole modifiche e prova spesso. Utilizzare l'utilità wee_reports per velocizzare il processo.
Ecco alcuni esempi di tag:
$current.outTemp $month.outTemp.max $month.outTemp.maxtime
Questi codificano rispettivamente la temperatura esterna corrente, la temperatura esterna massima per il mese e l'ora in cui si è verificato il massimo. Quindi un file modello che contiene:
<html> <head> <title>Condizioni attuali</title> </head> <body> <p>Temperatura attuale = $current.outTemp</p> <p>Il massimo per il mese è $month.outTemp.max , che si è verificato alle $month.outTemp.maxtime</p> </body> </html>
sarebbe tutto ciò di cui hai bisogno per una pagina HTML molto semplice che visualizzerebbe il testo (supponendo che il gruppo di unità per la temperatura sia degree_F ):
Temperatura attuale = 51,0°F
La massima per il mese è 68,8°F, che si è verificata il 07 ottobre 2009 15:15
Il formato utilizzato per formattare la temperatura ( 51.0 ) è specificato nella sezione [Units][[StringFormat]] . L'etichetta dell'unità °F proviene dalla sezione [Units][[Labels]] , mentre il formato dell'ora proviene da [Units][[TimeFormats]] .
Come abbiamo visto sopra, i tag possono essere molto semplici:
## Invia la temperatura esterna massima utilizzando un formato e un'etichetta appropriati: $month.outTemp.max
La maggior parte delle volte, i tag "fanno la cosa giusta" e sono tutto ciò di cui hai bisogno. Tuttavia, Weewx offre un'ampia personalizzazione dell'output generato per applicazioni specializzate come feed RSS XML o report formattati rigidamente (come i report NOAA). Questa sezione specifica le varie opzioni di tag disponibili.
Esistono due diverse versioni dei tag, a seconda che i dati siano "correnti" o un'aggregazione nel tempo. Tuttavia, entrambe le versioni sono simili.
Periodo di tempo $current
Il periodo di tempo $current rappresenta un'osservazione corrente . Un esempio potrebbe essere l'attuale pressione barometrica:
$current.barometer
Formalmente, Weewx cerca prima il tipo di osservazione nel record emesso dall'evento NEW_ARCHIVE_RECORD . Questi sono generalmente i dati emessi dalla console della stazione, aumentati da qualsiasi variabile derivata ( ad es. wind chill) che potresti aver specificato. Se il tipo di osservazione non può essere trovato lì, verrà cercata la registrazione più recente nel database.
Il tag più generale per un'osservazione "corrente" è simile a:
$current($timestamp=some_time, $max_delta=delta_t,$data_binding=binding_name).obstype[.optional_unit_conversion][.optional_rounding][.optional_formatting]
Dove:
• some_time è un timestamp che vuoi visualizzare. È facoltativo, l'impostazione predefinita è visualizzare il valore per l'ora corrente.
• delta_t è la più grande differenza di tempo (in secondi) tra l'ora specificata e un timestamp di un record nel database che verrà restituito. Per impostazione predefinita, è zero, il che significa che deve esserci una corrispondenza esatta con un'ora specificata per il recupero di un record.
• binding_name è un nome di associazione a un database. Un esempio potrebbe essere wx_binding . Vedere la sezione Nomi di associazione per ulteriori dettagli.
• obstype è un tipo di osservazione, come barometer . Questo tipo deve apparire come campo nel database o nel record corrente (di solito l'ultimo).
• optional_unit_conversion è un tag di conversione unità facoltativo. Se forniti, i risultati verranno convertiti nelle unità specificate, altrimenti verranno utilizzate le unità predefinite specificate nel file di configurazione della skin (nella sezione [Units][[Groups]] ). Vedere la sezione Opzioni di conversione unità .
• optional_rounding consente di arrotondare i risultati a un numero fisso di cifre decimali. Vedere la sezione Arrotondamento facoltativo
• optional_formatting è un insieme di tag di formattazione facoltativi, che controllano l'aspetto del valore. Vedere la sezione Opzioni di formattazione di seguito.
Periodo di tempo $latest
Il periodo di tempo $latest è molto simile a $current , tranne per il fatto che utilizza l'ultimo timestamp disponibile in un database. Di solito, $current e $latest sono uguali, ma se un data binding punta a un database remoto, potrebbero non esserlo. Vedere la sezione Utilizzo di più associazioni per un esempio in cui ciò è accaduto.
Periodi di aggregazione
Periodi di aggregazione è l'altro tipo di tag. Per esempio,
$week.rain.sum
rappresenta un'aggregazione nel tempo , utilizzando un certo tipo di aggregazione . In questo esempio, il tempo di aggregazione è una settimana e il tipo di aggregazione è sommatoria. Quindi, questo tag rappresenta le precipitazioni totali nell'arco di una settimana.
Il tag più generale per un'aggregazione nel tempo è simile a:
$period($data_binding=binding_name, $optional_ago=delta).statstype.aggregation[.optional_unit_conversion][.optional_rounding][.optional_formatting]
Dove:
• period è il periodo di tempo in cui deve essere eseguita l'aggregazione. Le scelte possibili sono elencate nella tabella sottostante .
• binding_name è un nome di associazione a un database. Un esempio potrebbe essere wx_binding . Vedere la sezione Nomi di associazione per ulteriori dettagli.
• optional_ago è una parola chiave che dipende dal periodo di aggregazione. Ad esempio, per week , sarebbe weeks_ago , per day , sarebbe days_ago , ecc.
• delta è un numero intero che indica il periodo di aggregazione desiderato. Ad esempio $week($weeks_ago=1) indica la scorsa settimana, $day($days_ago=2) sarebbe il giorno prima di ieri, ecc . Il valore predefinito è zero: ovvero questo periodo di aggregazione.
• statstype è un tipo statistico . Questo è generalmente qualsiasi tipo di osservazione che appare nel database, così come alcuni tipi sintetici (come i gradi giorno di riscaldamento e raffreddamento). Non tutte le aggregazioni sono supportate per tutti i tipi.
• aggregation è un tipo di aggregazione . Se chiedi $month.outTemp.avg, stai chiedendo la temperatura esterna media per il mese. I possibili tipi di aggregazione sono riportati in Appendice: Tipi di aggregazione .
• optional_unit_conversion è un tag di conversione unità facoltativo. Se forniti, i risultati verranno convertiti nelle unità specificate, altrimenti verranno utilizzatele unità predefinite specificate nel file di configurazione della skin (nella sezione [Units][[Groups]] ). Vedere la sezione Opzioni di conversione delle unità .
• optional_rounding consente di arrotondare i risultati a un numero fisso di cifre decimali. Vedere la sezione Arrotondamento facoltativo
• optional_formatting è un insieme di tag di formattazione facoltativi, che controllano l'aspetto del valore. Vedere la sezione Opzioni di formattazione di seguito.
Esistono diversi periodi di aggregazione che possono essere utilizzati:
PERIODO DI AGGREGAZIONE | DESCRIZIONE | ESEMPIO | SIGNIFICATO DELL'ESEMPIO |
$hour | Quest'ora. | $hour.outTemp.maxtime | L'ora della temperatura massima di quest'ora. |
$day | Oggi (da mezzanotte). | $day.outTemp.max | La temperatura massima da mezzanotte |
$yesterday | Ieri. Sinonimo di $day($days_ago=1). | $ieri.outTemp.maxtime | L'ora della temperatura massima di ieri. |
$week | Questa settimana. L'inizio della settimana è impostato dall'opzione week_start . | $week.outTemp.max | La temperatura massima di questa settimana. |
$month | Questo mese (dal primo del mese). | $month.outTemp.min | La temperatura minima di questo mese. |
$year | Quest'anno (dal 1 gennaio). | $year.outTemp.max | La temperatura massima dall'inizio dell'anno. |
$rainyear | L'anno delle piogge. L'inizio dell'anno delle piogge è impostato dall'opzione rain_year_start . | $rainyear.rain.sum | Le precipitazioni totali per l'anno delle piogge. L'inizio dell'anno delle piogge è impostato dall'opzione rain_year_start . |
$alltime | Tutti i record nel database forniti da binding_name . | $alltime.outTemp.max | La temperatura esterna massima nel database predefinito. |
I parametri $optional_ago possono essere utili per statistiche più lontane nel passato. Ecco alcuni esempi:
PERIODO DI AGGREGAZIONE | ESEMPIO | DESCRIZIONE |
$hour($hours_ago=h) | $hour($hours_ago=1).outTemp.avg | La temperatura media dell'ultima ora (1 ora fa). |
$day($days_ago=d) | $day($days_ago=2).outTemp.avg | La temperatura media dell'altro ieri (2 giorni fa). |
$week($weeks_ago=d) | $week($weeks_ago=1).outTemp.max | La temperatura massima della scorsa settimana. |
$month($months_ago=m) | $month($months_ago=1).outTemp.max | La temperatura massima del mese scorso. |
$year($years_ago=m) | $year($years_ago=1).outTemp.max | La temperatura massima dell'anno scorso. |
Opzioni di conversione delle unità
Il tag optional_unit_conversion può essere utilizzato con osservazioni o aggregazioni correnti. Se forniti, i risultati verranno convertiti nelle unità specificate. Ad esempio, se hai impostato group_pressure su pollici di mercurio ( inHg ), il tag
Pressione media di oggi=$day.barometer.avg
normalmente darebbe un risultato come
Pressione media di oggi = 30,05 inHg
Tuttavia, se aggiungi mbar alla fine del tag,
Pressione media di oggi=$day.barometer.avg.mbar
quindi i risultati saranno in millibar:
Pressione media odierna=1017,5 mbar
Conversioni illegali
Se viene richiesta una conversione inappropriata o senza senso, ad esempio ,
Pressione minima di oggi in mbar: $day.barometer.min.mbar o in gradi C: $day.barometer.min.degree_C o in unità foobar: $day.barometer.min.foobar
quindi i tag offensivi verranno inseriti nell'output:
Pressione minima odierna in mbar: 1015.3
o in gradi C: $day.barometer.min.degree_C
o in unità foobar: $day.barometer.min.foobar
Arrotondamento facoltativo
I dati nel tag risultante possono essere facoltativamente arrotondati a un numero fisso di cifre decimali. Questo è utile quando si emettono dati non elaborati o stringhe JSON. Non dovrebbe essere usato con dati formattati (usare una stringa di formato sarebbe una scelta migliore).
La struttura del tag è
.round(ndigits=None)
Dove
ndigits è il numero di cifre decimali da conservare. Se None (impostazione predefinita), verranno mantenute tutte le cifre.
Opzioni di formattazione
Sono disponibili vari tag e argomenti per personalizzare la formattazione del valore di osservazione finale. Questa tabella elenca i tag:
TAG DI FORMATTAZIONE FACOLTATIVO | DESCRIZIONE |
.format(args) | Formatta il valore come stringa, in base a un insieme di argomenti facoltativi (vedi sotto). |
.ordinal_compass | Formatta il valore come ordinale della bussola ( es. "SW"), utile per le direzioni del vento. Le abbreviazioni ordinali sono impostate dalle direzioni delle opzioni nel file di configurazione della skin skin.conf . |
.long_form | Formatta i tempi delta nella "forma lunga". Un "tempo delta" è la differenza tra due tempi. Un esempio è la quantità di tempo di attività (differenza tra l'ora di inizio e l'ora corrente). Per impostazione predefinita, questo sarà formattato come il numero di secondi trascorsi ( ad esempio, 45000 secondi ). La "forma lunga" scompone il tempo in elementi temporali costitutivi ( ad esempio, 12 ore, 30 minuti, 0 secondi ). |
.json | Formatta il valore come stringa JSON . |
.raw | Restituisce il valore "così com'è", senza essere convertito in una stringa e senza alcuna formattazione applicata. Questo può essere utile per eseguire operazioni aritmetiche direttamente all'interno dei modelli. Devi essere preparato a gestire un potenziale valore None . |
Il primo di questi tag ( .format() ) ha la struttura formale:
.format(format_string=None, None_string=None, add_label=True, localize=True)
Ecco il significato di ciascuno degli argomenti facoltativi:
Se si desidera rispettare l'ordine degli argomenti, il nome dell'argomento può essere omesso.
Esempi di formattazione
Questa sezione fornisce una serie di tag di esempio e il loro output previsto. Si assumono i seguenti valori:
OSSERVAZIONE | VALORE |
temp | 45,2 °F |
UV | Nessuno |
windDir | 138° |
dateTime | 1270250700 |
Ecco gli esempi:
Tieni presente che le stesse convenzioni di formattazione possono essere utilizzate per i periodi di aggregazione, ad esempio $month , così come $current .
Inizio, fine e dateTime
Sebbene non sia un tipo di osservazione, in molti modi l'ora di un'osservazione, dateTime , può essere trattata come tale. Un tag come
$current.dateTime
rappresenta l' ora corrente (più propriamente, l'ora dalla fine dell'ultimo intervallo di archiviazione) e produrrebbe qualcosa di simile
01/09/2010 12:30:00
Come i veri tipi di osservazione, i formati espliciti possono essere specificati, tranne per il fatto che richiedono un formato ora strftime(), piuttosto che un formato stringa .
Ad esempio, aggiungendo un descrittore di formato come questo:
$current.dateTime.format("%d-%b-%Y %H:%M")
produce
09-gen-2010 12:30
Per i periodi di aggregazione , ad esempio $month , puoi richiedere l' inizio , la fine o la durata del periodo utilizzando rispettivamente i suffissi .start , .end o .length . Per esempio,
Il mese corrente va da $month.start a $month.end e ha $month.length.format("%(day)d %(day_label)s").
risulta in
Il mese corrente va dal 01/01/2010 00:00:00 al 01/02/2010 00:00:00 e ha 31 giorni.
Oltre ai suffissi .start e .end , viene fornito il suffisso .dateTime per compatibilità con le versioni precedenti. Come .start , si riferisce all'inizio dell'intervallo.
I valori di stringa restituiti saranno sempre nell'ora locale . Tuttavia, se chiedi il valore grezzo
$current.dateTime.raw
il valore restituito sarà in Unix Epoch Time (numero di secondi dalle 00:00:00 UTC del 1 gennaio 1970, cioè un numero elevato), che devi convertire tu stesso. È garantito che non sarà mai None , quindi non preoccuparti di dover gestire un valore None .
Tag $trend
Il tag $trend è disponibile per le tendenze temporali, come i cambiamenti nella pressione barometrica. Ecco alcuni esempi:
ETICHETTA | RISULTATI |
$trend.barometer | -0,05 mmHg |
$trend($time_delta=3600).barometer | -0,02 mmHg |
$trend.outTemp | 1,1 °C |
$trend.time_delta | 10800 sec |
$trend.time_delta.hour | 3 ore |
Nota come puoi specificare esplicitamente un valore nel tag stesso (seconda riga nella tabella sopra). Se non si specifica un valore, verrà utilizzato un intervallo di tempo predefinito, impostato dall'opzione time_delta nel file di configurazione della skin. Questo valore può essere recuperato utilizzando la sintassi $trend.time_delta (quarta riga nella tabella).
Ad esempio, l'espressione modello
La tendenza del barometro su $trend.time_delta.hour è $trend.barometer.format("%+.2f")
risulterebbe in
La tendenza del barometro su 3 ore è +.03 inHg.
Tag $span
Il tag $span consente l'aggregazione in un periodo definito dall'utente fino all'ora corrente inclusa. La sua forma più generale è simile a:
$span([data_binding=binding_name][,optional_delta=delta][,boundary=[None|'midnight']) .obstype .aggregation [.optional_unit_conversion] [.optional_formatting]
Dove:
• binding_name è un nome di associazione a un database. Un esempio potrebbe essere wx_binding . Vedere la sezione Nomi di associazione per ulteriori dettagli.
• optional_delta = delta è una o più impostazioni delta separate da virgola dalla tabella sottostante. Se è inclusa più di un'impostazione delta, il periodo utilizzato per l'aggregazione è la somma delle singole impostazioni delta. Se non è inclusa alcuna impostazione delta o tutte le impostazioni delta incluse sono pari a zero, l'aggregato restituito si basa solo sull'obstype corrente .
• boundary è un identificatore facoltativo che può forzare l'ora di inizio a un limite di tempo. Se impostato su 'mezzanotte', l'ora di inizio sarà alla mezzanotte precedente. Se omesso, l'ora di inizio sarà la somma dei delta facoltativi.
• obstype è un tipo di osservazione, ad esempio outTemp .
• aggregation è un tipo di aggregazione . I possibili tipi di aggregazione sono riportati in Appendice: Tipi di aggregazione .
• optional_unit_conversion è un tag di conversione unità facoltativo. Vedere la sezione Opzioni di conversione unità .
• optional_formatting è un tag di formattazione facoltativo che controlla come verrà visualizzato il valore. Vedere la sezione Opzioni di formattazione .
Esistono diverse impostazioni delta che possono essere utilizzate:
IMPOSTAZIONE DELTA | ESEMPIO | DESCRIZIONE |
$time_delta=secondi | $span($time_delta=1800).outTemp.avg | La temperatura media negli ultimi 30 minuti immediati (1800 secondi). |
$hour_delta=ore | $span($hour_delta=6).outTemp.avg | La temperatura media nelle ultime 6 ore immediate. |
$day_delta=giorni | $span($day_delta=1).rain.sum | Le precipitazioni totali nelle ultime 24 ore immediate. |
$week_delta=settimane | $span($week_delta=2).barometer.max | La pressione barometrica massima nelle ultime 2 settimane immediate. |
Ad esempio, le espressioni modello
Le precipitazioni totali nelle ultime 30 ore sono $span($hour_delta=30).rain.sum
e
Le precipitazioni totali nelle ultime 30 ore sono $span($hour_delta=6, $day_delta=1).rain.sum
risulterebbe con entrambi
La pioggia totale nelle ultime 30 ore è di 1,24 pollici
Tag $unit
Sono inoltre disponibili i formati di tipo, etichetta e stringa per tutte le unità, consentendo di creare etichette altamente personalizzate:
ETICHETTA | RISULTATI |
$unit.unit_type.outTemp | degree_C |
$unit.label.outTemp | °C |
$unit.format.outTemp | %.1f |
Ad esempio, il tag
$day.outTemp.max.format(add_label=False)$unit.label.outTemp
risulterebbe in
21,2°C
(supponendo che i valori metrici siano stati specificati per group_temperature ), essenzialmente riproducendo i risultati del tag più semplice $day.outTemp.max .
Tag $obs
Le etichette utilizzate per i vari tipi di osservazione sono disponibili utilizzando il tag $obs . Questi sono fondamentalmente i valori forniti nel dizionario skin, sezione [Labels][[Generic]] .
ETICHETTA | RISULTATI |
$obs.label.outTemp | Temperatura esterna |
$obs.label.UV | Indice UV |
Iterazione
È possibile iterare su quanto segue:
SUFFISSO DELL'ETICHETTA | RISULTATI |
.records | Iterare su ogni record |
.hours | Itera per ore |
.days | Itera per giorni |
.months | Iterare per mesi |
.years | Iterare per anni |
.spans(interval=secondi ) | Itera per intervalli di lunghezza personalizzati. L'intervallo predefinito è 10800 secondi (3 ore). Gli intervalli si allineeranno ai limiti dell'ora locale. |
Il modello seguente usa un ciclo Cheetah for per scorrere tutti i mesi di un anno, stampando la temperatura minima e massima di ogni mese.
Temperature minime e massime per mese #for $month in $year.months
$month.dateTime.format("%B"): Temperature minime e massime: $month.outTemp.min $month.outTemp.max
#end for
Il risultato è:
Temperature minime e massime per mese:
gennaio: Temperature minime e massime: 30,1°F 51,5°F
febbraio: Temperature minime e massime: 24,4°F 58,6°F
marzo: Temperature minime e massime: 27,3°F 64,1°F
aprile: Temperature minime e massime: 33,2°F 52,5°F
maggio: Temperature minime e massime: N/A N/A
giugno: Temperature minime e massime: N/A N/A
luglio: Temperature minime e massime: N/A N/A
agosto: Temperature minime e massime: N/A N/A
settembre: Temperature minime e massime: N/A N/A
ottobre: Temperature minime e massime: N/A N/A
novembre: Temperature minime e massime: N/A N/A
dicembre: Temperature minime e massime: N/A N/A
Il modello seguente utilizza di nuovo un ciclo Cheetah for , questa volta per iterare su intervalli di 3 ore nelle ultime 24 ore, visualizzando le medie in ogni intervallo.
<p>Medie di 3 ore nelle ultime 24 ore</p> <table> <tr> <td>Data/ora</td><td>outTemp</td><td>outHumidity</td> </tr> #for $_span in $span($day_delta=1).spans(interval=10800) <tr> <td>$_span.start.format("%d/%m %H:%M")</td><td>$_span.outTemp.avg</td><td>$_span.outHumidity.avg</td> </tr> #end for </table>
Il risultato è:
Medie di 3 ore nelle ultime 24 ore
Data/ora | outTemp | outHumidity |
21/01 18:50 | 33,4 °F | 95% |
21/01 21:50 | 32,8°F | 96% |
22/01 00:50 | 33,2°F | 96% |
22/01 03:50 | 33,2°F | 96% |
22/01 06:50 | 33,8°F | 96% |
22/01 09:50 | 36,8°F | 95% |
22/01 12:50 | 39,4°F | 91% |
22/01 15:50 | 35,4 °F | 93% |
Vedere i file modello NOAA NOAA/NOAA-YYYY.txt.tmpl e NOAA/NOAA-YYYY-MM.txt.tmpl per altri esempi che utilizzano l'iterazione e la formattazione esplicita.
Esempio completo
Questo esempio è progettato per mettere insieme molti degli elementi sopra descritti, tra cui l'iterazione, l'inizio e la fine del periodo di aggregazione, la formattazione e l'override delle unità.
<html> <head> <style> td { border: 1px solid #cccccc; padding: 5px } </style> </head> <body> <table border=1 style="border-collapse:collapse;"> <tr style="font-weight:bold"> <td>Intervallo di tempo</td> < td>Temperatura massima</td> <td>Ora</td> </tr> #for $hour in $day($days_ago=1).hours <tr> <td>$hour.start.format("% H:%M")-$hour.end.format("%H:%M")</td> <td>$hour.outTemp.max ($hour.outTemp.max.degree_C)</td> <p> Temperature massime orarie ieri<br/> $day($days_ago=1).start.format("%d-%b-%Y") </p> </caption> </table> </body> </html>
Funzioni ausiliarie
Weewx include una serie di funzioni di supporto che possono essere utili durante la scrittura di modelli.
FUNZIONE | DESCRIZIONE |
$rnd(x, ndigits=None) | Arrotonda x a ndigits cifre decimali. L'argomento x può essere un float o un elenco di float . I valori di None vengono trasmessi. |
$jsonize(seq) | Converti il seq iterabile in una stringa JSON. |
$to_int(x) | Converti x in un numero intero. L'argomento x può essere di tipo float o str . I valori di None vengono trasmessi. |
$to_bool(x) | Converti x in un valore booleano. L'argomento x può essere di tipo int , float o str . Se la x minuscola è 'true', 'yes' o 'y' la funzione restituisce True . Se è 'false', 'no' o 'n' restituisce False . Altri valori di stringa generano un ValueError . Nel caso di un argomento numerico 0 significa False , tutti gli altri valori True . |
$to_list(x) | Converti x in una lista. Se x è già una lista, non cambia nulla. Se è un valore singolo, viene convertito in un elenco con questo valore come unico elemento dell'elenco. I valori di None vengono trasmessi. |
$getobs(plot_name) | Per un dato nome di grafico, questa funzione restituirà l'insieme di tutti i tipi di osservazione utilizzati dal grafico. |
Supporto per le serie di dati
Questa è un'API sperimentale che potrebbe cambiare.
Weewx V4.5 ha introdotto alcuni tag sperimentali per la produzione di serie di dati, eventualmente aggregati. Questo può essere utile per creare i dati JSON necessari per i pacchetti di tracciamento JavaScript, come HighCharts , Google Charts o C3.js .
Ad esempio, supponi di aver bisogno della temperatura massima per ogni giorno del mese. Questa etichetta
$month.outTemp.series(aggregate_type='max', aggregate_interval='day', time_series='start').json
produrrebbe quanto segue:
[[1614585600, 58.2], [1614672000, 55.8], [1614758400, 59.6], [1614844800, 57.8], ... ]
Questo è un elenco di (ora, temperatura) per ogni giorno del mese, in JSON, facilmente consumato da molti di questi pacchetti di plottaggio.
Sono possibili molte altre combinazioni. Vedere l'articolo Wiki Tag per serie .
Tag generali
Ci sono alcuni tag generali che non riflettono dati di osservazione, ma informazioni tecniche sui file modello. Sono spesso utili nelle espressioni #if per controllare come Cheetah elabora il modello.
ETICHETTA | DESCRIZIONE |
$encoding | Codifica dei caratteri, in cui il file viene convertito dopo la creazione. I valori possibili sono html_entities , strict_ascii , normalized_ascii e utf-8 . |
$filename | Nome del file da creare comprensivo del percorso relativo. Può essere utilizzato per impostare l'URL canonico per i motori di ricerca.
<link rel="canonical" href="$station.station_url/$filename"/> |
$lang | Codice lingua impostato dall'opzione lang per il report. Ad esempio, fr o gr . |
$month_name | Per i modelli elencati in SummaryByMonth , conterrà il nome del mese localizzato ( ad esempio , " Sep "). |
$page | Il nome della sezione da skin.conf in cui è descritto il modello. |
$skin | Il valore dell'opzione skin in weewx.conf . |
$SKIN_NAME | Tutte le skin incluse in Weewx, versione 4.6 o successiva, includono il tag $SKIN_NAME . Ad esempio, per la skin Seasons , $SKIN_NAME restituirebbe Seasons. |
$SKIN_VERSION | Tutte le skin incluse con Weewx, versione 4.6 o successive, includono il tag $SKIN_VERSION , che restituisce il numero di versione di Weewx di quando la skin è stata installata. Poiché le skin non vengono toccate durante il processo di aggiornamento, questo mostra l'origine della skin. |
$SummaryByDay | Un elenco di stringhe anno-mese-giorno ( ad esempio , ["2018-12-31", "2019-01-01"] ) per le quali è stato generato un riepilogo per giorno. La sezione [[SummaryByDay]] deve essere stata elaborata prima che questo tag sia valido, altrimenti sarà vuoto. |
$SummaryByMonth | Un elenco di stringhe anno-mese ( ad esempio , ["2018-12", "2019-01"] ) per le quali è stato generato un riepilogo per mese. La sezione [[SummaryByMonth]] deve essere stata elaborata prima che questo tag sia valido, altrimenti sarà vuoto. |
$SummaryByYear | Un elenco di stringhe dell'anno ( ad esempio , ["2018", "2019"] ) per le quali è stato generato un riepilogo per anno. La sezione [[SummaryByYear]] deve essere stata elaborata prima che questo tag sia valido, altrimenti sarà vuoto. |
$year_name | Per i modelli elencati in SummaryByMonth o SummaryByYear , conterrà l'anno ( ad es . "2018"). |
Supporto per l'internazionalizzazione con $gettext
Le pagine generate da Weewx non contengono solo dati di osservazione, ma anche testo statico. Il tag Weewx $gettext fornisce il supporto per l'internazionalizzazione per questo tipo di testi. È strutturato in modo molto simile alla funzione GNU gettext , ma la sua implementazione è molto diversa. Per supportare l'internazionalizzazione del tuo modello, non usare testo statico nei tuoi modelli, ma piuttosto usa $gettext . Ecco come.
Supponi di scrivere una skin chiamata " YourSkin " e di voler includere un titolo denominato "Condizioni attuali" in inglese, "aktuelle Werte" in tedesco, "Conditions actuelles" in francese, ecc. Quindi il file modello potrebbe contenere:
... <h1>$gettext("Current Conditions")</h1> ...
La sezione di weewx.conf che configura la tua skin dovrebbe essere simile a questa:
... [StdReport] ... [[YourSkinReport]] skin = YourSkin lang = fr ...
Con lang = fr il report è in francese. Per ottenerlo in inglese, sostituire il codice della lingua fr con il codice per l'inglese en . E per ottenerlo in tedesco usa de .
Per fare in modo che tutto funzioni, è necessario creare un file di lingua per ogni lingua supportata. I file di lingua risiedono nella sottodirectory lang della directory skin definita dall'opzione skin . Il nome del file della lingua è il codice della lingua aggiunto da .conf , ad esempio en.conf , de.conf o fr.conf .
Il file della lingua ha lo stesso layout di skin.conf , cioè puoi inserire versioni specifiche della lingua delle etichette lì. Inoltre è possibile definire una sezione [Texts] per contenere i testi statici utilizzati nella skin. Per l'esempio precedente, i file di lingua conterrebbero quanto segue:
en.conf
... [Texts] "Current Conditions" = Current Conditions ...
de.conf
... [Texts] "Current Conditions" = Aktuelle Werte ...
fr.conf
... [Texts] "Current Conditions" = Conditions actuelles ...
Sebbene non sia tecnicamente necessario, si consiglia di utilizzare l'intero testo inglese per la chiave. Ciò rende il modello più facile da leggere e più facile per il traduttore. In assenza di una traduzione, sarà anche l'impostazione predefinita, quindi la skin sarà comunque utilizzabile, anche se non è disponibile una traduzione.
Vedere la sottodirectory SKIN_ROOT /Seasons/lang per esempi di file di lingua.
Almanacco
Se è stato installato il modulo pyephem , Weewx può generare ampie informazioni di almanacco per Sole, Luna, Venere, Marte, Giove e altri corpi celesti, inclusi i loro tempi di ascesa, transito e tramonto, nonché il loro azimut e altitudine. Sono disponibili anche altre informazioni.
Ecco un modello di esempio:
L'ora corrente è $current.dateTime #if $almanac.hasExtras Alba, transito, tramonto: $almanac.sun.rise $almanac.sun.transit $almanac.sun.set Sorgere della luna, transito, tramonto della luna: $almanac.moon.rise $ almanac.moon.transit $almanac.moon.set Sorgere, transito, tramonto di Marte: $almanac.mars.rise $almanac.mars.transit $almanac.mars.set Azimut, altitudine di Marte: $almanac.mars.az $almanac .mars.alt Prossima luna nuova, piena: $almanac.next_new_moon $almanac.next_full_moon Prossima estate, solstizio d'inverno: $almanac.next_summer_solstice $almanac.next_winter_solstice #else Alba, tramonto: $almanac.sunrise $almanac.sunset #end if
Se pyephem è installato, ciò risulterebbe in:
L'ora attuale è 29-mar-2011 09:20
Alba, transito, tramonto: 06:51 13:11 19:30
Sorgere, transito, tramonto della luna: 04:33 09:44 15:04
Sorgere, transito, tramonto di Marte: 06: 35 12:30 18:26
Azimut, altitudine di Marte: 124.354959275 26.4808431952
Prossima luna nuova, piena: 03-apr-2011 07:32 17-apr-2011 19:43
Prossima estate, solstizio d'inverno: 21-giu-2011 10: 16 21-dic-2011 21:29
In caso contrario, viene utilizzato un fallback di calcoli di base, con il risultato di:
L'ora attuale è 29-Mar-2011 09:20
Alba, tramonto: 06:51 19:30
Come mostrato nell'esempio, puoi verificare se queste informazioni estese sull'almanacco sono disponibili con il valore $almanac.hasExtras .
Le informazioni dell'almanacco rientrano in tre categorie:
- • Eventi del calendario
- • Corpi celesti
- • Funzioni
Tratteremo ciascuno di questi separatamente.
Eventi del calendario
Gli "eventi del calendario" non richiedono un corpo celeste. Trattano cose come next_solstice , next_first_quarter_moon o sidereal_time . La sintassi qui è:
$almanac.next_solstice
O
$almanac.next_first_quarter_moon
O
$almanac.sidereal_time
Ecco una tabella delle informazioni che rientrano in questa categoria:
previous_equinox | next_equinox | previous_solstice | next_solstice |
previous_autumnal_equinox | next_autumnal_equinox | previous_vernal_equinox | next_vernal_equinox |
previous_winter_solstice | next_winter_solstice | previous_summer_solstice | next_summer_solstice |
previous_new_moon | next_new_moon | previous_first_quarter_moon | next_first_quarter_moon |
previous_full_moon | next_full_moon | previous_last_quarter_moon | next_last_quarter_moon |
sidereal_time |
Il tag $almanac.sidereal_time restituisce un valore in gradi decimali anziché un valore consueto compreso tra 0 e 24 ore.
Corpi celesti
La seconda categoria richiede un corpo celeste. Questo tratta domande come "Quando sorge Giove?" o "Quando transita il sole?" Gli esempi sono
$almanac.jupiter.rise
O
$almanac.sun.transit
Per calcolare con precisione questi tempi, Weewx utilizza automaticamente la temperatura e la pressione presenti per calcolare gli effetti di rifrazione. Tuttavia, puoi sovrascrivere questi valori, che saranno necessari se desideri abbinare i tempi dell'almanacco pubblicati dall'Osservatorio Navale come spiegato nella documentazione pyephem . Ad esempio, per far corrispondere l'ora dell'alba pubblicata dall'Osservatorio, invece di
$almanac.sun.rise
utilizzo
$almanac(pressure=0, horizon=-34.0/60.0).sun.rise
Impostando la pressione a zero stiamo bypassando i calcoli di rifrazione e impostando manualmente l'orizzonte in modo che sia 34 minuti d'arco più basso dell'orizzonte normale. Questo è ciò che usa la Marina.
Se desideri calcolare l'inizio del crepuscolo civile, puoi impostare l'orizzonte a -6 gradi, e anche dire a Weewx di usare il centro del sole (invece del lembo superiore, che usa normalmente) per fare il calcolo:
$almanac(pressure=0, horizon=-6).sun(use_center=1).rise
La sintassi generale è:
$almanac(almanac_time=time, ## Unix epoch time lat=latitude, lon=longitude, ## degrees altitude=altitude, ## meters pressure=pressure, ## mbars horizon=horizon, ## degrees temperature=temperature_C ## degrees C ).heavenly_body(use_center=[01]).attribute
Come puoi vedere, molte altre proprietà possono essere sovrascritte oltre alla pressione e all'angolo dell'orizzonte.
PyEphem offre un ampio elenco di oggetti che possono essere utilizzati per il tag Heavenly_body . Tutti i pianeti e molte stelle sono nella lista.
I possibili valori per il tag di attributo sono elencati nella tabella seguente:
az | alt | a_ra | a_dec |
g_ra | ra | g_dec | dec |
elong | radius | hlong | hlat |
sublat | sublong | next_rising | next_setting |
next_transit | next_antitransit | previous_rising | previous_setting |
previous_transit | previous_antitransit | rise | set |
transit | visible | visible_change |
I tag ra , a_ra e g_ra restituiscono valori in gradi decimali anziché valori consueti da 0 a 24 ore.
Funzioni
In realtà c'è una sola funzione in questa categoria: la separazione . Restituisce la separazione angolare tra due corpi celesti. Ad esempio, per calcolare la separazione angolare tra Venere e Marte useresti:
<p>La separazione tra Venere e Marte è $almanac.separation(($almanac.venus.alt,$almanac.venus.az), ($almanac.mars.alt,$almanac.mars.az))</p>
Ciò comporterebbe:
La separazione tra Venere e Marte è 55:55:31.8
Aggiunta di nuovi corpi all'almanacco
È possibile estendere l'almanacco di Weewx, aggiungendo nuovi corpi di cui prima non era a conoscenza. Ad esempio, supponiamo di voler aggiungere 433 Eros , il primo asteroide visitato da un veicolo spaziale. Ecco il processo:
- Inserisci quanto segue nel file user/extensions.py :
import ephem eros = ephem.readdb("433 Eros,e,10.8276,304.3222,178.8165,1.457940,0.5598795,0.22258902,71.2803,09/04.0/2017,2000,H11.16,0.46") ephem.Eros = eros
Questo fa due cose: aggiunge informazioni orbitali su 433 Eros al database interno di pyephem e rende tali dati disponibili sotto il nome Eros (notare la lettera maiuscola). - Puoi quindi utilizzare 433 Eros come qualsiasi altro corpo nei tuoi modelli. Ad esempio, per visualizzare quando sorgerà sopra l'orizzonte:
$almanac.eros.rise
Vento
Il vento merita qualche commento perché è memorizzato nel database in due modi diversi: come insieme di scalari e come vettore di velocità e direzione. Ecco i quattro scalari relativi al vento memorizzati nel database dell'archivio principale:
TIPO DI ARCHIVIO | DESCRIZIONE | CONTESTI VALIDI |
windSpeed | La velocità media del vento osservata durante il periodo di archiviazione. | $current, $latest, $hour, $day, $week, $month, $year, $rainyear |
windDir | Se viene utilizzata la generazione di record software, questa è la media vettoriale nel periodo di archiviazione. Se viene utilizzata la generazione di record hardware, il valore dipende dall'hardware. | |
windGust | La velocità del vento massima (raffica) osservata durante il periodo di archiviazione. | |
windGustDir | La direzione del vento quando è stata osservata la raffica. |
Alcuni tipi di aggregazione del vento, in particolare vecdir e vecavg , richiedono la velocità e la direzione del vento. Per questi, Weewx fornisce un tipo di osservazione composita chiamato vento . Viene memorizzato direttamente nei riepiloghi giornalieri, ma sintetizzato per aggregazioni diverse dai multipli di un giorno.
TIPO DI RIEPILOGO GIORNALIERO | DESCRIZIONE | CONTESTI VALIDI |
wind | Un composto vettoriale del vento. | $hour, $day, $week, $month, $year, $rainyear |
Ognuno di questi può essere utilizzato nei tuoi tag. Ecco alcuni esempi:
ETICHETTA | DESCRIZIONE |
$current.windSpeed | La velocità media del vento nell'intervallo di archiviazione più recente. |
$current.windDir | Se viene utilizzata la generazione di record tramite software, questa è la media vettoriale sull'intervallo di archiviazione. Se viene utilizzata la generazione di record hardware, il valore dipende dall'hardware. |
$current.windGust | La velocità massima del vento (raffica) nell'intervallo di archiviazione più recente. |
$current.windGustDir | La direzione della raffica. |
$day.windSpeed.avg $day.wind.avg |
La velocità media del vento dalla mezzanotte. Se il vento soffia da est a 5 m/s per 2 ore, poi da ovest a 5 m/s per 2 ore, la velocità media del vento è di 5 m/s. |
$day.wind.vecavg | La velocità media del vento vettoriale dalla mezzanotte. Se il vento soffia da est a 5 m/s per 2 ore, poi da ovest a 5 m/s per 2 ore, la velocità media del vento vettoriale è zero. |
$day.wind.vecdir | La direzione della velocità del vento mediata dal vettore. Se il vento soffia da nord-ovest a 5 m/s per due ore, poi da sud-ovest a 5 m/s per due ore, la direzione media del vettore è ovest. |
$day.windGust.max $day.wind.max |
La massima raffica di vento dalla mezzanotte. |
$day.wind.gustdir | La direzione della massima raffica di vento. |
$day.windGust.maxtime $day.wind.maxtime |
L'ora della massima raffica di vento. |
$day.windSpeed.max | La massima velocità media del vento. Il vento viene calcolato in media su ciascuno degli intervalli di archivio. Quindi viene preso il massimo di questi valori. Si noti che questo non è lo stesso della raffica di vento massima. |
$day.windDir.avg | Quantità non molto utile. Questa è la rigorosa media aritmetica di tutte le direzioni del vento della bussola. Se il vento soffia a 350° per due ore e poi a 10° per due ore, allora la direzione scalare media del vento sarà di 180°, probabilmente non quello che ti aspetti, né vuoi. |
Definizione di nuovi tag
Abbiamo visto come modificare un template e utilizzare i vari tag disponibili come $day.outTemp.max per la temperatura esterna massima della giornata. Ma cosa succede se si desidera introdurre alcuni nuovi dati per i quali non è disponibile alcun tag?
Se desideri introdurre un tag statico, cioè che non cambierà nel tempo (come un Tracker ID di Google Analytics o il tuo nome), allora è molto semplice: inseriscilo semplicemente nella sezione [Extra] della skin file di configurazione. Ulteriori informazioni su come eseguire questa operazione sono disponibili qui.
Ma cosa succede se si desidera introdurre un tag più dinamico, che richiede alcuni calcoli o che utilizza il database? Metterlo semplicemente nella sezione [Extra] non va bene, perché non può cambiare.
La risposta è scrivere un'estensione dell'elenco di ricerca . Le istruzioni complete su come eseguire questa operazione sono in un documento complementare Scrivere le estensioni dell'elenco di ricerca .
GENERATORE DI IMMAGINI
Questa sezione fornisce una panoramica del generatore di immagini. Per i dettagli su ciascuna delle sue varie opzioni, vedere la sezione [ImageGenerator] in Riferimento: opzioni di report .
La versione installata di Weewx è configurata per generare una serie di grafici utili. Ma cosa succede se non ti piace il loro aspetto o desideri generare trame diverse, magari con diversi tipi di aggregazione? Questa sezione illustra come eseguire questa operazione.
La generazione delle immagini è controllata dalla sezione [ImageGenerator] nel file di configurazione della skin skin.conf . Diamo un'occhiata alla parte iniziale di questa sezione:
[ImageGenerator] ... image_width = 500 image_height = 180 image_background_color = #f5f5f5 chart_background_color = #d8d8d8 chart_gridline_color = #a0a0a0 ...
Le opzioni sotto il nome della sezione [ImageGenerator] verranno applicate a tutti i grafici, a meno che non vengano sovrascritte nelle sottosezioni. Quindi, se non diversamente modificato, tutti i grafici avranno una larghezza di 500 pixel, un'altezza di 180 pixel e avranno un colore di sfondo RGB di #f5f5f5, un grigio molto chiaro (colore HTML "WhiteSmoke"). Il grafico stesso avrà un colore di sfondo #d8d8d8 (un grigio un po' più scuro) e le linee della griglia saranno #a0a0a0 (ancora più scure). Le altre opzioni più in basso (non mostrate) si applicheranno anche a tutti i grafici.
Periodi di tempo
Dopo le opzioni "globali" nella parte superiore della sezione [ImageGenerator] , arriva una serie di sottosezioni, una per ogni periodo di tempo (giorno, settimana, mese e anno). Queste sottosezioni definiscono la natura dell'aggregazione e i tipi di grafico per quel periodo di tempo. Ad esempio, ecco un tipico set di opzioni per la sottosezione [[month_images]] . Controlla quali immagini "mensili" verranno generate e come appariranno:
[[month_images]] x_label_format = %d bottom_label_format = %m/%d/%y %H:%M time_length = 2592000 # == 30 giorni aggregate_type = avg aggregate_interval = 10800 # == 3 ore show_daynight = false
L'opzione x_label_format fornisce un formato di tipo strftime() per l'asse x. In questo esempio, mostrerà solo i giorni (opzione di formato %d ). Il bottom_label_format è il formato utilizzato per contrassegnare l'ora dell'immagine in basso. In questo esempio, mostrerà l'ora qualcosa come 10/25/09 15:35 . Un grafico coprirà 30 giorni nominali e tutti gli elementi inclusi in esso utilizzeranno un tipo aggregato di media su 3 ore. Infine, impostando l'opzione show_daynight su false , richiediamo che le bande ombreggiate giorno-notte non vengano visualizzate.
File immagine
All'interno di ogni sottosezione di periodo di tempo c'è un altro annidamento, uno per ogni immagine da generare. Il titolo di ciascuna sotto-sotto-sezione è il nome del file da utilizzare per l'immagine. Infine, ad un ulteriore livello di nidificazione (!) ci sono i nomi logici di tutti i tipi di linea da disegnare nell'immagine. Come altrove, i valori specificati nel livello precedente possono essere sovrascritti. Ad esempio, ecco un tipico set di opzioni per la sottosottosezione [[[monthrain]]] :
[[[monthrain]]] plot_type = bar yscale = None, None, 0.02 [[[[rain]]]] aggregate_type = sum aggregate_interval = day label = Pioggia (totale giornaliero)
Questo genererà un file immagine con nome monthrain.png . Sarà un'istogramma. L'opzione yscale controlla il ridimensionamento dell'asse y — se omesso, la scala verrà scelta automaticamente. Tuttavia, in questo esempio scegliamo di esercitare un certo grado di controllo specificando i valori in modo esplicito. L'opzione è una tupla a 3 vie ( ylow , yhigh , min_interval ), dove ylow e yhigh sono rispettivamente i valori minimo e massimo dell'asse y e min_interval è l'intervallo di tick minimo. Se impostato su None , verrà scelto automaticamente il valore corrispondente. Quindi, in questo esempio, l'impostazione
yscale = None, None, 0.02
farà sì che Weewx scelga valori minimi e massimi sensati, ma richiede che l'incremento del tick ( min_interval ) sia almeno 0,02.
Continuando con l'esempio sopra, ci sarà solo una "linea" di trama (sarà in realtà una serie di barre) e avrà il nome logico rain . Poiché non abbiamo detto diversamente, il nome della colonna del database da utilizzare per questa riga sarà lo stesso del suo nome logico, ovvero rain , ma questo può essere sovrascritto. Il tipo di aggregazione sarà somma (sovrascrivendo la media specificata nella sottosezione [[month_images]] ), quindi ottieni la pioggia totale nel periodo aggregato (anziché la media) su un intervallo di aggregazione di 86.400 secondi (un giorno). Il grafico sarà intitolato con l'etichetta indicata di 'Pioggia (totale giornaliero)'.
Includere più di un'osservazione in un grafico
Più di un'osservazione può essere inclusa in un grafico. Ad esempio, ecco come generare un grafico con la temperatura esterna della settimana e il punto di rugiada.
[[[monthtempdew]]] [[[[outTemp]]]] [[[[dewpoint]]]]
Ciò creerebbe un'immagine nel file monthtempdew.png che include un grafico a linee della temperatura esterna e del punto di rugiada:
Includere un tipo più di una volta in un grafico
Un altro esempio. Supponi di volere un grafico della temperatura del giorno, sovrapposto alle medie orarie. Qui si utilizza lo stesso tipo di dati ( outTemp ) per entrambe le linee del grafico, la prima con le medie, la seconda senza. Ovviamente non funzionerà:
## ERRATO ## [[[daytemp_with_avg]]] [[[[outTemp]]]] aggregate_type = avg aggregate_interval = hour
[[[[outTemp]]]] # OOPS! Lo stesso nome di sezione appare più di una volta!
L'opzione parser non consente che lo stesso nome di sezione ( outTemp in questo caso) appaia più di una volta a un dato livello nel file di configurazione, quindi verrà dichiarato un errore (motivo tecnico: formalmente, le sezioni sono un dizionario non ordinato). Se desideri che la stessa osservazione appaia più di una volta in un grafico, c'è un trucco che devi conoscere: usa l'opzione data_type . Ciò sovrascriverà l'azione predefinita secondo cui il nome della riga logica viene utilizzato per la colonna del database. Quindi, il nostro esempio sarebbe simile a questo:
[[[daytemp_with_avg]]] [[[[avgTemp]]]] data_type = outTemp aggregate_type = avg aggregate_interval = hour label = Avg. temp. [[[[outTemp]]]]
Qui, alla prima riga della trama è stato assegnato il nome avgTemp per distinguerla dalla seconda riga outTemp . Qualsiasi nome andrà bene, deve solo essere diverso. Abbiamo specificato che la prima riga utilizzerà il tipo di dati outTemp e che utilizzerà la media su un periodo di un'ora. Anche il secondo utilizza outTemp , ma non utilizzerà la media.
Un altro esempio. Questo mostra le temperature massime e minime giornaliere per un anno:
[[year_images]] [[[yearhilow]]] [[[[hi]]]] data_type = outTemp aggregate_type = max label = Massima [[[[low]]]] data_type = outTemp aggregate_type = min label = Temperatura minima
Espressioni arbitrarie nei grafici
L'opzione data_type può effettivamente essere qualsiasi espressione SQL arbitraria, valida nel contesto dei tipi disponibili nello schema . Ad esempio, supponi di voler tracciare la differenza tra la temperatura interna ed esterna per l'anno. Questo potrebbe essere fatto con:
[[year_images]] [[[yeardiff]]] [[[[diff]]]] data_type = inTemp-outTemp label = Interno - Esterno
Si noti che l'opzione data_type è ora un'espressione che rappresenta la differenza tra inTemp e outTemp , rispettivamente la temperatura interna ed esterna. Ciò si traduce in un grafico yeardiff.png .
Modifica dell'unità utilizzata in un grafico
Normalmente, l'unità utilizzata in un grafico è impostata dal gruppo di unità dei tipi di osservazione nel grafico. Ad esempio, considera questo grafico della temperatura esterna e del punto di rugiada di oggi:
[[day_images]] ... [[[daytempdew]]] [[[[outTemp]]]] [[[[dewpoint]]]]
Sia outTemp che dewpoint appartengono al gruppo di unità group_temperature , quindi questo grafico utilizzerà qualsiasi unità sia stata specificata per quel gruppo. Vedere la sezione Unità miste per i dettagli.
Tuttavia, supponevi che ti piacerebbe offrire sia la versione metrica che quella consuetudinaria degli Stati Uniti dello stesso grafico? Puoi farlo utilizzando l'opzione unit per sovrascrivere l'unità utilizzata per i singoli grafici:
[[day_images]] ... [[[daytempdewUS]]] unit = degree_F [[[[outTemp]]]] [[[[dewpoint]]]] [[[daytempdewMetric]]] unit = degree_C [[[[outTemp]]]] [[[[dewpoint]]]]
Questo produrrà due grafici: il file daytempdewUS.png sarà in gradi Fahrenheit, mentre il file dayTempMetric.png utilizzerà i gradi Celsius.
Lacune di linea
Se c'è un intervallo di tempo nei dati, l'opzione line_gap_fraction controlla come verranno disegnati i grafici a linee.
Grafici vettoriali progressivi
Weewx può produrre grafici vettoriali progressivi così come grafici xy più convenzionali. Per produrli, usa il tipo di trama vector . Hai bisogno di un tipo vettoriale per produrre questo tipo di trama. Ce ne sono due: windvec e windgustvec . Anche se in realtà non appaiono nel database, Weewx comprende che rappresentano speciali tipi di vettore. Il primo, windvec , rappresenta il vento medio in un periodo di archivio, il secondo, windgustvec il vento massimo in un periodo di archivio. Ecco come produrre un vettore progressivo per una settimana che mostri le maggiori raffiche di vento orarie, insieme alle medie orarie:
[[[weekgustoverlay]]] aggregate_interval = hour [[[[windvec]]]] label = vento orario plot_type = vector aggregate_type = avg [[[[windgustvec]]]] label = raffica di vento plot_type = vector aggregate_type = max
Questo produrrà un file immagine con nome weekgustoverlay.png . Consisterà in due grafici vettoriali progressivi, entrambi utilizzando l'aggregazione oraria (3.600 secondi). Per il primo insieme di vettori verrà utilizzata la media oraria. Nella seconda verrà utilizzato il massimo delle raffiche. Per impostazione predefinita, i bastoncini nei grafici del vento progressivo puntano verso la sorgente del vento. Cioè, il bastone per un vento da ovest punterà a sinistra. Se hai una direzione del vento cronica, potresti voler ruotare la direzione predefinita in modo che tutti i vettori non si allineino sull'asse x, sovrapponendosi l'un l'altro. Fallo usando l'opzione vector_rotate . Ad esempio, con i venti occidentali cronici, ho impostato vector_rotate su 90.0 per la trama sopra, quindi si snoda dal punto ovest verso l'alto.
Se utilizzi questo tipo di grafico (la versione pronta all'uso di Weewx include grafici del vento progressivi giornalieri, settimanali, mensili e annuali), verrà inserita una piccola rosa dei venti nell'angolo in basso a sinistra dell'immagine per mostra l'orientamento del Nord.
Valori prioritari
Ricorda che i valori a qualsiasi livello possono sovrascrivere i valori specificati a un livello superiore. Ad esempio, supponiamo di voler generare i grafici standard, ma per alcuni tipi di osservazione chiave come il barometro, si desidera generare anche alcuni grafici sovradimensionati per fornire ulteriori dettagli, magari per un popup HTML. Il file weewx.conf standard specifica la dimensione del grafico di 300x180 pixel, che verrà utilizzata per tutti i grafici a meno che non venga sovrascritta:
[ImageGenerator] ... image_width = 300 image_height = 180
Il grafico standard della pressione barometrica apparirà in daybarometer.png :
[[[daybarometer]]] [[[[barometer]]]]
Ora aggiungiamo il nostro grafico speciale della pressione barometrica, ma specifichiamo una dimensione dell'immagine più grande. Questa immagine verrà inserita nel file daybarometer_big.png .
[[[daybarometer_big]]] image_width = 600 image_height = 360 [[[[barometer]]]]
Utilizzo di più associazioni
È facile utilizzare più di un database nei report. Ecco un esempio. Nel mio ufficio ho due console: una VantagePro2 collegata a un Dell Optiplex e una WMR100N, collegata a un Raspberry Pi. Ognuno esegue Weewx. Dell utilizza SQLite, RPi, MySQL.
Supponiamo di voler confrontare le temperature interne delle due console. Come potrei farlo?
È più facile accedere a MySQL attraverso una rete rispetto a SQLite, quindi eseguiamo i report su Dell, ma accediamo al database MySQL di RPi da remoto. Ecco come le associazioni e le sezioni del database di weewx.conf apparirebbero su Dell:
[DataBindings] # This section binds a data store to an actual database [[wx_binding]] # The database to be used - it should match one of the sections in [Databases] database = archive_sqlite # The name of the table within the database table_name = archive # The class to manage the database manager = weewx.manager.DaySummaryManager # The schema defines to structure of the database contents schema = schemas.wview_extended.schema [[wmr100_binding]] # Binding for my WMR100 on the RPi database = rpi_mysql # The name of the table within the database table_name = archive # The class to manage the database manager = weewx.manager.DaySummaryManager # The schema defines to structure of the database contents schema = schemas.wview_extended.schema [Databases] # This section binds to the actual database to be used [[archive_sqlite]] database_type = SQLite database_name = weewx.sdb [[rpi_mysql]] database_type = MySQL database_name = weewx host = rpi-bug [DatabaseTypes] # This section defines defaults for the different types of databases. [[SQLite]] driver = weedb.sqlite # Directory in which the database files are located SQLITE_ROOT = %(WEEWX_ROOT)s/archive [[MySQL]] driver = weedb.mysql # The host where the database is located host = localhost # The user name for logging in to the host user = weewx # The password for the user name password = weewx
Il primo, [[wmr100_binding]] , aggiunge un nuovo binding denominato wmr100_binding . Collega ("lega") al nuovo database, chiamato rpi_mysql , tramite l'opzione database . Definisce inoltre alcune caratteristiche dell'associazione, ad esempio quale gestore deve essere utilizzato e l'aspetto del suo schema.
La seconda aggiunta, [[rpi-mysql]] definisce il nuovo database. L'opzione database_type è impostata su MySQL , a indicare che si tratta di un database MySQL. I valori predefiniti per i database MySQL sono definiti nella sezione [[MySQL]] . Il nuovo database li accetta tutti, tranne host , che è stato impostato sull'host remoto rpi-bug , il nome del mio Raspberry Pi.
Associazione esplicita nei tag
Come utilizziamo questa nuova rilegatura? Per prima cosa, facciamo un confronto testuale, usando i tag. Ecco come appare il nostro modello:
<table> <tr> <td class="stats_label">Temperatura interna, Vantage</td> <td class="stats_data">$current.inTemp</td> </tr> <tr> <td class=" stats_label">Temperatura interna, WMR100</td> <td class="stats_data">$latest($data_binding='wmr100_binding').inTemp</td> </tr> </table>
Ciò dice al motore di reporting di sovrascrivere l'associazione predefinita specificata in [StdReport] , generalmente wx_binding , e utilizzare invece wmr100_binding .
Ciò si traduce in un output HTML simile a:
Temperatura interna, Vantage | 68,7 °F |
Temperatura interna, WMR100 | 68,9°F |
Rilegatura esplicita nelle immagini
Come produrremmo un grafico delle due diverse temperature? Ecco come dovrebbe apparire la sezione pertinente del file skin.conf .
[[[daycompare]]] [[[[inTemp]]]] label = Vantage inTemp [[[[WMR100Temp]]]] data_type = inTemp data_binding = wmr100_binding label = WMR100 inTemp
Questo produrrà un'immagine con nome daycompare.png , con due linee di trama. Il primo riguarderà la temperatura del Vantage. Utilizza l'associazione predefinita, wx_binding , e sarà etichettata Vantage inTemp . Il secondo usa esplicitamente wmr100_binding . Poiché utilizza lo stesso nome di variabile ( inTemp ) della prima riga, abbiamo dovuto specificarlo esplicitamente utilizzando l'opzione data_type , per evitare di utilizzare lo stesso nome di sottosezione due volte (vedere la sezione Includere un tipo più di una volta in un grafico per dettagli). Sarà etichettato WMR100 inTemp . I risultati sono simili a questo:
Dettaglio stupido
All'inizio non riuscivo a far funzionare questo esempio. Il problema si è rivelato essere che l'RPi stava elaborando le cose solo un battito dietro il Dell, quindi la temperatura per l'ora "corrente" non era pronta quando il Dell ne aveva bisogno. Continuavo a ricevere N/A . Per evitare ciò, ho introdotto il tag $latest , che utilizza l'ultimo timestamp disponibile nell'associazione, che può essere o meno lo stesso di quello utilizzato da $current . Ecco perché l'esempio sopra usa $latest invece di $current .
Localizzazione
Questa sezione fornisce suggerimenti per la localizzazione, compresa la traduzione in lingue diverse e la visualizzazione dei dati in formati specifici per una locale.
Se la skin è stata internazionalizzata
Tutte le skin fornite con Weewx sono state internazionalizzate , anche se potrebbero non essere state localizzate nella tua lingua specifica. Vedi la sezione Skin internazionalizzate per sapere come dirlo.
Internazionalizzato, la tua lingua è disponibile
Questo è il caso semplice: la skin è stata internazionalizzata e la tua localizzazione è disponibile. In questo caso, tutto ciò che devi fare è selezionare la tua localizzazione in weewx.conf . Ad esempio, per selezionare il tedesco (codice de) per la skin Seasons , basta aggiungere la riga evidenziata (o modificare, se è già presente):
... [StdReport] ... [[SeasonsReport]] # Il SeasonsReport usa la skin 'Seasons', che contiene le # immagini, modelli e grafici per il report. skin = Seasons enable = true
lang = de ...
Internazionalizzato, ma manca la tua lingua
Se la sottodirectory lang è presente nella directory skin, allora la skin è stata internazionalizzata. Tuttavia, se il codice della tua lingua non è incluso nella sottodirectory, dovrai localizzarlo nella tua lingua. Per fare ciò, copia il file en.conf e assegnagli un nome in base al codice della tua lingua. Quindi traduci tutte le stringhe sul lato destro dei segni di uguale nella tua lingua. Ad esempio, supponi di voler localizzare la skin in lingua francese. Quindi copia en.conf in fr.conf
cp en.conf fr.conf
Quindi cambia le stringhe che assomigliano a queste:
... [Texts] "Language" = "English" "7-day" = "7-day" "24h" = "24h" "About this weather station" = "About this weather station" ...
a qualcosa che assomigliano a queste:
... [Texts] Lingua = Francese "7-day" = "7-jours" "24h" = "24h"
"About this weather station" = "A propos de cette station" ...
E così via. Quando hai finito, l'autore della skin potrebbe essere interessato al tuo file di localizzazione per spedirlo insieme alla skin per l'uso da parte di altri utenti. Se la skin è quella fornita con Weewx, contatta il team di Weewx tramite un post nel gruppo weewx-user e, con il tuo permesso, potremmo includere il tuo file di localizzazione in una futura versione di Weewx.
Infine, imposta l'opzione lang in weewx.conf al codice della tua lingua ( fr in questo esempio) come descritto nella Guida per l'utente .
Come internazionalizzare una skin
Cosa succede quando ti imbatti in una skin che ti piace, ma non è stata internazionalizzata? Questa sezione spiega come convertire il rapporto nei formati e nella lingua locali.
L'internazionalizzazione dei template di Weewx utilizza uno schema molto simile al ben noto approccio " gettext " di GNU. L'unica differenza è che abbiamo sfruttato la funzione ConfigObj utilizzata in Weewx.
Crea il file di localizzazione
Crea una sottodirectory chiamata lang nella directory skin. Quindi crea un file chiamato dal codice della lingua con il suffisso .conf . Ad esempio, se desideri tradurre in spagnolo, chiama il file es.conf . Includere quanto segue nel file:
[Units] [[Labels]] # These are singular, plural meter = " meter", " meters" day = " day", " days" hour = " hour", " hours" minute = " minute", " minutes" second = " second", " seconds" [[Ordinates]] # Ordinal directions. The last one should be for no wind direction directions = N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW, N/A [Labels] # Set to hemisphere abbreviations suitable for your location: hemispheres = N, S, E, W # Generic labels, keyed by an observation type. [[Generic]] altimeter = Altimeter # QNH altimeterRate = Altimeter Change Rate appTemp = Apparent Temperature appTemp1 = Apparent Temperature barometer = Barometer # QFF barometerRate = Barometer Change Rate cloudbase = Cloud Base dateTime = Time dewpoint = Dew Point ET = ET extraTemp1 = Temperature1 extraTemp2 = Temperature2 extraTemp3 = Temperature3 heatindex = Heat Index inDewpoint = Inside Dew Point inHumidity = Inside Humidity inTemp = Inside Temperature interval = Interval lightning_distance = Lightning Distance lightning_strike_count = Lightning Strikes outHumidity = Outside Humidity outTemp = Outside Temperature pressure = Pressure # QFE pressureRate = Pressure Change Rate radiation = Radiation rain = Rain rainRate = Rain Rate THSW = THSW Index UV = UV Index wind = Wind windchill = Wind Chill windDir = Wind Direction windGust = Gust Speed windGustDir = Gust Direction windgustvec = Gust Vector windrun = Wind Run windSpeed = Wind Speed windvec = Wind Vector [Almanac] # The labels to be used for the phases of the moon: moon_phases = New, Waxing crescent, First quarter, Waxing gibbous, Full, Waning gibbous, Last quarter, Waning crescent [Texts] Language = Español # Rimpiazza con la lingua da tradurre
Passa attraverso il file, traducendo tutte le frasi sul lato destro dei segni di uguale nella tua lingua di destinazione (spagnolo in questo esempio).
Internazionalizza il modello
Dovrai internazionalizzare ogni modello HTML (questi in genere hanno un suffisso file di .html.tmpl ). Questo è più facile da fare aprendo il modello e il file della lingua in diverse finestre dell'editor. È molto più semplice se puoi modificare entrambi i file contemporaneamente.
Cambia l' attributo html lang
Nella parte superiore del modello, modifica l'attributo HTML "lang" impostandolo su un valore configurabile.
<!DOCTYPE html> <html lang=" $lang "> <head> <meta charset="UTF-8"> ...
Il valore $lang verrà sostituito dalla lingua effettiva da utilizzare.
Modifica il corpo del testo
Il passaggio successivo consiste nell'esaminare i modelli e modificare tutte le frasi in linguaggio naturale in ricerche utilizzando $gettext . Ad esempio, supponi che la tua skin abbia una sezione simile a questa:
<div> Condizioni attuali <table> <tr> <td>Temperatura esterna</td> <td>$current.outTemp</td> </tr> </table> </div>
Ci sono due frasi in linguaggio naturale qui: Condizioni attuali e Temperatura esterna . Sarebbero cambiati in:
<div> $gettext("Condizioni attuali") <table> <tr> <td>$obs.label.outTemp</td> <td>$current.outTemp</td> </tr> </table> < /div>
Abbiamo fatto due sostituzioni qui. Per la frase Condizioni attuali , abbiamo sostituito $gettext("Condizioni attuali") . Questo farà sì che cheetah generator cercherà la versione localizzata di "Condizioni attuali" nel file di localizzazione e la sostituirà. Avremmo potuto fare qualcosa di simile per Temperatura esterna , ma in questo caso abbiamo scelto di utilizzare il nome localizzato per type outTemp , che dovresti aver fornito nel tuo file di localizzazione, nella sezione [Labels] / [[Generic]] .
Nel file di localizzazione, includi la traduzione per Condizioni correnti nella sezione [Texts] :
... [Texts] "Language" = "Español" "Condizioni attuali" = "Condiciones Actuales" ...
Ripeti questo processo per tutte le stringhe che trovi. Assicurati di non sostituire i tag HTML e le opzioni HTML.
Pensa al tempo
Ogni volta che viene utilizzato un orario in un modello, sarà necessario un formato. Weewx viene fornito con il seguente set di default, definito in defaults.py :
[Units] ... [[TimeFormats]] day = %X week = %X (%A) month = %x %X year = %x %X rainyear = %x %X current = %x %X ephem_day = %X ephem_year = %x %X
Queste impostazioni predefinite daranno qualcosa di leggibile in ogni locale, ma potrebbero non essere molto carine. Pertanto, potresti voler cambiarli in qualcosa di più adatto alla locale che stai traducendo, usando le direttive specifiche di Python strftime() .
Esempio: la formattazione dell'ora predefinita per le condizioni "Corrente" è %x %x , che mostrerà la data odierna come 14/05/21 10:00:00 nella locale spagnola. Supponiamo che preferiresti vedere 14-mayo-2021 10:00. Dovresti aggiungere quanto segue al tuo file di localizzazione spagnolo es.conf :
... [Units] [[TimeFormats]] current = %d-%B-%Y %H:%M ...
Imposta la variabile di ambiente LANG
Infine, dovrai impostare la variabile d'ambiente LANG per riflettere la tua localizzazione. Ad esempio, supponendo che tu abbia impostato
$ export LANG=es_ES.UTF-8
prima di eseguire Weewx, verranno utilizzati i nomi spagnoli locali per i giorni della settimana e i mesi dell'anno. Anche il punto decimale per i numeri verrà opportunamente modificato.
PERSONALIZZARE IL MOTORE DI SERVIZI
Questo è un argomento avanzato destinato a coloro che desiderano cimentarsi nell'estensione del motore interno in Weewx. Prima di provare questi esempi, dovresti essere ragionevolmente abile con Python.
Tieni presente che l'API del motore di servizio potrebbe cambiare nelle versioni future!
Ad alto livello, Weewx è costituito da un motore responsabile della gestione di un insieme di servizi . Un servizio è costituito da una classe Python che lega le sue funzioni membro a vari eventi . Il motore fa in modo che la funzione membro associata venga chiamata quando si verifica un evento specifico, ad esempio l'arrivo di un nuovo pacchetto LOOP.
I servizi sono specificati negli elenchi nella stanza [Engine][[Services]] del file di configurazione. La sezione [[Servizi]] elenca tutti i servizi da eseguire, suddivisi in diversi elenchi di servizi .
Questi elenchi sono progettati per orchestrare i dati mentre vengono processati attraverso il motore Weewx. Ad esempio, si desidera assicurarsi che i dati siano stati elaborati, ad esempio, eseguendoli tramite il servizio di controllo qualità, StdQC , prima di inserirli nel database. Allo stesso modo, il sistema di segnalazione deve venire dopo il servizio di archiviazione. Questi gruppi assicurano che le cose accadano nella giusta sequenza.
Vedere la tabella Servizi predefiniti per un elenco dei servizi normalmente eseguiti.
Modifica di un servizio esistente
Il servizio weewx.engine.StdPrint stampa i nuovi LOOP e archivia i pacchetti sulla console quando arrivano. Per impostazione predefinita, stampa l'intero record, che generalmente include molte informazioni che potrebbero distrarre e può essere piuttosto disordinato. Supponiamo che non vi piaccia e che vogliate stampare solo l'ora, la lettura del barometro e la temperatura esterna ogni volta che arriva un nuovo pacchetto LOOP. Questo potrebbe essere fatto creando una sottoclasse del servizio di stampa predefinito StdPrint e sovrascrivendo la funzione membro new_loop_packet() .
Crea il file user/myprint.py :
from weewx.engine import StdPrint from weeutil.weeutil import timestamp_to_string class MyPrint(StdPrint): # Sovrascrive la funzione membro new_loop_packet predefinita: def new_loop_packet(self, event): packet = event.packet print("LOOP: ", timestamp_to_string(packet[ 'dateTime']), "BAR=", packet.get('barometer', 'N/A'), "TEMP=", packet.get('outTemp', 'N/A'))
Questo servizio sostituisce una nuova implementazione per la funzione membro new_loop_packet . Questa implementazione stampa l'ora, quindi la lettura del barometro (o N/A se non è disponibile) e la temperatura esterna (o N/A).
È quindi necessario specificare che la classe del servizio di stampa deve essere caricata anziché il servizio StdPrint predefinito . Questo viene fatto sostituendo il nome del tuo servizio per StdPrint in service_list , che si trova in [Engine][[Services]] :
[Engine] [[Services]] ... report_services = user.myprint.MyPrint, weewx.engine.StdReport
Si noti che report_services deve essere tutto su una riga. Sfortunatamente, il parser ConfigObj non consente alle opzioni di proseguire nelle righe successive.
Creazione di un nuovo servizio
Supponiamo che non ci sia un servizio che possa essere facilmente personalizzato per le tue esigenze. In questo caso, è possibile crearne facilmente una nuova creando una sottoclasse dalla classe di base astratta StdService e quindi aggiungendo la funzionalità necessaria. Ecco un esempio che implementa un allarme, che invia un messaggio di posta elettronica quando un'espressione arbitraria valuta True .
Questo esempio è incluso nella distribuzione standard come examples/alarm.py:
import smtplib import socket import syslog import threading import time from email.mime.text import MIMEText import weewx from weeutil.weeutil import timestamp_to_string, option_as_list from weewx.engine import StdService # Eredita dalla classe base StdService: class MyAlarm(StdService): "" "Servizio che invia email se un'espressione arbitraria restituisce true""" def __init__(self, engine, config_dict): # Passa le informazioni di inizializzazione alla mia superclasse: super(MyAlarm, self).__init__(engine, config_dict) # Questo mantenere l'ora in cui è uscito l'ultimo messaggio di allarme: self.last_msg_ts = 0 try: # Estrarre le opzioni necessarie dal dizionario di configurazione. # Se manca un'opzione critica, verrà sollevata un'eccezione e # l'allarme non verrà impostato. self.expression = config_dict['Alarm']['expression'] self.time_wait = int(config_dict['Alarm'].get('time_wait', 3600)) self.timeout = int(config_dict['Alarm']. get('timeout', 10)) self.smtp_host = config_dict['Alarm']['smtp_host'] self.smtp_user = config_dict['Alarm'].get('smtp_user') self.smtp_password = config_dict['Alarm' ].get('smtp_password') self.SUBJECT = config_dict['Alarm'].get('subject', "Messaggio di allarme da weewx") self.FROM = config_dict['Alarm'].get('from', 'alarm@example.com') self .TO = option_as_list(config_dict['Alarm']['mailto']) syslog.syslog(syslog.LOG_INFO, "alarm: Alarm set for expression: '%s'" % self.expression) # Se siamo arrivati fin qui, va bene iniziare ad intercettare gli eventi: self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_record) # NOTA 1 tranne KeyError come e: syslog.syslog(syslog.LOG_INFO, "alarm: Nessun allarme impostato. Parametro mancante: %s"% e) def new_archive_record(self, evento): """Viene chiamato su un nuovo evento record di archivio.""" # Per evitare una marea di email quasi identiche, questo farà # il controllo solo se non abbiamo mai inviato un'email, o se non # ne abbiamo inviata una l'ultimo self.time_wait secondi: if not self.last_msg_ts o abs(time.time() - self.last_msg_ts) >= self.time_wait: # Ottieni il nuovo record di archivio: record = event.record # Preparati a rilevare un'eccezione nel caso in cui l'espressione contenga # una variabile non presente nel record: try: # NOTA 2 # Valuta l'espressione nel contesto del record dell'archivio eventi. # Suona l'allarme se valuta true: if eval(self.expression, None, record): # NOTA 3 # Suona l'allarme! # Avvia in un thread separato in modo che non blocchi il thread LOOP principale: t = threading.Thread(target=MyAlarm.sound_the_alarm, args=(self, record)) t.start() # Registra quando il messaggio è uscito: self.last_msg_ts = time.time() tranne NameError as e: # Nel record mancava una variabile con nome. Registralo. syslog.syslog(syslog.LOG_DEBUG, "alarm: %s" % e) def sound_the_alarm(self, rec): """Suona l'allarme in un blocco 'try'""" # Racchiude il tentativo in un blocco 'try' quindi possiamo registrare un errore. try: self.do_alarm(rec) except socket.gaierror: # Un'eccezione gaierror è generalmente causata da un host sconosciuto syslog.syslog(syslog.LOG_CRIT, "alarm: unknown host %s" % self.smtp_host) # Rilancia l'eccezione. Ciò causerà l'uscita del thread. raise except Exception as e: syslog.syslog(syslog.LOG_CRIT, "allarme: impossibile suonare l'allarme. # Solleva nuovamente l'eccezione. Ciò causerà l'uscita del thread. raise def do_alarm(self, rec): """Invia una email""" # Prende l'ora e la converte in una stringa: t_str = timestamp_to_string(rec['dateTime']) # Registra l'allarme syslog.syslog(syslog. LOG_INFO, 'alarm: Espressione di allarme "%s" valutata True alle %s' % (self.expression, t_str)) # Forma il testo del messaggio: msg_text = 'Espressione di allarme "%s" valutata True alle %s\nRecord:\ n%s' % (self.expression, t_str, str(rec)) # Converti in MIME: msg = MIMEText(msg_text) # Compila le intestazioni MIME: msg['From'] = self.FROM msg['To'] = ','.join(self.TO) try: # Prima prova la crittografia end-to-end s = smtplib.SMTP_SSL(self.smtp_host, timeout= self.timeout) syslog.syslog(syslog.LOG_DEBUG, "allarme: utilizzo di SMTP_SSL") tranne (AttributeError, socket.timeout, socket.error): syslog.syslog(syslog.LOG_DEBUG, "allarme: impossibile utilizzare la connessione SMTP_SSL." ) # Se non funziona, prova a creare un host non sicuro, quindi aggiorna s = smtplib.SMTP(self.smtp_host, timeout=self.timeout) try: # Preparati a rilevare un'eccezione se il server # non supporta il trasporto crittografato. s.ehlo() s.starttls() s.ehlo() syslog.syslog(syslog.LOG_DEBUG, "alarm: utilizzo del trasporto crittografato SMTP") tranne smtplib.SMTPException: syslog.syslog(syslog.LOG_DEBUG, "alarm: utilizzo di SMTP trasporto non crittografato") try: # Se è stato fornito un nome utente, presumere che sia richiesto il login per questo host: if self.smtp_user: s.login(self.smtp_user, self.smtp_password) syslog.syslog(syslog.LOG_DEBUG, "alarm: loggato con nome utente %s" % self.smtp_user) # Invia l'email: s.sendmail(msg['From'], self.TO, msg.as_string()) # Disconnettersi dal server: s.quit() except Exception as e: syslog.syslog(syslog.LOG_ERR, "alarm: Mailer SMTP rifiutato messaggio con errore %s" % e) raise # Log invio email: syslog.syslog (syslog.LOG_INFO, "allarme: email inviata a: %s" % self.TO)
Questo servizio si aspetta che tutte le informazioni di cui ha bisogno siano nel file di configurazione weewx.conf in una nuova sezione chiamata [Alarm] . Quindi, aggiungi le seguenti righe al tuo file di configurazione:
[Alarm] expression = "outTemp < 40.0" time_wait = 3600 smtp_host = smtp.example.com smtp_user = myusername smtp_password = mypassword mailto = auser@example.com, anotheruser@example.com from = me@example.com subject = "Alarm messaggio da Weewx!"
Ci sono tre punti importanti da notare in questo esempio, ciascuno contrassegnato con un flag NOTE nel codice.
- • Qui è dove avviene l'associazione tra un evento, weewx.NEW_ARCHIVE_RECORD in questo esempio, e una funzione membro, self.new_archive_record . Quando si verifica l'evento NEW_ARCHIVE_RECORD , verrà chiamata la funzione self.new_archive_record . Ci sono molti altri eventi che possono essere intercettati. Cerca nel file weewx/__init__.py .
- • Alcuni hardware non emettono tutti i possibili tipi di osservazione in ogni record. Pertanto, è possibile che in un record manchino alcuni tipi utilizzati nell'espressione. Questo blocco try rileverà l' eccezione NameError che verrebbe sollevata se ciò si verificasse.
- • Qui è dove viene eseguito il test per stabilire se suonare o meno l'allarme. Le opzioni di configurazione [Alarm] specificano che l'allarme deve suonare quando outTemp < 40.0 restituisce True , cioè quando la temperatura esterna è inferiore a 40.0 gradi. È possibile utilizzare qualsiasi espressione Python valida, sebbene le uniche variabili disponibili siano quelle nel record di archivio corrente.
Un'altra espressione di esempio potrebbe essere:
expression = "outTemp < 32.0 and windSpeed > 10.0"
In questo caso l'allarme suona se la temperatura esterna scende sotto lo zero e la velocità del vento è superiore a 10.0.
Si noti che le unità devono essere le stesse di qualsiasi cosa venga utilizzata nel database. Cioè, lo stesso di quanto specificato nell'opzione target_unit .
L'opzione time_wait viene utilizzata per evitare un flusso di email quasi identiche. Il nuovo servizio attenderà così a lungo prima di inviare un'altra e-mail.
L'e-mail verrà inviata tramite l'host SMTP specificato dall'opzione smtp_host . I destinatari sono specificati dall'opzione separata da virgole mailto .
Molti host SMTP richiedono l'accesso dell'utente. In tal caso, l'utente e la password vengono specificati rispettivamente con le opzioni smtp_user e smtp_password .
Le ultime due opzioni, from e subject sono facoltative. Se non fornito, Weewx fornirà qualcosa di sensato. Si noti, tuttavia, che alcuni mailer richiedono un indirizzo email "from" valido e quello fornito da Weewx potrebbe non soddisfare i suoi requisiti.
Per far funzionare tutto questo, devi prima copiare il file alarm.py nella directory utente . Quindi dire al motore di caricare questo nuovo servizio aggiungendo il nome del servizio all'elenco report_services , che si trova in [Engine][[Services]] :
[Engine] [[Services]] report_services = weewx.engine.StdPrint, weewx.engine.StdReport, user.alarm.MyAlarm
Ancora una volta, si noti che l'opzione report_services deve essere tutta su una riga: il parser ConfigObj non consente alle opzioni di proseguire nelle righe successive.
Oltre a questo esempio, la distribuzione include anche un allarme di batteria scarica ( lowBattery.py ), che è simile, tranne per il fatto che intercetta gli eventi LOOP (invece di archiviare gli eventi).
Aggiunta di una seconda origine dati
Un problema molto comune è voler aumentare i dati della tua stazione meteorologica con i dati di qualche altro dispositivo. In generale, hai due approcci su come gestirlo:
- • Esegui due istanze di Weewx, ciascuna utilizzando il proprio database e il file di configurazione weewx.conf . I risultati vengono quindi combinati in un rapporto finale, sfruttando la capacità di Weewx di utilizzare più di un database . Vedi la voce Wiki How to run multiple instances of Weewx per i dettagli su come farlo.
- • Esegui un'istanza, ma utilizza un servizio Weewx personalizzato per aumentare i record provenienti dalla tua stazione meteorologica con i dati dell'altro dispositivo.
Questa sezione copre quest'ultimo approccio.
Supponiamo che tu abbia installato un contatore elettrico a casa tua e desideri correlare il consumo elettrico con il tempo. Il misuratore ha una sorta di connessione al tuo computer, che ti consente di scaricare l'energia totale consumata. Alla fine di ogni intervallo di archiviazione si desidera calcolare la quantità di energia consumata durante l'intervallo, quindi aggiungere i risultati al record proveniente dalla stazione meteorologica. come lo faresti?
Ecco lo schema di un servizio che recupera i dati di consumo elettrico e li aggiunge alla scheda di archivio. Presuppone che tu abbia già una funzione download_total_power() che, in qualche modo, scarica la quantità di energia consumata dal tempo zero.
File utente/electricity.py
import weewx from weewx.engine import StdService class AddElectricity(StdService): def __init__(self, engine, config_dict): # Inizializza prima la mia superclasse: super(AddElectricity, self).__init__(engine, config_dict) # Associa a qualsiasi nuovo record di archivio events: self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_record) self.last_total = None def new_archive_record(self, event): total_power = download_total_power() if self.last_total: net_consumed = total_power - self.last_total event.record['electricity'] = net_consumed self.last_total = total_power
Ciò aggiunge una nuova chiave electricity al dizionario dei record e la imposta uguale alla differenza tra la quantità di energia attualmente consumata e la quantità consumata nell'ultimo record di archivio. Quindi, sarà la quantità di energia consumata nell'intervallo di archiviazione. L'unità dovrebbe essere Watt-ora.
Per inciso, è importante che la funzione download_total_power() non ritardi molto a lungo perché si collocherà proprio nel ciclo principale del motore di Weewx. Se causerà un ritardo superiore a un paio di secondi, potresti volerlo inserire in un thread separato e inviare i risultati a AddElectricity tramite una coda.
Per assicurarti che il tuo servizio venga eseguito, devi aggiungerlo a uno degli elenchi di servizi in weewx.conf , sezione [Engine] , sottosezione [[Services]] .
Nel nostro caso, il posto ovvio per il nostro nuovo servizio è in data_services . Al termine, la sezione [Engine] sarà simile a questa:
# Questa sezione configura il motore interno di Weewx. [Engine] [[Services]] # This section specifies the services that should be run. They are # grouped by type, and the order of services within each group # determines the order in which the services will be run. xtype_services = weewx.wxxtypes.StdWXXTypes, weewx.wxxtypes.StdPressureCooker, weewx.wxxtypes.StdRainRater, weewx.wxxtypes.StdDelta prep_services = weewx.engine.StdTimeSynch data_services = user.electricity.AddElectricity process_services = weewx.engine.StdConvert, weewx.engine.StdCalibrate, weewx.engine.StdQC, weewx.wxservices.StdWXCalculate archive_services = weewx.engine.StdArchive restful_services = weewx.restx.StdStationRegistry, weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdWOW, weewx.restx.StdAWEKAS report_services = weewx.engine.StdPrint, weewx.engine.StdReport
PERSONALIZZAZIONE DEL DATABASE
Per la maggior parte degli utenti le impostazioni predefinite del database funzioneranno correttamente. Tuttavia, potrebbero esserci occasioni in cui potresti voler aggiungere un nuovo tipo di osservazione al tuo database o cambiarne il sistema di unità. Questa sezione mostra come farlo.
Ogni database relazionale dipende da uno schema per specificare quali tipi includere nel database. Quando un database Weewx viene creato per la prima volta, utilizza una versione Python dello schema per inizializzare il database. Tuttavia, una volta che il database è stato creato, lo schema viene letto direttamente dal database e la versione di Python non viene più utilizzata: eventuali modifiche non avranno alcun effetto. Ciò significa che la strategia per modificare lo schema dipende dal fatto che il database esista già.
Specifica di uno schema per un nuovo database
Se il database non esiste ancora, allora vorrai scegliere uno schema iniziale appropriato. Se non è esattamente quello che desideri, puoi modificarlo in base alle tue esigenze.
Scegliere uno schema di partenza
Weewx ti offre una scelta di tre diversi schemi tra cui scegliere quando crei un nuovo database:
NOME | NUMERO TIPI DI OSSERVAZIONE | DESCRIZIONE |
schemi.wview.schema | 49 | Lo schema originale fornito con wview. |
schemi.wview_extended.schema | 111 | Una versione dello schema wview, che è stata estesa con molti nuovi tipi. Questa è la versione predefinita. |
schemi.wview_small.schema | 20 | Una versione minimalista dello schema wview. |
Per la maggior parte degli utenti, lo schema del database predefinito, schemas.wview_extended.schema , funzionerà perfettamente.
Per specificare quale schema utilizzare durante la creazione di un database, modificare lo schema delle opzioni nella sezione [DataBindings] in weewx.conf . Ad esempio, supponi di voler utilizzare lo schema classico (e più piccolo) schemas.wview.schema invece dello schemas.wview_extended.schema predefinito . Quindi la sezione [DataBindings] sarebbe simile a:
[DataBindings] [[wx_binding]] database = archive_sqlite table_name = archive manager = weewx.manager.DaySummaryManager schema = schemas.wview.schema
Ora, quando avvii Weewx, userà questa nuova scelta invece di quella predefinita.
Funziona solo quando il database viene creato per la prima volta . Successivamente, Weewx legge lo schema direttamente dal database. La modifica di questa opzione non avrà alcun effetto!
Modifica di uno schema iniziale
Se nessuno dei tre schemi iniziali forniti con Weewx si adatta ai tuoi scopi, puoi facilmente crearne uno tuo. Basta scegliere uno dei tre schemi come punto di partenza, quindi modificarlo. Metti i risultati nella sottodirectory dell'utente , dove sarà al sicuro dagli aggiornamenti. Ad esempio, supponi che ti piaccia lo schema schemas.wview_small , ma devi archiviare il tipo electricity dall'esempio Aggiunta di una seconda origine dati precedente. Il tipo electricity non compare nello schema, quindi dovrai aggiungerlo prima di avviare Weewx. Chiameremo il nuovo schema risultante user.myschema.schema .
Se hai installato Debian, ecco come faresti:
# Copia lo schema wview_small nella sottodirectory utente e rinominalo myschema: sudo cp /usr/share/weewx/schemas/wview_small.py /usr/share/weewx/user/myschema.py # Modificalo utilizzando il tuo editor di testo preferito
sudo nano /usr/share/weewx/user/myschema.py
Se hai eseguito un'installazione setup.py , sarebbe simile a questo:
# Copia lo schema wview_small nella sottodirectory user e rinominalo myschema: cp /home/weewx/bin/schemas/wview_small.py /home/weewx/bin/user/myschema.py # Modificalo utilizzando il tuo editor di testo preferito
nano /home/weewx/bin/utente/myschema.py
In myschema.py cambia questo:
... ('windchill', 'REAL'), ('windDir', 'REAL'), ('windGust', 'REAL'), ('windGustDir', 'REAL'), ('windSpeed', 'REAL '), ]
a questo
... ('windchill', 'REAL'), ('windDir', 'REAL'), ('windGust', 'REAL'), ('windGustDir', 'REAL'), ('windSpeed', 'REAL'), ('electricity', 'REAL'), ]
Ora modifica lo schema delle opzioni in [DataBindings] in weewx.conf per utilizzare il tuo nuovo schema:
[DataBindings] [[wx_binding]] database = archive_sqlite table_name = archive manager = weewx.manager.DaySummaryManager schema = user.myschema.schema
Avvia Weewx. Quando viene creato il nuovo database, utilizzerà lo schema modificato anziché quello predefinito.
Funzionerà solo quando il database viene creato per la prima volta! Successivamente, Weewx legge lo schema direttamente dal database e le tue modifiche non avranno effetto!
Modifica di un database esistente
La sezione precedente tratta il caso in cui non si dispone di un database esistente, quindi si modifica uno schema iniziale, quindi lo si utilizza per inizializzare il database. Ma cosa succede se hai già un database e vuoi modificarlo, magari aggiungendo una o due colonne? Non è possibile creare un nuovo schema iniziale, perché viene utilizzato solo quando il database viene creato per la prima volta. Qui è dove lo strumento wee_database può essere utile. Assicurati di interrompere Weewx prima di tentare di usarlo.
Ci sono due modi per farlo. Entrambi sono trattati di seguito.
- • Modificare il database in situ utilizzando lo strumento wee_database . Questa scelta funziona meglio per piccoli cambiamenti.
- • Trasferisci il vecchio database in uno nuovo mentre lo modifichi lungo il percorso, sempre utilizzando lo strumento wee_database . Questa scelta è la migliore per grandi modifiche.
Prima di utilizzare lo strumento wee_database , FARE PRIMA UN BACKUP!
Modificare il database in situ
Se vuoi apportare alcune modifiche minori a un database esistente, magari aggiungendo o rimuovendo una colonna, allora questo può essere fatto facilmente usando lo strumento wee_database con un'opzione appropriata. Tratteremo i casi di aggiunta, rimozione e ridenominazione di un tipo. Vedere la documentazione per wee_database per maggiori dettagli.
Aggiunta di un tipo
Si supponga di disporre di un database esistente e di voler aggiungere un tipo, ad esempio il tipo electricity dell'esempio precedente Aggiunta di una seconda origine dati . Questo può essere fatto in un semplice passaggio usando lo strumento wee_database con l'opzione --add-column :
wee_database --add-column=electricity
Lo strumento non solo aggiunge electricity alla tabella dell'archivio principale, ma anche ai riepiloghi giornalieri.
Rimozione di un tipo
In modo simile, lo strumento può rimuovere tutti i tipi non necessari da un database esistente. Ad esempio, supponi di utilizzare lo schema schemas.wview , ma sei abbastanza sicuro di non dover immagazzinare l'umidità del suolo. Puoi eliminare i tipi non necessari in questo modo:
wee_database --drop-columns=soilMoist1,soilMoist2,soilMoist3,soilMoist4
A differenza dell'opzione --add-column , l'opzione --drop-columns può accettare più di un tipo. Questo viene fatto nell'interesse dell'efficienza: l'aggiunta di nuove colonne è facile e veloce con il database SQLite, ma l'eliminazione delle colonne richiede la copia dell'intero database. Specificando più di un tipo, è possibile ammortizzare il costo su una singola chiamata dell'utilità.
Eliminare i tipi da un database significa perdere tutti i dati ad essi associati! I dati non possono essere recuperati.
Ridenominazione di un tipo
Supponi di voler solo rinominare un tipo? Questo può essere fatto usando l'opzione --to-name . Ecco un esempio in cui si rinomina soilMoist1 in soilMoistGarden :
wee_database --rename-column=soilMoist1 --to-name=soilMoistGarden
Si noti come l'opzione --rename-column richieda anche l'opzione --to-name , che specifica il nome di destinazione.
Trasferisci il database utilizzando il nuovo schema
Se stai apportando modifiche importanti al tuo database, potresti trovare più semplice creare un nuovo database utilizzando lo schema che desideri, quindi trasferire tutti i dati dal vecchio database a quello nuovo. Questo approccio richiede più lavoro e richiede più tempo di elaborazione rispetto alle strategie in situ delineate sopra, ma ha il vantaggio di lasciare una traccia dello schema esatto che stai utilizzando.
Ecco la strategia generale su come farlo.
- • Crea un nuovo schema che includa esattamente i tipi desiderati.
- • Specificare questo schema come schema iniziale per il database.
- • Assicurati di disporre delle autorizzazioni necessarie per creare il nuovo database.
- • Utilizzare l'utilità wee_database per creare il nuovo database e popolarlo con i dati del vecchio database.
- • Unisce i database in modo che Weewx utilizzi il nuovo database.
Ecco i dettagli:
-
• Crea un nuovo schema. Il primo passaggio consiste nel creare un nuovo schema con esattamente i tipi desiderati. Vedere le istruzioni sopra Modificare uno schema iniziale . Ad esempio, supponiamo che il tuo nuovo schema sia chiamato user.myschema.schema .
-
• Imposta come schema iniziale. Imposta il tuo nuovo schema come schema iniziale con qualsiasi associazione di database con cui stai lavorando (generalmente, wx_binding ). Per esempio:
[DataBindings] [[wx_binding]] database = archive_sqlite table_name = archive manager = weewx.manager.DaySummaryManager schema = user.myschema.schema
-
• Controlla le autorizzazioni. L'utilità di riconfigurazione creerà un nuovo database con lo stesso nome del vecchio, ma con il suffisso _new aggiunto alla fine. Assicurati di disporre delle autorizzazioni necessarie per eseguire questa operazione. In particolare, se stai usando MySQL, avrai bisogno dei privilegi CREATE .
-
• Creare e popolare il nuovo database. Utilizzare l'utilità wee_database con l' opzione --reconfigure .
wee_database weewx.conf --reconfigure
Questo creerà un nuovo database (nominalmente, weewx.sdb_new se stai usando SQLite, weewx_new se stai usando MySQL), usando lo schema trovato in user.myschema.schema e lo popolerà con i dati del vecchio database.
-
• Unire i database. Ora organizza le cose in modo che Weewx possa trovare il nuovo database.
Fai un backup dei dati prima di eseguire uno dei passaggi successivi!
Puoi unire i database in modo che il nuovo database abbia lo stesso nome del vecchio database o modificare weewx.conf per utilizzare il nuovo nome del database. Per fare il primo:
Per SQLite:
cd SQLITE_ROOT mv weewx.sdb_new weewx.sdb
Per MySQL:
mysql -u <username> --password=<mypassword> mysql> DROP DATABASE weewx; # Elimina il vecchio database mysql> CREATE DATABASE weewx; # Creane una nuova con lo stesso nome mysql> RENAME TABELLA weewx_new.archive TO weewx.archive; # Rinomina al nome nominale
-
Vale la pena notare che in realtà c'è un ultimo passaggio nascosto: ricostruire i riepiloghi giornalieri all'interno del nuovo database. Questo verrà fatto automaticamente da Weewx al prossimo avvio. In alternativa, può essere fatto manualmente usando l' utility wee_database e l' opzione --rebuild-daily :
wee_database weewx.conf --rebuild-daily
Modifica del sistema di unità in un database esistente
Normalmente, i dati vengono archiviati nei database utilizzando le unità consuetudinarie statunitensi e non dovrebbe interessarti; è un "dettaglio di implementazione". I dati possono sempre essere visualizzati utilizzando qualsiasi set di unità desiderato: la sezione Come modificare le unità spiega come modificare le unità di reporting. Tuttavia, potrebbero esserci situazioni speciali in cui si desidera memorizzare i dati in unità metriche. Ad esempio, potrebbe essere necessario consentire l'accesso programmatico diretto al database da un altro software che prevede unità metriche.
Non è necessario modificare il sistema di unità di database midstream. Cioè, non iniziare con un sistema di unità e poi, qualche tempo dopo, passare a un altro. Weewx non può gestire database con sistemi di unità miste — vedi la sezione [StdConvert] nella Guida per l'utente di Weewx. Tuttavia, è possibile riconfigurare il database copiandolo in un nuovo database, eseguendo la conversione delle unità lungo il percorso. Quindi utilizzerai questo nuovo database.
La strategia generale è identica alla strategia delineata sopra nella sezione Trasferimento del database utilizzando il nuovo schema . L'unica differenza è che invece di specificare un nuovo schema iniziale, si specifica un diverso sistema di unità di database. Ciò significa che invece dei passaggi 1 e 2 sopra, si modifica il file di configurazione e si cambia l'opzione target_unit nella sezione [StdConvert] per riflettere la propria scelta. Ad esempio, se stai passando alle unità metriche, l'opzione sarà simile a:
[StdConvert] target_unit = METRICWX
Dopo aver modificato target_unit , vai avanti con il resto dei passaggi. Questo è eseguire wee_database con l' opzione --reconfigure , quindi unire i database.
Ricostruire i riepiloghi giornalieri
L' utilità wee_database può anche essere utilizzata per ricostruire i riepiloghi giornalieri:
wee_database weewx.conf --rebuild-daily
Nella maggior parte dei casi questo sarà sufficiente; tuttavia, se permangono anomalie nei riepiloghi giornalieri, le tabelle di riepilogo giornaliero possono essere eliminate prima della ricostruzione:
wee_database weewx.conf --drop-daily
I riepiloghi verranno ricostruiti automaticamente al successivo avvio di Weewx, oppure possono essere ricostruiti con l'utility:
wee_database weewx.conf --rebuild-daily
PERSONALIZZAZIONE DI UNITÀ E GRUPPI DI UNITÀ
Questa è un'area che sta cambiando rapidamente in Weewx. Attualmente, nuove unità e gruppi di unità vengono aggiunti manipolando i dizionari interni in Weewx (come descritto di seguito). In futuro, potrebbero essere specificati in weewx.conf .
Assegnazione di un gruppo di unità
Negli esempi sopra, abbiamo creato un nuovo tipo di osservazione, electricity e l'abbiamo aggiunto allo schema del database. Ora vorremmo riconoscere che è un membro del gruppo di unità group_energy (che esiste già), quindi può godere delle etichette e dei formati già previsti per questo gruppo. Questo viene fatto estendendo il dizionario weewx.units.obs_group_dict .
Aggiungi quanto segue al nostro nuovo file di servizi user/electricity.py , subito dopo l'ultima dichiarazione di importazione:
import weewx from weewx.engine import StdService import weewx.units weewx.units.obs_group_dict['electricity'] = 'group_energy' class AddElectricity(StdService): # [...]
Quando il nostro nuovo servizio verrà caricato dal motore di Weewx, queste poche righe verranno eseguite. Dicono a Weewx che il nostro nuovo tipo di osservazione, l'elettricità , fa parte del gruppo di unità group_energy . Una volta che l'osservazione è stata associata a un gruppo di unità, le etichette delle unità e l'altra sintassi dei tag funzioneranno per quell'osservazione. Quindi, ora un tag come:
$month.electricity.sum
restituirà la quantità totale di elettricità consumata per il mese, in Watt-ora.
Creazione di un nuovo gruppo di unità
È stato facile, perché esisteva già un gruppo esistente, group_energy , che copriva il nostro nuovo tipo di osservazione. Ma cosa succede se misuriamo qualcosa di completamente nuovo, come la forza con il tempo? Non c'è nulla nel sistema di unità esistente che tratti cose come newton o libbre. Dovremo definire queste nuove unità, così come il gruppo di unità a cui possono appartenere.
Supponiamo di avere un nuovo tipo di osservazione, rocketForce , che stiamo misurando nel tempo, per un servizio chiamato Rocket , che si trova in user/rocket.py . Creeremo un nuovo gruppo di unità, group_force , e nuove unità, newton e pound . La nostra nuova osservazione, rocketForce , apparterrà a group_force e sarà misurata in unità di newton o pound .
Per farlo funzionare, dobbiamo aggiungere quanto segue a user/rocket.py .
- Come prima, iniziamo specificando a quale gruppo appartiene il nostro nuovo tipo di osservazione:
import weewx.units weewx.units.obs_group_dict['rocketForce'] = 'group_force'
- Successivamente, specifichiamo quale unità viene utilizzata per misurare la forza nei tre sistemi di unità standard utilizzati da weewx.
weewx.units.USUnits['group_force'] = 'pound' weewx.units.MetricUnits['group_force'] = 'newton' weewx.units.MetricWXUnits['group_force'] = 'newton'
- Quindi specifichiamo quali formati ed etichette utilizzare per newton e pound :
weewx.units.default_unit_format_dict['newton'] = '%.1f' weewx.units.default_unit_format_dict['pound'] = '%.1f'
weewx.units.default_unit_label_dict['newton'] = ' newton' weewx.units.default_unit_label_dict['pound'] = ' pound'
- Infine, specifichiamo come convertire tra loro:
weewx.units.conversionDict['newton'] = {'pound': lambda x : x * 0.224809} weewx.units.conversionDict['pound'] = {'newton': lambda x : x * 4.44822}
Ora, quando il servizio Rocket viene caricato, queste righe di codice verranno eseguite, aggiungendo le estensioni unità necessarie a Weewx.
Utilizzando le nuove unità
Ora hai aggiunto un nuovo tipo di unità. Come lo usi?
Praticamente come qualsiasi altra unità. Ad esempio, per tracciare un grafico del consumo elettrico mensile, sommato per giorno, aggiungi questa sezione alla sezione [[month_images]] di skin.conf :
[[[monthelectric]]] [[[[electricity]]]] aggregate_type = sum aggregate_interval = day label = Consumo elettrico (totale giornaliero)
Ciò causerà la generazione di un'immagine monthelectric.png , che mostra un grafico del consumo di ogni giorno per il mese passato.
Se desideri utilizzare il nuovo tipo nei modelli, sarà disponibile utilizzando la stessa sintassi di qualsiasi altro tipo. Ecco alcuni altri tag che potrebbero essere utili:
ETICHETTA | DESCRIZIONE |
$day.electricity.sum | Consumo totale dalla mezzanotte |
$year.electricity.sum | Consumo totale dal primo dell'anno |
$year.electricity.max | Il più consumato durante qualsiasi periodo di archiviazione |
$year.electricity.maxsum | Il più consumato durante la giornata |
$year.electricity.maxsumtime | Il giorno in cui è successo. |
$year.electricity.sum_ge((5000.0, 'kWh', 'group_energy')) | Il numero di giorni dell'anno in cui sono stati consumati più di 5,0 kWh di energia. L'argomento è un ValueTuple . |
PORTING SU NUOVO HARDWARE
Un driver comunica con l'hardware. Ogni driver è un singolo file python che contiene il codice che è l'interfaccia tra un dispositivo e Weewx. Un driver può comunicare direttamente con l'hardware utilizzando un'interfaccia fisica MODBus, USB, seriale o di altro tipo. Oppure può comunicare su una rete con un dispositivo fisico o un servizio web.
Linee guida generali
- • Il driver dovrebbe emettere i dati mentre li riceve dall'hardware (nessuna memorizzazione nella cache).
- • Il driver dovrebbe emettere solo i dati che riceve dall'hardware (senza "riempire i vuoti").
- • Il driver non dovrebbe modificare i dati a meno che la modifica non sia direttamente correlata all'hardware (ad esempio , decodificare un valore del sensore specifico dell'hardware).
- • Se l'hardware contrassegna "dati errati", il driver dovrebbe emettere un valore nullo per quel dato (Python None).
- • Il driver non deve calcolare alcuna variabile derivata (come il punto di rugiada). Il servizio StdWXService lo farà.
- • Tuttavia, se l'hardware emette una variabile derivata, il driver dovrebbe emetterla.
Implementare il driver
Crea un file nella directory utente, diciamo mydriver.py . Questo file conterrà la classe del driver e qualsiasi codice specifico dell'hardware. Non metterlo nella directory weewx/drivers o verrà eliminato quando aggiorni Weewx.
Eredita dalla classe base astratta weewx.drivers.AbstractDevice . Cerca di implementare quanti più metodi puoi. Come minimo, devi implementare i primi tre metodi, loader , hardware_name e genLoopPackets .
loader
Questa è una funzione di fabbrica che restituisce un'istanza del driver. Ha due argomenti: il dizionario di configurazione e un riferimento al motore di Weewx.
hardware_name
Restituisce una stringa con un breve soprannome per l'hardware, ad esempio "ACME X90"
genLoopPackets
Questa dovrebbe essere una funzione del generatore Python che produce pacchetti di loop, uno dopo l'altro. Non preoccuparti di interromperlo: il motore lo farà quando è necessario un record di archivio. Un "pacchetto loop" è un dizionario. Come minimo deve contenere chiavi per il tempo di osservazione e per le unità utilizzate all'interno del pacchetto.
dateTime | L'ora dell'osservazione in unix epoch time. |
usUnits | Il sistema di unità utilizzato. weewx.US per US consuetudine, weewx.METRICWX o weewx.METRIC per metrica. Vedi l'Appendice Unità per le loro esatte definizioni. Anche i dizionari USUnits , MetricWXUnits e MetricUnits nel file units.py possono essere utili. |
Quindi includi tutti i tipi di osservazione che hai nel dizionario. Non è necessario che ogni pacchetto contenga lo stesso insieme di tipi di osservazione. Diversi pacchetti possono utilizzare diversi sistemi di unità, ma tutte le osservazioni all'interno di un pacchetto devono utilizzare lo stesso sistema di unità. Se il tuo hardware è in grado di misurare un tipo di osservazione ma, per qualsiasi motivo, il suo valore è errato (forse un checksum errato?), imposta il suo valore su None . Se il tuo hardware non è in grado di misurare un tipo di osservazione, lascialo fuori dal dizionario.
Un paio di tipi di osservazione sono complicati, in particolare la pioggia . La pioggia sul campo in un pacchetto LOOP dovrebbe essere la quantità di pioggia caduta dall'ultimo pacchetto . Poiché i pacchetti LOOP vengono emessi abbastanza frequentemente, è probabile che si tratti di un numero ridotto. Se il tuo hardware non fornisce questo valore, potresti doverlo dedurre dai cambiamenti di qualunque valore fornisca, ad esempio i cambiamenti nelle precipitazioni giornaliere o mensili.
Il vento è un altro problema. In realtà è suddiviso in quattro diverse osservazioni: windSpeed windDir , windGust e windGustDir . Forniscine il maggior numero possibile. Le direzioni devono essere indicazioni della bussola in gradi (0=Nord, 90=Est, ecc.).
Prestare attenzione quando si segnala la pressione. Ci sono tre osservazioni relative alla pressione. Alcune stazioni riportano solo la pressione della stazione, altre calcolano e riportano le pressioni a livello del mare.
pressure | La pressione della stazione (SP), che è la pressione assoluta grezza misurata dalla stazione. Questa è la vera pressione barometrica per la stazione. |
barometer | La pressione a livello del mare (SLP) ottenuta correggendo la pressione della stazione per l'altitudine e la temperatura locale. Questa è la lettura della pressione più comunemente usata dai meteorologi per tracciare i sistemi meteorologici in superficie, e questa è la pressione che viene caricata sui servizi meteorologici da Weewx. È la pressione della stazione ridotta al livello medio del mare utilizzando l'altitudine e la temperatura locali. |
altimeter | L' impostazione dell'altimetro (AS) ottenuta correggendo la pressione della stazione per l'altitudine. Questa è la lettura della pressione più comunemente ascoltata nei bollettini meteorologici. Non è la vera pressione barometrica di una stazione, ma piuttosto la pressione della stazione ridotta al livello medio del mare utilizzando l'altitudine e una presunta temperatura media. |
genArchiveRecords()
Se il tuo hardware non dispone di un registratore di record di archivio, Weewx può eseguire la generazione dei record per te. Raccoglierà automaticamente tutti i tipi che vede nei pacchetti del loop, quindi emetterà un record con le medie (in alcuni casi la somma o il valore massimo) di tutti quei tipi. Se non vede un tipo, allora non apparirà nel record emesso.
Tuttavia, se il tuo hardware ha un logger, allora dovresti implementare anche il metodo genArchiveRecords() . Dovrebbe essere una funzione generatore che restituisce tutti i record da un dato momento.
archive_interval
Se implementi la funzione genArchiveRecords() , dovresti anche implementare archive_interval come attributo o come proprietà function . Dovrebbe restituire l'intervallo di archiviazione in secondi.
getTime()
Se il tuo hardware ha un orologio integrato e supporta la lettura dell'ora da esso, allora potresti voler implementare questo metodo. Non ci vuole argomento. Dovrebbe restituire l'ora in Unix Epoch Time.
setTime()
Se il tuo hardware ha un orologio integrato e supporta l' impostazione , allora potresti voler implementare questo metodo. Non richiede argomentazioni e non ha bisogno di restituire nulla.
closePort()
Se il driver deve chiudere una porta seriale, terminare un thread, chiudere un database o eseguire qualsiasi altra attività prima che l'applicazione venga terminata, è necessario fornire questa funzione. Weewx lo chiamerà se ha bisogno di spegnere la tua console (di solito in caso di errore).
Definire la configurazione
Quindi includi una nuova sezione nel file di configurazione weewx.conf che include tutte le opzioni necessarie al tuo driver. Dovrebbe anche includere un driver di ingresso che indichi dove è possibile trovare il tuo driver. Imposta l'opzione station_type sul tuo nuovo tipo di sezione e il tuo driver verrà caricato.
Esempi
Il driver fileparse è forse l'esempio più semplice di driver Weewx. Legge le coppie nome-valore da un file e utilizza i valori come "letture" del sensore. Il codice è effettivamente impacchettato come un'estensione, situata in examples/fileparse , rendendolo un buon esempio non solo di scrittura di un driver di dispositivo, ma anche di come impacchettare un'estensione. Il driver vero e proprio si trova in examples/fileparse/bin/user/fileparse.py .
Un altro buon esempio è il codice del simulatore che si trova in weewx/drivers/simulator.py . È semplicissimo e puoi giocarci facilmente. Molte persone lo hanno utilizzato con successo come punto di partenza per scrivere il proprio driver personalizzato.
I driver Ultimeter ( ultimeter.py ) e WMR100 ( wmr100.py ) illustrano come comunicare rispettivamente con l'hardware seriale e USB. Mostrano anche diversi approcci per la decodifica dei dati. Tuttavia, sono piuttosto semplici.
Il driver per la serie Vantage è di gran lunga il più complicato. In realtà eredita più volte non solo da AbstractDevice , ma anche da StdService . Cioè, partecipa anche al motore come servizio.
Naturalmente, ci sono molte sottigliezze che sono state sorvolate in questa descrizione di alto livello. Se ti imbatti in problemi, cerca aiuto nel forum di sviluppo di weewx .
ESTENSIONI
Una caratteristica chiave di Weewx è la sua capacità di essere estesa installando estensioni di terze parti . Le estensioni sono un modo per impacchettare una o più personalizzazioni in modo che possano essere installate e distribuite come gruppo funzionale.
Le personalizzazioni in genere rientrano in una di queste categorie:
- • estensione dell'elenco di ricerca
- • modello
- • skin
- • servizio
- • generatore
- • driver
Dai un'occhiata al wiki di Weewx per un esempio di alcune delle estensioni disponibili.
Creazione di un'estensione
Ora che hai apportato alcune personalizzazioni, potresti voler condividere tali modifiche con altri utenti di Weewx. Inserisci le tue personalizzazioni in un'estensione per semplificare l'installazione, la rimozione e la distribuzione.
Ecco alcune linee guida per la creazione di estensioni:
- Le estensioni non devono modificare o dipendere da skin esistenti. Un'estensione dovrebbe includere il proprio skin autonomo per illustrare qualsiasi modello, estensione dell'elenco di ricerca o funzionalità del generatore.
- Le estensioni non dovrebbero modificare gli schemi del database. Se richiede dati non trovati nei database predefiniti, un'estensione dovrebbe fornire il proprio database e schema.
Sebbene un'estensione possa utilizzare un'altra estensione, fare attenzione a scrivere l'estensione dipendente in modo che fallisca normalmente. Ad esempio, uno skin potrebbe utilizzare i dati dell'estensione di previsione, ma cosa succede se l'estensione di previsione non è installata? Fai in modo che la skin visualizzi un messaggio "previsione non installata" ma che continui a funzionare.
Impacchettare un'estensione
La struttura di un'estensione rispecchia quella di Weewx stesso. Se le personalizzazioni includono una skin, l'estensione avrà una directory delle skin. Se le personalizzazioni includono codice Python, l'estensione avrà una directory bin/user .
Ogni estensione dovrebbe includere anche:
- • readme.txt : un riepilogo di ciò che fa l'estensione, un elenco di prerequisiti (se presenti) e le istruzioni per l'installazione manuale dell'estensione
- • changelog - un'enumerazione delle modifiche in ogni versione
- • install.py - codice python utilizzato da Weewx ExtensionInstaller
Ad esempio, ecco la struttura di una skin chiamata basic :
basic/ basic/changelog basic/install.py basic/readme.txt basic/skins/ basic/skins/basic/ basic/skins/basic/basic.css basic/skins/basic/current.inc basic/skins/basic/favicon .ico basic/skins/basic/hilo.inc basic/skins/basic/index.html.tmpl basic/skins/basic/skin.conf
Ecco la struttura di un'estensione dell'elenco di ricerca chiamata xstats :
xstats/ xstats/changelog xstats/install.py xstats/readme.txt xstats/bin/ xstats/bin/user/ xstats/bin/user/xstats.py
Vedere la directory delle estensioni del sorgente Weewx per esempi.
Per distribuire un'estensione, è sufficiente creare un archivio compresso della directory dell'estensione.
Ad esempio, crea l'archivio compresso per la skin di base in questo modo:
tar cvfz basic.tar.gz basic
Una volta che un'estensione è stata impacchettata, può essere installata utilizzando l' utilità wee_extension .
Valori standard
Quando possibile, un'estensione dovrebbe semplicemente funzionare , con un minimo di input da parte dell'utente. Allo stesso tempo, i parametri per le opzioni più frequentemente richieste dovrebbero essere facilmente accessibili e facili da modificare. Per le skin, ciò potrebbe significare parametrizzare le stringhe in [Labels] per una personalizzazione più semplice. Oppure potrebbe significare fornire parametri in [Extras] per controllare il comportamento della skin o per parametrizzare i collegamenti.
Alcuni parametri devono essere specificati e nessun valore predefinito sarebbe appropriato. Ad esempio, un uploader potrebbe richiedere un nome utente e una password oppure un driver potrebbe richiedere un numero di serie o un indirizzo IP. In questi casi, utilizzare un valore predefinito nella configurazione che richiederà ovviamente modifiche. Il nome utente predefinito potrebbe essere REPLACE_ME . Assicurarsi inoltre di aggiungere una voce di registro che indichi che la funzione è disabilitata fino a quando non viene specificato il valore.
Nel caso dei driver, utilizzare l'editor di configurazione per richiedere questo tipo di valore richiesto.
RIFERIMENTO: OPZIONI DI REPORT
Questa sezione contiene le opzioni disponibili nel file di configurazione della skin, skin.conf . Le stesse opzioni si applicano ai file di lingua trovati nella sottodirectory lang , come lang/en.conf per English .
Si consiglia di mettere
- • opzioni che controllano il comportamento della skin in skin.conf;
- • etichette e testi dipendenti dalla lingua nei file di lingua.
Vale la pena notare che, come il file di configurazione principale weewx.conf , UTF-8 viene utilizzato ovunque.
[Extra]
Questa sezione è disponibile per aggiungere eventuali tag statici che potresti voler utilizzare nei tuoi modelli.
Ad esempio, il file skin.conf per la skin Seasons include tre opzioni:
OPZIONE SKIN | TAG MODELLO |
radar_img | $Extra.radar_img |
URL_radar | $Extra.radar_url |
ID googleAnalytics | ID $Extras.googleAnalytics |
Se dai un'occhiata al modello radar.inc vedrai esempi di test per questi tag.
radar_img
Imposta su un URL per mostrare un'immagine radar locale per la tua regione.
radar_url
Se si fa clic sull'immagine radar, il browser andrà a questo URL. Questo di solito è usato per mostrare un'immagine radar più dettagliata, ravvicinata.
Ad esempio in Oregon, impostando le due opzioni su:
[Extra] radar_img = http://radar.weather.gov/ridge/lite/N0R/RTX_loop.gif radar_url = http://radar.weather.gov/ridge/radar.php?product=NCR&rid=RTX&loop=yes
si traduce in una bella immagine di un radar centrato su Portland, Oregon. Quando fai clic su di esso, ti dà una vista dettagliata e animata. Se vivi negli Stati Uniti, dai un'occhiata al sito web del radar NOAA per trovarne uno carino che funzioni per te. In altri paesi, dovrai consultare il tuo servizio meteorologico locale.
googleAnalyticsId
Se disponi di un ID Google Analytics , puoi impostarlo qui. Il codice Javascript di Google Analytics verrà quindi incluso, consentendo l'analisi dell'utilizzo del tuo sito web. Se commentato, il codice non verrà incluso.
Estendere [Extras]
Altri tag possono essere aggiunti in modo simile, comprese le sottosezioni. Ad esempio, supponi di aver aggiunto una videocamera e di voler aggiungere un fermo immagine con un collegamento ipertestuale a una pagina con il video. Vuoi che tutte queste opzioni siano ordinatamente contenute in una sottosezione.
[Extras] [[video]] still = video_capture.jpg hyperlink = http://www.eatatjoes.com/video.html
Quindi nel tuo modello potresti fare riferimento a questi come:
<a href="$Extras.video.hyperlink"> <img src="$Extras.video.still" alt="Cattura video"/> </a>
[Labels]
Questa sezione definisce varie etichette.
hemispheres
Elenco separato da virgole per le etichette da utilizzare per i quattro emisferi. Il valore predefinito è N, S, E, W .
latlon_formats
Elenco separato da virgole per la formattazione da utilizzare durante la conversione di latitudine e longitudine in stringhe. Dovrebbero esserci tre elementi:
- • Il formato da utilizzare per i gradi interi di latitudine
- • Il formato da utilizzare per i gradi interi di longitudine
- • Il formato da utilizzare per i minuti.
Ciò ti consente di decidere se desideri o meno zeri iniziali. Il valore predefinito include zeri iniziali ed è "%02d", "%03d", "%05.2f"
[[Generic]]
Questa sottosezione specifica le etichette predefinite da utilizzare per ciascun tipo di osservazione. Ad esempio, opzioni
inTemp = Temperatura all'interno della casa outTemp = Temperatura esterna UV = Indice UV
causerebbe l'utilizzo delle etichette fornite per i grafici di inTemp e outTemp . Se non viene fornita alcuna opzione, verrà utilizzato il tipo di osservazione stesso ( ad esempio , outTemp ).
[Almanac]
Questa sezione controlla quale testo usare per l'almanacco. Consiste in una sola voce
moon_phases
Questa opzione è un elenco separato da virgole di etichette da utilizzare per le otto fasi lunari. L'impostazione predefinita è Luna nuova, Luna crescente, Primo quarto, Gibbosa crescente, Luna piena, Gibbosa calante, Ultimo quarto, Luna calante.
[Units]
Questa sezione controlla come le unità vengono gestite e visualizzate.
[[Groups]]
Questa sottosezione elenca tutti i Gruppi di Unità e specifica quale unità di misura deve essere utilizzata per ognuno di essi.
Poiché ci sono molti diversi tipi di misurazione osservativa (come outTemp , barometer , ecc.) utilizzati in Weewx (più di 50 all'ultimo conteggio), sarebbe noioso, per non dire forse incoerente, specificare un diverso sistema di misurazione per ognuno di loro. All'estremo opposto, richiedere che tutti siano "US Custom" o "Metric" sembra eccessivamente restrittivo. Weewx ha preso una via di mezzo e ha diviso tutti i diversi tipi di osservazione in 12 diversi gruppi di unità . Un gruppo di unità è qualcosa come group_temperature . Rappresenta il sistema di misurazione utilizzato da tutti i tipi di osservazione misurati in temperatura, come la temperatura interna (type inTemp), la temperatura esterna ( outTemp), punto di rugiada (dewpoint), vento gelido ( windchill ) e così via. Se decidi che vuoi che il gruppo di unità group_temperature sia misurato in gradi_C , stai dicendo che tutti i membri del suo gruppo saranno riportati in gradi Celsius.
Si noti che l'unità di misura è sempre specificata al singolare. Ovvero, specifica degree_C o foot , non degrees_C o feet . Vedere l' Appendice: Unità per ulteriori informazioni, incluso un breve riepilogo dei gruppi, dei loro membri e delle opzioni che possono essere utilizzate per ciascun gruppo.
Quale unità di misura utilizzare per l'altitudine. Le opzioni possibili sono foot o meter.
group_direction
Quale unità di misura utilizzare per la direzione. L'unica opzione è degree_compass .
group_distance
Quale unità di misura utilizzare per la distanza (ad esempio per la corsa del vento). Le opzioni possibili sono mile o km.
group_moisture
L'unità di misura da utilizzare per l'umidità del suolo. L'unica opzione è il centibar .
group_percent
L'unità di misura da utilizzare per le percentuali. L'unica opzione è percent .
group_pressure
L'unità di misura da utilizzare per la pressione. Le opzioni possibili sono inHg (pollici di mercurio), mbar , hPa o kPa .
group_pressurerate
L'unità di misura da utilizzare per la velocità di variazione della pressione. Le opzioni possibili sono inHg_per_hour (pollici di mercurio all'ora), mbar_per_hour , hPa_per_hour o kPa_per_hour .
group_radiation
L'unità di misura da utilizzare per la radiazione. L'unica opzione è watt_per_meter_squared .
group_rain
L'unità di misura da utilizzare per le precipitazioni. Le opzioni sono inch , cm o mm .
group_rainrate
L'unità di misura da utilizzare per il tasso di precipitazione. Le opzioni possibili sono inch_per_hour , cm_per_hour o mm_per_hour .
group_speed
L'unità di misura da utilizzare per la velocità del vento. Le opzioni possibili sono mile_per_hour , km_per_hour , knot , meter_per_second o beaufort .
group_speed2
Questo gruppo è simile a group_speed , ma viene utilizzato per le velocità del vento calcolate che in genere hanno una risoluzione leggermente superiore. Le opzioni possibili sono one mile_per_hour2 , km_per_hour2 , knot2 o meter_per_second2 .
L'unità di misura da utilizzare per le temperature. Le opzioni sono degree_C , degree_E , degree_F o degree_K .
group_volt
L'unità di misura da utilizzare per le tensioni. L'unica opzione è volt .
[[StringFormats]]
Questa sottosezione viene utilizzata per specificare quale formato di stringa deve essere utilizzato per ciascuna unità quando una quantità deve essere convertita in una stringa. In genere, ciò accade con l'etichettatura dell'asse y sui grafici e per le statistiche nella generazione di file HTML. Ad esempio, le opzioni
degree_C = %.1f inch = %.2f
specificherebbe che i formati di stringa dati devono essere utilizzati quando si formatta qualsiasi temperatura misurata in gradi Celsius o qualsiasi quantità di precipitazione misurata in pollici, rispettivamente. I codici di formattazione sono quelli usati da Python e sono molto simili ai codici sprintf() di C.
È inoltre possibile specificare quale stringa utilizzare per una misurazione non valida o non disponibile (valore None ). Per esempio,
NONE = " N/A "
[[Labels]]
Questa sottosezione specifica quale etichetta deve essere utilizzata per ciascun tipo di unità di misura. Ad esempio, le opzioni
degree_F = °F inch = ' in'
farebbe sì che tutte le temperature abbiano etichette di unità °F e tutte le precipitazioni abbiano etichette in . Se devono essere utilizzati simboli speciali (come il segno di grado), devono essere codificati in UTF-8. Questo è generalmente ciò che la maggior parte degli editor di testo utilizza se si taglia e incolla da una mappa dei caratteri.
Se l'etichetta include due valori, si presume che il primo sia la forma singolare, il secondo quella plurale. Per esempio,
foot = " foot", " feet" ... day = " day", " days" hour = " hour", " hours" minute = " minute", " minutes" second = " second", " seconds"
[[TimeFormats]]
Questa sottosezione specifica il formato dell'ora da utilizzare per contesti temporali diversi . Ad esempio, potresti voler utilizzare un formato diverso per visualizzare l'ora di un giorno rispetto all'ora di un mese. Utilizza i formati strftime() . L'impostazione predefinita è simile a questa:
[[TimeFormats]] hour = %H:%M day = %X week = %X (%A) month = %x %X year = %x %X rainyear = %x %X current = %x %X ephem_day = %X ephem_year = %x %X
Gli identificatori %x , %X e %A codificano rispettivamente i nomi di data, ora e giorno della settimana dipendenti dalle impostazioni locali. Quindi, se imposti una variabile d'ambiente appropriata LANG , la data e l'ora dovrebbero seguire le convenzioni locali (vedi la sezione Variabile d'ambiente LANG per i dettagli su come farlo). Tuttavia, i risultati potrebbero non sembrare particolarmente gradevoli e potresti volerli modificare. Ad esempio, negli Stati Uniti:
[[TimeFormats]] # # Formati più attraenti che funzionano nella maggior parte dei paesi occidentali. # day = %H:%M week = %H:%M on %A month = %d-%b-%Y %H:%M year = %d-%b-%Y %H:%M rainyear = %d-%b-%Y %H:%M current = %d-%b-%Y %H:%M ephem_day = %H:%M ephem_year = %d-%b-%Y %H:%M
Gli ultimi due formati, ephem_day e ephem_year consentono di impostare la formattazione per gli orari dell'almanacco. Il primo, ephem_day , viene utilizzato per gli orari dell'almanacco all'interno della giornata, come l'alba o il tramonto. Il secondo, ephem_year , viene utilizzato per i tempi dell'almanacco all'interno dell'anno, come il prossimo equinozio o la luna piena.
[[Ordinates]]
directions
Impostare sulle abbreviazioni da utilizzare per le direzioni ordinali. Per impostazione predefinita, è N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW, N .
[[DegreeDays]]
heating_base
cooling_base
growing_base
Impostare sulla temperatura di base per il calcolo del riscaldamento, del raffreddamento e dei gradi giorno di crescita, insieme all'unità da utilizzare. Esempi:
heating_base = 65.0, degree_F cooling_base = 20.0, degree_C growing_base = 50.0, degree_
[[Trend]]
time_delta
Impostare sulla differenza di orario su cui si desidera calcolare le tendenze. Il valore predefinito è 3 ore.
time_grace
Durante la ricerca di un record precedente da utilizzare nel calcolo di una tendenza, verrà accettato un record compreso in questo intervallo di time_delta . L'impostazione predefinita è 300 secondi.
[Texts]
La sezione [Texts] contiene i testi statici utilizzati nei modelli. Generalmente ci sono più file di lingua, uno per ogni lingua supportata, denominati dai codici lingua definiti in ISO 639-1 . Le voci forniscono la traduzione dei testi nella lingua di destinazione. Per esempio,
[Texts] "Current Conditions" = "Aktuelle Werte"
causerebbe l'uso di "Aktuelle Werte" ogni volta che appare $gettext("Current Conditions". Vedere la sezione su $gettext .
Le stringhe che includono virgole devono essere racchiuse tra virgolette singole o doppie.
[CheetahGenerator]
Questa sezione contiene le opzioni per il generatore Cheetah. Si applica solo a skin.conf .
search_list
Questo è l'elenco degli oggetti dell'elenco di ricerca che verranno scansionati dal motore dei modelli, alla ricerca di tag. Vedere la sezione Definizione di nuovi tag e la documentazione di Cheetah per i dettagli sugli elenchi di ricerca. Se non viene specificato alcun search_list , verrà utilizzato un elenco predefinito.
search_list_extensions
Questo definisce uno o più oggetti dell'elenco di ricerca che verranno aggiunti a search_list . Ad esempio, se utilizzi le estensioni dell'elenco di ricerca "sette giorni" e "previsione", l'opzione avrà il seguente aspetto
search_list_extensions = user.seven_day.SevenDay, user.forecast.ForecastVariables
encoding
Mentre Cheetah esegue il modello, sostituisce le stringhe per tutti i valori dei tag. Questa opzione controlla quale codifica usare per le nuove stringhe. La codifica può essere scelta in base al file. Sono disponibili tutte le codifiche elencate nella documentazione di Python Codifiche standard , così come queste codifiche specifiche di Weewx:
CODIFICA | DESCRIZIONE |
html_entities | I caratteri non a 7 bit saranno rappresentati come entità HTML ( ad esempio , il segno di grado sarà rappresentato come ° ) |
strict_ascii | I caratteri non a 7 bit verranno ignorati. |
normalized_ascii | Sostituisci i caratteri accentati con analoghi non accentati ( ad esempio , 'ö' sarà sostituito con 'o'). |
La codifica html_entities è quella predefinita. Altre scelte comuni sono utf8 , cp1252 ( aka Windows-1252) e latin1 .
template
Il nome di un file modello. Un nome file modello deve terminare con .tmpl . I nomi dei file fanno distinzione tra maiuscole e minuscole. Se nel nome del file del modello sono presenti le lettere YYYY , MM , WW o DD , queste verranno sostituite rispettivamente con l'anno, il mese, la settimana e il giorno del mese. Quindi, un modello con il nome summary-YYYY-MM.html.tmpl avrebbe il nome summary-2010-03.html per il mese di marzo 2010.
generate_once
Se impostato su True , il modello viene elaborato solo alla prima chiamata del servizio del motore di report. Questa funzione è utile per i file che non cambiano quando cambiano i valori dei dati, come i file HTML che definiscono un layout. L'impostazione predefinita è False .
stale_age
Età di obsolescenza del file, in secondi. Se il file è più vecchio di questa età, verrà generato dal modello. Se non viene specificato stale_age , il file verrà generato ogni volta che viene eseguito il generatore.
Il controllo preciso su quando viene eseguito un report è disponibile tramite l'uso dell'opzione report_timing in weewx.conf . L' opzione report_timing utilizza un'impostazione simile a CRON per controllare con precisione quando viene eseguito un report. Vedere la sezione Pianificazione dei report per i dettagli sull'opzione report_timing .
[[SummaryByDay]]
La sezione SummaryByDay definisce alcuni comportamenti speciali. Ogni modello in questa sezione verrà utilizzato più volte, ogni volta con un intervallo di tempo giornaliero diverso. Assicurati di includere YYYY , MM e DD nel nome file di qualsiasi modello in questa sezione.
[[SummaryByMonth]]
La sezione SummaryByMonth definisce alcuni comportamenti speciali. Ogni modello in questa sezione verrà utilizzato più volte, ogni volta con un periodo di tempo mensile diverso. Assicurati di includere YYYY e MM nel nome file di qualsiasi modello in questa sezione.
[[SummaryByYear]]
La sezione SummaryByYear definisce alcuni comportamenti speciali. Ogni modello in questa sezione verrà utilizzato più volte, ogni volta con un periodo di tempo diverso all'anno. Assicurati di includere YYYY nel nome file di qualsiasi modello in questa sezione.
[ImageGenerator]
Questa sezione descrive le varie opzioni disponibili per il generatore di immagini.
Opzioni generali
Queste sono opzioni che influenzano l'immagine complessiva.
anti_alias
L'impostazione su 2 o più potrebbe dare un'immagine più nitida, con meno bordi frastagliati. La sperimentazione è d'obbligo. Il valore predefinito è 1 .
chart_background_color
Il colore di sfondo del grafico stesso. Opzionale. L'impostazione predefinita è #d8d8d8 .
chart_gridline_color
Il colore delle linee della griglia del grafico. Opzionale. L'impostazione predefinita è #a0a0a0
daynight_day_color
Il colore da utilizzare per la fascia diurna. Opzionale. L'impostazione predefinita è #ffffff .
daynight_edge_color
Il colore da utilizzare nella zona di transizione tra notte e giorno. Opzionale. L'impostazione predefinita è #efefef , un grigio medio.
daynight_night_color
Il colore da utilizzare per la fascia notturna. Opzionale. L'impostazione predefinita è #f0f0f0 , un grigio scuro.
image_background_color
Il colore di sfondo dell'intera immagine. Opzionale. L'impostazione predefinita è #f5f5f5 ("SmokeGray")
image_width
image_height
La larghezza e l'altezza dell'immagine in pixel. Opzionale. L'impostazione predefinita è 300 x 180 pixel.
show_daynight
Impostare su true per mostrare le bande giorno/notte in un'immagine. In caso contrario, impostare su false. Questo va bene solo con trame giornaliere o settimanali. Opzionale. L'impostazione predefinita è false .
skip_if_empty
Se impostato su true , ignora la generazione dell'immagine se tutti i dati in essa contenuti sono nulli. Se impostato su un periodo di tempo, ad esempio month o year , salta la generazione dell'immagine se tutti i dati in quel periodo sono nulli. L'impostazione predefinita è false .
stale_age
Età di obsolescenza del file immagine, in secondi. Se il file immagine è più vecchio di questa età, verrà generato. Se non viene specificato stale_age , il file immagine verrà generato ogni volta che viene eseguito il generatore.
unit
Normalmente, l'unità utilizzata in un grafico è impostata da qualsiasi gruppo di unità in cui si trovano i tipi . Tuttavia, questa opzione consente di ignorare l'unità utilizzata in un grafico specifico.
Varie opzioni di etichetta
Queste sono le opzioni per le varie etichette utilizzate nell'immagine.
axis_label_font_color
Il colore del carattere dell'etichetta dell'asse x e y. Opzionale. L'impostazione predefinita è il nero .
axis_label_font_path
Il percorso del font da utilizzare per le etichette degli assi x e y. Opzionale. Se non viene fornito, o se Weewx non riesce a trovare il font, verrà utilizzato il font PIL predefinito.
axis_label_font_size
La dimensione delle etichette degli assi x e y in pixel. Opzionale. Il valore predefinito è 10 .
bottom_label_font_color
Il colore del carattere dell'etichetta inferiore. Opzionale. L'impostazione predefinita è il nero .
bottom_label_font_path
Il percorso del carattere da utilizzare per l'etichetta inferiore. Opzionale. Se non viene fornito, o se Weewx non riesce a trovare il font, verrà utilizzato il font PIL predefinito.
bottom_label_font_size
La dimensione dell'etichetta inferiore in pixel. Opzionale. Il valore predefinito è 10 .
bottom_label_format
Il formato da utilizzare per l'etichetta inferiore. Dovrebbe essere un formato strftime . Opzionale. Il valore predefinito è '%m/%d/%y %H:%M' .
bottom_label_offset
Il margine dell'etichetta inferiore dal fondo della trama. Il valore predefinito è 3.
top_label_font_path
Il percorso del carattere da utilizzare per l'etichetta superiore. Opzionale. Se non viene fornito, o se Weewx non riesce a trovare il font, verrà utilizzato il font PIL predefinito.
top_label_font_size
La dimensione dell'etichetta superiore in pixel. Opzionale. Il valore predefinito è 10 .
unit_label_font_color
Il colore del carattere dell'etichetta dell'unità. Opzionale. L'impostazione predefinita è il nero .
unit_label_font_path
Il percorso del carattere da utilizzare per l'etichetta dell'unità. Opzionale. Se non viene fornito, o se Weewx non riesce a trovare il font, verrà utilizzato il font PIL predefinito.
unit_label_font_size
La dimensione dell'etichetta dell'unità in pixel. Opzionale. Il valore predefinito è 10 .
x_interval
L'intervallo di tempo in secondi tra i segni di graduazione dell'asse x. Opzionale. Se non fornito, verrà scelto un valore predefinito adeguato.
x_label_format
Il formato da utilizzare per le etichette temporali sull'asse x. Dovrebbe essere un formato strftime . Opzionale. Se non fornito, verrà scelto automaticamente un formato ragionevole.
x_label_spacing
Specifica l'incremento ordinale tra le etichette sull'asse x: ad esempio, 3 indica un'etichetta ogni 3 segni di graduazione. Opzionale. Il valore predefinito è 2 .
y_label_side
Specifica se le etichette dell'asse y devono trovarsi a sinistra, a destra o su entrambi i lati del grafico. I valori validi sono sinistra , destra o entrambi . Opzionale. L'impostazione predefinita è sinistra .
y_label_spacing
Specifica l'incremento ordinale tra le etichette sull'asse y: ad esempio, 3 indica un'etichetta ogni 3 segni di graduazione. Opzionale. Il valore predefinito è 2 .
y_nticks
Il numero nominale di tick lungo l'asse y. Il valore predefinito è 10 .
Opzioni di ridimensionamento del grafico
time_length
La durata nominale del periodo di tempo da coprire in secondi. La lunghezza esatta dell'asse x viene scelta dal motore grafico per coprire questo periodo. Opzionale. Il valore predefinito è 86400 (un giorno).
yscale
Una tupla a 3 vie ( ylow , yhigh , min_interval ), dove ylow e yhigh sono rispettivamente i valori minimo e massimo dell'asse y e min_interval è l'intervallo di tick minimo. Se impostato su None , verrà scelto automaticamente il valore corrispondente. Opzionale. Il valore predefinito è None, None, None . (Scegli automaticamente l'incremento minimo, massimo e minimo dell'asse y.)
Opzioni rosa dei venti
rose_label
L'etichetta da utilizzare nella rosa dei venti per indicare il nord. Opzionale. L' impostazione predefinita è N.
rose_label_font_path
Il percorso del carattere da utilizzare per l'etichetta della rosa (la lettera "N", che indica il nord). Opzionale. Se non viene fornito, o se Weewx non riesce a trovare il font, verrà utilizzato il font PIL predefinito.
rose_label_font_size
La dimensione dell'etichetta della rosa dei venti in pixel. Opzionale. Il valore predefinito è 10 .
rose_label_font_color
Il colore dell'etichetta della rosa dei venti. Opzionale. L'impostazione predefinita è dello stesso colore della rosa stessa.
vector_rotate
Fa ruotare i vettori di questo numero di gradi. Positivo è in senso orario. Se i venti occidentali dominano nella tua posizione, allora potresti voler specificare +90 per questa opzione. Ciò farà sì che il vettore medio punti verso l'alto, piuttosto che giacere piatto contro l'asse x. Opzionale. Il valore predefinito è 0 .
Opzioni di linea di trama condivise
Queste sono opzioni condivise da tutte le trame.
chart_line_colors
Ogni linea del grafico è disegnata in un colore diverso. Questa opzione è un elenco di quei colori. Se il numero di righe supera la lunghezza dell'elenco, i colori vanno a capo fino all'inizio dell'elenco. Opzionale. Nel caso dei grafici a barre, questo è il colore del contorno della barra. Il valore predefinito è #0000ff, #00ff00, #ff0000 .
Il colore della singola linea può essere sovrascritto utilizzando l'opzione color .
chart_fill_colors
Un elenco del colore da utilizzare come riempimento dei grafici a barre. Opzionale. L'impostazione predefinita prevede l'utilizzo dello stesso colore del colore del contorno (opzione chart_line_colors ).
chart_line_width
Ciascuna linea del grafico può essere disegnata utilizzando uno spessore di linea diverso. Questa opzione è un elenco di queste larghezze. Se il numero di righe supera la lunghezza dell'elenco, le larghezze vanno a capo fino all'inizio dell'elenco. Opzionale. Il valore predefinito è 1, 1, 1 .
Le singole larghezze di linea possono essere sovrascritte utilizzando l'opzione width .
Opzioni di linea individuali
Si tratta di opzioni impostate per le singole linee.
aggregate_interval
Il periodo di tempo in cui i dati devono essere aggregati, in secondi. Obbligatorio se aggregate_type è stato impostato. In alternativa, l'ora può essere specificata utilizzando una delle "scorciatoie" (ovvero hour, day, week, month, o year).
aggregate_type
L'impostazione predefinita è tracciare ogni punto dati, ma probabilmente non è una buona idea per grafici più lunghi di un giorno. Impostando questa opzione, è possibile aggregare i dati in base a un intervallo di tempo prestabilito. I tipi di aggregazione disponibili includono avg , count , cumulative , diff , last , max , min , sum e tderiv .
color
Questa opzione consente di ignorare il colore per una singola linea. Opzionale. L'impostazione predefinita è utilizzare il colore in chart_line_colors .
data_type
Il tipo di dati SQL da utilizzare per questa linea di trama. Per ulteriori informazioni, vedere la sezione Includere un tipo più di una volta in un grafico . Opzionale. L'impostazione predefinita prevede l'utilizzo del nome della sezione.
fill_color
Questa opzione consente di ignorare il colore di riempimento per un grafico a barre. Opzionale. L'impostazione predefinita è utilizzare il colore in chart_fill_colors .
label
L'etichetta da utilizzare per questa linea di trama nell'etichetta superiore. Opzionale. L'impostazione predefinita prevede l'utilizzo del nome della variabile SQL.
line_gap_fraction
Se c'è uno spazio tra i punti dati più grande di questa quantità frazionaria dell'asse x, allora verrà disegnato uno spazio, piuttosto che una linea di collegamento. Vedere la sezione Interruzioni di linea . Opzionale. L'impostazione predefinita è tracciare sempre la linea.
line_type
Il tipo di linea da utilizzare. Le scelte sono solide o nessuna . Opzionale. L'impostazione predefinita è solido .
marker_size
La dimensione del marcatore. Opzionale. Il valore predefinito è 8 .
marker_type
Il tipo di indicatore da utilizzare per contrassegnare ciascun punto dati. Le scelte sono cross , x , circle , box o none . Opzionale. L'impostazione predefinita è none .
plot_type
Il tipo di trama per questa linea. Le scelte sono line, bar, o vector. Opzionale. L'impostazione predefinita è line .
width
Questa opzione consente di sovrascrivere lo spessore della linea per una singola linea. Opzionale. L'impostazione predefinita è utilizzare la larghezza in chart_line_width .
[CopyGenerator]
Questa sezione è utilizzata dal generatore weewx.reportengine.CopyGenerator e controlla quali file devono essere copiati dalla directory skin alla directory di destinazione. Pensala come "generazione di file", tranne per il fatto che invece di passare attraverso il motore dei modelli, i file vengono semplicemente copiati.
copy_once
Questa opzione controlla quali file vengono copiati alla prima chiamata del servizio del motore di report. In genere, si tratta di cose come fogli di stile o GIF di sfondo. È possibile utilizzare i caratteri jolly.
copy_always
Questo è un elenco di file che devono essere copiati a ogni chiamata. È possibile utilizzare i caratteri jolly.
Ecco la sezione [CopyGenerator] da Standard skin.conf
[CopyGenerator] # Questa sezione è utilizzata dal generatore CopyGenerator # Elenco dei file da copiare solo la prima volta che il generatore esegue copy_once = backgrounds/*, weewx.css, mobile.css, favicon.ico # Elenco dei file da copiare ogni volta che il generatore viene eseguito # copy_always =
La skin Standard include alcune immagini di sfondo, file CSS e icone che devono essere copiate una volta. Non ci sono file che devono essere copiati ogni volta che il generatore viene eseguito.
[Generators]
Questa sezione definisce l'elenco dei generatori che devono essere eseguiti.
generator_list
Questa opzione controlla quali generatori vengono eseguiti per questa skin. È un elenco separato da virgole. I generatori funzioneranno in questo ordine.
Ecco la sezione [Generators] da Standard skin.conf
[Generators] generator_list = weewx.cheetahgenerator.CheetahGenerator, weewx.imagegenerator.ImageGenerator, weewx.reportengine.CopyGenerator
La skin Standard utilizza tre generatori: CheetahGenerator, ImageGenerator e CopyGenerator.
APPENDICE
Tipi di aggregazione
TIPO | DESCRIZIONE |
avg | Il valore medio nel periodo di aggregazione. |
avg_ge(val) | Il numero di giorni in cui il valore medio è maggiore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
avg_le(val) | Il numero di giorni in cui il valore medio è minore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
count | Il numero di valori non nulli nel periodo di aggregazione. |
diff | La differenza tra l'ultimo e il primo valore nel periodo di aggregazione. |
exists | Restituisce True se il tipo di osservazione esiste nel database. |
first | Il primo valore diverso da null nel periodo di aggregazione. |
firsttime | L'ora del primo valore diverso da null nel periodo di aggregazione. |
gustdir | La direzione della raffica massima nel periodo di aggregazione. |
has_data | Restituisce True se il tipo di osservazione esiste nel database ed è diverso da null. |
last | L'ultimo valore diverso da null nel periodo di aggregazione. |
lasttime | L'ora dell'ultimo valore diverso da null nel periodo di aggregazione. |
max | Il valore massimo nel periodo di aggregazione. |
maxmin | Il minimo giornaliero massimo nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
maxmintime | Il tempo del minimo giornaliero massimo. |
maxsum | La somma giornaliera massima nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
maxsumtime | L'ora della somma massima giornaliera. |
maxtime | Il tempo del valore massimo. |
max_ge(val) | Il numero di giorni in cui il valore massimo è maggiore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
max_le(val) | Il numero di giorni in cui il valore massimo è minore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
meanmax | Il massimo giornaliero medio nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
meanmin | Il minimo giornaliero medio nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
min | Il valore minimo nel periodo di aggregazione. |
minmax | Il minimo massimo giornaliero nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
minmaxtime | Il tempo del minimo massimo giornaliero. |
minsum | La somma giornaliera minima nel periodo di aggregazione. Il periodo di aggregazione deve essere di un giorno o più. |
minsumtime | Il tempo della somma minima giornaliera. |
mintime | Il tempo del valore minimo. |
min_ge(val) | Il numero di giorni in cui il valore minimo è maggiore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
min_le(val) | Il numero di giorni in cui il valore minimo è minore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
not_null | Restituisce true se qualsiasi valore nel periodo di aggregazione non è nullo. |
rms | Il valore quadratico medio nel periodo di aggregazione. |
sum | La somma dei valori nel periodo di aggregazione. |
sum_ge(val) | Il numero di giorni in cui la somma di value è maggiore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
sum_le(val) | Il numero di giorni in cui la somma di value è minore o uguale a val . Il periodo di aggregazione deve essere di un giorno o più. L'argomento val è un ValueTuple . |
tderiv | La derivata temporale tra l'ultimo e il primo valore nel periodo di aggregazione. Questa è la differenza di valore divisa per la differenza di tempo. |
vecavg | La velocità media del vettore nel periodo di aggregazione. |
vecdir | La direzione mediata dal vettore durante il periodo di aggregazione. |
Unità
Weewx offre tre diversi sistemi di unità :
NOME | VALORE CODIFICATO | DESCRIZIONE |
US | 0x01 | Consuetudine USA |
METRICWX | 0x11 | Sistema metrico, con misurazioni relative alla pioggia in mm e velocità in m/s |
METRIC | 0x10 | Sistema metrico, con misurazioni relative alla pioggia in cm e velocità in km/h |
La tabella seguente elenca tutti i gruppi di unità, i loro membri, quali unità sono opzioni per il gruppo e quali sono le impostazioni predefinite per ciascun sistema di unità standard.
- - - Per ragioni di spazio la tabella non è riportata, la si può consultare nella guida sul sito weewx.com, sezione Appendix/Units - - -
Classe ValueTuple
Un valore, insieme all'unità in cui si trova, può essere rappresentato da una tupla a 3 vie chiamata "tupla di valori". Sono usati in tutto Weewx. Tutte le routine di Weewx possono accettare una semplice tupla disadorna a 3 vie come tupla di valori, ma restituiscono il tipo ValueTuple . È utile perché è possibile accedere al suo contenuto utilizzando attributi denominati. Puoi pensarlo come un valore consapevole dell'unità, utile per la conversione da e verso altre unità.
Sono presenti i seguenti attributi e il relativo indice:
INDICE | ATTRIBUTO | DESCRIZIONE |
0 | value | Il/i valore/i dei dati. Può essere una serie (ad esempio, [20.2, 23.2, ...] ) o uno scalare (ad esempio, 20.2 ) |
1 | unit | L'unità in cui si trova ( "degree_C" ) |
2 | group | Il gruppo di unità ( "group_temperature" ) |
È valido avere un valore dato pari a None.
È anche valido avere un tipo di unità None (ovvero non ci sono informazioni sull'unità in cui si trova il valore). In questo caso, non sarai in grado di convertirlo in un'altra unità.
Ecco alcuni esempi:
from weewx.units import ValueTuple freezing_vt = ValueTuple(0.0, "degree_C", "group_temperature") body_temperature_vt = ValueTuple(98.6, "degree_F", group_temperature") station_altitude_vt = ValueTuple(120.0, "meter", "group_altitude")
Classe ValueHelper
La classe ValueHelper contiene tutte le informazioni necessarie per eseguire la corretta formattazione di un valore, inclusa un'etichetta di unità.
Attributo di istanza
ValueHelper.value_t
Restituisce l' istanza ValueTuple conservata internamente.
Metodi di istanza
ValueHelper.__str__()
Formatta il valore come stringa, inclusa un'etichetta di unità, e lo restituisce.
ValueHelper.format(format_string=None, None_string=None, add_label=True, localize=True)
Formatta il valore come stringa, utilizzando varie opzioni specificate, e lo restituisce. Se non diversamente specificato, è inclusa un'etichetta.
format_string - Una stringa da utilizzare per la formattazione. Deve includere uno e un solo identificatore di formato .
None_string - Nel caso di un valore di Python None, questa stringa verrà sostituita. Se None, verrà utilizzata una stringa predefinita da skin.conf .
add_label - Se veritiero, verrà allegata un'etichetta di unità appropriata. In caso contrario, non viene allegata alcuna etichetta.
localize - Se veritiero, i risultati saranno localizzati. Ad esempio, in alcune impostazioni locali, verrà utilizzata una virgola come identificatore decimale.