Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions simple_rpc/simple_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from serial import serial_for_url
from serial.serialutil import SerialException
from serial.urlhandler.protocol_socket import Serial as socket_serial

from .extras import make_function
from .io import read, read_byte_string, write
Expand All @@ -28,6 +29,7 @@ def __init__(self, device, baudrate=9600, wait=1, autoconnect=True):
self._wait = wait

self._connection = serial_for_url(device)
self._is_socket = isinstance(self._connection, socket_serial)
self._connection.baudrate = baudrate
self._version = (0, 0, 0)
self._endianness = b'<'
Expand All @@ -44,6 +46,21 @@ def __enter__(self):
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()

def _auto_open(f):
"""Decorator for automatic opening and closing of ethernet sockets."""
def _auto_open_wrapper(self, *args, **kwargs):
if self._is_socket:
self._connection.open()

result = f(self, *args, **kwargs)

if self._is_socket:
self._connection.close()

return result

return _auto_open_wrapper

def _select(self, index):
"""Initiate a remote procedure call, select the method.

Expand Down Expand Up @@ -73,6 +90,7 @@ def _read(self, obj_type):
return read(
self._connection, self._endianness, self._size_t, obj_type)

@_auto_open
def _get_methods(self):
"""Get remote procedure call methods.

Expand Down Expand Up @@ -114,22 +132,20 @@ def open(self):
self._connection.open()
except SerialException as error:
raise IOError(error.strerror.split(':')[0])
sleep(self._wait)

self.methods = self._get_methods()
for method in self.methods.values():
setattr(
self, method['name'], MethodType(make_function(method), self))
if not self._is_socket or len(self.methods) == 0:
sleep(self._wait)
self.methods = self._get_methods()
for method in self.methods.values():
setattr(
self, method['name'], MethodType(make_function(method), self))

def close(self):
"""Disconnect from device."""
if not self.is_open():
return

for method in self.methods:
delattr(self, method)

self.methods = {}
if not self._is_socket:
for method in self.methods:
delattr(self, method)
self.methods = {}

if (self._connection):
self._connection.close()
Expand All @@ -138,7 +154,7 @@ def is_open(self):
"""Query device state."""
return self._connection.isOpen()


@_auto_open
def call_method(self, name, *args):
"""Execute a method.

Expand Down