pywws.WeatherStation

Ottenere i dati da stazioni meteo compatibili con WH1080/WH3080.

Derivato da wwsr.c by Michael Pendec (michael.pendec@gmail.com), wwsrdump.c by Svend Skafte (svend@skafte.net), modificato da Dave Wells, e altre fonti.

Introduzione

Questo è il modulo che in realtà comunica con l’unità di base della stazione meteo. Non ho molta comprensione dell’ USB, quindi copiato molto dal programma in C wwsr di Michael Pendec’s

La memoria della stazione meteo è divisa in due parti: “fixed block” di 256 byte e un buffer circolare di 65280 byte. Siccome ogni stringa prende 16 byte la stazione può immagazzinare 4080 letture, o 14 giorni di letture di intervallo di 5 minuti. (Le stazioni tipo 3080 memorizzano 20 byte per la stringa, quindi memorizzano un massimo di 3264). Siccome lettura dei dati è in blocchi di 32 byte, ma ogni lettura meteo è 16 o 20 byte, una piccola cache viene utilizzata per ridurre il traffico USB. Il comportamento di memorizzazione nella cache può essere esclusa con il parametro unbuffered in get_data e get_raw_data.

La decodifica dei dati è controllato da dizionari statici reading_format, lo_fix_format e fixed_format. Le chiavi sono i nomi di elementi di dati e i valori possono essere di tipo (offset, type, multiplier) o un altro dizionario. Così, per esempio, la voce del dizionario reading_format 'rain' : (13, 'us', 0.3) significa che il valore di pioggia è un breve short senza segno (due byte), 13 byte dall’inizio del blocco e deve essere moltiplicato per 0,3 per ottenere un valore utile.

L’uso di dizionari annidati nel dizionario fixed_format permette utili sottoinsiemi di dati per essere decodificati. Ad esempio, per decodificare l’intero blocco get_fixed_block viene chiamato senza parametri

ws = WeatherStation.weather_station()
print ws.get_fixed_block()

Per ottenere la temperatura esterna minima memorizzata, è chiamato get_fixed_block con una sequenza di comandi:

ws = WeatherStation.weather_station()
print ws.get_fixed_block(['min', 'temp_out', 'val'])

Spesso non non c’è nessun obbligo di leggere e decodificare l’intero blocco, siccome i primi 64 byte contengono i dati più utili: l’intervallo dei valori memorizzati, l’indirizzo del buffer dove è memorizzata la lettura corrente e l’ora della data corrente. Il metodo get_lo_fix_block fornisce facile accesso a questi dati.

Per ulteriori esempi di utilizzo del modulo WeatherStation, consultare il programma TestWeatherStation.

Dettagli API

Funzioni

decode_status(status)

Classi

CUSBDrive()

Interfaccia di basso livello della stazione meteo tramite USB.

USBDevice(vendor_id, product_id)

Basso livello di accesso al dispositivo USB tramite la libreria hidapi.

