Skip to content

Commit

Permalink
merge with master
Browse files Browse the repository at this point in the history
  • Loading branch information
pi committed Apr 21, 2016
2 parents 16369a8 + f60a1a4 commit 1bae999
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 45 deletions.
4 changes: 2 additions & 2 deletions bin/weewx/drivers/ultimeter.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@
from weeutil.weeutil import timestamp_to_string

DRIVER_NAME = 'Ultimeter'
DRIVER_VERSION = '0.15'
DRIVER_VERSION = '0.16'

INHG_PER_MBAR = 0.0295333727
INHG_PER_MBAR = 0.0295299830714
METER_PER_FOOT = 0.3048
MILE_PER_KM = 0.621371

Expand Down
103 changes: 61 additions & 42 deletions bin/weewx/drivers/ws1.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import weewx.drivers

DRIVER_NAME = 'WS1'
DRIVER_VERSION = '0.24'
DRIVER_VERSION = '0.25'


def loader(config_dict, _):
Expand All @@ -30,7 +30,7 @@ def confeditor_loader():
return WS1ConfEditor()


INHG_PER_MBAR = 0.0295333727
INHG_PER_MBAR = 0.0295299830714
METER_PER_FOOT = 0.3048
MILE_PER_KM = 0.621371

Expand Down Expand Up @@ -60,12 +60,13 @@ class WS1Driver(weewx.drivers.AbstractDevice):
[Required. Default is serial]
port - Serial port or network address.
[Required. Default is /dev/ttyS0 for serial, and 192.168.36.25:3000 for TCP]
[Required. Default is /dev/ttyS0 for serial,
and 192.168.36.25:3000 for TCP/IP]
max_tries - how often to retry serial communication before giving up.
[Optional. Default is 5]
retry_wait - how long to wait, in seconds, before retrying after a failure.
wait_before_retry - how long to wait, in seconds, before retrying after a failure.
[Optional. Default is 10]
timeout - The amount of time, in seconds, before the connection fails if
Expand All @@ -81,23 +82,31 @@ def __init__(self, **stn_dict):

con_mode = stn_dict.get('mode', 'serial').lower()
if con_mode == 'tcp' or con_mode == 'udp':
self.port = stn_dict.get(
port = stn_dict.get(
'port', '%s:%d' % (DEFAULT_TCP_ADDR, DEFAULT_TCP_PORT))
elif con_mode == 'serial':
port = stn_dict.get('port', DEFAULT_SER_PORT)
else:
self.port = stn_dict.get('port', DEFAULT_SER_PORT)
raise ValueError("Invalid driver connection mode %s" % con_mode)

self.max_tries = int(stn_dict.get('max_tries', 5))
self.retry_wait = int(stn_dict.get('retry_wait', 10))
self.last_rain = None
self.wait_before_retry = float(stn_dict.get('wait_before_retry', 10))
timeout = int(stn_dict.get('timeout', 3))
loginf('using %s port %s' % (con_mode, self.port))

self.last_rain = None

loginf('using %s port %s' % (con_mode, port))

global DEBUG_READ
DEBUG_READ = int(stn_dict.get('debug_read', DEBUG_READ))

if con_mode == 'tcp' or con_mode == 'udp':
self.station = StationInet(self.port, con_mode, timeout=timeout)
self.station = StationSocket(port, protocol=con_mode,
timeout=timeout,
max_tries=self.max_tries,
wait_before_retry=self.wait_before_retry)
else:
self.station = StationSerial(self.port, timeout=timeout)
self.station = StationSerial(port, timeout=timeout)
self.station.open()

def closePort(self):
Expand All @@ -114,7 +123,7 @@ def genLoopPackets(self):
packet = {'dateTime': int(time.time() + 0.5),
'usUnits': weewx.US}
readings = self.station.get_readings_with_retry(self.max_tries,
self.retry_wait)
self.wait_before_retry)
data = StationData.parse_readings(readings)
packet.update(data)
self._augment_packet(packet)
Expand Down Expand Up @@ -248,7 +257,7 @@ def get_readings(self):
buf = buf.strip()
return buf

def get_readings_with_retry(self, max_tries=5, retry_wait=10):
def get_readings_with_retry(self, max_tries=5, wait_before_retry=10):
import serial
for ntries in range(0, max_tries):
try:
Expand All @@ -258,7 +267,7 @@ def get_readings_with_retry(self, max_tries=5, retry_wait=10):
except (serial.serialutil.SerialException, weewx.WeeWxIOError), e:
loginf("Failed attempt %d of %d to get readings: %s" %
(ntries + 1, max_tries, e))
time.sleep(retry_wait)
time.sleep(wait_before_retry)
else:
msg = "Max retries (%d) exceeded for readings" % max_tries
logerr(msg)
Expand All @@ -271,54 +280,72 @@ def get_readings_with_retry(self, max_tries=5, retry_wait=10):
# =========================================================================== #


class StationInet(object):
def __init__(self, addr, protocol='tcp', timeout=3):
class StationSocket(object):
def __init__(self, addr, protocol='tcp', timeout=3, max_tries=5,
wait_before_retry=10):
import socket

