# HG changeset patch # User Edouard Tisserant # Date 1664994358 -7200 # Node ID f75b11506fb236458877e447cd381972a135801c # Parent f08b59f7c00aad2a2747c2e9c9dd4f059b9a2ce4 CLI: poll runtime log and output new entries to stdout. diff -r f08b59f7c00a -r f75b11506fb2 CLIController.py --- a/CLIController.py Wed Oct 05 20:15:28 2022 +0200 +++ b/CLIController.py Wed Oct 05 20:25:58 2022 +0200 @@ -4,6 +4,8 @@ import os import sys from functools import wraps +from threading import Timer +from datetime import datetime import click @@ -11,6 +13,8 @@ from ProjectController import ProjectController from LocalRuntimeMixin import LocalRuntimeMixin +from runtime.loglevels import LogLevelsCount, LogLevels + class Log: @@ -74,6 +78,64 @@ log = Log() LocalRuntimeMixin.__init__(self, log, use_gui=False) ProjectController.__init__(self, None, log) + self.CLIStatusTimer = None + self.KillCLIStatusTimer = False + + + def StartCLIStatusTimer(self): + if self.CLIStatusTimer is not None: + return + self.CLIStatusTimer = Timer(0.5, self.CLIStatusTimerProc) + self.KillCLIStatusTimer = False + self.CLIStatusTimer.start() + + def StopCLIStatusTimer(self): + if self.CLIStatusTimer is None: + return + self.KillCLIStatusTimer = True + self.CLIStatusTimer.cancel() + self.CLIStatusTimer = None + + def CLIStatusTimerProc(self): + self.CLIStatusTimer = None + if not self.KillCLIStatusTimer: + self.PullPLCStatusProc(None) + self.StartCLIStatusTimer() + + def _SetConnector(self, connector, update_status=True): + self._connector = connector + self.previous_log_count = [None]*LogLevelsCount + if connector is not None: + self.StartCLIStatusTimer() + else: + self.StopCLIStatusTimer() + if update_status: + self.UpdateMethodsFromPLCStatus() + + def UpdatePLCLog(self, log_count): + connector = self._connector + new_messages = [] + if connector: + for level, count, prev in zip( + xrange(LogLevelsCount), log_count, self.previous_log_count): + if count is not None and prev != count: + if prev is None: + dump_end = max(-1, count - 10) + else: + dump_end = prev - 1 + for msgidx in range(count-1, dump_end, -1): + message = connector.GetLogMessage(level, msgidx) + if message is not None: + msg, _tick, tv_sec, tv_nsec = message + date = datetime.utcfromtimestamp(tv_sec + tv_nsec * 1e-9) + txt = "%s at %s: %s\n" % (LogLevels[level], date.isoformat(' '), msg) + new_messages.append((date,txt)) + else: + break + self.previous_log_count[level] = count + new_messages.sort() + for date, txt in new_messages: + self.logger.write(txt) def check_and_load_project(self): if not os.path.isdir(self.session.project_home):