view wh1080_dev.h @ 1:01496de9f722

Ignore build cruft.
author Daniel O'Connor <darius@dons.net.au>
date Tue, 09 Feb 2010 13:48:22 +1030
parents 9dab44dcb331
children
line wrap: on
line source

/*
 * 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;