From 7e8f4e550cd45eeb9ce5e457f90e332118f80bce Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Tue, 26 Nov 2013 04:38:45 +0000 Subject: [PATCH] enable modification of archive interval and clearing station memory on ws23xx --- bin/wee_config_ws23xx | 44 +++++++++++++++++++- bin/weewx/drivers/ws23xx.py | 80 +++++++++++++++++++++++++++++-------- weewx.conf | 18 +-------- 3 files changed, 107 insertions(+), 35 deletions(-) diff --git a/bin/wee_config_ws23xx b/bin/wee_config_ws23xx index ad852de5..c4689e46 100644 --- a/bin/wee_config_ws23xx +++ b/bin/wee_config_ws23xx @@ -16,10 +16,8 @@ """Command line utility for configuring LaCrosse WS-23xx weather stations""" # FIXME: set time -# FIXME: clear station memory # FIXME: turn on/off backlight # FIXME: turn buzzer on/off -# FIXME: change archive interval (not possible?) # FIXME: can we read/modify DST on the console? import optparse @@ -55,6 +53,10 @@ def main(): help="display N history records") parser.add_option("--set-time", dest="settime", action="store_true", help="set the station clock to the current time") + parser.add_option("--set-interval", dest="interval", type=int, metavar="N", + help="set the station archive interval to N minutes") + parser.add_option("--clear-memory", dest="clear", action="store_true", + help="clear station memory") parser.add_option("-y", dest="noprompt", action="store_true", help="answer yes to every prompt") parser.add_option("--debug", dest="debug", action="store_true", @@ -92,6 +94,10 @@ def main(): history(station, ts=ts) elif options.settime: setclock(station, prompt) + elif options.interval: + setinterval(station, options.interval, prompt) + elif options.clear: + clearhistory(station, prompt) else: info(station) @@ -140,6 +146,40 @@ def setclock(station, prompt): elif ans == 'n': print "Set clock cancelled." +def setinterval(station, interval, prompt): + v = station.getArchiveInterval() + ans = None + while ans not in ['y', 'n']: + print "Interval is", v + if prompt: + ans = raw_input("Set interval to %d minutes (y/n)? " % interval) + else: + print "Setting interval to %d minutes" % interval + ans = 'y' + if ans == 'y' : + station.setArchiveInterval(interval) + v = station.getArchiveInterval() + print "Interval is now", v + elif ans == 'n': + print "Set interval cancelled." + +def clearhistory(station, prompt): + ans = None + while ans not in ['y', 'n']: + v = station.getRecordCount() + print "Records in memory:", v + if prompt: + ans = raw_input("Clear console memory (y/n)? ") + else: + print 'Clearing console memory' + ans = 'y' + if ans == 'y' : + station.clearHistory() + v = station.getRecordCount() + print "Records in memory:", v + elif ans == 'n': + print "Clear memory cancelled." + if __name__=="__main__" : main() diff --git a/bin/weewx/drivers/ws23xx.py b/bin/weewx/drivers/ws23xx.py index 473dbae2..b5ff4149 100644 --- a/bin/weewx/drivers/ws23xx.py +++ b/bin/weewx/drivers/ws23xx.py @@ -112,11 +112,11 @@ import select import struct import tty -import weeutil +import weeutil.weeutil import weewx.abstractstation import weewx.wxformulas -DRIVER_VERSION = '0.4' +DRIVER_VERSION = '0.5' DEFAULT_PORT = '/dev/ttyUSB0' def logmsg(dst, msg): @@ -268,11 +268,10 @@ class WS23xx(weewx.abstractstation.AbstractStation): def hardware_name(self): return self.model - # FIXME: do not use archive interval until we can change it # weewx wants the archive interval in seconds, but the console uses minutes -# @property -# def archive_interval(self): -# return self.getArchiveInterval() * 60 + @property + def archive_interval(self): + return self.getArchiveInterval() * 60 # def closePort(self): # pass @@ -370,6 +369,17 @@ class WS23xx(weewx.abstractstation.AbstractStation): serial_port.close() serial_port = None + def setArchiveInterval(self, interval): + serial_port = None + try: + serial_port = LinuxSerialPort(self.port) + ws = Ws2300(serial_port) + set_archive_interval(ws, interval) + finally: + if serial_port is not None: + serial_port.close() + serial_port = None + def getConfig(self): serial_port = None try: @@ -385,6 +395,17 @@ class WS23xx(weewx.abstractstation.AbstractStation): serial_port.close() serial_port = None + def getRecordCount(self): + serial_port = None + try: + serial_port = LinuxSerialPort(self.port) + ws = Ws2300(serial_port) + return get_record_count(ws) + finally: + if serial_port is not None: + serial_port.close() + serial_port = None + def get_wait(self, wait, conn, last_conn): if self.polling_interval is not None: wait = self.polling_interval @@ -398,8 +419,7 @@ class WS23xx(weewx.abstractstation.AbstractStation): # ids for current weather conditions and connection type SENSOR_IDS = [ - 'it','ih','ot','oh','pa', 'ws','wsh','w0','rh','rt','dp','wc','cn' - ] + 'it','ih','ot','oh','pa', 'ws','wsh','w0','rh','rt','dp','wc','cn' ] # polling interval, in seconds, for various connection types POLLING_INTERVAL = { 0:("cable",8), 3:("lost",60), 15:("wireless",30) } @@ -414,19 +434,41 @@ def set_time(ws, ts): def get_time(ws): """Return station time as unix epoch.""" - measures = [Measure.IDS['sw']] - raw_data = read_measurements(ws, measures) - ts = int(measures[0].conv.binary2value(raw_data[0])) + data = get_raw_data(ws, ['sw']) + ts = int(data['sw']) logdbg('station clock is %s' % weeutil.weeutil.timestamp_to_string(ts)) return ts +def set_archive_interval(ws, interval): + """Set the archive interval in minutes.""" + logdbg('setting hardware archive interval to %s minutes' % interval) + for m,v in [(Measure.IDS['hi'],interval), # archive interval + (Measure.IDS['hc'],1), # time till next sample + (Measure.IDS['hn'],0)]: # number of valid records + data = m.conv.value2binary(v) + cmd = m.conv.write(data, None) + ws.write_safe(m.address, *cmd[1:]) + def get_archive_interval(ws): """Return archive interval in minutes.""" - measures = [Measure.IDS['hi']] - raw_data = read_measurements(ws, measures) - interval = int(measures[0].conv.binary2value(raw_data[0])) - logdbg('station archive interval is %s minutes' % interval) - return interval + data = get_raw_data(ws, ['hi']) + x = int(data['hi']) + logdbg('station archive interval is %s minutes' % x) + return x + +def clear_memory(ws): + """Clear station memory.""" + logdbg('clearing console memory') + for m,v in [(Measure.IDS['hn'],0)]: # number of valid records + data = m.conv.value2binary(v) + cmd = m.conv.write(data, None) + ws.write_safe(m.address, *cmd[1:]) + +def get_record_count(ws): + data = get_raw_data(ws, ['hn']) + x = int(data['hn']) + logdbg('record count is %s' % x) + return x def gen_records(ws, since_ts=None, count=None, use_computer_clock=True): """Get latest count records from the station from oldest to newest. If @@ -445,11 +487,13 @@ def gen_records(ws, since_ts=None, count=None, use_computer_clock=True): # FIXME: this is not atomic - if we overlap an interval, data are bogus - measures = [Measure.IDS['hi'],Measure.IDS['hw'],Measure.IDS['hc']] + measures = [ Measure.IDS['hi'], Measure.IDS['hw'], + Measure.IDS['hc'], Measure.IDS['hn'] ] raw_data = read_measurements(ws, measures) interval = 1 + int(measures[0].conv.binary2value(raw_data[0])) # minutes latest_ts = int(measures[1].conv.binary2value(raw_data[1])) # epoch time_to_next = int(measures[2].conv.binary2value(raw_data[2])) # minutes + numrec = int(measures[3].conv.binary2value(raw_data[3])) now = int(time.time()) cstr = 'station' @@ -466,6 +510,8 @@ def gen_records(ws, since_ts=None, count=None, use_computer_clock=True): if count == 0: return + if count and count > numrec: + count = numrec if count and count > HistoryMeasure.MAX_HISTORY_RECORDS: count = HistoryMeasure.MAX_HISTORY_RECORDS diff --git a/weewx.conf b/weewx.conf index 6302f8a4..db97d0fb 100644 --- a/weewx.conf +++ b/weewx.conf @@ -2,20 +2,11 @@ # # # WEEWX CONFIGURATION FILE # # # -############################################################################## -# # # Copyright (c) 2009-2013 Tom Keffer # -# See the file LICENSE.txt for your full rights. # -# # -############################################################################## -# # $Id$ -# ############################################################################## -# # This section is for general configuration information -# # Set to 1 for extra debug info, otherwise comment it out or set to zero. debug = 0 @@ -148,12 +139,7 @@ version = 2.5.0 # Connection type. For now, 'serial' is the only option. type = serial - # A port must be specified: - # Debian, Ubuntu, Redhat, Fedora, and SuSE: - # /dev/ttyUSB0 is a common USB port name - # /dev/ttyS0 is a common serial port name - # BSD: - # /dev/cuaU0 is a common serial port name + # Serial port such as /dev/ttyS0, /dev/ttyUSB0, or /dev/cuaU0 port = /dev/ttyUSB0 # The driver to use @@ -219,7 +205,7 @@ version = 2.5.0 ############################################################################## [TE923] - # This section is for the La Crosse WS-2300 series of weather stations. + # This section is for the Hideki TE923 series of weather stations. # The TE923 is branded by various vendors. Use the model parameter to # indicate the brand, e.g., 'Meade TE923W' or 'TFA Nexus'