Skip to content

Commit

Permalink
still working on error handling
Browse files Browse the repository at this point in the history
pyownet.protocol.Error hierarchy reorganized

better code for fetching errcodes from owserver
  • Loading branch information
miccoli committed Apr 6, 2014
1 parent e6ebe54 commit c2b0d5d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pyownet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

__version__ = '0.7.1.dev0'
__version__ = '0.7.1.dev1'
51 changes: 34 additions & 17 deletions pyownet/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import struct
import socket

# see msg_classification from ow_message.h
# see 'enum msg_classification' from ow_message.h
MSG_ERROR = 0
MSG_NOP = 1
MSG_READ = 2
Expand Down Expand Up @@ -93,13 +93,18 @@
FLG_FORMAT_FIC = 0x05000000 # /1067C6697351FF8D
MSK_DEVFORMAT = 0xFF000000

# useful paths
PTH_ERRCODES = '/settings/return_codes/text.ALL'


# internal constants

# socket timeout (s)
_SCK_TIMEOUT = 2.0
# do not attempt to read messages bigger than this (bytes)
_MAX_PAYLOAD = 65536


def str2bytez(s):
"transform string to zero-terminated bytes"
if not isinstance(s, basestring):
Expand All @@ -123,23 +128,33 @@ class Error(Exception):


class ConnError(Error, IOError):
"""Connection failed"""
"""raised if no valid connection can be established with owserver"""
pass


class ShortRead(Error):
class ProtocolError(Error):
"""raised if no valid server response was received"""
pass


class ShortWrite(Error):
class MalformedHeader(ProtocolError):
def __init__(self, msg, header):
self.msg = msg
self.header = header
def __str__(self):
return "{0.msg}: {0.header!s} == {0.header!r}".format(self)


class ShortRead(ProtocolError):
pass


class ProtocolError(Error):
class ShortWrite(ProtocolError):
pass


class OwnetError(Error, EnvironmentError):
"""raised if owserver returns error code"""
pass


Expand Down Expand Up @@ -292,11 +307,9 @@ def _read_msg(self):
if self.verbose:
print('<-', repr(header))
if header.version != 0:
raise ProtocolError('got malformed header: %s "%s"' %
(repr(header), header))
raise MalformedHeader('bad version magic', header)
if header.payload > _MAX_PAYLOAD:
raise ProtocolError('huge data, unwilling to read: %s "%s"' %
(repr(header), header))
raise MalformedHeader('huge data, unwilling to read', header)
if header.payload > 0:
payload = self.socket.recv(header.payload)
if len(payload) < header.payload:
Expand Down Expand Up @@ -349,22 +362,26 @@ def __init__(self, host='localhost', port=4304, flags=0,
# here we have an open connection, close for now
conn.shutdown()

# setup self attributes
self._sockaddr, self._family = sockaddr, family
self._hostport = (host, port) # for display only

self.verbose = verbose
self.flags = flags | FLG_OWNET

# check if owserver on the line
self.ping()
self.errmess = _errtuple()

#self.errmess = _dummy()
# final sanity checks
# does the remote end speak the ownet protocol?
self.ping()

# fetch errcodes array from owserver
errcodes = '/settings/return_codes/text.ALL'
assert self.present(errcodes)
self.errmess = _errtuple(
m for m in bytes2str(self.read(errcodes)).split(','))
try:
self.errmess = _errtuple(
m for m in bytes2str(self.read(PTH_ERRCODES)).split(','))
except OwnetError:
# failed, leave the default defined above
pass

def __str__(self):
return "ownet server at %s" % (self._hostport, )
Expand Down Expand Up @@ -455,7 +472,7 @@ def _main():
except ConnError:
print("No owserver on localhost")
return 1
print("directory on %s:" % proxy)
print("directory on {0}:".format(proxy))
print("id".center(17), "type".center(7))
for sensor in proxy.dir(slash=False, bus=False):
stype = bytes2str(proxy.read(sensor + '/type'))
Expand Down
13 changes: 7 additions & 6 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ class TestProtocolModule(unittest.TestCase):

@classmethod
def setUpClass(cls):
cls.proxy = protocol.OwnetProxy()
try:
cls.proxy = protocol.OwnetProxy()
except protocol.ConnError as exc:
raise RuntimeError('no owserver on localhost, got:%s' % exc)

def test_ping(self):
self.assertIsNone(self.proxy.ping())
Expand All @@ -14,15 +17,13 @@ def test_present(self):
self.assertIs(self.proxy.present('/'), True)
self.assertIs(self.proxy.present('/nonexistent'), False)

def test_dir(self):
def test_dir_read(self):
for i in self.proxy.dir(bus=False):
self.assertTrue(self.proxy.present(i))
self.assertTrue(self.proxy.present(i + 'type'))
stype = self.proxy.read(i + 'type')
self.proxy.read(i + 'type')
if self.proxy.present(i + 'temperature'):
temp = self.proxy.read(i + 'temperature')
else:
temp = ''
self.proxy.read(i + 'temperature')

def test_exceptions(self):
self.assertRaises(protocol.OwnetError, self.proxy.dir, '/nonexistent')
Expand Down

0 comments on commit c2b0d5d

Please sign in to comment.