Reading data from a 1W340A

PCsensor.com manufacture a range of temperature and humidity measuring equipment. Their offerings are cheap and cheerful, but ultimately fail in one key area: the software. You are (nearly) always limited to a closed-source windows option. The 1W340A allows you to log data over the network, which is a big step up from the generic USB HID type options of the past.

It still has the software problem though.

So what can be done? Well, the best option is to watch the 1W340A talk to the software, capture the data packets, and attempt to implement polling in another program. My program of choice is python.

To get this working, you will need the following:

A computer with python 2.7 (or 2.6 should be fine) running, and preferably with wireshark installed. You also need access to a windows machine which you can install the 1W340A’s software on to test and observe.

When I fired up the software, and watched the packets on wireshark my heart filled with joy: decipherable text in the packets. However this is just for reading the configuration, to poll for data you get “jibberish” binary packets back. Luckily they don’t appear to be encrypted, and are very easy to decipher. So far I’ve found the parts I need, and it appears to work for my configuration, so I’ve gone no further in investigating the protocol yet. I may go into the investigation in further detail in a future post, but for now I’ll just tell you how to get the data.

My test setup at the moment, uses two probes, one in each socket.

import socket, binascii, time
import struct

global HOST
global PORT
HOST = “192.168.1.188”
PORT = 5200
datafile = “/Volumes/IT/temp_logging/”
extension = “.csv”
filename = “%(date)s_datafile”
pattern = “%Y-%m-%d”
polling = 15

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

def log_data(tempa, tempb, filename):
params = {“tempa”:tempa, “tempb”:tempb}
try:
filer = open(filename, “r”)
filer.close()
filer = open(filename, “a”)
except:
filer = open(filename, “w”)
filer.write(“timestamp,temp-A (C),temp-B (C)\n”)
filer.write(time.strftime(“%H:%M:%S %d/%m/%Y”) + “,%(tempa)s,%(tempb)s\n” % params)
filer.close()

def send_command(s, command, display = False):
if display:
print “Me:”, command, binascii.b2a_hex(command)
try:
s.send(command)
X = s.recv(2048)
except:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(command)
X = s.recv(2048)
if display:
print str(HOST)+”:”, X, binascii.b2a_hex(X)
return X

print ‘Connected to’, HOST
send_command(s,”call pcsensor!”)
send_command(s,”display configs!”)
send_command(s,”bye pcsensor!”)
send_command(s,”\xbb\x80\x03″, True)
while 1:
x = send_command(s,”\xbb\x80\x00″)
tmp = binascii.b2a_hex(x)
size = 2
offset = 1
tempa = int(binascii.b2a_hex(x)[9:11], base=16)
if tmp[11:12] == “8”:
tempa = tempa + 0.5
tempb = int(binascii.b2a_hex(x)[13:15], base=16)
if tmp[15:16] == “8”:
tempb = tempb + 0.5
#print str(tempa)+”c”, str(tempb)+”c”
log_data(tempa, tempb, datafile+filename % {“date”:time.strftime(pattern)}+extension )
#print len(tmp), binascii.b2a_hex(x)[:9], int(binascii.b2a_hex(x)[9:11], base=16), binascii.b2a_hex(x)[11:12], int(binascii.b2a_hex(x)[13:15], base=16), tmp[15:16]
time.sleep(polling)
s.close()

In terms of how it’s working, I check the config at the start just because that’s what the software normally does. It doesn’t appear to be required, but it’s not like it costs me anything to do it, and it’s a good troubleshooting step in case this begins to fail. In effect, we send “\xbb\x80\x00” to the device, and it sends back some binary, some of which can be interpreted into the readings from the “B0” and “B1” devices. It’s two bytes per int for the degrees, the next byte appears to be “8” when it’s set to a 0.5 increment. It doesn’t appear to get any more accurate than that, but hey, if you wanted accurate you’d spend a bit more money on a temperature probe, right? It’s good enough to log some basic data.

It looks like WP has killed my indents, but you should be able to work it out. This code is both ugly, potentially has security issues, and isn’t robust. I don’t expect it will work with more/less temperature probes, or slightly different models/configurations. I’ll start fiddling with that stuff so I can work out what the rest of the data sent from the device is “for”.

Let me know in the comments if this helps, or if you have any issues. But at the end of the day you may need to use wireshark to test the original software again and validate that your setup is the same.

 

One thought on “Reading data from a 1W340A

  1. Hey! I enjoy this post very well! I need your help! I have a 1W340A and I need to know how can I get the values of the temperature without use the program of windows. I need to do this in linux.

    If you could help me.

    Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s