The first form prints a list of values (measures) in the WS-2300 that ws2300 can read and set. The second form is used to read and set the measures individually. The third form is used capturing a single sample to a log file or SQL database. The fourth form causes ws2300 to become a daemon continuously saving samples to log files and databases.
tty-device is the name of the tty device the WS-2300's serial interface is connected to. It can also have the form ws2300://host:port, which means share the port a ws2300 daemon that is running on host and listening to port is using.
In the past LaCrosse has threatened to legally pursue people who publish the protocols used by WS-2300. As the source code to this program documents the protocols publishing it may put you at risk.
The following Python modules are also available:
All Python's builtin methods are available. In addition these functions can be used:
mydb.py: class Db: def __init__(self, filename): self.handle = file(filename, "a") def cursor(self): return self def commit(self): pass def close(self): self.handle.close() # # Called by ws2300 each to write each new record. # data is a tuple containing the fields, ie the # result of evaluating the Python expressions # given on the command line. # def execute(self, sql, data): record = '|'.join([str(field) for field in data]) self.handle.write(record+"\n") def connect(filename=None): return Db(filename)
To use your module simply stick it in the current directory, and pass a url like mydb:filename='weather.txt' to ws2300.
To do really radical things ws2300.py can be used as a module. Things defined in there are:
A complete program that would print the indoor temperature and humidity reported by the WS-2300, followed by the same things from the first 10 history records.
#!/usr/bin/python import ws2300 serialPort = ws2300.LinuxSerialPort("/dev/ttyS0") try: ws = ws2300.Ws2300(serialPort) measures = [ ws2300.Measure.IDS["it"], ws2300.Measure.IDS["ih"]] data = ws2300.read_measurements(ws, measures) hist_measures = [ws2300.HistoryMeasure(recno) for recno in range(10)] hist_data = ws2300.read_measurements(ws, hist_measures) finally: serialPort.close() print [ m.conv.binary2value(d) for m, d in zip(measures, data)] for recno in range(len(hist_measures)): history_record = hist_measures[recno].conv.binary2value(hist_data[recno]) print history_record.temp_indoor, history_record.humidity_indoor
# # This first capture spec writes the data to csv text # file, overwriting it for each new data sample. The # data is actually written to a temporary file which # is then moved to the correct filename so it someone # reading it never sees 1/2 written data. This format # easily digested by CGI scripts to generate web pages. # db.TimestampFromTicks(ws.cw[-1]-time.timezone) ! db.TimestampFromTicks(ws.sw[-1]-time.timezone) ! ws.ot[-1] ! ws.oh[-1] ! ws.wv.speed.avg ! ws.wv.dir.avg ! ws.rd[-1] ! ws.pa[-1] CSV:/var/lib/ws2300/current-weather.csv 8 8 # # This capture spec captures all weather data every hour. # It is written to an SQL database. # db.TimestampFromTicks(starttime) ! db.TimestampFromTicks(endtime) ! db.TimestampFromTicks(ws.sw[-1]) ! db.TimestampFromTicks(ws.cw[-1]) ! ws.sw.cnt ! ws.ot.avg ! ws.oh.avg ! ws.rt[-1] ! ws.pa.avg ! ws.it.avg ! ws.ih.avg ! ws.wv.speed.avg ! ws.wv.speed.std ! ws.wv.dir.avg ! ws.wv.dir.std ! ws.ws.avg kinterbasdb: dsn="127.0.0.1:/var/lib/ws2300/weather.gdb", user="sysdba", password="sysdba", dialect=3 8 3600 insert into weather_all values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) # # This capture spec captures the wind velocity data # every 5 minutes and writes it to an SQL database. # Wind velocity changes rapidly, so I like to keep a # close eye on it. # db.TimestampFromTicks(starttime) ! db.TimestampFromTicks(endtime) ! ws.ws.cnt ! ws.ws.avg ! ws.wv.speed.avg ! ws.wv.speed.std ! ws.wv.dir.avg ! ws.wv.dir.std kinterbasdb: dsn="127.0.0.1:/var/lib/ws2300/weather.gdb", user="sysdba", password="sysdba", dialect=3 8 300 insert into weather_wind values (?,?,?,?,?,?,?,?)