def doDownloadUpdate(self): oClient = WebClient() oRespSys = None if (not self.m_strSystemUrl): Globs.err("Die URL für die Systemaktualisierung ist ungültig") Globs.setSetting("Updater", "strSystemUrl", Updater.s_strSystemUrl) if (not self.m_oSystemUpdateIO): return False if (not self.m_oSystemUpdateIO or (self.m_fChkVersion > self.m_fUpdVersion and not self.m_bUpdateOffline)): oRespSys = oClient.GET(self.m_strSystemUrl) if (not oRespSys or not oRespSys.m_bOK): Globs.err("Fehler (%s) beim Herunterladen der Systemaktualisierungsdatei '%s'" % ( oRespSys, self.m_strSystemUrl)) Globs.setSetting("Updater", "strSystemUrl", Updater.s_strSystemUrl) return False self.m_oSystemUpdateIO = BytesIO(oRespSys.m_oData) self.m_fUpdVersion = self.m_fChkVersion return True if (self.m_oSystemUpdateIO): Globs.log("Eine Aktualisierung wurde bereitgestellt.") return True return False
def do(self): Globs.s_strExitMode = self.m_strMode for oInstance in self.m_oWorker.m_dictModules.values(): oInstance.moduleExit() self.m_oWorker.m_dictModules.clear() Globs.saveSettings() Globs.shutdown() return
def moduleInit(self, dictModCfg={}, dictCfgUsr={}): dictSettings = { "nSilenceFrom" : 19, "nSilenceTo" : 6, "nTellTimeInt" : 30, "strSoundHour" : "BellToll", } if (not dictModCfg): dictModCfg.update(dictSettings) else: for (strName, strValue) in dictSettings.items(): if strName not in dictModCfg: dictModCfg.update({strName : strValue}) dictCfgUsr.update({ "nSilenceFrom" : { "title" : "Beginn der Ruhezeit", "description" : ("Der Beginn der Ruhezeit gibt an, ab welcher Stunde (0..23) "+ "keine Glockenschläge und keine Zeitansagen ausgegeben werden "+ "sollen. Zusammen mit dem Ende der Ruhezeit kann so ein "+ "Zeitfenster der Stille festgelegt werden, um Ruhestörungen "+ "zu vermeiden."), "default" : "0" }, "nSilenceTo" : { "title" : "Ende der Ruhezeit", "description" : ("Das Ende der Ruhezeit gibt an, bis zu welcher Stunde (0..23) "+ "keine Glockenschläge und keine Zeitansagen ausgegeben werden "+ "sollen. Zusammen mit dem Beginn der Ruhezeit kann so ein "+ "Zeitfenster der Stille festgelegt werden, um Ruhestörungen "+ "zu vermeiden."), "default" : "0" }, "nTellTimeInt" : { "title" : "Uhrzeitansage", "description" : ("Die Uhrzeit kann in einem festen Raster von stündlich bis "+ "alle 5 Minuten angesagt werden."), "default" : "30", "choices" : { "Jede volle Stunde" : "60", "Jede halbe Stunde" : "30", "Jede viertel Stunde" : "15", "Alle 5 Minuten" : "5" } }, "strSoundHour" : { "title" : "Klang Stundenschlag", "description" : ("Die akustische Anzeige der Uhrzeit erfolgt durch den "+ "angegebenen Klang."), "default" : "BellToll", "choices" : Globs.s_dictSettings["Sounds"], "keyIsValue" : True }, }) self.m_nSilenceFrom = Globs.getSetting("Clock", "nSilenceFrom", "\\d{1,2}", 19) self.m_nSilenceTo = Globs.getSetting("Clock", "nSilenceTo", "\\d{1,2}", 6) self.m_nTellTimeInt = Globs.getSetting("Clock", "nTellTimeInt", "\\d{1,2}", 30) return True
def getNetworkInfo(strComputerName="google.com"): strIpAddr = "" try: oSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) oSocket.connect((strComputerName, 0)) strIpAddr = oSocket.getsockname()[0] oSocket.close() except: Globs.exc("Ermitteln der IP-Adresse") return strIpAddr
def sound(self, strSound): strFile = None strPlay = "aplay" # >>> Critical Section Globs.s_oSettingsLock.acquire() try: if "Sounds" in Globs.s_dictSettings: # Direkte Übereinstimmung finden for (strCategory, dictSounds) in Globs.s_dictSettings["Sounds"].items(): if strSound in dictSounds: strFile = Globs.s_dictSettings["Sounds"][strCategory][strSound] break if not strFile: # Partiellen Treffer finden for (strCategory, dictSounds) in sorted(Globs.s_dictSettings["Sounds"].items()): for (strName, strPath) in dictSounds.items(): if re.match(".*" + strSound + ".*", strName): Globs.log("Sound '%s' für angeforderten Sound '%s' verwendet." % (strName, strSound)) strFile = strPath break except: Globs.exc("Sound '%s' finden" % (strSound)) Globs.s_oSettingsLock.release() # <<< Critical Section if not strFile: Globs.wrn("Der angeforderte Sound konnte nicht gefunden werden: '%s'" % (strSound)) print("\\a") return if os.path.isfile(strFile): if re.match(".*\\.[Ww][Aa][Vv]", strFile): strPlay = "aplay" elif re.match(".*\\.[Mm][Pp]3", strFile): strPlay = "omxplayer" else: Globs.wrn("Das Format der Sound-Datei wird nicht unterstützt: '%s'" % (strFile)) print("\\a") return else: Globs.wrn("Die Datei des angeforderten Sounds ist ungültig: '%s'" % (strFile)) print("\\a") return print("Now playing: '%s' <%s>" % (strSound, strFile)) os.system('%s "%s"' % (strPlay, strFile)) return
def updateTime(self): self.m_strMonName = time.strftime("%B") self.m_strDayName = time.strftime("%A") self.m_nMonYear = int(time.strftime("%m")) self.m_nDayWeek = int(time.strftime("%w")) self.m_nYear4xY = int(time.strftime("%Y")) self.m_nYear2xY = int(time.strftime("%y")) self.m_nWeekOfY = int(time.strftime("%W")) self.m_nHour24h = int(time.strftime("%H")) self.m_nHour12h = int(time.strftime("%I")) self.m_nMinutes = int(time.strftime("%M")) self.m_nTimeSpoken = 0 self.m_nSilenceFrom = Globs.getSetting("Clock", "nSilenceFrom", "\\d{1,2}", 19) self.m_nSilenceTo = Globs.getSetting("Clock", "nSilenceTo", "\\d{1,2}", 6) self.m_nTellTimeInt = Globs.getSetting("Clock", "nTellTimeInt", "\\d{1,2}", 30) return
def start(self): bResult = False Globs.dbg("'%s' (schwer) starten: Warten auf Freigabe" % (self)) # >>> Critical Section self.m_oWorker.m_oLock.acquire() Globs.dbg("'%s' (schwer) starten: Freigabe erhalten" % (self)) if (self.m_oWorker.m_evtRunning.isSet()): Globs.dbg("'%s' (schwer) starten: In Warteschlange" % (self)) self.m_oWorker.m_oQueueLong.put(self) bResult = True else: Globs.wrn("'%s' (schwer) starten: Bearbeitung verweigert" % (self)) self.m_oWorker.m_oLock.release() # <<< Critical Section Globs.dbg("'%s' (schwer) starten: Freigabe abgegeben (%r)" % (self, bResult)) return bResult
def GET(self, strUrl, bFollowRedirects = True ): lstRedirect = ( http.client.MOVED_PERMANENTLY, http.client.FOUND, http.client.SEE_OTHER, http.client.TEMPORARY_REDIRECT) oConn = None oResp = None oUrlSplit = urllib.parse.urlsplit(strUrl) if (re.match("[Hh][Tt][Tt][Pp][Ss]", oUrlSplit.scheme)): oConn = http.client.HTTPSConnection(oUrlSplit.netloc) else: oConn = http.client.HTTPConnection(oUrlSplit.netloc) oConn.request("GET", strUrl) oResp = oConn.getresponse() if (oResp.status == http.client.OK): oWebResponse = WebResponse( nStatus=oResp.status, oReason=oResp.reason, oHeader=oResp.getheaders(), oData=oResp.read()) elif (oResp.status in lstRedirect and oResp.getheader("Location") and bFollowRedirects): Globs.wrn("Weiterleitung von '%s' nach '%s'" % ( strUrl, oResp.getheader("Location"))) oWebResponse = self.GET(oResp.getheader("Location")) else: Globs.wrn("Fehler beim Abrufen von '%s' (Weiterleitung=%s, Location=%s)" % ( strUrl, bFollowRedirects, oResp.getheader("Location"))) oWebResponse = WebResponse( nStatus=oResp.status, oReason=oResp.reason, oHeader=oResp.getheaders(), oData=oResp.read()) oConn.close() return oWebResponse
def moduleExec(self, strPath, oHtmlPage, dictQuery, dictForm ): print("%r::moduleExec(strPath=%s, dictQuery=%s, dictForm=%s) [%s]" % ( self, strPath, dictQuery, dictForm, datetime.today().strftime("%X"))) if not dictQuery: return False # Akustische Uhrzeitanzeige bResult = False for (strCmd, lstArg) in dictQuery.items(): if (strCmd == "timer" and lstArg and lstArg[0] == "cron"): self.updateTime() # Default: Aktustische Zeitanzeige if Globs.getSetting("System", "bTestMode", "True|False", False): TaskSpeak(self.getWorker(), "Entschuldigung. Test.").start() self.gong() self.speakTime() elif (self.isAllowed() and (self.m_nMinutes % self.m_nTellTimeInt) == 0): self.gong() self.speakTime() bResult = True elif (strCmd == "clock"): for strArg in lstArg: self.updateTime() # Nur Glockenschlag ausführen if (strArg == "gong"): self.gong() bResult = True continue # Nur Zeitansage ausführen if (strArg == "speak"): self.speakTime() bResult = True continue # Modultest ausführen if (strArg == "test"): TaskSpeak(self.getWorker(), "Der Modultest für die Uhr wird jetzt gestartet").start() nHour = 1 nMinute = 0 while (nHour <= 12): self.m_nHour12h = nHour TaskSpeak(self.getWorker(), "Stunde " + str(self.m_nHour12h)).start() while (nMinute <= 59): self.m_nMinutes = nMinute TaskSpeak(self.getWorker(), "Minute " + str(self.m_nMinutes)).start() self.speakTime() self.m_nTimeSpoken = 0 nMinute += 1 nMinute = 0 nHour += 1 TaskSpeak(self.getWorker(), "Der Modultest für die Uhr ist jetzt beendet").start() # Unbekanntes Kommando return bResult
def gong(self): nCount = 0 if (self.m_nMinutes % self.m_nTellTimeInt) == 0: if self.m_nMinutes == 0: nCount = self.m_nHour12h elif self.m_nTellTimeInt == 30 or self.m_nTellTimeInt == 5: nCount = 1 else: nCount = int(self.m_nMinutes / 15) # Testmodus berücksichtigen if (nCount == 0 and Globs.getSetting("System", "bTestMode", "True|False", False)): nCount = 1 # Ggf. Sound abspielen if (nCount >= 1): TaskSound(self.getWorker(), Globs.getSetting("Clock", "strSoundHour", ".+", "BellToll"), nLoops = nCount).start() return
def longThreadProc(self): self.m_bIsQueueLongShutdown = False Globs.log("Schwere Aufgabenbearbeitung: Gestartet") while True: bDone = False try: oTask = self.m_oQueueLong.get( block = not self.m_bIsQueueLongShutdown) except: # Abbruchbedingung für "do-while" Globs.log("Schwere Aufgabenbearbeitung: Abbruchbedingung") break Globs.dbg("Schwere Aufgabenbearbeitung: %s" % (oTask)) try: oTask.do() bDone = True except: Globs.exc("Schwere Aufgabenbearbeitung: %s" % (oTask)) oTask.done() Globs.log("Schwere Aufgabenbearbeitung: Beendet") return
def updateContext(self): self.m_nHour24h = int(time.strftime("%H")) self.m_nMinutes = int(time.strftime("%M")) self.m_nUpdateHour = Globs.getSetting("Updater", "nUpdateHour", "\\d{1,2}", 1) self.m_bAutoUpdate = Globs.getSetting("Updater", "bAutoUpdate", "True|False", False) self.m_bAutoReboot = Globs.getSetting("Updater", "bAutoReboot", "True|False", False) self.m_strSystemUrl = Globs.getSetting("Updater", "strSystemUrl", "[Hh][Tt][Tt][Pp][Ss]+\\://.+/.+", "") self.m_strChkUpdUrl = Globs.getSetting("Updater", "strChkUpdUrl", "[Hh][Tt][Tt][Pp][Ss]+\\://.+/.+", "") Globs.setSetting("Updater", "fChkVersion", self.m_fChkVersion) return
def getCpuTemp(): fResult = 273.15 fResult *= -1 regexSep = r"[\=\']" parts = [[1, 2],] strResult = subprocess.check_output( "vcgencmd measure_temp", stderr = subprocess.STDOUT, shell = True, universal_newlines = True) temp = partList(re.split(regexSep, strResult), parts)[0] fResult = float(temp) if (Globs.getSetting("System", "bTestMode", "True|False", False) and not Globs.s_oQueueTestCpuTempValues.empty()): fResult = Globs.s_oQueueTestCpuTempValues.get(False) return fResult
def done(self, bResult = True): Globs.dbg("'%s' (schwer): Bearbeitung abgeschlossen (%r)" % (self, bResult)) self.m_oWorker.m_oQueueLong.task_done() return
def do(self): Globs.saveSettings() return
def do(self): fCpuTemp = SDK.getCpuTemp() strCpuUse = SDK.getCpuUse().strip() lstRamInfo = SDK.getRamInfo() lstDiskSpace = SDK.getDiskSpace() fCpuTempA = Globs.getSetting("System", "fCpuTempA", "\\d{2,}\\.\\d+", 60.0) fCpuTempB = Globs.getSetting("System", "fCpuTempB", "\\d{2,}\\.\\d+", 56.0) fCpuTempC = Globs.getSetting("System", "fCpuTempC", "\\d{2,}\\.\\d+", 53.0) fCpuTempH = Globs.getSetting("System", "fCpuTempH", "\\d{2,}\\.\\d+", 1.0) try: fCpuUse = float(strCpuUse.replace(",", ".", 1)) except: fCpuUse = 0.0 # IP-Adresse ermitteln if not TaskSystemWatchDog.s_strIpAddr: TaskSystemWatchDog.s_strIpAddr = SDK.getNetworkInfo( Globs.getSetting("System", "strNetInfoName")) if TaskSystemWatchDog.s_strIpAddr: TaskSpeak(self.m_oWorker, "Die aktuelle Netzwerkadresse ist: %s" % ( TaskSystemWatchDog.s_strIpAddr.replace(".", " Punkt "))).start() elif TaskSystemWatchDog.s_nIpFailCnt < 4: TaskSystemWatchDog.s_nIpFailCnt += 1 TaskSpeak(self.m_oWorker, "Die aktuelle Netzwerkadresse konnte nicht ermittelt werden.").start() else: TaskSystemWatchDog.s_strIpAddr = "127.0.0.1" TaskSpeak(self.m_oWorker, "Die Netzwerkadresse kann nicht ermittelt werden, daher wird %s angenommen." % ( TaskSystemWatchDog.s_strIpAddr.replace(".", " Punkt "))).start() # CPU-Statistik erstellen if not TaskSystemWatchDog.s_bHistory: # Statistik initialisieren TaskSystemWatchDog.s_fCpuTempMin = fCpuTemp TaskSystemWatchDog.s_fCpuTempMax = fCpuTemp TaskSystemWatchDog.s_fCpuTempAvg = fCpuTemp TaskSystemWatchDog.s_fCpuUseMin = fCpuUse TaskSystemWatchDog.s_fCpuUseMax = fCpuUse TaskSystemWatchDog.s_fCpuUseAvg = fCpuUse else: # CPU-Temperaturen TaskSystemWatchDog.s_fCpuTempMin = min( TaskSystemWatchDog.s_fCpuTempMin, fCpuTemp) TaskSystemWatchDog.s_fCpuTempMax = max( TaskSystemWatchDog.s_fCpuTempMax, fCpuTemp) TaskSystemWatchDog.s_fCpuTempAvg += fCpuTemp TaskSystemWatchDog.s_fCpuTempAvg /= 2.0 # CPU-Auslastungen TaskSystemWatchDog.s_fCpuUseMin = min( TaskSystemWatchDog.s_fCpuUseMin, fCpuUse) TaskSystemWatchDog.s_fCpuUseMax = max( TaskSystemWatchDog.s_fCpuUseMax, fCpuUse) TaskSystemWatchDog.s_fCpuUseAvg += fCpuUse TaskSystemWatchDog.s_fCpuUseAvg /= 2.0 # Systemwerte vorbereiten if "CPU" not in Globs.s_dictSystemValues: Globs.s_dictSystemValues.update({"CPU" : {}}) if "RAM" not in Globs.s_dictSystemValues: Globs.s_dictSystemValues.update({"Arbeitsspeicher" : {}}) if "MEM" not in Globs.s_dictSystemValues: Globs.s_dictSystemValues.update({"Speicherkapazität" : {}}) if "Netzwerk" not in Globs.s_dictSystemValues: Globs.s_dictSystemValues.update({"Netzwerk" : {}}) # Systemwerte eintragen Globs.s_dictSystemValues["CPU"].update({ "Auslastung" : "%s%%" % (strCpuUse), "Auslastung Min" : "%0.2f%%" % (TaskSystemWatchDog.s_fCpuUseMin), "Auslastung Max" : "%0.2f%%" % (TaskSystemWatchDog.s_fCpuUseMax), "Auslastung Avg" : "%0.2f%%" % (TaskSystemWatchDog.s_fCpuUseAvg), "Temperatur" : "%0.1f°C" % (fCpuTemp), "Temperatur Min" : "%0.2f°C" % (TaskSystemWatchDog.s_fCpuTempMin), "Temperatur Max" : "%0.2f°C" % (TaskSystemWatchDog.s_fCpuTempMax), "Temperatur Avg" : "%0.2f°C" % (TaskSystemWatchDog.s_fCpuTempAvg),}) Globs.s_dictSystemValues["Netzwerk"].update({ "IP-Adresse" : "%s" % (TaskSystemWatchDog.s_strIpAddr),}) lstLabels = ["Gesamt", "Belegt", "Frei", "Geteilt", "Gepuffert", "Im Cache"] nIndex = 0 for strData in lstRamInfo: Globs.s_dictSystemValues["RAM"].update({ lstLabels[nIndex] : strData + "K"}) nIndex += 1 lstLabels = ["Gesamt", "Belegt", "Verfügbar", "Belegung"] nIndex = 0 for strData in lstDiskSpace: Globs.s_dictSystemValues["MEM"].update({ lstLabels[nIndex] : strData}) nIndex += 1 # Nächsten Durchlauf einplanen self.m_oWorker.runSystemWatchDog() # CPU-Temperatur auswerten strCpuTemp = ("%0.1f Grad" % (TaskSystemWatchDog.s_fCpuTempAvg) ).replace(".", " Komma ") if TaskSystemWatchDog.s_fCpuTempAvg > fCpuTempA: # # Warn-Level 3 - Notabschaltung # TaskSystemWatchDog.s_nCpuTooHot += 1 if TaskSystemWatchDog.s_nCpuTempLvl != 3: TaskSpeak(self.m_oWorker, "Achtung!").start() TaskSpeak(self.m_oWorker, "Temperaturüberschreitung mit %s!" % ( strCpuTemp)).start() TaskSystemWatchDog.s_nCpuTempLvl = 3 if (TaskSystemWatchDog.s_nCpuTooHot >= 10): TaskSpeak(self.m_oWorker, "Notabschaltung eingeleitet!").start() TaskExit(self.m_oWorker, "term").start() Globs.stop() else: TaskSpeak(self.m_oWorker, "Für Abkühlung sorgen! Notabschaltung %s Prozent!" % ( TaskSystemWatchDog.s_nCpuTooHot * 10)).start() elif (TaskSystemWatchDog.s_fCpuTempAvg > fCpuTempB and TaskSystemWatchDog.s_fCpuTempAvg < (fCpuTempA - fCpuTempH)): # # Warn-Level 2 # TaskSystemWatchDog.s_nCpuTooHot = 0 # if TaskSystemWatchDog.s_nCpuTooHot > 0: # TaskSystemWatchDog.s_nCpuTooHot -= 1 if TaskSystemWatchDog.s_nCpuTempLvl != 2: TaskSpeak(self.m_oWorker, "Die Temperatur ist mit %s zu hoch!" % ( strCpuTemp)).start() TaskSystemWatchDog.s_nCpuTempLvl = 2 elif (TaskSystemWatchDog.s_fCpuTempAvg > fCpuTempC and TaskSystemWatchDog.s_fCpuTempAvg < (fCpuTempB - fCpuTempH)): # # Warn-Level 1 # TaskSystemWatchDog.s_nCpuTooHot = 0 if TaskSystemWatchDog.s_nCpuTempLvl != 1: TaskSpeak(self.m_oWorker, "Die Temperatur ist mit %s erhöht!" % ( strCpuTemp)).start() TaskSystemWatchDog.s_nCpuTempLvl = 1 elif (TaskSystemWatchDog.s_nCpuTempLvl != 0 and TaskSystemWatchDog.s_fCpuTempAvg < (fCpuTempC - fCpuTempH)): # # Warn-Level 0 - Normalbereich # TaskSystemWatchDog.s_nCpuTooHot = 0 TaskSpeak(self.m_oWorker, "Die Temperatur ist mit %s wieder im normalen Bereich" % ( strCpuTemp)).start() TaskSystemWatchDog.s_nCpuTempLvl = 0 elif not TaskSystemWatchDog.s_bHistory: TaskSpeak(self.m_oWorker, "Die Temperatur liegt mit %s im normalen Bereich" % ( strCpuTemp)).start() # Es liegen jetzt Statistikwerte aus der Vergangenheit vor if not TaskSystemWatchDog.s_bHistory: TaskSystemWatchDog.s_bHistory = True return
def stopQueue(self): bResult = True if not self.m_evtRunning.isSet: Globs.log("Stop Aufgabenbearbeitung: Wurde bereits angefordert") return bResult Globs.dbg("Stop Aufgabenbearbeitung: Warten auf Freigabe") # >>> Critical Section self.m_oLock.acquire() Globs.dbg("Stop Aufgabenbearbeitung: Freigabe erhalten") if self.m_oWatchDogTimer: self.m_oWatchDogTimer.cancel() self.m_oWatchDogTimer = None if not TaskQueueFastStop(self).start(): bResult = False if not TaskQueueLongStop(self).start(): bResult = False self.m_evtRunning.clear() self.m_oLock.release() # <<< Critical Section Globs.dbg("Stop Aufgabenbearbeitung: Freigabe abgegeben") if (self.m_oThreadFast): # Synchronization Point (Fast Thread Termination) Globs.dbg("Stop Aufgabenbearbeitung: Warten auf leichte Bearbeitung") self.m_oThreadFast.join(20.0) if self.m_oThreadFast.is_alive(): Globs.err("Stop Aufgabenbearbeitung: Leichte Bearbeitung nicht beendet") bResult = False else: Globs.dbg("Stop Aufgabenbearbeitung: Leichte Bearbeitung beendet") self.m_oQueueFast = None self.m_oThreadFast = None if (self.m_oThreadLong): # Synchronization Point (Long Thread Termination) Globs.dbg("Stop Aufgabenbearbeitung: Warten auf schwere Bearbeitung") self.m_oThreadLong.join(60.0) if self.m_oThreadLong.is_alive(): Globs.err("Stop Aufgabenbearbeitung: Schwere Bearbeitung nicht beendet") bResult = False else: Globs.dbg("Stop Aufgabenbearbeitung: Schwere Bearbeitung beendet") self.m_oQueueLong = None self.m_oThreadLong = None Globs.dbg("Stop Aufgabenbearbeitung: Abgeschlossen (%r)" % (bResult)) return bResult
def startQueue(self): Globs.dbg("Start Aufgabenbearbeitung: Warten auf Freigabe") # >>> Critical Section self.m_oLock.acquire() Globs.dbg("Start Aufgabenbearbeitung: Freigabe erhalten") self.m_oThreadFast = threading.Thread(target=self.fastThreadProc) self.m_oThreadFast.daemon = True self.m_oThreadLong = threading.Thread(target=self.longThreadProc) self.m_oThreadLong.daemon = True self.m_oQueueFast = queue.Queue() self.m_oQueueLong = queue.Queue() self.m_oThreadFast.start() self.m_oThreadLong.start() self.m_evtRunning.set() Globs.dbg("Start Aufgabenbearbeitung: Freigabe abgeben") self.m_oLock.release() # <<< Critical Section TaskInit(self).start() # Synchronization Point (Initialisation) Globs.dbg("Start Aufgabenbearbeitung: Warten auf Initialisierung") self.m_evtInit.wait() Globs.dbg("Start Aufgabenbearbeitung: Initialisierung abgeschlossen") # Set up cyclic monitoring of system values Globs.dbg("Start Aufgabenbearbeitung: Systemüberwachung starten") TaskSystemWatchDog(self).start() return
def runSystemWatchDog(self): self.m_oWatchDogTimer = threading.Timer( 10.0, self.onRunSystemWatchDog).start() Globs.dbg("Systemüberwachung: Nächste Prüfung eingeplant (%s)" % ( self.m_oWatchDogTimer)) return
def do(self): # Gegebenenfalls die alte Instanz des Moduls entladen bUnloaded = False if (self.m_strComponent in self.m_oWorker.m_dictModules): oInstance = self.m_oWorker.m_dictModules.pop(self.m_strComponent) oInstance.moduleExit() del oInstance bUnloaded = True if (self.m_strComponent in Globs.s_dictSettings["dictModules"] and self.m_strComponent not in Globs.s_dictSettings["listInactiveModules"]): # Klasse des Moduls laden clsModule = Globs.importComponent("modules." + self.m_strComponent, Globs.s_dictSettings["dictModules"][self.m_strComponent]) if not clsModule: strMsg = "Das Modul %s kann nicht geladen werden. Wahrscheinlich sind die Einstellungen falsch." % ( self.m_strComponent) Globs.wrn(strMsg) TaskSpeak(self.m_oWorker, strMsg).start() return # Module instanziieren oInstance = clsModule(self.m_oWorker) del clsModule # >>> Critical Section Globs.s_oSettingsLock.acquire() if self.m_strComponent not in Globs.s_dictSettings: Globs.s_dictSettings.update({self.m_strComponent : {}}) dictModCfg = Globs.s_dictSettings[self.m_strComponent] Globs.s_oSettingsLock.release() # <<< Critical Section dictCfgUsr = {} try: if not oInstance.moduleInit(dictModCfg=dictModCfg, dictCfgUsr=dictCfgUsr): strMsg = "Das Modul %s konnte nicht initialisiert werden." % (self.m_strComponent) Globs.wrn(strMsg) TaskSpeak(self.m_oWorker, strMsg).start() return except: Globs.exc("Verwalten des Moduls %s" % (self.m_strComponent)) strMsg = "Das Modul %s konnte nicht initialisiert werden. Wahrscheinlich ist es veraltet und nicht mehr kompatibel." % ( self.m_strComponent) Globs.wrn(strMsg) TaskSpeak(self.m_oWorker, strMsg).start() return # Module registrieren self.m_oWorker.m_dictModules.update({self.m_strComponent : oInstance}) Globs.s_dictUserSettings.update({self.m_strComponent : dictCfgUsr}) return if (self.m_strComponent not in Globs.s_dictSettings["dictModules"]): # >>> Critical Section Globs.s_oSettingsLock.acquire() if self.m_strComponent in Globs.s_dictSettings: Globs.s_dictSettings.pop(self.m_strComponent) if self.m_strComponent in Globs.s_dictUserSettings: Globs.s_dictUserSettings.pop(self.m_strComponent) Globs.s_oSettingsLock.release() # <<< Critical Section strMsg = "Das Modul %s wurde dauerhaft entfernt." % (self.m_strComponent) Globs.log(strMsg) TaskSpeak(self.m_oWorker, strMsg).start() return strMsg = "Das Modul %s wurde ausgeschaltet" % (self.m_strComponent) if (bUnloaded): strMsg += " und entladen" strMsg += "." Globs.log(strMsg) TaskSpeak(self.m_oWorker, strMsg).start() Globs.log(strMsg) return
def done(self, bResult = True): Globs.dbg("'%s' (leicht): Bearbeitung abgeschlossen (%r)" % (self, bResult)) self.m_oWorker.m_oQueueFast.task_done() return
def moduleExec(self, strPath, oHtmlPage, dictQuery, dictForm ): print("%r::moduleExec(strPath=%s, oHtmlPage=%s, dictQuery=%r, dictForm=%r)" % ( self, strPath, oHtmlPage, dictQuery, dictForm)) if not dictQuery: return False bResult = False for (strCmd, lstArg) in dictQuery.items(): if (strCmd == "cputemp"): for strArg in lstArg: # Modultest für die CPU-Temperaturüberwachung if (strArg == "hysterese"): TaskSpeak(self.getWorker(), "Der Modultest für die Temperaturüberwachung der CPU wird vorbereitet").start() fCpuTempA = Globs.getSetting("System", "fCpuTempA", "\\d{2,}\\.\\d+", 60.0) fCpuTempB = Globs.getSetting("System", "fCpuTempB", "\\d{2,}\\.\\d+", 56.0) fCpuTempC = Globs.getSetting("System", "fCpuTempC", "\\d{2,}\\.\\d+", 53.0) fCpuTempH = Globs.getSetting("System", "fCpuTempH", "\\d{2,}\\.\\d+", 1.0) fCpuTempStep = fCpuTempH / 2.0 fCpuTempDir = 1.0 fCpuTempBase = SDK.getCpuTemp() fCpuTemp = fCpuTempBase fCpuTempHyst = fCpuTempH * 2.0 nHysTest = 0 Globs.s_oQueueTestCpuTempValues.put(fCpuTemp, block=False) # Erst steigende, dann sinkende Temperaturen while (fCpuTemp >= (fCpuTempC - (fCpuTempHyst * 2.0))): fCpuTemp += (fCpuTempStep * fCpuTempDir) Globs.s_oQueueTestCpuTempValues.put(fCpuTemp, block=False) # Erste Hysterese testen if (fCpuTemp > (fCpuTempC + fCpuTempHyst) and nHysTest == 0): while (fCpuTemp > (fCpuTempC - fCpuTempHyst)): fCpuTemp -= fCpuTempStep Globs.s_oQueueTestCpuTempValues.put(fCpuTemp, block=False) nHysTest += 1 # Zweite Hysterese testen if (fCpuTemp > (fCpuTempB + fCpuTempHyst) and nHysTest == 1): while (fCpuTemp > (fCpuTempB - fCpuTempHyst)): fCpuTemp -= fCpuTempStep Globs.s_oQueueTestCpuTempValues.put(fCpuTemp, block=False) nHysTest += 1 # Dritte Hysterese testen if (fCpuTemp > (fCpuTempA + fCpuTempHyst) and nHysTest == 2): while (fCpuTemp > (fCpuTempA - fCpuTempHyst)): fCpuTemp -= fCpuTempStep Globs.s_oQueueTestCpuTempValues.put(fCpuTemp, block=False) nHysTest += 1 # Temperaturrichtung umkehren if (fCpuTemp >= (fCpuTempA + (fCpuTempHyst * 0.75)) and nHysTest == 3): fCpuTempDir *= (-1.0) nHysTest += 1 bResult = True TaskSpeak(self.getWorker(), "Der Modultest für die Temperaturüberwachung der CPU ist jetzt bereit").start() continue # Unbekanntes Kommando return bResult
def moduleExec(self, strPath, oHtmlPage, dictQuery, dictForm ): dictQueryKeys = None dictFormKeys = None if (dictQuery): dictQueryKeys = dictQuery.keys() if (dictForm): dictFormKeys = dictForm.keys() print("%r::moduleExec(strPath=%s, oHtmlPage=%s, dictQuery=%s, dictForm=%s) [%s]" % ( self, strPath, oHtmlPage, dictQueryKeys, dictFormKeys, datetime.today().strftime("%X"))) if (re.match("/modules/Updater\\.html", strPath) and not oHtmlPage == None): return self.serveHtmlPage(oHtmlPage, dictQuery, dictForm) self.updateContext() if not dictQuery: return False # Zyklische Prüfung bResult = False bCheck = False bFetch = False bSetup = False for (strCmd, lstArg) in dictQuery.items(): if (strCmd == "timer" and lstArg and lstArg[0] == "cron"): # Aktualisierungszeitpunkt erreicht? if (not self.m_nHour24h == self.m_nUpdateHour or not self.m_nMinutes == 0): return True bCheck = True break if (strCmd == "token" and self.m_strDownloadToken in lstArg): if (self.m_fChkVersion <= Globs.getVersion()): # Jetzt auf Aktualisierung prüfen! Globs.log("Jetzt auf Aktualisierung prüfen.") bCheck = True break if (self.m_fChkVersion > Globs.getVersion()): # Jetzt Aktualisierung herunterladen! Globs.log("Jetzt Aktualisierung herunterladen.") bFetch = True break if (strCmd == "token" and self.m_strUpdateToken in lstArg): # Jetzt ausstehende Installation ausführen! Globs.log("Jetzt ausstehende Installation ausführen.") bSetup = True break Globs.log("Keine Funktion mit Cmd=%s und Arg=%s" % (strCmd, lstArg)) if bCheck or bFetch or bSetup: # Aktualisierung verfügbar? if (not self.doCheckUpdate()): return True # Automatische Aktualisierung aktiviert? if (not self.m_bAutoUpdate and not bFetch and not bSetup): TaskSpeak(self.getWorker(), "Eine neue Version steht zur Verfügung und kann heruntergeladen werden.").start() return True if (not self.doDownloadUpdate()): TaskSpeak(self.getWorker(), "Beim Herunterladen der neuen Version sind Probleme aufgetreten.").start() return False if (not self.m_bAutoReboot and not bSetup): TaskSpeak(self.getWorker(), "Eine neue Version steht zur Verfügung und kann installiert werden.").start() return True if (not self.doInstallUpdate()): TaskSpeak(self.getWorker(), "Beim Installieren der neuen Version sind Probleme aufgetreten.").start() return False return True
def doCheckUpdate(self): oClient = WebClient() oResp = None if (not self.m_strChkUpdUrl): Globs.err("Die URL für die Aktualisierungsinformation ('%s') ist ungültig" % ( self.m_strChkUpdUrl)) if (not self.m_oSystemUpdateIO): return False oResp = oClient.GET(self.m_strChkUpdUrl) if (not oResp or not oResp.m_bOK): Globs.err("Fehler (%s) beim Herunterladen der Aktualisierungsinformation '%s'" % ( oResp, self.m_strChkUpdUrl)) if (not self.m_oSystemUpdateIO): return False strUpdInf = oResp.m_oData.decode() try: strUpdInf = strUpdInf[:10] + (strUpdInf[10:] and "..") self.m_fChkVersion = float(strUpdInf) Globs.setSetting("Updater", "fChkVersion", self.m_fChkVersion) except: Globs.exc("Fehler beim Auswerten der Aktualisierungsinformation '%s'" % ( strUpdInf)) Globs.setSetting("Updater", "strChkUpdUrl", Updater.s_strChkUpdUrl) if (not self.m_oSystemUpdateIO): return False if (self.m_oSystemUpdateIO): if (self.m_fChkVersion > self.m_fUpdVersion): Globs.log("Neuere Aktualisierung '%s' als bereitgestellte '%s' verfügbar" % ( self.m_fChkVersion, self.m_fUpdVersion)) else: Globs.log("Eine Aktualisierung '%s' wurde bereitgestellt." % ( self.m_fUpdVersion)) return True if (self.m_fChkVersion <= Globs.getVersion()): Globs.log("Keine Aktualisierung für Version '%s' verfügbar" % ( Globs.getVersion())) return False Globs.log("Neuere Aktualisierung von Version '%s' auf '%s' verfügbar" % ( Globs.getVersion(), self.m_fChkVersion)) return True
def doInstallUpdate(self): if (not self.m_oSystemUpdateIO): self.m_fUpdVersion = float(0.0) self.m_bUpdateOffline = False return False if (not zipfile.is_zipfile(self.m_oSystemUpdateIO)): Globs.err("Die Systemaktualisierungsdatei ist keine gültige Zip-Datei") del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) self.m_bUpdateOffline = False return False dictSysUpdate = OrderedDict() dictModUpdate = OrderedDict() dictBackup = OrderedDict() bUpdateComplete = False try: with \ tempfile.TemporaryDirectory() as oTmpDir,\ ZipFile(self.m_oSystemUpdateIO, "r") as oSysZipFile: # Aktualisierung vorbereiten for oZipInfo in (oSysZipFile.infolist()): foFile = oSysZipFile.open(oZipInfo) if (os.path.isabs(oZipInfo.filename)): Globs.err("Absolute Pfadangabe in Zip-Datei: '%s'" % ( oZipInfo.filename)) del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) return False if (not re.match("\\A" + re.escape(Updater.s_strPrefix) + "\\w+.+", oZipInfo.filename)): continue strEntryName = oZipInfo.filename.replace(Updater.s_strPrefix, "") oSysZipFile.extract(oZipInfo, oTmpDir) Globs.dbg("Extrahieren von '%s' nach '%s'" % (oZipInfo.filename, oTmpDir)) strFilename = os.path.join(oTmpDir, oZipInfo.filename) if (os.path.isdir(strFilename)): continue if (not os.path.isfile(strFilename)): Globs.err("Die extrahierte Systemdatei '%s' wurde nicht gefunden" % ( strFilename)) del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) return False Globs.dbg("Das extrahierte Element '%s' liegt unter '%s'" % ( strEntryName, strFilename)) if (re.match("\\Amodules/\\w+\\.[Pp][Yy]\\Z", strEntryName)): dictModUpdate.update({strEntryName : strFilename}) elif (re.match(".+\\.([Pp][Yy]|[Pp][Nn][Gg]|[Hh][Tt][Mm][Ll]?|[Cc][Ss][Ss])\\Z", strEntryName)): dictSysUpdate.update({strEntryName : strFilename}) else: Globs.dbg("Das element '%s' wird nicht installiert" % (strEntryName)) # Systemaktualisierung durchführen for (strRelDst, strSrcFile) in dictSysUpdate.items(): strDstFile = os.path.join(Globs.s_strBasePath, strRelDst) if (os.path.isfile(strDstFile)): strDstFileBak = "%s.bak" % strDstFile os.rename(strDstFile, strDstFileBak) dictBackup.update({strDstFile : strDstFileBak}) Globs.dbg("Backup von Datei '%s' ('%s') erstellt." % (strDstFile, strDstFileBak)) foSource = open(strSrcFile, "r+b") self.installFile(foSource, strDstFile) foSource.close() Globs.dbg("Update von Datei '%s' installiert." % (strDstFile)) # Modulaktualisierung durchführen for (strRelDst, strSrcFile) in dictModUpdate.items(): strDstFile = os.path.join(Globs.s_strBasePath, strRelDst) if (os.path.isfile(strDstFile)): strDstFileBak = "%s.bak" % strDstFile os.rename(strDstFile, strDstFileBak) dictBackup.update({strDstFile : strDstFileBak}) Globs.dbg("Backup von Modul '%s' ('%s') erstellt." % (strDstFile, strDstFileBak)) foSource = open(strSrcFile, "r+b") self.installFile(foSource, strDstFile) foSource.close() Globs.dbg("Update von Modul '%s' installiert." % (strDstFile)) bUpdateComplete = True del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) self.m_bUpdateOffline = False TaskExit(self.getWorker(), "boot").start() except: Globs.exc("Ausnahmefall während der Aktualisierung - Wiederherstellung ausführen") del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) self.m_bUpdateOffline = False try: if (not bUpdateComplete): for (strDstFile, strDstFileBak) in dictBackup.items(): os.rename(strDstFileBak, strDstFile) Globs.wrn("Das Element '%s' wurde wiederhergestellt" % (strDstFile)) Globs.err("Die Aktualisierung ist fehlgeschlagen - Wiederherstellung erfolgreich") except: Globs.exc("Ausnahmefall während der Wiederherstellung nach Fehler bei Aktualisierung") del self.m_oSystemUpdateIO self.m_oSystemUpdateIO = None self.m_fUpdVersion = float(0.0) self.m_bUpdateOffline = False return True
def serveHtmlPage(self, oHtmlPage, dictQuery, dictForm): Globs.log("Updater::serveHtmlPage()") if (dictQuery and "token" in dictQuery): if (self.m_strUploadToken in dictQuery["token"]): self.m_strUploadToken = uuid.uuid4().hex if (dictForm and "SystemFile" in dictForm): oSystemFile = dictForm["SystemFile"][0] if not oSystemFile.filename or not oSystemFile.file: oHtmlPage.createBox( "Systemaktualisierung", "Es konnte keine gültige Aktualisierungsdatei hochgeladen werden.", strType="warning") return True self.m_oSystemUpdateIO = BytesIO(oSystemFile.file.read()) self.m_strUpdateToken = uuid.uuid4().hex self.m_bUpdateOffline = True TaskModuleEvt(self.getWorker(), "/modules/Updater.cmd", dictQuery={"token" : self.m_strUpdateToken}).start() oHtmlPage.createBox( "Systemaktualisierung", "Die Aktualisierung wird jetzt durchgeführt. Danach wird das System neu "+ "gestartet. Dieser Vorgang kann einige Zeit in Anspruch nehmen.", strType="info") return True oHtmlPage.createBox( "Systemaktualisierung", "Über diese Funktion kann eine manuelle Aktualisierung durchgeführt werden.", bClose=False) oHtmlPage.openForm( dictQueries={"token" : self.m_strUploadToken}) oHtmlPage.appendForm("SystemFile", strTitle="Datei für Systemaktualisierung", strTip="Zip-Datei für die Systemaktualisierung angeben", strTextType="file", strTypePattern="accept=\"application/zip\"") oHtmlPage.closeForm(strUrlCancel="/system/settings.html") oHtmlPage.closeBox() return True if (self.m_strDownloadToken in dictQuery["token"]): self.m_strDownloadToken = uuid.uuid4().hex TaskModuleEvt(self.getWorker(), "/modules/Updater.cmd", dictQuery={"token" : self.m_strDownloadToken}).start() oHtmlPage.createBox( "Systemaktualisierung", "Es wird nach einer Aktualisierung gesucht. Dieser Vorgang kann einige Zeit "+ "in Anspruch nehmen.", strType="info") return True if (self.m_strUpdateToken in dictQuery["token"]): self.m_strUpdateToken = uuid.uuid4().hex TaskModuleEvt(self.getWorker(), "/modules/Updater.cmd", dictQuery={"token" : self.m_strUpdateToken}).start() oHtmlPage.createBox( "Systemaktualisierung", "Die Installation der Aktualisierung wurde angefordert. Dieser Vorgang kann "+ "einige Zeit in Anspruch nehmen.", strType="info") return True # Wenn die automatische Installation von Aktualisierungen deaktiviert wurde und eine neuere # Version bereitgestellt wurde, dann anbieten, die Installation anzufordern. if ((not self.m_bAutoReboot) and (self.m_fUpdVersion > Globs.getVersion())): oHtmlPage.createBox( "Systemaktualisierung", "Die automatische Installation von Aktualisierungen ist ausgeschaltet aber es "+ "steht eine neuere Version zur Installation bereit.", strType="warning", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert und Version %s steht bereit" % ( Globs.getVersion(), self.m_fUpdVersion)) oHtmlPage.createButton( "Jetzt installieren", strClass="ym-warning", strHRef="/modules/Updater.html?token=%s" % (self.m_strUpdateToken)) oHtmlPage.closeBox() return True # Wenn das automatische Herunterladen von Aktualisierungen deaktiviert wurde und online # eine neuere Version zur Verfügung steht, dann anbieten, das Herunterladen anzufordern. if ((not self.m_bAutoUpdate) and (self.m_fChkVersion > Globs.getVersion())): oHtmlPage.createBox( "Systemaktualisierung", "Das automatische Herunterladen von Aktualisierungen ist ausgeschaltet aber es "+ "steht eine neuere Version zum Herunterladen bereit.", strType="warning", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert und Version %s ist verfügbar." % ( Globs.getVersion(), self.m_fChkVersion)) oHtmlPage.createButton( "Jetzt herunterladen", strClass="ym-warning", strHRef="/modules/Updater.html?token=%s" % (self.m_strDownloadToken)) oHtmlPage.closeBox() return True # Wenn eine neuere Version bereitsteht, die Versionsinformationen anzeigen if (self.m_fUpdVersion > Globs.getVersion()): oHtmlPage.createBox( "Systemaktualisierung", "Es steht eine neuere Version zur Installation bereit, die zum nächsten "+ "Aktualisierungszeitpunkt automatisch installiert wird.", strType="info", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert und Version %s steht bereit" % ( Globs.getVersion(), self.m_fUpdVersion)) oHtmlPage.createButton( "Aktualisierung hochladen", strHRef="/modules/Updater.html?token=%s" % (self.m_strUploadToken)) oHtmlPage.closeBox() return True # Wenn eine neuere Version gefunden wurde, die Versionsinformationen anzeigen if (self.m_fChkVersion > Globs.getVersion()): oHtmlPage.createBox( "Systemaktualisierung", "Es steht eine neuere Version zum Herunterladen bereit, die zum nächsten "+ "Aktualisierungszeitpunkt automatisch heruntergeladen wird.", strType="info", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert und Version %s ist verfügbar." % ( Globs.getVersion(), self.m_fChkVersion)) oHtmlPage.createButton( "Aktualisierung hochladen", strHRef="/modules/Updater.html?token=%s" % (self.m_strUploadToken)) oHtmlPage.closeBox() return True # Es ist keine Aktualisierung verfügbar if (self.m_fChkVersion == Globs.getVersion()): oHtmlPage.createBox( "Systemaktualisierung", "Das System ist auf dem aktuellen Stand. Es sind keine Aktualisierungen verfügbar.", strType="success", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert." % (Globs.getVersion())) oHtmlPage.createButton( "Aktualisierung suchen", strHRef="/modules/Updater.html?token=%s" % (self.m_strDownloadToken)) oHtmlPage.createButton( "Aktualisierung hochladen", strHRef="/modules/Updater.html?token=%s" % (self.m_strUploadToken)) oHtmlPage.closeBox() return True # Default, noch nicht nach Aktualisierungen gesucht oder keine Aktualisierungen verfügbar. oHtmlPage.createBox( "Systemaktualisierung", "Es wurde noch nicht nach Aktualisierungen gesucht.", strType="info", bClose=False) oHtmlPage.createText( "Derzeit ist die Version %s installiert." % (Globs.getVersion())) oHtmlPage.createButton( "Aktualisierung suchen", strHRef="/modules/Updater.html?token=%s" % (self.m_strDownloadToken)) oHtmlPage.createButton( "Aktualisierung hochladen", strHRef="/modules/Updater.html?token=%s" % (self.m_strUploadToken)) oHtmlPage.closeBox() return True
def do(self): Globs.loadSettings() self.m_oWorker.m_evtInit.set() for strComponent in Globs.s_dictSettings["dictModules"].keys(): TaskModuleInit(self.m_oWorker, strComponent).start() return
def run(self): strProgram = None strPID = None oSysCallCmd = False strGoodBye = "Tschüssikovski!" print("Attempt to start message queue ...") self.m_oWorker.startQueue() print("OK") TaskSpeak(self.m_oWorker, "Servus!").start() while True: print("Attempt to start HTTP Server ...") try: self.m_oHttpd.run() break except: Globs.exc("HTTP Server starten und laufen lassen") if not (strProgram and strPID): # Einmalig versuchen, den belegten Port freizugeben oLines = SDK.getShellCmdOutput("netstat -pant") for strLine in oLines: if re.match("tcp\\s+.*\\s+%s\\:%s\\s+%s\\s+LISTEN\\s+\\d+/dbus-daemon" % ( re.escape(Globs.s_oHttpd.server_address[0]), Globs.s_oHttpd.server_address[1], re.escape("0.0.0.0:*"), strLine)): for strToken in re.split("\\s+", strLine): if (re.match("\\d+/dbus-daemon", strToken)): strPID, strProgram = re.split("/", strToken) break if (strProgram and strPID): break; if (strProgram and strPID): TaskSpeak(self.m_oWorker, "Das Program %s mit der Prozesskennung %s belegt den Port %s" % ( strProgram, strPID, Globs.s_oHttpd.server_address[1])).start() TaskSpeak(self.m_oWorker, "Ich versuche, das Program %s mit der Prozesskennung %s zu beenden" % ( strProgram, strPID)).start() SDK.getShellCmdOutput("sudo kill %s" % strPID) continue TaskSpeak(self.m_oWorker, "Hoppla! Es gibt wohl Probleme mit dem Webb-Sörver.").start() break print("HTTP Server STOPPED") if Globs.s_strExitMode == "halt": oSysCallCmd = "sudo halt" strGoodBye += " Das System wird jetzt heruntergefahren." if Globs.s_strExitMode == "boot": oSysCallCmd = "sudo reboot" strGoodBye += " Das System wird jetzt neu gestartet." TaskSpeak(self.m_oWorker, strGoodBye).start() print("Attempt to stop message queue ...") if not self.m_oWorker.stopQueue(): print("FAILED") else: print("OK") if oSysCallCmd: print("Executing final syscall: " + oSysCallCmd) subprocess.Popen(oSysCallCmd, shell=True) return