public static bool IsConnected() { var result = false; var handle = HIDAPI.hid_open(VENDOR_ID, PRODUCT_ID, IntPtr.Zero); if (handle.ToInt32() > 0) { try { result = true; } finally { HIDAPI.hid_close(handle); } } return(result); }
public static Record[] ReadRecord() { var records = new List <Record>(); var handle = HIDAPI.hid_open(VENDOR_ID, PRODUCT_ID, IntPtr.Zero); if (handle.ToInt32() <= 0) { Debug.Print("Could not open device."); return(null); } try { var outBuffer = new byte[] { 0x02, // USB Read Report 0x02, // Size of payload READ_RECORD, // READ_RECORD READ_RECORD // Checksum (only one byte so same as command) }; var numWritten = HIDAPI.hid_write(handle, outBuffer, outBuffer.Length); if (numWritten < 4) { Debug.Print("Failed to write request to device."); return(null); } using (var mem = new MemoryStream(1024)) { var payload = PerformRead(handle); if (payload == null) { Debug.Print("Could not read data from device."); return(null); } if (payload[0] != READ_RECORD) { Debug.Print("Payload is not a READ_RECORD result."); return(null); } var totalSize = payload[1]; var data = new byte[payload.Length - 2]; Array.Copy(payload, 2, data, 0, data.Length); mem.Write(data, 0, data.Length); while (mem.Length < totalSize) { data = PerformRead(handle); if (data == null) { Debug.Print("Could not read data from device."); return(null); } if ((mem.Length + data.Length) >= totalSize) { mem.Write(data, 0, data.Length - 1); // -1 because we don't want to include the final checksum byte } else { mem.Write(data, 0, data.Length); } } mem.Seek(0, SeekOrigin.Begin); while (mem.Position < mem.Length) { var type = Utils.ReadByte(mem); var item = type; var hasDate = (type & ITEM_DATE) != 0; var hasTime = (type & ITEM_TIME) != 0; if (hasDate) { item = Convert.ToByte(item & ~ITEM_DATE); } if (hasTime) { item = Convert.ToByte(item & ~ITEM_TIME); } var valueBytes = new byte[0]; switch (item) { case ITEM_INTEMP: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_OUTTEMP: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_DEWPOINT: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_WINDCHILL: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_HEATINDEX: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_INHUMI: valueBytes = Utils.ReadBytes(mem, 1); break; case ITEM_OUTHUMI: valueBytes = Utils.ReadBytes(mem, 1); break; case ITEM_ABSBARO: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_RELBARO: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_WINDDIRECTION: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_WINDSPEED: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_GUSTSPEED: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_RAINEVENT: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINRATE: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINHOUR: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINDAY: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINWEEK: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINMONTH: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINYEAR: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_RAINTOTALS: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_LIGHT: valueBytes = Utils.ReadBytes(mem, 4); break; case ITEM_UV: valueBytes = Utils.ReadBytes(mem, 2); break; case ITEM_UVI: valueBytes = Utils.ReadBytes(mem, 1); break; default: return(null); } RecordDate date = null; RecordTime time = null; if (hasDate) { var dateBuffer = new byte[3]; var numRead = mem.Read(dateBuffer, 0, dateBuffer.Length); if (numRead < dateBuffer.Length) { Debug.Print("Could not read date from memory."); return(null); } date = new RecordDate(dateBuffer[0], dateBuffer[1], dateBuffer[2]); } if (hasTime) { var timeBuffer = new byte[2]; var numRead = mem.Read(timeBuffer, 0, timeBuffer.Length); if (numRead < timeBuffer.Length) { Debug.Print("Could not read time from memory."); return(null); } time = new RecordTime(timeBuffer[0], timeBuffer[1]); } Record record = null; switch (item) { case ITEM_INTEMP: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_OUTTEMP: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_DEWPOINT: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_WINDCHILL: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_HEATINDEX: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_INHUMI: { record = new Record8(item, date, time, valueBytes[0]); break; } case ITEM_OUTHUMI: { record = new Record8(item, date, time, valueBytes[0]); break; } case ITEM_ABSBARO: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_RELBARO: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_WINDDIRECTION: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_WINDSPEED: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_GUSTSPEED: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_RAINEVENT: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINRATE: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINHOUR: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINDAY: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINWEEK: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINMONTH: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINYEAR: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_RAINTOTALS: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_LIGHT: { uint value = BitConverter.ToUInt32(Utils.ReverseBytes(valueBytes), 0); record = new Record32(item, date, time, value); break; } case ITEM_UV: { ushort value = BitConverter.ToUInt16(Utils.ReverseBytes(valueBytes), 0); record = new Record16(item, date, time, value); break; } case ITEM_UVI: { record = new Record8(item, date, time, valueBytes[0]); break; } } if (record != null) { records.Add(record); } } } } finally { HIDAPI.hid_close(handle); } return(records.ToArray()); }