ip_addr = None
ip_port = None
self.protocol = protocol

self.max_tries = max_tries
self.wait_before_retry = wait_before_retry

if addr.find(':') != -1:
self.conn_info = addr.split(':')
try:
self.conn_info[1] = int(self.conn_info[1], 10)
except TypeError:
self.conn_info[1] = DEFAULT_TCP_PORT
self.conn_info[1] = int(self.conn_info[1], 10)
self.conn_info = tuple(self.conn_info)
else:
ip_addr = addr
ip_port = DEFAULT_TCP_PORT
self.conn_info = (ip_addr, ip_port)

try:
if self.protocol == 'tcp':
if protocol == 'tcp':
self.net_socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
elif self.protocol == 'udp':
elif protocol == 'udp':
self.net_socket = socket.socket(
socket.AF_INET, socket.SOCK_DGRAM)
except (socket.error, socket.herror), ex:
logerr("Cannot create socket for some reason: %s" % ex)
raise weewx.WeeWxIOError(ex)

self.net_socket.settimeout(timeout)
self.rec_start = False

def open(self):
import socket

logdbg("Connecting to %s:%d." % (self.conn_info[0], self.conn_info[1]))
try:
self.net_socket.connect(self.conn_info)
except (socket.error, socket.timeout, socket.herror), ex:
logerr("Cannot connect to %s:%d for some reason: %s" % (
self.conn_info[0], self.conn_info[1], ex))
raise weewx.WeeWxIOError(ex)

for conn_attempt in range(self.max_tries):
try:
if conn_attempt > 1:
logdbg("Retrying connection...")
self.net_socket.connect(self.conn_info)
break
except (socket.error, socket.timeout, socket.herror), ex:
logerr("Cannot connect to %s:%d for some reason: %s. "
"%d tries left." % (
self.conn_info[0], self.conn_info[1], ex,
self.max_tries - (conn_attempt + 1)))
logdbg("Will retry in %.2f seconds..." % self.wait_before_retry)
time.sleep(self.wait_before_retry)
else:
logerr("Max tries (%d) exceeded for connection." %
self.max_tries)
raise weewx.RetriesExceeded("Max tries exceeding while attempting connection")

def close(self):
import socket

logdbg("Closing connection to %s:%d." %
(self.conn_info[0], self.conn_info[1]))
try:
self.net_socket.close()
except (socket.error, socket.herror, socket.timeout), ex:
logerr("Cannot close connection to %s:%d for some reason: %s" % (
logerr("Cannot close connection to %s:%d. Reason: %s" % (
self.conn_info[0], self.conn_info[1], ex))
raise weewx.WeeWxIOError(ex)

Expand Down Expand Up @@ -386,27 +413,19 @@ def get_readings(self):
raise weewx.WeeWxIOError(ex)
if DEBUG_READ >= 2:
logdbg("buf: %s" % buf)
# This code assumes CRLF will be transmitted at the end of each record,
# which may not always be the case. See Matthew Wall's comment on
# GitHub here:
# https://github.com/weewx/weewx/pull/86#issuecomment-166716509

# try:
# self.net_socket.recv(2, socket.MSG_WAITALL) # CRLF
# except (socket.error, socket.timeout), ex:
# raise weewx.WeeWxIOError(ex)

buf.strip()
return buf

def get_readings_with_retry(self, max_tries=5, retry_wait=10):
def get_readings_with_retry(self, max_tries=5, wait_before_retry=10):
for _ in range(0, max_tries):
buf = ''
try:
buf = self.get_readings()
StationData.validate_string(buf)
return buf
except (weewx.WeeWxIOError), e:
loginf("Failed to get data for some reason: %s" % e)
logdbg("Failed to get data. Reason: %s" % e)
self.rec_start = False

# NOTE: WeeWx IO Errors may not always occur because of
Expand All @@ -417,7 +436,7 @@ def get_readings_with_retry(self, max_tries=5, retry_wait=10):
logdbg("buf: %s (%d bytes), rec_start: %r" %
(buf, len(buf), self.rec_start))

time.sleep(retry_wait)
time.sleep(wait_before_retry)
else:
msg = "Max retries (%d) exceeded for readings" % max_tries
logerr(msg)
Expand Down
2 changes: 1 addition & 1 deletion bin/weewx/restx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ def _get_connect(self, server, port):
# Unsuccessful. Close it in case it was open:
try:
_sock.close()
except socket.error:
except AttributeError, socket.error:
pass
raise ConnectError(e)

Expand Down
5 changes: 5 additions & 0 deletions docs/changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ Fixed anti-alias bug in genplot. Issue #111.

Corrected the conversion factor between inHg and mbar. Thanks to user Olivier.

Corrected conversion factor for inHg and mbar in ultimeter driver.

Plots longer than two years now use an x-axis increment of one year. Thanks to
user Olivier!

The WS1 driver now retries connection if it fails. Thanks to user
Kevin Caccamo! PR #112.

Major update to the CC3000 driver:
- reading historical records is more robust
- added better error handling and reporting
Expand Down

0 comments on commit 1bae999

Please sign in to comment.