Skip to content

Commit

Permalink
[FX-431]-v12.0.0 (#123)
Browse files Browse the repository at this point in the history
* Catches exception if close fails.

* Adds fxIsOpen, fxIsStreaming, and find_device_ports.

* Bumps version to 12.0.0.

* Adds motorStopOnDisconnect.

* Adds pyserial as a dependency.

* Fixes a bug in streaming.

* Reverted stdout redirection in find_device_ports.

* Lints.

* Adds stop_motor to the demos.

* Makes find_device_ports only work on linux.

* find_device_ports no longer raises an exception if no devices are found.

* Uses pyudev instead of pyserial to find ports.

* Adds pyudev as a dependency.

* Adds pyudev to pre-commit and lints.

---------

Co-authored-by: Jared <jcoughlin@dephy.com>
  • Loading branch information
jcoughlin11 and Jared authored Oct 31, 2023
1 parent 207be38 commit 657504f
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 126 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ repos:
- --output-format=colorized
additional_dependencies:
- boto3
- pyserial
- pyudev
- semantic-version
- seaborn
- nox
Expand Down
1 change: 1 addition & 0 deletions demos/demo1.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@

# Once we're done using the device, we should clean up by calling the
# close method
device.stop_motor()
device.close()
1 change: 1 addition & 0 deletions demos/demo2.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
# complete the command
sleep(commandDelay)

device.stop_motor()
device.close()


Expand Down
1 change: 1 addition & 0 deletions demos/demo3.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,5 @@ def clear() -> None:
device.stop_motor()
sleep(commandDelay)

device.stop_motor()
device.close()
1 change: 1 addition & 0 deletions demos/demo4.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@

sleep(commandDelay)

device.stop_motor()
device.close()


Expand Down
2 changes: 1 addition & 1 deletion flexsea/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "11.0.9"
__version__ = "12.0.0"
67 changes: 46 additions & 21 deletions flexsea/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ class Device:
Time, in seconds, spent trying to connect to S3 before an
exception is raised.
stopMotorOnDisconnect : bool, optional
If ``True``, ``stop_motor`` is called by ``close`` (which, in
turn, is called by the desctructor). If ``False``, ``stop_motor``
is **not** called by ``close`` or the destructor. The default
value is ``False``. This is useful for on-device controllers
(controllers that are baked into the device firmware), so
that, should the device become disconnected from the computer it
is streaming data to, the controller will not suddenly shut off
and cause the wearer to potentially fall. If this is ``True``, you
must call ``stop_motor`` manually.
Attributes
----------
Expand Down Expand Up @@ -165,19 +176,15 @@ def __init__(
interactive: bool = True,
debug: bool = False,
s3Timeout: int = 60,
stopMotorOnDisconnect: bool = False,
) -> None:
if not debug:
sys.tracebacklimit = 0
fxc.dephyPath.mkdir(parents=True, exist_ok=True)
# These are first so the destructor won't complain about the
# class not having connected and streaming attributes if getting
# and loading the C library fails (since these attrs are
# referenced in the destructor)
self.connected: bool = False
self.streaming: bool = False

self.port: str = port
self.interactive = interactive
self._stopMotorOnDisconnect = stopMotorOnDisconnect

self.firmwareVersion = validate_given_firmware_version(
firmwareVersion, self.interactive, s3Timeout
Expand Down Expand Up @@ -240,7 +247,13 @@ def __init__(
# destructor
# -----
def __del__(self) -> None:
self.close()
if self.connected:
try:
self.close()
except RuntimeError:
print("Failed to close connection. Is the device disconnected or off?")
else:
print("Closed connection to device.")

# -----
# open
Expand All @@ -257,7 +270,7 @@ def open(self, bootloading: bool = False) -> None:
----------
bootloading : bool (optional)
This keyword is really onlymeant to be used by the
bootloader and a user of `flexsea` should not have to use
bootloader and a user of ``flexsea`` should not have to use
it at all.
Starting with v12.0.0, a development version number was
introduced. We can only connect to the device if both the
Expand Down Expand Up @@ -285,8 +298,6 @@ def open(self, bootloading: bool = False) -> None:
if self.id in (self._INVALID_DEVICE.value, -1):
raise RuntimeError("Failed to connect to device.")

self.connected = True

self._name = self.name
self._side = self.side
self._hasHabs = self._name not in fxc.noHabs
Expand Down Expand Up @@ -352,17 +363,19 @@ def _get_fields(self) -> None:
# -----
def close(self) -> None:
"""
Severs connection with device.
Severs connection with device. Does not stop the motor by
default. To stop the motor on a call to ``close``,
Will no longer be able to send commands or receive data.
"""
if self.streaming:
self.stop_streaming()
if self.connected or self.streaming:
if self._stopMotorOnDisconnect:
self.stop_motor()
# fxClose calls fxStopStreaming for us
retCode = self._clib.fxClose(self.id)

if self.connected:
self.stop_motor()
self._clib.fxClose(self.id)
self.connected = False
if retCode != self._SUCCESS.value:
raise RuntimeError("Failed to close connection.")

# -----
# start_streaming
Expand Down Expand Up @@ -415,8 +428,6 @@ def start_streaming(
else:
self._stream_without_safety()

self.streaming = True

# -----
# _stream_with_safety
# -----
Expand Down Expand Up @@ -453,8 +464,6 @@ def stop_streaming(self) -> None:
if retCode != self._SUCCESS.value:
raise RuntimeError("Failed to stop streaming.")

self.streaming = False

# -----
# set_gains
# -----
Expand Down Expand Up @@ -1631,3 +1640,19 @@ def set_file_size(self, size) -> None:
The desired name of the log file
"""
return self._clib.fxSetLoggerSize(size, self.id)

# -----
# connected
# -----
@property
def connected(self) -> bool:
return self._clib.fxIsOpen(self.id)

# -----
# streaming
# -----
@property
def streaming(self) -> bool:
if self.connected:
return self._clib.fxIsStreaming(self.id)
return False
6 changes: 6 additions & 0 deletions flexsea/utilities/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ def _set_prototypes(clib: c.CDLL, firmwareVersion: Version) -> c.CDLL:
clib.fxOpen.argtypes = [c.c_char_p, c.c_uint, c.c_uint]
clib.fxOpen.restype = c.c_int

clib.fxIsOpen.argtypes = [c.c_uint]
clib.fxIsOpen.restype = c.c_bool

# Limited open
if firmwareVersion >= Version("12.0.0"):
try:
Expand All @@ -160,6 +163,9 @@ def _set_prototypes(clib: c.CDLL, firmwareVersion: Version) -> c.CDLL:
clib.fxStartStreaming.argtypes = [c.c_uint, c.c_uint, c.c_bool]
clib.fxStartStreaming.restype = c.c_int

clib.fxIsStreaming.argtypes = [c.c_uint]
clib.fxIsStreaming.restype = c.c_bool

# Log file specification
if firmwareVersion >= Version("12.0.0"):
try:
Expand Down
22 changes: 21 additions & 1 deletion flexsea/utilities/system.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import platform
from typing import List

# ...
import pyudev


# ============================================
# get_os
# ============================================
def get_os() -> str:
"""
Returns the operating system and "bitness" (64 or 32 bit).
Expand All @@ -26,3 +30,19 @@ def get_os() -> str:
system = "pi"

return system + "_" + platform.architecture()[0]


# ============================================
# find_stm_ports
# ============================================
def find_stm_ports() -> List[str]:
if "windows" in get_os():
raise OSError("This function only works on Linux.")

context = pyudev.Context()
devicePorts = []

for device in context.list_devices(ID_VENDOR="STMicroelectronics", block="tty"):
devicePorts.append(device.device_node)

return devicePorts
Loading

0 comments on commit 657504f

Please sign in to comment.