comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:9dab44dcb331
1 /*
2 * WH-1080 data input utility.
3 * This bases on code supplied to me by Steve Woodford.
4 *
5 * Greg Lehey, 16 November 2009
6 *
7 * $Id: wh1080_dev.h,v 1.4 2009/12/08 01:03:12 grog Exp grog $
8 */
9
10 #ifdef linux
11 /*
12 * I wish I understood linux header files. This whole thing looks like a mess.
13 * If you can explain it to me, please do.
14 */
15 #include <endian.h>
16 #include <asm/byteorder.h>
17 #define htobe16 __cpu_to_be16
18 #define le16toh __le16_to_cpu
19 #include <time.h>
20 #else
21 #include <sys/endian.h>
22 #endif
23 /*
24 * This file describes the WH-1080 weather station as well as I can understand
25 * it. The station is not documented, and I've pulled this together from
26 * various source code written by others without access to documentation.
27 */
28
29 /* Vendor and product number for WH-1080 */
30 #define WH1080_USB_VENDOR 0x1941
31 #define WH1080_USB_PRODUCT 0x8021
32
33 #define WH1080_PAGE_SIZE 32
34 #define WH1080_PAGE_MASK (~ (WH1080_PAGE_SIZE - 1))
35
36 /* Offsets of the first 2 pages */
37 #define WH1080_PAGE0 0
38 #define WH1080_PAGE1 0x20
39 /* First archive record appears to start here */
40 #define WH1080_FIRST_ARCHIVE 0x100
41 /* And the last one must be here */
42 #define WH1080_LAST_ARCHIVE 0xfff0
43 /* And thus there appear to be this many of them. */
44 #define WH1080_ARCHIVE_COUNT 4088
45 /* The records swap this often, in seconds */
46 #define WH1080_ARCHIVE_INTERVAL 1800
47 /* Size of archive record */
48 #define WH1080_ARCHIVE_RECORD_SIZE 16
49
50 /* Descriptor stuff. I'm not sure what this is all about. XXX */
51 #define WH1080_DESCRIPTOR1_SIZE 18
52 #define WH1080_DESCRIPTOR2_SIZE 9
53 /*
54 * Steve Woodford has:
55 * #define WH1080_DESCRIPTOR3_SIZE 34
56 * #define WH1080_DESCRIPTOR34_SIZE 0x74
57 */
58 #define WH1080_DESCRIPTOR3_SIZE 34
59 #define WH1080_DESCRIPTOR34_SIZE 0x74
60
61 /*
62 * The device appears to have its data stored in pages of 32 bytes. I have very
63 * little information beyond what I've gleaned from other people's code, so some
64 * of this looks very strange.
65 *
66 * The following structures define what we know of the first two pages.
67 */
68 struct wh1080_page0
69 {
70 uint64_t magic; /* one of apparently 2 different magic numbers */
71 uint64_t magic2;
72 char mumble [14];
73 uint16_t current_page; /* byte offset of current readings */
74 };
75
76 /* These seem to be alternate values. No idea why. */
77 #if BYTE_ORDER == LITTLE_ENDIAN
78 /* XXX find out which endian this is */
79 #define WH1080_PAGE0_MAGIC1A 0xffffffffffffaa55ull
80 #define WH1080_PAGE0_MAGIC1B 0xffffffffffaaaa55ull
81 #define WH1080_PAGE0_MAGIC2 0xffffffffffffffffull
82 #else
83 #define WH1080_PAGE0_MAGIC1A 0x55aaffffffffffffull
84 #define WH1080_PAGE0_MAGIC1B 0x55aaaaffffffffffull
85 #define WH1080_PAGE0_MAGIC2 0xffffffffffffffffull
86 #endif
87 /* It's not clear what the purpose of page 1 is. One pressure reading comes with the current data. */
88 struct wh1080_page1
89 {
90 uint16_t rel_pressure; /* hPa / 10 */
91 uint16_t abs_pressure; /* hPa / 10 */
92 char mumble1 [28];
93 };
94
95 /*
96 * At least current weather data looks like this. This record should be exactly
97 * 16 bytes long.
98 */
99 struct wh1080_readings
100 { /* offset: */
101 uint8_t last_save_mins; /* 0: last save minutes (?) */
102 uint8_t inside_humidity; /* 1: humidity in percent */
103 int16_t inside_temp; /* 2: inside temperature, °C/10 */
104 uint8_t outside_humidity; /* 4: humidity in percent */
105 int16_t outside_temp; /* 5: outside temperature, °C/10 */
106 uint16_t pressure; /* 7: absolute pressure, hPa / 10 */
107 uint8_t wind_speed; /* 9: wind speed in m/s/10, up to 25.5 m/s */
108 uint8_t wind_gust; /* 10: wind gust speed in m/s/10, up to 25.5 m/s */
109 char mumble1; /* 11: apparently unused byte */
110 /*
111 * wind direction is a number between 0 and 15, repesenting increments of
112 * 22.5°. It may also have the value 0x80 if there's no wind at all.
113 */
114 uint8_t wind_direction; /* 12: */
115 /*
116 * Rainfall is measured in units of 0.3 mm, and the value returned is a
117 * counter. There's only real rainfall if the value returned here is
118 * different from the previous reading.
119 */
120 uint16_t rain; /* 13: */
121 char mumble2; /* 15: pad to 16 bytes */
122 } __packed;
123