Skip to content

Commit 9d6154e

Browse files
authored
Merge pull request #142 from openUC2/mergemaster
Mergemaster
2 parents 62a9f41 + ba40ad6 commit 9d6154e

4 files changed

Lines changed: 37 additions & 5 deletions

File tree

uc2rest/canota.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ def __init__(self, parent=None, nCallbacks=10):
5858
"""
5959
self._parent = parent
6060
self.nCallbacks = nCallbacks
61-
61+
62+
# Threading event: set to True to request cancellation of any running
63+
# streaming upload.
64+
self._cancel_event = threading.Event()
65+
6266
# Initialize callback functions for different types of OTA events
6367
self.init_callback_functions(self.nCallbacks)
6468

@@ -294,6 +298,15 @@ def get_platformio_upload_command(self, can_id, project_path="."):
294298
# MD5) and wait for ``{"ota_status":"success"|"error"}``.
295299
# ========================================================================
296300

301+
def cancel_streaming_ota(self):
302+
"""Request cancellation of any running streaming upload.
303+
304+
The upload worker checks this flag at every chunk boundary and will
305+
abort cleanly (restoring the parent serial connection) on the next
306+
iteration.
307+
"""
308+
self._cancel_event.set()
309+
297310
def start_can_streaming_ota(self, can_id: int, firmware_path: str,
298311
progress_callback=None, status_callback=None,
299312
port: str = None, baud: int = STREAMING_BAUD):
@@ -349,6 +362,8 @@ def start_can_streaming_ota(self, can_id: int, firmware_path: str,
349362
crc32, num_chunks, progress_callback, status_callback)
350363
)
351364
upload_thread.daemon = True
365+
# Reset any previous cancellation before starting the new upload
366+
self._cancel_event.clear()
352367
upload_thread.start()
353368

354369
return upload_thread
@@ -434,6 +449,12 @@ def _streaming_upload_worker(self, can_id, port, baud, firmware_data, firmware_s
434449
chunk_no = 0
435450

436451
while sent < firmware_size:
452+
# Honour cancellation requests between chunks
453+
if self._cancel_event.is_set():
454+
if status_callback:
455+
status_callback("Upload cancelled by user", False)
456+
return
457+
437458
end = min(sent + CHUNK_SIZE, firmware_size)
438459
payload = firmware_data[sent:end]
439460
chunk_no += 1
@@ -445,6 +466,11 @@ def _streaming_upload_worker(self, can_id, port, baud, firmware_data, firmware_s
445466
# Block until the master ACKs at least ``sent`` bytes.
446467
deadline = time.time() + ACK_TIMEOUT_S
447468
while last_ack < sent:
469+
# Check for cancellation inside the ACK wait loop as well
470+
if self._cancel_event.is_set():
471+
if status_callback:
472+
status_callback("Upload cancelled by user", False)
473+
return
448474
last_ack, err = self._drain_acks(ser, ack_buf, last_ack)
449475
if err is not None:
450476
if status_callback:
@@ -545,6 +571,8 @@ def _wait_for_status(self, ser, deadline, key_values=None,
545571
buf = bytearray()
546572
while time.time() < deadline:
547573
chunk = ser.read(ser.in_waiting or 1)
574+
# debug print of chunks
575+
# self._parent.logger.debug(f"Received chunk: {chunk}")
548576
if chunk:
549577
buf.extend(chunk)
550578
obj = self._try_extract_json_status(bytes(buf))

uc2rest/home.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ def home(self, axis=None, timeout=None, speed=None, direction=None, endposreleas
322322

323323
timeout = timeout if isBlocking else 0
324324
nResponses = 2 # one for command received, one for home reached
325+
if timeout and timeout > 1000:
326+
timeout = timeout / 1000.0
325327

326328
# if we get a return, we will receive the latest position feedback from the driver by means of the axis that moves the longest
327329
r = self._parent.post_json(path, payload, getReturn=isBlocking, timeout=timeout, nResponses=nResponses)

uc2rest/motor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,10 @@ def move_a(self, steps=0, speed=1000, acceleration=None, is_blocking=False, is_a
402402
return self.move_axis_by_name(axis="A", steps=steps, speed=speed, acceleration=acceleration, is_blocking=is_blocking, is_absolute=is_absolute, is_enabled=is_enabled, timeout=timeout, is_reduced=is_reduced)
403403

404404
def move_xyz(self, steps=(0,0,0), speed=(1000,1000,1000), acceleration=None, is_blocking=False, is_absolute=False, is_enabled=True, timeout=gTIMEOUT, is_reduced=False):
405-
if len(speed)!= 3:
405+
if not (type(speed)==list) or len(speed)!= 3:
406406
speed = (speed,speed,speed)
407+
if acceleration is None:
408+
acceleration = (self.DEFAULT_ACCELERATION,self.DEFAULT_ACCELERATION,self.DEFAULT_ACCELERATION)
407409

408410
# motor axis is 1,2,3,0 => X,Y,Z,T # FIXME: Hardcoded
409411
r = self.move_xyza(steps=(0,steps[0],steps[1],steps[2]), acceleration=(0,acceleration[0],acceleration[1],acceleration[2]), speed=(0,speed[0],speed[1],speed[2]), is_blocking=is_blocking, is_absolute=is_absolute, is_enabled=is_enabled, timeout=timeout, is_reduced=is_reduced)

uc2rest/mserial.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ def sendMessage(self, command, nResponses=1, timeout = 20):
490490
except Exception as e:
491491
if self.DEBUG:
492492
self._logger.error(e) # TODO: write failed: Device not configured - why?!
493-
# attempt to reconnect
494-
self.reconnect()
493+
# attempt to reconnect # TODO: do we want that?
494+
# self.reconnect()
495495
return "Failed to Send"
496496
self.commands[identifier]=command # FIXME: Need to clear this after the response is received
497497
if nResponses <= 0 or not self.is_connected or self.manufacturer=="UC2Mock":
@@ -526,7 +526,7 @@ def sendMessage(self, command, nResponses=1, timeout = 20):
526526
iRetry = 0
527527
while self.running:
528528
time.sleep(0.002)
529-
isTimeout = time.time()-t0>timeout
529+
isTimeout = (time.time()-t0)>timeout
530530
if self.resetLastCommand or isTimeout or not self.is_connected:
531531
self.resetLastCommand = False
532532
if self.DEBUG:

0 commit comments

Comments
 (0)