Mercurial > ~darius > hgwebdir.cgi > wh1080
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 |