Add support for Fine Offset WH3080 weather station.
This commit is contained in:
parent
e6608c4f2e
commit
1ca9779307
3 changed files with 256 additions and 129 deletions
1
AUTHORS
1
AUTHORS
|
@ -19,3 +19,4 @@ Baruch Even <baruch@ev-en.org>
|
|||
Andrea <andrea@andreaaizza.com>
|
||||
Helge Weissig <helgew@grajagan.org>
|
||||
Robert Fraczkiewicz <aromring@gmail.com>
|
||||
Nicola Quiriti <nik@wifi4all.it>
|
||||
|
|
|
@ -113,7 +113,7 @@ Supported device protocols:
|
|||
[29] Chuango Security Technology
|
||||
[30] Generic Remote SC226x EV1527
|
||||
[31] TFA-Twin-Plus-30.3049 and Ea2 BL999
|
||||
[32] Fine Offset WH1080 Weather Station
|
||||
[32] Fine Offset Electronics WH1080/WH3080 Weather Station
|
||||
[33] WT450
|
||||
[34] LaCrosse WS-2310 Weather Station
|
||||
[35] Esperanza EWS
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
|
||||
/*
|
||||
* *** Fine Offset WH1080 Weather Station ***
|
||||
* (aka Watson W-8681)
|
||||
* (aka Digitech XC0348 Weather Station)
|
||||
* (aka PCE-FWS 20)
|
||||
* (aka Elecsa AstroTouch 6975)
|
||||
* (aka Froggit WH1080)
|
||||
* (aka .....)
|
||||
* *** Fine Offset WH1080/WH3080 Weather Station ***
|
||||
*
|
||||
* This module is based on Stanisław Pitucha ('viraptor' https://github.com/viraptor ) earl code for the Digitech XC0348
|
||||
* This module is based on Stanisław Pitucha ('viraptor' https://github.com/viraptor ) code stub for the Digitech XC0348
|
||||
* Weather Station, which seems to be a rebranded Fine Offset WH1080 Weather Station.
|
||||
*
|
||||
* Some info and code derived from Kevin Sangelee's page:
|
||||
|
@ -16,9 +10,18 @@
|
|||
*
|
||||
* See also Frank 'SevenW' page ( https://www.sevenwatt.com/main/wh1080-protocol-v2-fsk/ ) for some other useful info.
|
||||
*
|
||||
* I only have re-elaborated and merged their works. Credits (and kudos) should go to them all (and to many others too).
|
||||
* For the WH1080 part I mostly have re-elaborated and merged their works. Credits (and kudos) should go to them all
|
||||
* (and to many others too).
|
||||
*
|
||||
*********************
|
||||
*****************************************
|
||||
* WH1080
|
||||
*****************************************
|
||||
* (aka Watson W-8681)
|
||||
* (aka Digitech XC0348 Weather Station)
|
||||
* (aka PCE-FWS 20)
|
||||
* (aka Elecsa AstroTouch 6975)
|
||||
* (aka Froggit WH1080)
|
||||
* (aka .....)
|
||||
*
|
||||
* This weather station is based on an indoor touchscreen receiver, and on a 5+1 outdoor wireless sensors group
|
||||
* (rain, wind speed, wind direction, temperature, humidity, plus a DCF77 time signal decoder, maybe capable to decode
|
||||
|
@ -26,45 +29,63 @@
|
|||
* See the product page here: http://www.foshk.com/weather_professional/wh1080.htm .
|
||||
* It's a very popular weather station, you can easily find it on eBay or Amazon (just do a search for 'WH1080').
|
||||
*
|
||||
* The module seems to work fine, decoding all of the data as read into the original console (there is some minimal difference
|
||||
* The module works fine, decoding all of the data as read into the original console (there is some minimal difference
|
||||
* sometime on the decimals due to the different architecture of the console processor, which is a little less precise).
|
||||
*
|
||||
* Please note that the pressure sensor (barometer) is enclosed in the indoor console unit, NOT in the outdoor
|
||||
* wireless sensors group.
|
||||
* That's why it's NOT possible to get pressure data by wireless communication. If you need pressure data you should try
|
||||
* an Arduino/Raspberry solution wired with a BMP180 or BMP085 sensor.
|
||||
* an Arduino/Raspberry solution wired with a BMP180/280 or BMP085 sensor.
|
||||
*
|
||||
* Data are trasmitted in a 48 seconds cycle (data packet, then wait 48 seconds, then data packet...).
|
||||
*
|
||||
* This module is also capable to decode the DCF77 time signal sent by the wireless time signal decoder:
|
||||
* around the minute 59 of the even hours the sensor's TX stops sending weather data, probably to receive (and sync with)
|
||||
* DCF77 signal.
|
||||
* This module is also capable to decode the DCF77/WWVB time signal sent by the time signal decoder
|
||||
* (which is enclosed on the sensor tx): around the minute 59 of the even hours the sensor's TX stops sending weather data,
|
||||
* probably to receive (and sync with) DCF77/WWVB signals.
|
||||
* After around 3-4 minutes of silence it starts to send just time data for some minute, then it starts again with
|
||||
* weather data as usual.
|
||||
*
|
||||
* By living in Europe I can only test DCF77 time decoding, so if you live outside Europe and you find garbage instead
|
||||
* of correct time, you should disable/ignore time decoding
|
||||
* (or, better, try to implement a more complete time decoding system :) ).
|
||||
*
|
||||
* To recognize message type (weather or time) you can use the 'msg_type' field on json output:
|
||||
* msg_type 0 = weather data
|
||||
* msg_type 1 = time data
|
||||
*
|
||||
* By living in Europe I can only test DCF77 time decoding, so if you live outside Europe and you find garbage instead
|
||||
* of correct time,
|
||||
* you should disable time decoding (or, better, try to implement a more complete time decoding system :) ).
|
||||
*
|
||||
* The 'Total rainfall' field is a cumulative counter, increased by 0.3 millimeters of rain at once.
|
||||
*
|
||||
* The station comes in three TX operating frequency versions: 433, 868.3 and 915 Mhz.
|
||||
* I've had tested the module with a 'Froggit WH1080' on 868.3 Mhz, using '-f 868140000' as frequency parameter and
|
||||
* it works fine
|
||||
* (compiled in x86, RaspberryPi 1 (v2) and RaspberryPi 2, and also on a BananaPi platform. Everything is OK).
|
||||
* I don't know if it works also with other versions and, generally speaking, with ALL of the rebranded versions of
|
||||
* this weather station.
|
||||
* The module is tested with a 'Froggit WH1080' on 868.3 Mhz, using '-f 868140000' as frequency parameter and
|
||||
* it works fine (compiled in x86, RaspberryPi 1 (v2), Raspberry Pi2 and Pi3, and also on a BananaPi platform. Everything is OK).
|
||||
* I don't know if it works also with ALL of the rebranded versions/models of this weather station.
|
||||
* I guess it *should* do... Just give it a try! :)
|
||||
*
|
||||
*
|
||||
* ***TODO***: check if negative temperature values (and sign) are OK (no real winter this year where I live, so cannot test...) .
|
||||
*
|
||||
*
|
||||
* 2016 Nicola Quiriti ('ovrheat')
|
||||
*****************************************
|
||||
* WH3080
|
||||
*****************************************
|
||||
*
|
||||
* The WH3080 Weather Station seems to be basically a WH1080 with the addition of UV/Light sensors onboard.
|
||||
* The weather/datetime radio protocol used for both is identical, the only difference is for the addition in the WH3080
|
||||
* of the UV/Light part.
|
||||
* UV/Light radio messages are disjointed from (and shorter than) weather/datetime radio messages and are transmitted
|
||||
* in a 'once-every-60-seconds' cycle.
|
||||
*
|
||||
* The module is able to decode all kind of data coming from the WH3080: weather, datetime, UV and light plus some
|
||||
* error/status code.
|
||||
*
|
||||
* To recognize message type (weather, datetime or UV/light) you can refer to the 'msg_type' field on json output:
|
||||
* msg_type 0 = weather data
|
||||
* msg_type 1 = datetime data
|
||||
* msg_type 2 = UV/light data
|
||||
*
|
||||
* While the LCD console seems to truncate/round values in order to best fit to its display, this module keeps entire values
|
||||
* as received from externals sensors (exception made for some rounding while converting values from lux to watts/m and fc),
|
||||
* so you can see -sometimes- some little difference between module's output and LCD console's values.
|
||||
*
|
||||
*
|
||||
* 2016-2017 Nicola Quiriti ('ovrheat' - 'seven')
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
@ -80,17 +101,15 @@
|
|||
|
||||
|
||||
|
||||
unsigned short msg_type = 0; // 0=Weather 1=Time
|
||||
|
||||
char* wind_dir_string[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",};
|
||||
char* wind_dir_degr[]= {"0", "23", "45", "68", "90", "113", "135", "158", "180", "203", "225", "248", "270", "293", "315", "338",};
|
||||
|
||||
static const char* wind_dir_string[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",};
|
||||
static const char* wind_dir_degr[]= {"0", "23", "45", "68", "90", "113", "135", "158", "180", "203", "225", "248", "270", "293", "315", "338",};
|
||||
|
||||
static unsigned short get_device_id(const uint8_t* br) {
|
||||
unsigned short get_device_id(const uint8_t* br) {
|
||||
return (br[1] << 4 & 0xf0 ) | (br[2] >> 4);
|
||||
}
|
||||
|
||||
static char* get_battery(const uint8_t* br) {
|
||||
char* get_battery(const uint8_t* br) {
|
||||
if ((br[9] >> 4) != 1) {
|
||||
return "OK";
|
||||
} else {
|
||||
|
@ -100,92 +119,127 @@ static char* get_battery(const uint8_t* br) {
|
|||
|
||||
// ------------ WEATHER SENSORS DECODING ----------------------------------------------------
|
||||
|
||||
static float get_temperature(const uint8_t* br) {
|
||||
float get_temperature(const uint8_t* br) {
|
||||
const int temp_raw = (br[2] << 8) + br[3];
|
||||
return ((temp_raw & 0x0fff) - 0x190) / 10.0;
|
||||
}
|
||||
|
||||
static int get_humidity(const uint8_t* br) {
|
||||
int get_humidity(const uint8_t* br) {
|
||||
return br[4];
|
||||
}
|
||||
|
||||
static const char* get_wind_direction_str(const uint8_t* br) {
|
||||
char* get_wind_direction_str(const uint8_t* br) {
|
||||
return wind_dir_string[br[9] & 0x0f];
|
||||
}
|
||||
|
||||
static const char* get_wind_direction_deg(const uint8_t* br) {
|
||||
char* get_wind_direction_deg(const uint8_t* br) {
|
||||
return wind_dir_degr[br[9] & 0x0f];
|
||||
}
|
||||
|
||||
static float get_wind_speed_raw(const uint8_t* br) {
|
||||
float get_wind_speed_raw(const uint8_t* br) {
|
||||
return br[5]; // Raw
|
||||
}
|
||||
|
||||
static float get_wind_avg_ms(const uint8_t* br) {
|
||||
float get_wind_avg_ms(const uint8_t* br) {
|
||||
return (br[5] * 34.0f) / 100; // Meters/sec.
|
||||
}
|
||||
|
||||
static float get_wind_avg_mph(const uint8_t* br) {
|
||||
float get_wind_avg_mph(const uint8_t* br) {
|
||||
return ((br[5] * 34.0f) / 100) * 2.23693629f; // Mph
|
||||
}
|
||||
|
||||
static float get_wind_avg_kmh(const uint8_t* br) {
|
||||
float get_wind_avg_kmh(const uint8_t* br) {
|
||||
return ((br[5] * 34.0f) / 100) * 3.6f; // Km/h
|
||||
}
|
||||
|
||||
static float get_wind_avg_knot(const uint8_t* br) {
|
||||
float get_wind_avg_knot(const uint8_t* br) {
|
||||
return ((br[5] * 34.0f) / 100) * 1.94384f; // Knots
|
||||
}
|
||||
|
||||
static float get_wind_gust_raw(const uint8_t* br) {
|
||||
float get_wind_gust_raw(const uint8_t* br) {
|
||||
return br[6]; // Raw
|
||||
}
|
||||
|
||||
static float get_wind_gust_ms(const uint8_t* br) {
|
||||
float get_wind_gust_ms(const uint8_t* br) {
|
||||
return (br[6] * 34.0f) / 100; // Meters/sec.
|
||||
}
|
||||
|
||||
static float get_wind_gust_mph(const uint8_t* br) {
|
||||
float get_wind_gust_mph(const uint8_t* br) {
|
||||
return ((br[6] * 34.0f) / 100) * 2.23693629f; // Mph
|
||||
|
||||
}
|
||||
|
||||
static float get_wind_gust_kmh(const uint8_t* br) {
|
||||
float get_wind_gust_kmh(const uint8_t* br) {
|
||||
return ((br[6] * 34.0f) / 100) * 3.6f; // Km/h
|
||||
}
|
||||
|
||||
static float get_wind_gust_knot(const uint8_t* br) {
|
||||
float get_wind_gust_knot(const uint8_t* br) {
|
||||
return ((br[6] * 34.0f) / 100) * 1.94384f; // Knots
|
||||
}
|
||||
|
||||
static float get_rainfall(const uint8_t* br) {
|
||||
return ((((unsigned short)br[7] & 0x0f) << 8) | br[8]) * 0.3f;
|
||||
float get_rainfall(const uint8_t* br) {
|
||||
unsigned short rain_raw = (((unsigned short)br[7] & 0x0f) << 8) | br[8];
|
||||
return (float)rain_raw * 0.3f;
|
||||
}
|
||||
|
||||
|
||||
// ------------ WH3080 UV SENSOR DECODING ----------------------------------------------------
|
||||
|
||||
unsigned short get_uv_sensor_id(const uint8_t* br) {
|
||||
return (br[1] << 4 & 0xf0 ) | (br[2] >> 4);
|
||||
}
|
||||
|
||||
char* get_uvstatus(const uint8_t* br) {
|
||||
if (br[3] == 85) {
|
||||
return "OK";
|
||||
} else {
|
||||
return "ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short wh3080_uvi(const uint8_t* br) {
|
||||
return (br[2] & 0x0F );
|
||||
}
|
||||
|
||||
|
||||
// ------------ WH3080 LIGHT SENSOR DECODING -------------------------------------------------
|
||||
|
||||
float get_rawlight(const uint8_t* br) {
|
||||
return (((((br[4]) << 16) | ((br[5]) << 8) | br[6])));
|
||||
}
|
||||
|
||||
|
||||
//----------------- TIME DECODING ----------------------------------------------------
|
||||
|
||||
static int get_hours(const uint8_t* br) {
|
||||
char* get_signal(const uint8_t* br) {
|
||||
if ((br[2] & 0x0F) == 10) {
|
||||
return "DCF77";
|
||||
} else {
|
||||
return "WWVB/MSF";
|
||||
}
|
||||
}
|
||||
|
||||
int get_hours(const uint8_t* br) {
|
||||
return ((br[3] >> 4 & 0x03) * 10) + (br[3] & 0x0F);
|
||||
}
|
||||
|
||||
static int get_minutes(const uint8_t* br) {
|
||||
int get_minutes(const uint8_t* br) {
|
||||
return (((br[4] & 0xF0) >> 4) * 10) + (br[4] & 0x0F);
|
||||
}
|
||||
|
||||
static int get_seconds(const uint8_t* br) {
|
||||
int get_seconds(const uint8_t* br) {
|
||||
return (((br[5] & 0xF0) >> 4) * 10) + (br[5] & 0x0F);
|
||||
}
|
||||
|
||||
static int get_year(const uint8_t* br) {
|
||||
int get_year(const uint8_t* br) {
|
||||
return (((br[6] & 0xF0) >> 4) * 10) + (br[6] & 0x0F);
|
||||
}
|
||||
|
||||
static int get_month(const uint8_t* br) {
|
||||
int get_month(const uint8_t* br) {
|
||||
return ((br[7] >> 4 & 0x01) * 10) + (br[7] & 0x0F);
|
||||
}
|
||||
|
||||
static int get_day(const uint8_t* br) {
|
||||
int get_day(const uint8_t* br) {
|
||||
return (((br[8] & 0xF0) >> 4) * 10) + (br[8] & 0x0F);
|
||||
}
|
||||
|
||||
|
@ -198,29 +252,45 @@ static int fineoffset_wh1080_callback(bitbuffer_t *bitbuffer) {
|
|||
data_t *data;
|
||||
char time_str[LOCAL_TIME_BUFLEN];
|
||||
const uint8_t *br;
|
||||
uint8_t bbuf[12];
|
||||
int msg_type; // 0=Weather 1=Datetime 2=UV/Light
|
||||
int sens_msg = 12; // 12=Weather/Time sensor 8=UV/Light sensor
|
||||
int i;
|
||||
uint8_t bbuf[sens_msg];
|
||||
local_time_str(0, time_str);
|
||||
|
||||
if (bitbuffer->num_rows != 1) {
|
||||
return 0;
|
||||
}
|
||||
if ((bitbuffer->bits_per_row[0] != 88) && (bitbuffer->bits_per_row[0] != 87)) {
|
||||
if ((bitbuffer->bits_per_row[0] != 88) && (bitbuffer->bits_per_row[0] != 87) &&
|
||||
(bitbuffer->bits_per_row[0] != 64) && (bitbuffer->bits_per_row[0] != 63)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(bitbuffer->bits_per_row[0] == 88) {
|
||||
if(bitbuffer->bits_per_row[0] == 88) { // FineOffset WH1080/3080 Weather data msg
|
||||
sens_msg = 12;
|
||||
br = bitbuffer->bb[0];
|
||||
} else {
|
||||
} else if(bitbuffer->bits_per_row[0] == 87) { // FineOffset WH1080/3080 Weather data msg (different version (newest?))
|
||||
sens_msg = 12;
|
||||
/* 7 bits of preamble, bit shift the whole buffer and fix the bytestream */
|
||||
bitbuffer_extract_bytes(bitbuffer, 0, 7,
|
||||
(uint8_t *)&bbuf+1, 10*8);
|
||||
br = bbuf;
|
||||
bbuf[0] = 0xFF;
|
||||
} else if(bitbuffer->bits_per_row[0] == 64) { // FineOffset WH3080 UV/Light data msg
|
||||
sens_msg = 8;
|
||||
br = bitbuffer->bb[0];
|
||||
|
||||
} else if(bitbuffer->bits_per_row[0] == 63) { // FineOffset WH3080 UV/Light data msg (different version (newest?))
|
||||
sens_msg = 8;
|
||||
/* 7 bits of preamble, bit shift the whole buffer and fix the bytestream */
|
||||
bitbuffer_extract_bytes(bitbuffer, 0, 7,
|
||||
(uint8_t *) & bbuf +1, 7*8);
|
||||
br = bbuf;
|
||||
bbuf[0] = 0xFF;
|
||||
}
|
||||
|
||||
if (debug_output) {
|
||||
for (i=0 ; i<11 ; i++)
|
||||
for (i=0 ; i<((sens_msg)-1) ; i++)
|
||||
fprintf(stderr, "%02x ", bbuf[i]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
@ -230,15 +300,25 @@ static int fineoffset_wh1080_callback(bitbuffer_t *bitbuffer) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (br[10] != crc8(br, 10, CRC_POLY, CRC_INIT)) {
|
||||
if (sens_msg == 12) {
|
||||
if (br[10] != crc8(br, 10, CRC_POLY, CRC_INIT)) {
|
||||
// crc mismatch
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (br[7] != crc8(br, 7, CRC_POLY, CRC_INIT)) {
|
||||
// crc mismatch
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (br[0] == 0xff && (br[1] >> 4) == 0x0a) {
|
||||
msg_type = 0;
|
||||
msg_type = 0; // WH1080/3080 Weather msg
|
||||
} else if (br[0] == 0xff && (br[1] >> 4) == 0x0b) {
|
||||
msg_type = 1;
|
||||
msg_type = 1; // WH1080/3080 Datetime msg
|
||||
} else if (br[0] == 0xff && (br[1] >> 4) == 0x07) {
|
||||
msg_type = 2; // WH3080 UV/Light msg
|
||||
}
|
||||
|
||||
|
||||
|
@ -262,7 +342,6 @@ static int fineoffset_wh1080_callback(bitbuffer_t *bitbuffer) {
|
|||
const float speed = get_wind_avg_kmh(br); // <--- Data will be shown in Km/h
|
||||
//const float speed = get_wind_avg_knot((br) // <--- Data will be shown in Knots
|
||||
|
||||
|
||||
// Wind gust speed :
|
||||
|
||||
//const float gust = get_wind_gust_ms(br); // <--- Data will be shown in Meters/sec.
|
||||
|
@ -273,83 +352,130 @@ static int fineoffset_wh1080_callback(bitbuffer_t *bitbuffer) {
|
|||
const float rain = get_rainfall(br);
|
||||
const int device_id = get_device_id(br);
|
||||
const char* battery = get_battery(br);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//-------- GETTING UV DATA --------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//-------- GETTING TIME DATA ------------------------------------------------------------
|
||||
int uv_sensor_id = get_uv_sensor_id(br);
|
||||
char* uv_status = get_uvstatus(br);
|
||||
int uv_index = wh3080_uvi(br);
|
||||
|
||||
const int the_hours = get_hours(br);
|
||||
const int the_minutes = get_minutes(br);
|
||||
const int the_seconds = get_seconds(br);
|
||||
const int the_year = 2000 + get_year(br);
|
||||
const int the_month = get_month(br);
|
||||
const int the_day = get_day(br);
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//-------- GETTING LIGHT DATA -----------------------------------------------------------
|
||||
|
||||
float light = get_rawlight(br);
|
||||
float lux = (get_rawlight(br)/10);
|
||||
float wm = (get_rawlight(br)/6830);
|
||||
float fc = ((get_rawlight(br)/10.76)/10.0);
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//-------- GETTING TIME DATA ------------------------------------------------------------
|
||||
|
||||
char* signal = get_signal(br);
|
||||
int hours = get_hours(br);
|
||||
int minutes = get_minutes(br);
|
||||
int seconds = get_seconds(br);
|
||||
int year = 2000 + get_year(br);
|
||||
int month = get_month(br);
|
||||
int day = get_day(br);
|
||||
|
||||
|
||||
//--------- PRESENTING DATA --------------------------------------------------------------
|
||||
//--------- PRESENTING DATA --------------------------------------------------------------
|
||||
|
||||
if (msg_type == 0) {
|
||||
|
||||
data = data_make("time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Fine Offset WH1080 weather station",
|
||||
"msg_type", "Msg type", DATA_INT, msg_type,
|
||||
"id", "StationID", DATA_FORMAT, "%04X", DATA_INT, device_id,
|
||||
"temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temperature,
|
||||
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
|
||||
"direction_str", "Wind string", DATA_STRING, direction_str,
|
||||
"direction_deg", "Wind degrees", DATA_STRING, direction_deg,
|
||||
"speed", "Wind avg speed", DATA_FORMAT, "%.02f", DATA_DOUBLE, speed,
|
||||
"gust", "Wind gust", DATA_FORMAT, "%.02f", DATA_DOUBLE, gust,
|
||||
"rain", "Total rainfall", DATA_FORMAT, "%.01f", DATA_DOUBLE, rain,
|
||||
"battery", "Battery", DATA_STRING, battery, // Unsure about Battery byte...
|
||||
NULL);
|
||||
|
||||
data = data_make(
|
||||
"time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Fine Offset Electronics WH1080/WH3080 Weather Station",
|
||||
"msg_type", "Msg type", DATA_INT, msg_type,
|
||||
"id", "Station ID", DATA_FORMAT, "%d", DATA_INT, device_id,
|
||||
"temperature_C","Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temperature,
|
||||
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
|
||||
"direction_str","Wind string", DATA_STRING, direction_str,
|
||||
"direction_deg","Wind degrees", DATA_STRING, direction_deg,
|
||||
"speed", "Wind avg speed",DATA_FORMAT, "%.02f", DATA_DOUBLE, speed,
|
||||
"gust", "Wind gust", DATA_FORMAT, "%.02f", DATA_DOUBLE, gust,
|
||||
"rain", "Total rainfall",DATA_FORMAT, "%3.1f", DATA_DOUBLE, rain,
|
||||
"battery", "Battery", DATA_STRING, battery,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
return 1;
|
||||
|
||||
} else if (msg_type == 1) {
|
||||
|
||||
data = data_make(
|
||||
"time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Fine Offset Electronics WH1080/WH3080 Weather Station",
|
||||
"msg_type", "Msg type", DATA_INT, msg_type,
|
||||
"id", "Station ID", DATA_FORMAT, "%d", DATA_INT, device_id,
|
||||
"signal", "Signal Type", DATA_STRING, signal,
|
||||
"hours", "Hours\t", DATA_FORMAT, "%02d", DATA_INT, hours,
|
||||
"minutes", "Minutes", DATA_FORMAT, "%02d", DATA_INT, minutes,
|
||||
"seconds", "Seconds", DATA_FORMAT, "%02d", DATA_INT, seconds,
|
||||
"year", "Year\t", DATA_FORMAT, "%02d", DATA_INT, year,
|
||||
"month", "Month\t", DATA_FORMAT, "%02d", DATA_INT, month,
|
||||
"day", "Day\t", DATA_FORMAT, "%02d", DATA_INT, day,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
|
||||
data = data_make(
|
||||
"time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Fine Offset Electronics WH3080 Weather Station",
|
||||
"msg_type", "Msg type", DATA_INT, msg_type,
|
||||
"uv_sensor_id", "UV Sensor ID", DATA_FORMAT, "%d", DATA_INT, uv_sensor_id,
|
||||
"uv_status", "Sensor Status",DATA_STRING, uv_status,
|
||||
"uv_index", "UV Index", DATA_INT, uv_index,
|
||||
"lux", "Lux\t", DATA_FORMAT, "%.1f", DATA_DOUBLE, lux,
|
||||
"wm", "Watts/m\t", DATA_FORMAT, "%.2f", DATA_DOUBLE, wm,
|
||||
"fc", "Foot-candles", DATA_FORMAT, "%.2f", DATA_DOUBLE, fc,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
data = data_make("time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Fine Offset WH1080 weather station",
|
||||
"msg_type", "Msg type", DATA_INT, msg_type,
|
||||
"id", "StationID", DATA_FORMAT, "%04X", DATA_INT, device_id,
|
||||
"hours", "Hours", DATA_FORMAT, "%02d", DATA_INT, the_hours,
|
||||
"minutes", "Minutes", DATA_FORMAT, "%02d", DATA_INT, the_minutes,
|
||||
"seconds", "Seconds", DATA_FORMAT, "%02d", DATA_INT, the_seconds,
|
||||
"year", "Year", DATA_FORMAT, "%02d", DATA_INT, the_year,
|
||||
"month", "Month", DATA_FORMAT, "%02d", DATA_INT, the_month,
|
||||
"day", "Day", DATA_FORMAT, "%02d", DATA_INT, the_day,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *output_fields[] = {
|
||||
"time",
|
||||
"model",
|
||||
"id",
|
||||
"temperature_C",
|
||||
"humidity",
|
||||
"direction_str",
|
||||
"direction_deg",
|
||||
"speed",
|
||||
"gust",
|
||||
"rain",
|
||||
"msg_type",
|
||||
"hours",
|
||||
"minutes",
|
||||
"seconds",
|
||||
"year",
|
||||
"month",
|
||||
"day",
|
||||
"battery",
|
||||
NULL
|
||||
"time",
|
||||
"model",
|
||||
"id",
|
||||
"temperature_C",
|
||||
"humidity",
|
||||
"direction_str",
|
||||
"direction_deg",
|
||||
"speed",
|
||||
"gust",
|
||||
"rain",
|
||||
"msg_type",
|
||||
"signal",
|
||||
"hours",
|
||||
"minutes",
|
||||
"seconds",
|
||||
"year",
|
||||
"month",
|
||||
"day",
|
||||
"battery",
|
||||
"sensor_code",
|
||||
"uv_status",
|
||||
"uv_index",
|
||||
"lux",
|
||||
"wm",
|
||||
"fc",
|
||||
NULL
|
||||
};
|
||||
|
||||
r_device fineoffset_wh1080 = {
|
||||
.name = "Fine Offset WH1080 Weather Station",
|
||||
.name = "Fine Offset Electronics WH1080/WH3080 Weather Station",
|
||||
.modulation = OOK_PULSE_PWM_RAW,
|
||||
.short_limit = 976,
|
||||
.long_limit = 2400,
|
||||
.reset_limit = 10520,
|
||||
.short_limit = 800,
|
||||
.long_limit = 2800,
|
||||
.reset_limit = 2800,
|
||||
.json_callback = &fineoffset_wh1080_callback,
|
||||
.disabled = 0,
|
||||
.demod_arg = 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue