lpcmanager

Parents e1a2eec302e9
Children cacb76868d13
Added progress dialog for firmware, among other fixes in HostFirmwareUpdater.py
--- a/HostFirmwareUpdater.py Tue Aug 21 10:02:06 2018 +0200
+++ b/HostFirmwareUpdater.py Fri Aug 24 14:29:40 2018 +0200
@@ -33,109 +33,102 @@
import os
import hashlib
-import threading
-from time import sleep
-import wx
-WAIT_BEFORE_FEED_SEC = 5
UPDATE_SCRIPT_TIMEOUT = 600
class HostFirmwareUpdater(object):
# Create a new HostFirmwareUpdater
- def __init__(self, _connector, firmwareImagePath, updateType, chunksSize, reboot, logger):
+ def __init__(self, controller, firmwareImagePath, updateType, chunksSize, reboot, dialog):
self.Reset()
- self._connector = _connector
self.firmwareImagePath = firmwareImagePath
self.updateType = updateType
self.chunksSize = chunksSize
self.reboot = reboot
- self.logger = logger
- self.logger.write(_("HostFirmwareUpdater init.\n"))
- self.threadUpdateScript = None
- self.runUpdateScriptStatus = None
- self.runUpdateScriptTextError = None
+ self.controller = controller
+ self.dialog = dialog
+ self.controller.logger.write(_("HostFirmwareUpdater init.\n"))
# Reset HostFirmwareUpdater internal variables
def Reset(self):
self.Running = 0
def update(self):
- self.logger.write(_("HostFirmwareUpdater update.\n"))
+ self.controller.logger.write(_("HostFirmwareUpdater update.\n"))
self.firmwareImageFile = open(self.firmwareImagePath, "rb")
# Read the image file
self.imageData = self.firmwareImageFile.read()
self.firmwareImageFileSize = os.stat(self.firmwareImagePath).st_size
- self.logger.write(_("Firmware image %s size: %d\n")%(self.firmwareImagePath, self.firmwareImageFileSize))
+ self.controller.logger.write(_("Firmware image %s size: %d\n")%(self.firmwareImagePath, self.firmwareImageFileSize))
# Note Pyro exceptions are already caught by catcher_func and PyroCatcher in PyroProxyProxy
# Create the necessary files on the target
self._CreateFirmwareImageFileSizeFile()
self._CreateFirmwareImageFileSizeMD5File()
self._CreateFirmwareImageFileMD5File()
- # Create and start the thread for the update script
- self.threadUpdateScript = threading.Thread(target=self._RunUpdateScript)
- self.threadUpdateScript.start()
- # Waiting some time for the update script launching
- self.logger.write(_("Waiting %s s until the update script is running...\n")%WAIT_BEFORE_FEED_SEC)
- sleep(WAIT_BEFORE_FEED_SEC)
+ # start the update script
+ status, textError = self.controller._connector.RunUpdateScript(self.updateType)
+ if not status :
+ raise Exception(textError)
# The update script is now running: Feeding the update script with firmware image data
self._RunFeedPipe()
- # Wait the end of the script
- self.threadUpdateScript.join(timeout = UPDATE_SCRIPT_TIMEOUT)
# Here, the update is successful, reboot?
if self.reboot:
self._RebootTarget()
def _CreateFirmwareImageFileSizeFile(self):
# Note Pyro exceptions are already caught by catcher_func and PyroCatcher in PyroProxyProxy
- status, textError = self._connector.CreateFirmwareImageFileSizeFile(self.firmwareImageFileSize)
+ status, textError = self.controller._connector.CreateFirmwareImageFileSizeFile(self.firmwareImageFileSize)
if not status :
raise Exception(textError)
def _CreateFirmwareImageFileSizeMD5File(self):
# Note Pyro exceptions are already caught by catcher_func and PyroCatcher in PyroProxyProxy
self.firmwareImageFileMD5Size = hashlib.md5("%s\n"%self.firmwareImageFileSize).hexdigest()
- self.logger.write(_("Firmware image size md5: %s\n")%(self.firmwareImageFileMD5Size))
- status, textError = self._connector.CreateFirmwareImageFileSizeMD5File(self.firmwareImageFileMD5Size)
+ self.controller.logger.write(_("Firmware image size md5: %s\n")%(self.firmwareImageFileMD5Size))
+ status, textError = self.controller._connector.CreateFirmwareImageFileSizeMD5File(self.firmwareImageFileMD5Size)
if not status :
raise Exception(textError)
def _CreateFirmwareImageFileMD5File(self):
# Note Pyro exceptions are already caught by catcher_func and PyroCatcher in PyroProxyProxy
self.firmwareImageFileMD5 = hashlib.md5(self.imageData).hexdigest()
- self.logger.write(_("Firmware image %s md5: %s\n")%(self.firmwareImagePath, self.firmwareImageFileMD5))
- status, textError = self._connector.CreateFirmwareImageFileMD5File(self.firmwareImageFileMD5)
+ self.controller.logger.write(_("Firmware image %s md5: %s\n")%(self.firmwareImagePath, self.firmwareImageFileMD5))
+ status, textError = self.controller._connector.CreateFirmwareImageFileMD5File(self.firmwareImageFileMD5)
if not status :
raise Exception(textError)
- def _RunUpdateScript(self):
- # Put the update script run status in class attributes because,
- # since we are in a child thread, exceptions thrown in this one are painful to catch.
- # The update script run status will be checked on joining this thread.
- self.runUpdateScriptStatus, self.runUpdateScriptTextError = self._connector.RunUpdateScript(self.updateType)
-
def _RunFeedPipe(self):
# Check if a multiple chunks transfer is needed
if self.firmwareImageFileSize <= self.chunksSize :
# Only a single chunk transfer is needed
isLastChunk = True
chunksSize = self.firmwareImageFileSize
- self.logger.write(_("Single chunk transfer\n"))
+ self.controller.logger.write(_("Single chunk transfer\n"))
else:
# Multiple chunks transfer is needed
isLastChunk = False
chunksSize = self.chunksSize
- self.logger.write(_("Multiple chunks transfer\n"))
+ self.controller.logger.write(_("Multiple chunks transfer\n"))
# Start the image transfer
transferedBytes = 0
while transferedBytes < self.firmwareImageFileSize:
+
+ # User feedback as percentage
+ keepGoing, _skip = self.dialog.Update(
+ transferedBytes * 100 / self.firmwareImageFileSize)
+
+ if not keepGoing:
+ status = False
+ textError = _("Canceled")
+ raise Exception(textError)
+
chunkData = self.imageData[transferedBytes:transferedBytes + chunksSize]
- self.logger.write(_("Transfer chunk, size: %d\n")%(chunksSize))
- status, textError = self._connector.RunFeedPipe(chunkData, isLastChunk, chunksSize)
+ status, textError = self.controller._connector.RunFeedPipe(chunkData, isLastChunk, chunksSize)
if not status :
break
transferedBytes = transferedBytes + chunksSize
+
# Detect if the next chunk is the last chunk
if (self.firmwareImageFileSize - transferedBytes) <= self.chunksSize:
isLastChunk = True
@@ -143,11 +136,10 @@
# Check the transfer and the update status
if not status :
- if self.runUpdateScriptTextError != "" and not self.runUpdateScriptStatus:
- textError = "Update script message: " + self.runUpdateScriptTextError + "\n" + textError
raise Exception(textError)
else:
- self.logger.write(_("Firmware update log: \n\n") + textError + "\nFirmware update successful.")
+ self.dialog.Update(100,_("Firmware update successful."))
+ self.controller.logger.write(_("Firmware update log: \n\n") + textError + "\nFirmware update successful.")
def _RebootTarget(self):
- self._connector.RebootTarget()
+ self.controller._connector.RebootTarget()
--- a/LPCProjectController.py Tue Aug 21 10:02:06 2018 +0200
+++ b/LPCProjectController.py Fri Aug 24 14:29:40 2018 +0200
@@ -229,16 +229,34 @@
self.AppFrame.Refresh()
self.AppFrame.Update()
+ dlg = wx.ProgressDialog(_("Firmware update"),
+ _("Updating firmware, please wait."),
+ maximum = 100,
+ parent=self.AppFrame,
+ style = 0
+ | wx.PD_APP_MODAL
+ | wx.PD_CAN_ABORT
+ | wx.PD_ESTIMATED_TIME
+ | wx.PD_REMAINING_TIME
+ )
+
# Lauch the firmaware update on the remote PLC
- updater = HostFirmwareUpdater(self._connector, imageFilePath, updateType, chunksSize, reboot, self.logger)
+ updater = HostFirmwareUpdater(self, imageFilePath, updateType, chunksSize, reboot, dlg)
try:
updater.update()
except Exception as e:
self.logger.write_error(str(e) + "\n")
- self.logger.write_error(_("Firmware update canceled!\n"))
+ self.logger.write_error(_("Firmware update failed!\n"))
self.firmwareUpadateIsRunning = False
self._Disconnect()
+ if not dlg.WasCanceled():
+ dlg.Update(0, _("Firmware update failed!\n(%s)"%str(e)))
+ dlg.ShowModal()
+ dlg.Destroy()
return
+
+ dlg.Destroy()
+
self._Disconnect()
self.firmwareUpadateIsRunning = False
return True