Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved resource cleanup #226

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
14 changes: 14 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Configuration for extra --hardware flag, used for raising an Exception
# on real hardware when not specified.
# This is to avoid accidental plotter outputs within a py.test session

def pytest_addoption(parser):
parser.addoption("--hardware", action="store_true", help="do HW tests")

def pytest_generate_tests(metafunc):
if "do_hw" in metafunc.fixturenames:
if metafunc.config.getoption("hardware"):
hw = True
else:
hw = False
metafunc.parametrize("do_hw", (hw, ))
29 changes: 25 additions & 4 deletions silhouette/Graphtec.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
else: # if sys_platform.startswith('linux'):
try:
import usb.core # where???
import usb.util
except Exception as e:
try:
import libusb1 as usb
Expand Down Expand Up @@ -157,7 +158,7 @@
CMD_EOT = b'\x04'
# Enquiry - Returns device status
CMD_ENQ = b'\x05'
# Negative Acnoledge - Returns device tool setup
# Negative Acknowledge - Returns device tool setup
CMD_NAK = b'\x15'

### Query codes
Expand Down Expand Up @@ -331,7 +332,7 @@ def sharpen_corners(self, start, end):

class SilhouetteCameo:
def __init__(self, log=sys.stderr, cmdfile=None, inc_queries=False,
dry_run=False, progress_cb=None, force_hardware=None):
dry_run=False, progress_cb=None, force_hardware=None, umockdev_mode = False):
""" This initializer simply finds the first known device.
The default paper alignment is left hand side for devices with known width
(currently Cameo and Portrait). Otherwise it is right hand side.
Expand Down Expand Up @@ -497,10 +498,19 @@ def __init__(self, log=sys.stderr, cmdfile=None, inc_queries=False,
self.enable_sw_clipping = True
self.clip_fuzz = 0.05
self.mock_response = None
# Within an umockdev run, the safe write command will likely timeout.
# Use umockdev_mode to skip this part of the reality.
if umockdev_mode:
self.safe_write = self.write
else:
self.safe_write = self._safe_write

def __del__(self, *args):
if self.commands:
self.commands.close()
# TBD: Do we want to auto-close upon deletion?
self.close()


# Class data providing mock responses when there is no device:
mock_responses = {
Expand Down Expand Up @@ -602,7 +612,7 @@ def write(self, data, is_query=False, timeout=10000):
if o != len(data):
raise ValueError('write all %d bytes failed: o=%d' % (len(data), o))

def safe_write(self, data):
def _safe_write(self, data):
"""
Wrapper for write with special emphasis not overloading the cutter
with long commands.
Expand Down Expand Up @@ -726,7 +736,9 @@ def wait_for_ready(self, timeout=30, poll_interval=2.0, verbose=False):
# not actually sending commands, so don't really care about being ready
return state
npolls = int(timeout/poll_interval)

for i in range(1, npolls):
print("wait for ready", i, state)
if (state == 'ready'): break
if (state == 'None'):
raise NotImplementedError("Waiting for ready but no device exists.")
Expand All @@ -739,6 +751,8 @@ def wait_for_ready(self, timeout=30, poll_interval=2.0, verbose=False):
time.sleep(poll_interval)
state = self.status()
if verbose: print("",file=sys.stderr)
if state == 'moving':
raise ValueError("Timed out")
return state

def initialize(self):
Expand All @@ -748,7 +762,8 @@ def initialize(self):
try:
self.send_escape(CMD_EOT)
except Exception as e:
raise ValueError("Write Exception: %s, %s errno=%s\n\nFailed to write the first 3 bytes. Permissions? inf-wizard?" % (type(e), e, e.errno))
e.args += ("Write Exception: \n\nFailed to write the first 3 bytes. Permissions? inf-wizard?" ,)
raise e

# Initial palaver
print("Device Version: '%s'" % self.get_version(), file=self.log)
Expand Down Expand Up @@ -846,6 +861,12 @@ def set_cutting_mat(self, cuttingmat, mediawidth, mediaheight):
right = _mm_2_SU(self.hardware['width_mm'] if 'width_mm' in self.hardware else mediawidth)
self.set_boundary(0, 0, bottom, right)

def close(self):
"Free resources to allow reconnection"
if self.dev is not None:
usb.util.dispose_resources(self.dev)
self.dev = None

def setup(self, media=132, speed=None, pressure=None, toolholder=None, pen=None, cuttingmat=None, sharpencorners=False, sharpencorners_start=0.1, sharpencorners_end=0.1, autoblade=False, depth=None, sw_clipping=True, clip_fuzz=0.05, trackenhancing=False, bladediameter=0.9, landscape=False, leftaligned=None, mediawidth=210.0, mediaheight=297.0):
"""Setup the Silhouette Device

Expand Down
Loading