lpcmanager

More non-working SplashScreen code removal.

2018-01-30, Edouard Tisserant
2a141a3cf524
More non-working SplashScreen code removal.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
#based on the plcopen standard.
#
#Copyright (C) 2015: Yvan ROCH
#
#See COPYING file for copyrights details.
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#General Public License for more details.
#
#You should have received a copy of the GNU General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#-------------------------------------------------------------------------------
# Firmware Updater for the host (the IDE)
#-------------------------------------------------------------------------------
"""
Class which controls the firmware update on the remote PLC
See also TargetFirmwareUpdater
"""
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):
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
# Reset HostFirmwareUpdater internal variables
def Reset(self):
self.Running = 0
def update(self):
self.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))
# 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)
# 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)
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)
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)
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"))
else:
# Multiple chunks transfer is needed
isLastChunk = False
chunksSize = self.chunksSize
self.logger.write(_("Multiple chunks transfer\n"))
# Start the image transfer
transferedBytes = 0
while transferedBytes < self.firmwareImageFileSize:
chunkData = self.imageData[transferedBytes:transferedBytes + chunksSize]
self.logger.write(_("Transfer chunk, size: %d\n")%(chunksSize))
status, textError = self._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
chunksSize = self.firmwareImageFileSize - transferedBytes
# 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.")
def _RebootTarget(self):
self._connector.RebootTarget()