datetime(year, month, day[, hour[, minute[, ...) The year, month and day arguments are required.
weather_station([ws_type, params, status, avoid])

Classe che rappresenta la stazione meteorologica nel programma utente.

pywws.WeatherStation.decode_status(status)[sorgente]
class pywws.WeatherStation.CUSBDrive[sorgente]

Interfaccia di basso livello della stazione meteo tramite USB.

Liberamente ispirato su una classe C++ ottenuta da http://site.ambientweatherstore.com/easyweather/ws_1080_2080_protocol.zip.Non so la provenienza di questo, ma sembra che siano venuti dal produttore.

EndMark = 32
ReadCommand = 161
WriteCommand = 160
WriteCommandWord = 162
read_block(address)[sorgente]

Legge 32 byte dalla stazione meteo.

Se la lettura non riesce per qualche motivo, None viene restituito.

Parametri:address (int) – Indirizzo di lettura da.
Ritorna:I dati della stazione meteo.
Tipo di ritorno:
 list(int)
write_byte(address, data)[sorgente]

Scrive un singolo byte sulla stazione meteo.

Parametri:
  • address (int) – Indirizzo di scrittura su.
  • data (int) – il valore da scrivere.
Ritorna:

eseguito con successo.

Tipo di ritorno:
 

bool

class pywws.WeatherStation.weather_station(ws_type='1080', params=None, status=None, avoid=3.0)[sorgente]

Classe che rappresenta la stazione meteorologica nel programma utente.

Connettersi alla stazione metereologica e preparare per la lettura dei dati.

min_pause = 0.5
margin = 0.9
live_data(logged_only=False)[sorgente]
inc_ptr(ptr)[sorgente]

Ottenere il puntatore ai dati successivi del buffer circolare.

dec_ptr(ptr)[sorgente]

Ottenere il puntatore ai dati precedenti nel buffer circolare.

get_raw_data(ptr, unbuffered=False)[sorgente]

Ottiene i dati grezzi (raw) dal buffer circolare.

Se ‘unbuffered’ è false, potrebbe essere restituito un valore memorizzato nella cache, che è stato ottenuto in precedenza.

get_data(ptr, unbuffered=False)[sorgente]

Ottiene i dati decodificati dal buffer circolare.

Se ‘unbuffered’ è false, potrebbe essere restituito un valore memorizzato nella cache, che è stato ottenuto in precedenza.

current_pos()[sorgente]

Ottiene la posizione del buffer circolare dove sono scritti dati correnti.

get_raw_fixed_block(unbuffered=False)[sorgente]

Ottiene il grezzo (raw) “fixed block” di impostazioni e dati di min/max.

get_fixed_block(keys=[], unbuffered=False)[sorgente]

Ottiene decodificato “fixed block” di impostazioni e dati di min/max.

Per selezionare un sottoinsieme di tutto il blocco tasti.

write_data(data)[sorgente]

Scrive una serie di byte singoli sulla stazione meteo. Dati devono essere una matrice di coppie (ptr, value).

reading_format = {'3080': {'status': (15, 'pb', None), 'hum_out': (4, 'ub', None), 'wind_gust': (10, 'wg', 0.1), 'uv': (19, 'ub', None), 'wind_ave': (9, 'wa', 0.1), 'rain': (13, 'us', 0.3), 'temp_in': (2, 'ss', 0.1), 'illuminance': (16, 'u3', 0.1), 'abs_pressure': (7, 'us', 0.1), 'delay': (0, 'ub', None), 'hum_in': (1, 'ub', None), 'temp_out': (5, 'ss', 0.1), 'wind_dir': (12, 'ub', None)}, '1080': {'status': (15, 'pb', None), 'wind_ave': (9, 'wa', 0.1), 'rain': (13, 'us', 0.3), 'hum_in': (1, 'ub', None), 'temp_out': (5, 'ss', 0.1), 'wind_dir': (12, 'ub', None), 'hum_out': (4, 'ub', None), 'wind_gust': (10, 'wg', 0.1), 'temp_in': (2, 'ss', 0.1), 'delay': (0, 'ub', None), 'abs_pressure': (7, 'us', 0.1)}}
lo_fix_format = {'alarm_1': (21, 'bf', ('bit0', 'time', 'wind_dir', 'bit3', 'hum_in_lo', 'hum_in_hi', 'hum_out_lo', 'hum_out_hi')), 'alarm_3': (23, 'bf', ('temp_in_lo', 'temp_in_hi', 'temp_out_lo', 'temp_out_hi', 'wind_chill_lo', 'wind_chill_hi', 'dew_point_lo', 'dew_point_hi')), 'alarm_2': (22, 'bf', ('wind_ave', 'wind_gust', 'rain_hour', 'rain_day', 'pressure_abs_lo', 'pressure_abs_hi', 'pressure_rel_lo', 'pressure_rel_hi')), 'data_changed': (26, 'ub', None), 'settings_1': (17, 'bf', ('temp_in_F', 'temp_out_F', 'rain_in', 'bit3', 'bit4', 'pressure_hPa', 'pressure_inHg', 'pressure_mmHg')), 'settings_2': (18, 'bf', ('wind_mps', 'wind_kmph', 'wind_knot', 'wind_mph', 'wind_bft', 'bit5', 'bit6', 'bit7')), 'read_period': (16, 'ub', None), 'unknown_01': (25, 'pb', None), 'timezone': (24, 'sb', None), 'data_count': (27, 'us', None), 'current_pos': (30, 'us', None), 'display_2': (20, 'bf', ('temp_out_temp', 'temp_out_chill', 'temp_out_dew', 'rain_hour', 'rain_day', 'rain_week', 'rain_month', 'rain_total')), 'display_3': (29, 'bf', ('illuminance_fc', 'bit1', 'bit2', 'bit3', 'bit4', 'bit5', 'bit6', 'bit7')), 'display_1': (19, 'bf', ('pressure_rel', 'wind_gust', 'clock_12hr', 'date_mdy', 'time_scale_24', 'show_year', 'show_day_name', 'alarm_time'))}
fixed_format = {'alarm_1': (21, 'bf', ('bit0', 'time', 'wind_dir', 'bit3', 'hum_in_lo', 'hum_in_hi', 'hum_out_lo', 'hum_out_hi')), 'alarm_3': (23, 'bf', ('temp_in_lo', 'temp_in_hi', 'temp_out_lo', 'temp_out_hi', 'wind_chill_lo', 'wind_chill_hi', 'dew_point_lo', 'dew_point_hi')), 'alarm_2': (22, 'bf', ('wind_ave', 'wind_gust', 'rain_hour', 'rain_day', 'pressure_abs_lo', 'pressure_abs_hi', 'pressure_rel_lo', 'pressure_rel_hi')), 'data_changed': (26, 'ub', None), 'max': {'windchill': {'date': (181, 'dt', None), 'val': (110, 'ss', 0.1)}, 'dewpoint': {'date': (191, 'dt', None), 'val': (114, 'ss', 0.1)}, 'wind_ave': {'date': (221, 'dt', None), 'val': (126, 'us', 0.1)}, 'rain': {'week': {'date': (241, 'dt', None), 'val': (134, 'us', 0.3)}, 'total': {'date': (251, 'dt', None), 'val': (138, 'us', 0.3)}, 'day': {'date': (236, 'dt', None), 'val': (132, 'us', 0.3)}, 'hour': {'date': (231, 'dt', None), 'val': (130, 'us', 0.3)}, 'month': {'date': (246, 'dt', None), 'val': (136, 'us', 0.3)}}, 'rel_pressure': {'date': (211, 'dt', None), 'val': (122, 'us', 0.1)}, 'hum_in': {'date': (141, 'dt', None), 'val': (98, 'ub', None)}, 'temp_out': {'date': (171, 'dt', None), 'val': (106, 'ss', 0.1)}, 'hum_out': {'date': (151, 'dt', None), 'val': (100, 'ub', None)}, 'wind_gust': {'date': (226, 'dt', None), 'val': (128, 'us', 0.1)}, 'uv': {'val': (93, 'ub', None)}, 'temp_in': {'date': (161, 'dt', None), 'val': (102, 'ss', 0.1)}, 'illuminance': {'val': (94, 'u3', 0.1)}, 'abs_pressure': {'date': (201, 'dt', None), 'val': (118, 'us', 0.1)}}, 'settings_1': (17, 'bf', ('temp_in_F', 'temp_out_F', 'rain_in', 'bit3', 'bit4', 'pressure_hPa', 'pressure_inHg', 'pressure_mmHg')), 'settings_2': (18, 'bf', ('wind_mps', 'wind_kmph', 'wind_knot', 'wind_mph', 'wind_bft', 'bit5', 'bit6', 'bit7')), 'read_period': (16, 'ub', None), 'rel_pressure': (32, 'us', 0.1), 'unknown_01': (25, 'pb', None), 'unknown_18': (97, 'pb', None), 'timezone': (24, 'sb', None), 'display_1': (19, 'bf', ('pressure_rel', 'wind_gust', 'clock_12hr', 'date_mdy', 'time_scale_24', 'show_year', 'show_day_name', 'alarm_time')), 'date_time': (43, 'dt', None), 'data_count': (27, 'us', None), 'min': {'hum_out': {'date': (156, 'dt', None), 'val': (101, 'ub', None)}, 'dewpoint': {'date': (196, 'dt', None), 'val': (116, 'ss', 0.1)}, 'abs_pressure': {'date': (206, 'dt', None), 'val': (120, 'us', 0.1)}, 'windchill': {'date': (186, 'dt', None), 'val': (112, 'ss', 0.1)}, 'hum_in': {'date': (146, 'dt', None), 'val': (99, 'ub', None)}, 'temp_out': {'date': (176, 'dt', None), 'val': (108, 'ss', 0.1)}, 'rel_pressure': {'date': (216, 'dt', None), 'val': (124, 'us', 0.1)}, 'temp_in': {'date': (166, 'dt', None), 'val': (104, 'ss', 0.1)}}, 'display_2': (20, 'bf', ('temp_out_temp', 'temp_out_chill', 'temp_out_dew', 'rain_hour', 'rain_day', 'rain_week', 'rain_month', 'rain_total')), 'display_3': (29, 'bf', ('illuminance_fc', 'bit1', 'bit2', 'bit3', 'bit4', 'bit5', 'bit6', 'bit7')), 'alarm': {'windchill': {'lo': (62, 'ss', 0.1), 'hi': (60, 'ss', 0.1)}, 'dewpoint': {'lo': (66, 'ss', 0.1), 'hi': (64, 'ss', 0.1)}, 'wind_ave': {'ms': (77, 'ub', 0.1), 'bft': (76, 'ub', None)}, 'rain': {'day': (85, 'us', 0.3), 'hour': (83, 'us', 0.3)}, 'rel_pressure': {'lo': (74, 'us', 0.1), 'hi': (72, 'us', 0.1)}, 'hum_in': {'lo': (49, 'ub', None), 'hi': (48, 'ub', None)}, 'temp_out': {'lo': (58, 'ss', 0.1), 'hi': (56, 'ss', 0.1)}, 'wind_dir': (82, 'ub', None), 'hum_out': {'lo': (55, 'ub', None), 'hi': (54, 'ub', None)}, 'wind_gust': {'ms': (80, 'ub', 0.1), 'bft': (79, 'ub', None)}, 'uv': (92, 'ub', None), 'temp_in': {'lo': (52, 'ss', 0.1), 'hi': (50, 'ss', 0.1)}, 'illuminance': (89, 'u3', 0.1), 'abs_pressure': {'lo': (70, 'us', 0.1), 'hi': (68, 'us', 0.1)}, 'time': (87, 'tt', None)}, 'current_pos': (30, 'us', None), 'lux_wm2_coeff': (36, 'us', 0.1), 'abs_pressure': (34, 'us', 0.1)}
data_start = 256
reading_len = {'3080': 20, '1080': 16}