Thank you, Ralph, for giving the Ultimeter driver a try! Looking through the code, it appears that, under Python 3, the driver is attempting to use unicode strings, when bytes are called for. In the attached version, I've fixed the most obvious cases where this is happening, but I've probably missed a few.
Can you give it a try? Thanks -tk On Fri, Dec 13, 2019 at 4:07 PM Ralph Underwood <[email protected]> wrote: > Hi, > > > I used Vince's script to install ( that was easy). After all worked with > Simulator, I changed the driver to the Ultimeter, shut down the Rpi4 and > connected the hardware and restarted. > This is my log output. I'm thinking I may need to look into USB rules or > the serialutl.py python3 issue?? > > > Dec 13 14:51:17 JV-Wx systemd[1]: Started weewx weather system. > Dec 13 14:51:17 JV-Wx weewx[1441] INFO weewx.engine: Initializing weewx > version 4.0.0b5 > Dec 13 14:51:17 JV-Wx weewx[1441] INFO weewx.engine: Using Python 3.7.3 > (default, Apr 3 2019, 05:39:12) #012[GCC 8.2.0] > Dec 13 14:51:17 JV-Wx weewx[1441] INFO weewx.engine: Platform > Linux-4.19.75-v7l+-armv7l-with-debian-10.1 > Dec 13 14:51:17 JV-Wx weewx[1441] INFO weewx.engine: Locale is > 'en_US.UTF-8' > Dec 13 14:51:17 JV-Wx weewx[1441] INFO weewx.engine: PID file is > /var/run/weewx.pid > Dec 13 14:51:17 JV-Wx weewx[1448] INFO weewx.engine: Using configuration > file /home/weewx/weewx.conf > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Debug is 1 > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Initializing engine > Dec 13 14:51:17 JV-Wx weewx[1448] INFO weewx.engine: Loading station type > Ultimeter (weewx.drivers.ultimeter) > Dec 13 14:51:17 JV-Wx weewx[1448] INFO weewx.drivers.ultimeter: driver > version is 0.30 > Dec 13 14:51:17 JV-Wx weewx[1448] INFO weewx.drivers.ultimeter: using > serial port /dev/ttyUSB0 > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.drivers.ultimeter: open > serial port /dev/ttyUSB0 > Dec 13 14:51:17 JV-Wx systemd[1]: weewx.service: Supervising process 1448 > which is not our child. We'll most likely not notice when it exits. > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdTimeSynch > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdTimeSynch > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdConvert > Dec 13 14:51:17 JV-Wx weewx[1448] INFO weewx.engine: StdConvert target > unit is 0x1 > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdConvert > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdCalibrate > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdCalibrate > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdQC > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdQC > Dec 13 14:51:17 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.wxservices.StdWXCalculate > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.manager: Daily summary > version is 2.0 > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.wxservices: The following > values will be calculated: altimeter=prefer_hardware, > appTemp=prefer_hardware, barometer=prefer_hardware, > beaufort=prefer_hardware, cloudbase=prefer_hardware, > dewpoint=prefer_hardware, ET=prefer_hardware, heatindex=prefer_hardware, > humidex=prefer_hardware, inDewpoint=prefer_hardware, > maxSolarRad=prefer_hardware, pressure=prefer_hardware, > rainRate=prefer_hardware, windchill=prefer_hardware, windrun=prefer_hardware > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.wxservices: The following > algorithms will be used for calculations: altimeter=aaASOS, maxSolarRad=RS > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.wxservices.StdWXCalculate > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdArchive > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Archive will use data > binding wx_binding > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Record generation > will be attempted in 'hardware' > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Using archive > interval of 300 seconds (specified in weewx configuration) > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Use LOOP data in > hi/low calculations: 1 > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdArchive > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdStationRegistry > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: StationRegistry: > Registration not requested. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdStationRegistry > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdWunderground > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: Wunderground: Posting > not enabled. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdWunderground > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdPWSweather > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: PWSweather: Posting > not enabled. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdPWSweather > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdCWOP > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: CWOP: Posting not > enabled. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdCWOP > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdWOW > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: WOW: Posting not > enabled. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdWOW > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.restx.StdAWEKAS > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.restx: AWEKAS: Posting not > enabled. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.restx.StdAWEKAS > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdPrint > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdPrint > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Loading service > weewx.engine.StdReport > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Finished loading > service weewx.engine.StdReport > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Starting up weewx > version 4.0.0b5 > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.engine: Station does not > support reading the time > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Using binding > 'wx_binding' to database 'weewx.sdb' > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.manager: Starting backfill of > daily summaries > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Starting main packet > loop. > Dec 13 14:51:18 JV-Wx weewx[1448] INFO weewx.engine: Main loop exiting. > Shutting engine down. > Dec 13 14:51:18 JV-Wx weewx[1448] DEBUG weewx.drivers.ultimeter: close > serial port /dev/ttyUSB0 > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: Caught > unrecoverable exception: > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** unicode > strings are not supported, please encode to bytes: '>I\r' > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > Traceback (most recent call last): > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/home/weewx/bin/weewx/engine.py", line 892, in main > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > engine.run() > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/home/weewx/bin/weewx/engine.py", line 193, in run > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** for > packet in self.console.genLoopPackets(): > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/home/weewx/bin/weewx/drivers/ultimeter.py", line 123, in genLoopPackets > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > self.station.set_logger_mode() > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/home/weewx/bin/weewx/drivers/ultimeter.py", line 213, in set_logger_mode > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > self.serial_port.write(">I\r") > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/usr/lib/python3/dist-packages/serial/serialposix.py", line 532, in write > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** d = > to_bytes(data) > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** File > "/usr/lib/python3/dist-packages/serial/serialutil.py", line 63, in to_bytes > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > raise TypeError('unicode strings are not supported, please encode to bytes: > {!r}'.format(seq)) > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** > TypeError: unicode strings are not supported, please encode to bytes: '>I\r' > Dec 13 14:51:19 JV-Wx weewx[1448] CRITICAL weewx.engine: **** Exiting. > Dec 13 14:51:19 JV-Wx systemd[1]: weewx.service: Main process exited, > code=exited, status=1/FAILURE > Dec 13 14:51:19 JV-Wx systemd[1]: weewx.service: Failed with result > 'exit-code'. > > > > > > > On Tuesday, November 26, 2019 at 5:24:07 PM UTC-8, Tom Keffer wrote: >> >> In the usual place <http://weewx.com/downloads/development_versions/>. >> >> What we really need is testing of the drivers, particularly under Python >> 3. If you have something other than a Vantage, please install and check it >> out! >> >> -tk >> > -- > You received this message because you are subscribed to the Google Groups > "weewx-development" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/weewx-development/0bc517bb-8a0b-41b0-b522-24b5116bd85e%40googlegroups.com > <https://groups.google.com/d/msgid/weewx-development/0bc517bb-8a0b-41b0-b522-24b5116bd85e%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "weewx-development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/weewx-development/CAPq0zEB8PYtzn%2Bq5vRdcEpbZsPjH3J8%3DdOv%2BDU2ekmCgLP%3DHvw%40mail.gmail.com.
#!/usr/bin/env python # # Copyright 2014 Matthew Wall # Copyright 2014 Nate Bargmann <[email protected]> # See the file LICENSE.txt for your rights. # # Credit to and contributions from: # Jay Nugent (WB8TKL) and KRK6 for weather-2.kr6k-V2.1 # http://server1.nuge.com/~weather/ # Steve (sesykes71) for testing the first implementations of this driver # Garret Power for improved decoding and proper handling of negative values # Chris Thompstone for testing the fast-read implementation # # Thanks to PeetBros for publishing the communication protocols and details # about each model they manufacture. """Driver for Peet Bros Ultimeter weather stations except the Ultimeter II This driver assumes the Ultimeter is emitting data in Peet Bros Data Logger mode format. This driver will set the mode automatically on stations manufactured after 2004. Stations manufactured before 2004 must be set to data logger mode using the buttons on the console. Resources for the Ultimeter stations Ultimeter Models 2100, 2000, 800, & 100 serial specifications: http://www.peetbros.com/shop/custom.aspx?recid=29 Ultimeter 2000 Pinouts and Parsers: http://www.webaugur.com/ham-radio/52-ultimeter-2000-pinouts-and-parsers.html Ultimeter II not supported by this driver All models communicate over an RS-232 compatible serial port using three wires--RXD, TXD, and Ground (except Ultimeter II which omits TXD). Port parameters are 2400, 8N1, with no flow control. The Ultimeter hardware supports several "modes" for providing station data to the serial port. This driver utilizes the "modem mode" to set the date and time of the Ultimeter upon initialization and then sets it into Data Logger mode for continuous updates. Modem Mode commands used by the driver >Addddmmmm Set Date and Time (decimal digits dddd = day of year, mmmm = minute of day; Jan 1 = 0000, Midnight = 0000) >I Set output mode to Data Logger Mode (continuous output) """ from __future__ import with_statement from __future__ import absolute_import from __future__ import print_function import logging import serial import time import weewx.drivers import weewx.wxformulas from weewx.units import INHG_PER_MBAR, MILE_PER_KM from weeutil.weeutil import timestamp_to_string log = logging.getLogger(__name__) DRIVER_NAME = 'Ultimeter' DRIVER_VERSION = '0.30' def loader(config_dict, _): return UltimeterDriver(**config_dict[DRIVER_NAME]) def confeditor_loader(): return UltimeterConfEditor() def _fmt(x): return ' '.join(["%0.2X" % ord(c) for c in x]) class UltimeterDriver(weewx.drivers.AbstractDevice): """weewx driver that communicates with a Peet Bros Ultimeter station model: station model, e.g., 'Ultimeter 2000' or 'Ultimeter 100' [Optional. Default is 'Ultimeter'] port - serial port [Required. Default is /dev/ttyUSB0] max_tries - how often to retry serial communication before giving up [Optional. Default is 5] """ def __init__(self, **stn_dict): self.model = stn_dict.get('model', 'Ultimeter') self.port = stn_dict.get('port', Station.DEFAULT_PORT) self.max_tries = int(stn_dict.get('max_tries', 5)) self.retry_wait = int(stn_dict.get('retry_wait', 3)) debug_serial = int(stn_dict.get('debug_serial', 0)) self.last_rain = None log.info('driver version is %s' % DRIVER_VERSION) log.info('using serial port %s' % self.port) self.station = Station(self.port, debug_serial=debug_serial) self.station.open() def closePort(self): if self.station is not None: self.station.close() self.station = None @property def hardware_name(self): return self.model def DISABLED_getTime(self): return self.station.get_time() def DISABLED_setTime(self): self.station.set_time(int(time.time())) def genLoopPackets(self): self.station.set_logger_mode() while True: packet = {'dateTime': int(time.time() + 0.5), 'usUnits': weewx.US} readings = self.station.get_readings_with_retry(self.max_tries, self.retry_wait) data = Station.parse_readings(readings) packet.update(data) self._augment_packet(packet) yield packet def _augment_packet(self, packet): packet['rain'] = weewx.wxformulas.calculate_rain( packet['rain_total'], self.last_rain) self.last_rain = packet['rain_total'] class Station(object): DEFAULT_PORT = '/dev/ttyUSB0' def __init__(self, port, debug_serial=0): self._debug_serial = debug_serial self.port = port self.baudrate = 2400 self.timeout = 3 # seconds self.serial_port = None # setting the year works only for models 2004 and later self.can_set_year = True # modem mode is available only on models 2004 and later # not available on pre-2004 models 50/100/500/700/800 self.has_modem_mode = True def __enter__(self): self.open() return self def __exit__(self, _, value, traceback): self.close() def open(self): log.debug("open serial port %s" % self.port) self.serial_port = serial.Serial(self.port, self.baudrate, timeout=self.timeout) def close(self): if self.serial_port is not None: log.debug("close serial port %s" % self.port) self.serial_port.close() self.serial_port = None def get_time(self): try: self.set_logger_mode() buf = self.get_readings_with_retry() data = Station.parse_readings(buf) d = data['day_of_year'] # seems to start at 0 m = data['minute_of_day'] # 0 is midnight before start of day tt = time.localtime() y = tt.tm_year s = tt.tm_sec ts = time.mktime((y, 1, 1, 0, 0, s, 0, 0, -1)) + d * 86400 + m * 60 log.debug("station time: day:%s min:%s (%s)" % (d, m, timestamp_to_string(ts))) return ts except (serial.serialutil.SerialException, weewx.WeeWxIOError) as e: log.error("get_time failed: %s" % e) return int(time.time()) def set_time(self, ts): # go to modem mode so we do not get logger chatter self.set_modem_mode() # set time should work on all models tt = time.localtime(ts) cmd = b">A%04d%04d" % (tt.tm_yday - 1, tt.tm_min + tt.tm_hour * 60) log.debug("set station time to %s (%s)" % (timestamp_to_string(ts), cmd)) self.serial_port.write(b"%s\r" % cmd) # year works only for models 2004 and later if self.can_set_year: cmd = b">U%s" % tt.tm_year log.debug("set station year to %s (%s)" % (tt.tm_year, cmd)) self.serial_port.write(b"%s\r" % cmd) def set_logger_mode(self): # in logger mode, station sends logger mode records continuously if self._debug_serial: log.debug("set station to logger mode") self.serial_port.write(b">I\r") def set_modem_mode(self): # setting to modem mode should stop data logger output if self.has_modem_mode: if self._debug_serial: log.debug("set station to modem mode") self.serial_port.write(b">\r") def get_readings(self): buf = self.serial_port.readline() if self._debug_serial: log.debug("station said: %s" % _fmt(buf)) buf = buf.strip() # FIXME: is this necessary? return buf @staticmethod def validate_string(buf): if len(buf) not in [42, 46, 50]: raise weewx.WeeWxIOError("Unexpected buffer length %d" % len(buf)) if buf[0:2] != '!!': raise weewx.WeeWxIOError("Unexpected header bytes '%s'" % buf[0:2]) return buf def get_readings_with_retry(self, max_tries=5, retry_wait=3): for ntries in range(max_tries): try: buf = self.get_readings() self.validate_string(buf) return buf except (serial.serialutil.SerialException, weewx.WeeWxIOError) as e: log.info("Failed attempt %d of %d to get readings: %s" % (ntries + 1, max_tries, e)) time.sleep(retry_wait) else: msg = "Max retries (%d) exceeded for readings" % max_tries log.error(msg) raise weewx.RetriesExceeded(msg) @staticmethod def parse_readings(raw): """Ultimeter stations emit data in PeetBros format. Each line has 52 characters - 2 header bytes, 48 data bytes, and a carriage return and line feed (new line): !!000000BE02EB000027700000023A023A0025005800000000\r\n SSSSXXDDTTTTLLLLPPPPttttHHHHhhhhddddmmmmRRRRWWWW SSSS - wind speed (0.1 kph) XX - wind direction calibration DD - wind direction (0-255) TTTT - outdoor temperature (0.1 F) LLLL - long term rain (0.01 in) PPPP - pressure (0.1 mbar) tttt - indoor temperature (0.1 F) HHHH - outdoor humidity (0.1 %) hhhh - indoor humidity (0.1 %) dddd - date (day of year) mmmm - time (minute of day) RRRR - daily rain (0.01 in) WWWW - one minute wind average (0.1 kph) "pressure" reported by the Ultimeter 2000 is correlated to the local official barometer reading as part of the setup of the station console so this value is assigned to the 'barometer' key and the pressure and altimeter values are calculated from it. Some stations may omit daily_rain or wind_average, so check for those. """ buf = raw[2:] data = dict() data['windSpeed'] = Station._decode(buf[0:4], 0.1 * MILE_PER_KM) # mph data['windDir'] = Station._decode(buf[6:8], 1.411764) # compass deg data['outTemp'] = Station._decode(buf[8:12], 0.1, neg=True) # degree_F data['rain_total'] = Station._decode(buf[12:16], 0.01) # inch data['barometer'] = Station._decode(buf[16:20], 0.1 * INHG_PER_MBAR) # inHg data['inTemp'] = Station._decode(buf[20:24], 0.1, neg=True) # degree_F data['outHumidity'] = Station._decode(buf[24:28], 0.1) # percent data['inHumidity'] = Station._decode(buf[28:32], 0.1) # percent data['day_of_year'] = Station._decode(buf[32:36]) data['minute_of_day'] = Station._decode(buf[36:40]) if len(buf) > 40: data['daily_rain'] = Station._decode(buf[40:44], 0.01) # inch if len(buf) > 44: data['wind_average'] = Station._decode(buf[44:48], 0.1 * MILE_PER_KM) # mph return data @staticmethod def _decode(s, multiplier=None, neg=False): """Ultimeter puts hyphens in the string when a sensor is not installed. When we get a hyphen or any other non-hex character, return None. Negative values are represented in twos complement format. Only do the check for negative values if requested, since some parameters use the full set of bits (e.g., wind direction) and some do not (e.g., temperature). """ # TODO: The twos-complement arithmetic is unnecessary. Better to use the 'struct' module. v = None try: v = int(s, 16) if neg: bits = 4 * len(s) if v & (1 << (bits - 1)) != 0: v -= (1 << bits) if multiplier is not None: v *= multiplier except ValueError as e: if s != b'----': log.debug("decode failed for '%s': %s" % (s, e)) return v class UltimeterConfEditor(weewx.drivers.AbstractConfEditor): @property def default_stanza(self): return """ [Ultimeter] # This section is for the PeetBros Ultimeter series of weather stations. # Serial port such as /dev/ttyS0, /dev/ttyUSB0, or /dev/cua0 port = %s # The station model, e.g., Ultimeter 2000, Ultimeter 100 model = Ultimeter # The driver to use: driver = weewx.drivers.ultimeter """ % Station.DEFAULT_PORT def prompt_for_settings(self): print("Specify the serial port on which the station is connected, for") print("example: /dev/ttyUSB0 or /dev/ttyS0 or /dev/cua0.") port = self._prompt('port', Station.DEFAULT_PORT) return {'port': port} # define a main entry point for basic testing of the station without weewx # engine and service overhead. invoke this as follows from the weewx root dir: # # PYTHONPATH=bin python bin/weewx/drivers/ultimeter.py if __name__ == '__main__': import optparse import weewx import weeutil.logger usage = """%prog [options] [--help]""" parser = optparse.OptionParser(usage=usage) parser.add_option('--version', dest='version', action='store_true', help='display driver version') parser.add_option('--debug', dest='debug', action='store_true', help='provide additional debug output in log') parser.add_option('--port', dest='port', metavar='PORT', help='serial port to which the station is connected', default=Station.DEFAULT_PORT) (options, args) = parser.parse_args() if options.version: print("ultimeter driver version %s" % DRIVER_VERSION) exit(0) if options.debug: weewx.debug = 1 weeutil.logger.setup('ultimeter', {}) with Station(options.port, debug_serial=options.debug) as station: station.set_logger_mode() while True: print(time.time(), _fmt(station.get_readings()))
