diff --git a/WeatherStation.ino b/WeatherStation.ino
new file mode 100644
index 0000000..3ae4ad3
--- /dev/null
+++ b/WeatherStation.ino
@@ -0,0 +1,54 @@
+
+#include <avr/pgmspace.h>
+
+#include <avrpins.h>
+#include <max3421e.h>
+#include <usbhost.h>
+#include <usb_ch9.h>
+#include <Usb.h>
+#include <usbhub.h>
+#include <avr/pgmspace.h>
+#include <address.h>
+#include <hid.h>
+#include <hiduniversal.h>
+
+#include <printhex.h>
+#include <message.h>
+#include <hexdump.h>
+#include <parsetools.h>
+
+#include "hidwh1080rptparser.h"
+
+USB                                             Usb;
+USBHub                                          Hub(&Usb);
+HIDUniversal                                    Hid(&Usb);
+
+WH1080ReportParser parser;
+
+void setup()
+{
+  Serial.begin( 9600 );
+  Serial.println("Start");
+
+  if (Usb.Init() == -1)
+      Serial.println("OSC did not start.");
+      
+  delay( 200 );
+
+  if (!Hid.SetReportParser(0, &parser))
+      ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  ); 
+}
+
+void loop()
+{
+    Usb.Task();
+    if ((Usb.getUsbTaskState() == USB_STATE_RUNNING) && parser.startDelay && (parser.startDelay <= millis())) {
+      int rcode = Hid.SetReport(0, 0, 0x02, 0x01, sizeof(parser.report), parser.report);
+      if (rcode != 0) {
+        Serial.print("Rcode = ");
+        Serial.println(rcode, HEX);
+      }
+      parser.startDelay = 0;
+    }
+}
+
diff --git a/hidwh1080rptparser.cpp b/hidwh1080rptparser.cpp
new file mode 100644
index 0000000..d87ec50
--- /dev/null
+++ b/hidwh1080rptparser.cpp
@@ -0,0 +1,58 @@
+#include "hidwh1080rptparser.h"
+
+void WH1080ReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
+{
+  // See http://www.jim-easterbrook.me.uk/weather/mm/
+  if ((chunkStart + len) >= WH1080_BUFFER_CHUNK) {
+    memcpy(chunk + chunkStart, buf, WH1080_BUFFER_CHUNK - chunkStart);
+    chunkStart = 0;
+    if (readingBlockZero) {
+      unsigned short currentPos = chunk[WH1080_CURRENT_POS] + (chunk[WH1080_CURRENT_POS + 1] << 8);
+      report[1] = (uint8_t)(currentPos / 256);
+      report[2] = (uint8_t)(currentPos & 255);
+      report[5] = (uint8_t)(currentPos / 256);
+      report[6] = (uint8_t)(currentPos & 255);
+      readingBlockZero = false;
+      startDelay = millis() + 250;
+    } else {
+      if (memcmp(chunk, lastChunk, WH1080_BUFFER_CHUNK) != 0) {
+        memcpy(lastChunk, chunk, WH1080_BUFFER_CHUNK);
+        Serial.print("Time since last change: ");
+        Serial.println(millis() - lastMillis);
+        lastMillis = millis();
+        Serial.print("Delay: ");
+        Serial.println(chunk[0]);
+        Serial.print("Indoor humidity: ");
+        Serial.println(chunk[1]);
+        Serial.print("Indoor temperature: ");
+        Serial.println((((chunk[3] & 0x7f) << 8) + chunk[2]) * ((chunk[3] & 0x80) ? -0.1 : 0.1));
+        Serial.print("Outdoor humidity: ");
+        Serial.println(chunk[4]);
+        Serial.print("Outdoor temperature: ");
+        Serial.println((((chunk[6] & 0x7f) << 8) + chunk[5]) * ((chunk[6] & 0x80) ? -0.1 : 0.1));
+        Serial.print("Absolute pressure: ");
+        Serial.println(((chunk[8] << 8) + chunk[7]) * 0.1);
+        Serial.print("Average wind speed: ");
+        Serial.println((chunk[9] + ((chunk[11] & 0x0f) << 8)) * 0.1);
+        Serial.print("Gust wind speed: ");
+        Serial.println((chunk[10] + ((chunk[11] & 0xf0) << 4)) * 0.1);
+        Serial.print("Wind direction: ");
+        Serial.println(chunk[12] * 22.5);
+        Serial.print("Total rain: ");
+        Serial.println(((chunk[14] << 8) + chunk[13]) * 0.3);
+        Serial.print("Status: ");
+        Serial.println(chunk[15], HEX);
+      }
+      readingBlockZero = true;
+      report[1] = 0;
+      report[2] = 0;
+      report[5] = 0;
+      report[6] = 0;
+      startDelay = millis() + 5000;
+    }
+  } else {
+    memcpy(chunk + chunkStart, buf, len);
+    chunkStart += len;
+  }
+}
+
diff --git a/hidwh1080rptparser.h b/hidwh1080rptparser.h
new file mode 100644
index 0000000..4732cba
--- /dev/null
+++ b/hidwh1080rptparser.h
@@ -0,0 +1,83 @@
+#if !defined(__HIDWH1080RPTPARSER_H__)
+#define __HIDWH1080RPTPARSER_H__
+
+#include <inttypes.h>
+#include <avr/pgmspace.h>
+#include "avrpins.h"
+#include "max3421e.h"
+#include "usbhost.h"
+#include "usb_ch9.h"
+#include "Usb.h"
+
+#if defined(ARDUINO) && ARDUINO >=100
+#include "Arduino.h"
+#else
+#include <WProgram.h>
+#endif
+
+#include "printhex.h"
+#include "hexdump.h"
+#include "message.h"
+#include "confdescparser.h"
+#include "hid.h"
+
+// Following taken from wview-5.20.2
+//
+// Define the rain rate acuumulator period (minutes):
+#define WH1080_RAIN_RATE_PERIOD         5
+
+// Weather Station buffer parameters:
+#define WH1080_RAIN_MAX             0x10000     // Wrap value for rain counter
+#define WH1080_BUFFER_START         0x100       // Size of fixed block
+                                                // start of buffer records
+#define WH1080_BUFFER_CHUNK         0x20        // Size of chunk received over USB
+// Weather Station record memory positions:
+#define WH1080_DELAY                0   // Position of delay parameter
+#define WH1080_HUMIDITY_IN          1   // Position of inside humidity parameter
+#define WH1080_TEMPERATURE_IN       2   // Position of inside temperature parameter
+#define WH1080_HUMIDITY_OUT         4   // Position of outside humidity parameter
+#define WH1080_TEMPERATURE_OUT      5   // Position of outside temperature parameter
+#define WH1080_ABS_PRESSURE         7   // Position of absolute pressure parameter
+#define WH1080_WIND_AVE             9   // Position of wind direction parameter
+#define WH1080_WIND_GUST            10  // Position of wind direction parameter
+#define WH1080_WIND_DIR             12  // Position of wind direction parameter
+#define WH1080_RAIN                 13  // Position of rain parameter
+#define WH1080_STATUS               15  // Position of status parameter
+
+// Control block offsets:
+#define WH1080_SAMPLING_INTERVAL    16  // Position of sampling interval
+#define WH1080_DATA_COUNT           27  // Position of data_count parameter
+#define WH1080_CURRENT_POS          30  // Position of current_pos parameter
+
+const prog_char WH1080_REPORT[] PROGMEM = {
+  0xa1, 0x00, 0x00, 0x20, 0xa1, 0x00, 0x00, 0x20
+};
+
+class WH1080ReportParser : public HIDReportParser
+{
+  uint8_t chunk[WH1080_BUFFER_CHUNK], lastChunk[WH1080_BUFFER_CHUNK];
+  uint8_t chunkStart;
+  bool readingBlockZero;
+  unsigned short currentPos;
+  unsigned long lastMillis;
+    
+public:
+
+  unsigned long startDelay;
+  uint8_t report[8];
+
+  WH1080ReportParser() {
+    chunkStart = 0;
+    readingBlockZero = true;
+    for (uint8_t i = 0; i < sizeof(WH1080_REPORT); i++) {
+      report[i] = pgm_read_byte(&WH1080_REPORT[i]);
+    }
+    memset(lastChunk, 0, WH1080_BUFFER_CHUNK);
+    lastMillis = millis();
+    startDelay = 1000 + millis();
+  }
+
+  virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
+};
+
+#endif // __HIDWH1080RPTPARSER_H__