CLI: poll runtime log and output new entries to stdout.
--- 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):