Mercurial > ~darius > hgwebdir.cgi > wh1080
diff wh1080_dev.h @ 0:9dab44dcb331
Initial commit of Greg's code from http://www.lemis.com/grog/tmp/wh1080.tar.gz
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Tue, 09 Feb 2010 13:44:25 +1030 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wh1080_dev.h Tue Feb 09 13:44:25 2010 +1030 @@ -0,0 +1,123 @@ +/* + * WH-1080 data input utility. + * This bases on code supplied to me by Steve Woodford. + * + * Greg Lehey, 16 November 2009 + * + * $Id: wh1080_dev.h,v 1.4 2009/12/08 01:03:12 grog Exp grog $ + */ + +#ifdef linux +/* + * I wish I understood linux header files. This whole thing looks like a mess. + * If you can explain it to me, please do. + */ +#include <endian.h> +#include <asm/byteorder.h> +#define htobe16 __cpu_to_be16 +#define le16toh __le16_to_cpu +#include <time.h> +#else +#include <sys/endian.h> +#endif +/* + * This file describes the WH-1080 weather station as well as I can understand + * it. The station is not documented, and I've pulled this together from + * various source code written by others without access to documentation. + */ + +/* Vendor and product number for WH-1080 */ +#define WH1080_USB_VENDOR 0x1941 +#define WH1080_USB_PRODUCT 0x8021 + +#define WH1080_PAGE_SIZE 32 +#define WH1080_PAGE_MASK (~ (WH1080_PAGE_SIZE - 1)) + +/* Offsets of the first 2 pages */ +#define WH1080_PAGE0 0 +#define WH1080_PAGE1 0x20 +/* First archive record appears to start here */ +#define WH1080_FIRST_ARCHIVE 0x100 +/* And the last one must be here */ +#define WH1080_LAST_ARCHIVE 0xfff0 +/* And thus there appear to be this many of them. */ +#define WH1080_ARCHIVE_COUNT 4088 +/* The records swap this often, in seconds */ +#define WH1080_ARCHIVE_INTERVAL 1800 +/* Size of archive record */ +#define WH1080_ARCHIVE_RECORD_SIZE 16 + +/* Descriptor stuff. I'm not sure what this is all about. XXX */ +#define WH1080_DESCRIPTOR1_SIZE 18 +#define WH1080_DESCRIPTOR2_SIZE 9 +/* + * Steve Woodford has: + * #define WH1080_DESCRIPTOR3_SIZE 34 + * #define WH1080_DESCRIPTOR34_SIZE 0x74 + */ +#define WH1080_DESCRIPTOR3_SIZE 34 +#define WH1080_DESCRIPTOR34_SIZE 0x74 + +/* + * The device appears to have its data stored in pages of 32 bytes. I have very + * little information beyond what I've gleaned from other people's code, so some + * of this looks very strange. + * + * The following structures define what we know of the first two pages. + */ +struct wh1080_page0 +{ + uint64_t magic; /* one of apparently 2 different magic numbers */ + uint64_t magic2; + char mumble [14]; + uint16_t current_page; /* byte offset of current readings */ +}; + +/* These seem to be alternate values. No idea why. */ +#if BYTE_ORDER == LITTLE_ENDIAN +/* XXX find out which endian this is */ +#define WH1080_PAGE0_MAGIC1A 0xffffffffffffaa55ull +#define WH1080_PAGE0_MAGIC1B 0xffffffffffaaaa55ull +#define WH1080_PAGE0_MAGIC2 0xffffffffffffffffull +#else +#define WH1080_PAGE0_MAGIC1A 0x55aaffffffffffffull +#define WH1080_PAGE0_MAGIC1B 0x55aaaaffffffffffull +#define WH1080_PAGE0_MAGIC2 0xffffffffffffffffull +#endif +/* It's not clear what the purpose of page 1 is. One pressure reading comes with the current data. */ +struct wh1080_page1 +{ + uint16_t rel_pressure; /* hPa / 10 */ + uint16_t abs_pressure; /* hPa / 10 */ + char mumble1 [28]; +}; + +/* + * At least current weather data looks like this. This record should be exactly + * 16 bytes long. + */ +struct wh1080_readings +{ /* offset: */ + uint8_t last_save_mins; /* 0: last save minutes (?) */ + uint8_t inside_humidity; /* 1: humidity in percent */ + int16_t inside_temp; /* 2: inside temperature, °C/10 */ + uint8_t outside_humidity; /* 4: humidity in percent */ + int16_t outside_temp; /* 5: outside temperature, °C/10 */ + uint16_t pressure; /* 7: absolute pressure, hPa / 10 */ + uint8_t wind_speed; /* 9: wind speed in m/s/10, up to 25.5 m/s */ + uint8_t wind_gust; /* 10: wind gust speed in m/s/10, up to 25.5 m/s */ + char mumble1; /* 11: apparently unused byte */ + /* + * wind direction is a number between 0 and 15, repesenting increments of + * 22.5°. It may also have the value 0x80 if there's no wind at all. + */ + uint8_t wind_direction; /* 12: */ + /* + * Rainfall is measured in units of 0.3 mm, and the value returned is a + * counter. There's only real rainfall if the value returned here is + * different from the previous reading. + */ + uint16_t rain; /* 13: */ + char mumble2; /* 15: pad to 16 bytes */ +} __packed; +