From 322b4d8a90d2259746697aec17ea794af16c7bd4 Mon Sep 17 00:00:00 2001 From: Patrick Schmidt Date: Tue, 2 Jan 2024 17:13:03 +0100 Subject: [PATCH] Fixes #73 - Ignore pauses for Timelapse plugins --- .../data/dtos/moonraker/printer_snapshot.py | 4 +- mobileraker/mobileraker_companion.py | 6 ++- mobileraker/service/data_sync_service.py | 42 +++++++++---------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/mobileraker/data/dtos/moonraker/printer_snapshot.py b/mobileraker/data/dtos/moonraker/printer_snapshot.py index b38962e..518bf1e 100644 --- a/mobileraker/data/dtos/moonraker/printer_snapshot.py +++ b/mobileraker/data/dtos/moonraker/printer_snapshot.py @@ -1,7 +1,7 @@ from datetime import datetime, timedelta +from typing import Optional import math import pytz -from typing import Optional from mobileraker.data.dtos.moonraker.printer_objects import GCodeFile, GCodeMove, PrintStats, Toolhead, VirtualSDCard @@ -24,6 +24,7 @@ def __init__( self.gcode_move: Optional[GCodeMove] = None self.gcode_response: Optional[str] = None self.gcode_response_hash: Optional[str] = None + self.timelapse_pause: Optional[bool] = None def __str__(self): return '%s(%s)' % ( @@ -43,6 +44,7 @@ def __eq__(self, other): and self.virtual_sdcard == other.virtual_sdcard and self.current_file == other.current_file and self.gcode_response == other.gcode_response + and self.timelapse_pause == other.timelapse_pause ) @property diff --git a/mobileraker/mobileraker_companion.py b/mobileraker/mobileraker_companion.py index 60093d5..51b3122 100644 --- a/mobileraker/mobileraker_companion.py +++ b/mobileraker/mobileraker_companion.py @@ -181,7 +181,7 @@ def _fulfills_evaluation_threshold(self, snapshot: PrinterSnapshot) -> bool: self._logger.info('No last snapshot available. Evaluating!') return True - if self._last_snapshot.print_state != snapshot.print_state: + if self._last_snapshot.print_state != snapshot.print_state and not snapshot.timelapse_pause: self._logger.info('State changed. Evaluating!') return True @@ -310,6 +310,10 @@ def _progress_notification(self, cfg: DeviceNotificationEntry, cur_snap: Printer # also skip if progress is at 100 since this notification is handled via the print state transition from printing to completed if cur_snap.print_state not in ["printing", "paused"] or cur_snap.progress is None or cur_snap.progress == 100: return None + + # Ignore paused state caused by timelapse plugin + if cur_snap.timelapse_pause: + return None self._logger.info( 'ProgressNoti preChecks: cfg.progress.config: %i - %i = %i < %i RESULT: %s', diff --git a/mobileraker/service/data_sync_service.py b/mobileraker/service/data_sync_service.py index ec71e9d..295750c 100644 --- a/mobileraker/service/data_sync_service.py +++ b/mobileraker/service/data_sync_service.py @@ -2,13 +2,26 @@ import asyncio import hashlib import logging -from typing import Any, Callable, Dict, List, Optional, cast +from typing import Any, Callable, Dict, List, Optional from mobileraker.client.moonraker_client import MoonrakerClient from mobileraker.data.dtos.moonraker.printer_objects import DisplayStatus, GCodeFile, GCodeMove, PrintStats, ServerInfo, Toolhead, VirtualSDCard from mobileraker.data.dtos.moonraker.printer_snapshot import PrinterSnapshot + + class DataSyncService: + _OBJECTS_TO_SUBSCRIBE = { + "objects": { + "print_stats": None, + "display_status": None, + "virtual_sdcard": None, + "toolhead": None, + "gcode_move": None, + "gcode_macro TIMELAPSE_TAKE_FRAME": None, + } + } + ''' This service is responsible for keeping track of the latest printer data and then providing a snapshot of all data to any service that requires it. @@ -43,6 +56,7 @@ def __init__( self.virtual_sdcard: VirtualSDCard = VirtualSDCard() self.current_file: Optional[GCodeFile] = None self.gcode_response: Optional[str] = None + self.timelapse_pause: Optional[bool] = None self.resync_retries: int = resync_retries self._snapshot_listeners: List[Callable[[PrinterSnapshot], None]] = [] @@ -91,6 +105,8 @@ def _parse_objects(self, status_objects: Dict[str, Any], err: Optional[str] = No self.toolhead = self.toolhead.updateWith(object_data) elif key == 'gcode_move': self.gcode_move = self.gcode_move.updateWith(object_data) + elif key == 'gcode_macro TIMELAPSE_TAKE_FRAME': + self.timelapse_pause = object_data.get('is_paused', None) # Kinda hacky but this works! # It would be better if the _notify_listeners()/sync current file is called in a different context since this method should only parse! @@ -178,16 +194,7 @@ async def _sync_printer_data(self) -> None: ''' try: self._logger.info("Syncing printer Objects") - params = { - "objects": { - "print_stats": None, - # "display_status": None, - "virtual_sdcard": None, - "toolhead": None, - "gcode_move": None, - } - } - response, k_err = await self._jrpc.send_and_receive_method("printer.objects.query", params) + response, k_err = await self._jrpc.send_and_receive_method("printer.objects.query", self._OBJECTS_TO_SUBSCRIBE) if k_err: self._logger.warning("Could not sync printer data. Moonraker returned error %s", k_err) return @@ -218,16 +225,8 @@ async def _subscribe_for_object_updates(self) -> None: None ''' self._logger.info("Subscribing to printer Objects") - params = { - "objects": { - "print_stats": None, - "display_status": None, - "virtual_sdcard": None, - "toolhead": None, - "gcode_move": None, - } - } - await self._jrpc.send_method("printer.objects.subscribe", None, params) + await self._jrpc.send_method("printer.objects.subscribe", None, self._OBJECTS_TO_SUBSCRIBE) + self._logger.info("Subscribed to printer Objects") def _notify_listeners(self): ''' @@ -330,6 +329,7 @@ def take_snapshot(self) -> PrinterSnapshot: snapshot.gcode_response = self.gcode_response snapshot.gcode_response_hash = hashlib.sha256(snapshot.gcode_response.encode( "utf-8")).hexdigest() if snapshot.gcode_response else '' + snapshot.timelapse_pause = self.timelapse_pause self._logger.debug('Took a PrinterSnapshot: %s', snapshot) return snapshot