FROGGIT DL5000 Weather Data Logger
Posted on Sun 28 October 2018 in projects
The Data Logger
Some time ago I've bought a Froggit weather data logger with the intention to connect it to my home server. I've chosen this one as it was the cheapest device I came across with an USB port and some sort of Software.
This Device is actually sold by many distributors, I've seen some Amazon listings with the same device and just some other brandname on it. (MISOL, ELV to name a few)
So its totally possible that this will work with other data loggers too.
Powersupply
After some time the original powersupply got a bit flakey and soon died on me.
So the only modification I've done on the device was to route the 5V USB power from the USB port all the way to the other side.
Now the logger runs from the USB Port, and much more stable than before.
USB Communication
With the OEM Software and with the help of a Windows VM (as the Software supplied with the logger is windows only) and wireshark I was able to sniff the USB traffic and reverse engineer the polling protocol for all the sensors.
The Protocol
The data is queried by sending a block of 64 bytes to the device with the first 4 bytes with the values 0x7b 0x03 0x40 0x7d and the rest 0x00
The logger will answer with 64 bytes of data, with 3 bytes for each sensor connected.
- The first two bytes (int_16) are the temperature in <Measured Value>*10 as measured by the sensor.
- The last byte (uint_8) is the relative humidity as measured by the sensor.
- Unknown or not connected sensors are transmitted with 0xff 0xff 0xff
Connecting it to InfluxDB
With the protocol figured out putting the data to good use is pretty straigt forward.
This will pull the data off the logger and print it as InfluxDB Textdata and can be easily called by Telegraf.
#!/usr/bin/env python
import struct
import sys
import usb.core
import usb.util
data = [0x00] * 64
data[0] = 0x7b
data[1] = 0x03
data[2] = 0x40
data[3] = 0x7d
def main():
dev = usb.core.find(idVendor=0x0483, idProduct=0x5750)
dev.reset()
# was it found?
if dev is None:
print('no device found', file=sys.stderr)
return 1
for config in dev:
for i in range(config.bNumInterfaces):
if dev.is_kernel_driver_active(i):
dev.detach_kernel_driver(i)
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
# print(cfg)
intf = cfg[(0, 0)]
out = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match= \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
in_ = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match= \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)
assert out is not None
assert in_ is not None
if out is None or in_ is None:
print('error initializing device', file=sys.stderr)
return 1
out.write(data)
in_data = in_.read(64)
for sensor_id in range(0, 8):
dat = struct.unpack('!hB', in_data[1 + 3 * sensor_id:1 + 3 * (sensor_id + 1)])
if dat[1] == 255 and dat[0] == 32767:
continue
print('froggit,sensor_id={sensor} temperature={temperature:f},humidity={humidity:d}'.format(
sensor=sensor_id,
temperature=dat[0] / 10,
humidity=dat[1]))
return 0
if __name__ == '__main__':
sys.exit(main())