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 (?,?,?,?,?,?,?,?)