diff --git a/library/lcd/lcd_comm_rev_b.py b/library/lcd/lcd_comm_rev_b.py index 4bd958b6..e1010154 100644 --- a/library/lcd/lcd_comm_rev_b.py +++ b/library/lcd/lcd_comm_rev_b.py @@ -245,3 +245,10 @@ def DisplayPILImage( # Send image data by multiple of "display width" bytes for chunk in chunked(rgb565be, self.get_width() * 8): self.SendLine(chunk) + + # Implement a cooldown between two bitmaps, because we are not listening to events coming from the display + # Cooldown of 0.05 decreases "corrupted bitmap" significantly without slowing down too much + if self.update_queue: + self.update_queue.put((time.sleep, [0.05])) + else: + time.sleep(0.05) \ No newline at end of file diff --git a/main.py b/main.py index a58520c2..c161c8d7 100755 --- a/main.py +++ b/main.py @@ -80,6 +80,17 @@ logger.debug("Using Python %s" % sys.version) + def wait_for_empty_queue(timeout: int = 5): + # Waiting for all pending request to be sent to display + logger.info("Waiting for all pending request to be sent to display (%ds max)..." % timeout) + + wait_time = 0 + while not scheduler.is_queue_empty() and wait_time < timeout: + time.sleep(0.1) + wait_time = wait_time + 0.1 + + logger.debug("(Waited %.1fs)" % wait_time) + def clean_stop(tray_icon=None): # Turn screen and LEDs off before stopping display.turn_off() @@ -88,15 +99,8 @@ def clean_stop(tray_icon=None): # Instead, ask the scheduler to empty the action queue before stopping scheduler.STOPPING = True - # Allow 5 seconds max. delay in case scheduler is not responding - wait_time = 5 - logger.info("Waiting for all pending request to be sent to display (%ds max)..." % wait_time) - - while not scheduler.is_queue_empty() and wait_time > 0: - time.sleep(0.1) - wait_time = wait_time - 0.1 - - logger.debug("(%.1fs)" % (5 - wait_time)) + # Waiting for all pending request to be sent to display + wait_for_empty_queue(5) # Remove tray icon just before exit if tray_icon: @@ -194,34 +198,42 @@ def on_win32_wm_event(hWnd, msg, wParam, lParam): win32api.SetConsoleCtrlHandler(on_win32_ctrl_event, True) # Initialize the display + logger.info("Initialize display") display.initialize_display() + # Start serial queue handler + scheduler.QueueHandler() + # Create all static images display.display_static_images() # Create all static texts display.display_static_text() - # Run our jobs that update data + # Wait for static images/text to be displayed before starting monitoring (to avoid filling the queue while waiting) + wait_for_empty_queue(10) + + # Start sensor scheduled reading. Avoid starting them all at the same time to optimize load + logger.info("Starting system monitoring") import library.stats as stats - scheduler.CPUPercentage() - scheduler.CPUFrequency() - scheduler.CPULoad() - scheduler.CPUTemperature() - scheduler.CPUFanSpeed() + scheduler.CPUPercentage(); time.sleep(0.25) + scheduler.CPUFrequency(); time.sleep(0.25) + scheduler.CPULoad(); time.sleep(0.25) + scheduler.CPUTemperature(); time.sleep(0.25) + scheduler.CPUFanSpeed(); time.sleep(0.25) if stats.Gpu.is_available(): - scheduler.GpuStats() - scheduler.MemoryStats() - scheduler.DiskStats() - scheduler.NetStats() - scheduler.DateStats() - scheduler.SystemUptimeStats() - scheduler.CustomStats() - scheduler.WeatherStats() - scheduler.PingStats() - scheduler.QueueHandler() - + scheduler.GpuStats(); time.sleep(0.25) + scheduler.MemoryStats(); time.sleep(0.25) + scheduler.DiskStats(); time.sleep(0.25) + scheduler.NetStats(); time.sleep(0.25) + scheduler.DateStats(); time.sleep(0.25) + scheduler.SystemUptimeStats(); time.sleep(0.25) + scheduler.CustomStats(); time.sleep(0.25) + scheduler.WeatherStats(); time.sleep(0.25) + scheduler.PingStats(); time.sleep(0.25) + + # OS-specific tasks if tray_icon and platform.system() == "Darwin": # macOS-specific from AppKit import NSBundle, NSApp, NSApplicationActivationPolicyProhibited