paneldue: use cached subscription data

Now that all subscriptions are cached it is no longer required for
the paneldue component to cache its own printer state.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2023-07-31 11:19:04 -04:00
parent d3bab5de94
commit e433252934
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
1 changed files with 57 additions and 65 deletions

View File

@ -29,6 +29,7 @@ from typing import (
) )
if TYPE_CHECKING: if TYPE_CHECKING:
from ..confighelper import ConfigHelper from ..confighelper import ConfigHelper
from ..klippy_connection import KlippyConnection
from .klippy_apis import KlippyAPI as APIComp from .klippy_apis import KlippyAPI as APIComp
from .file_manager.file_manager import FileManager as FMComp from .file_manager.file_manager import FileManager as FMComp
FlexCallback = Callable[..., Optional[Coroutine]] FlexCallback = Callable[..., Optional[Coroutine]]
@ -167,10 +168,8 @@ class PanelDue:
def __init__(self, config: ConfigHelper) -> None: def __init__(self, config: ConfigHelper) -> None:
self.server = config.get_server() self.server = config.get_server()
self.event_loop = self.server.get_event_loop() self.event_loop = self.server.get_event_loop()
self.file_manager: FMComp = \ self.file_manager: FMComp = self.server.lookup_component('file_manager')
self.server.lookup_component('file_manager') self.klippy_apis: APIComp = self.server.lookup_component('klippy_apis')
self.klippy_apis: APIComp = \
self.server.lookup_component('klippy_apis')
self.kinematics: str = "none" self.kinematics: str = "none"
self.machine_name = config.get('machine_name', "Klipper") self.machine_name = config.get('machine_name', "Klipper")
self.firmware_name: str = "Repetier | Klipper" self.firmware_name: str = "Repetier | Klipper"
@ -182,10 +181,8 @@ class PanelDue:
self.debug_queue: Deque[str] = deque(maxlen=100) self.debug_queue: Deque[str] = deque(maxlen=100)
# Initialize tracked state. # Initialize tracked state.
self.printer_state: Dict[str, Dict[str, Any]] = { kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
'gcode_move': {}, 'toolhead': {}, 'virtual_sdcard': {}, self.printer_state: Dict[str, Dict[str, Any]] = kconn.get_subscription_cache()
'fan': {}, 'display_status': {}, 'print_stats': {},
'idle_timeout': {}, 'gcode_macro PANELDUE_BEEP': {}}
self.extruder_count: int = 0 self.extruder_count: int = 0
self.heaters: List[str] = [] self.heaters: List[str] = []
self.is_ready: bool = False self.is_ready: bool = False
@ -216,24 +213,24 @@ class PanelDue:
# command is the value # command is the value
self.confirmed_macros = {m.split()[0]: m for m in conf_macros} self.confirmed_macros = {m.split()[0]: m for m in conf_macros}
self.available_macros.update(self.confirmed_macros) self.available_macros.update(self.confirmed_macros)
self.non_trivial_keys = config.getlist('non_trivial_keys', ["Klipper state"])
self.non_trivial_keys = config.getlist('non_trivial_keys',
["Klipper state"])
self.ser_conn = SerialConnection(config, self) self.ser_conn = SerialConnection(config, self)
logging.info("PanelDue Configured") logging.info("PanelDue Configured")
# Register server events # Register server events
self.server.register_event_handler( self.server.register_event_handler(
"server:klippy_ready", self._process_klippy_ready) "server:klippy_ready", self._process_klippy_ready
)
self.server.register_event_handler( self.server.register_event_handler(
"server:klippy_shutdown", self._process_klippy_shutdown) "server:klippy_shutdown", self._process_klippy_shutdown
)
self.server.register_event_handler( self.server.register_event_handler(
"server:klippy_disconnect", self._process_klippy_disconnect) "server:klippy_disconnect", self._process_klippy_disconnect
)
self.server.register_event_handler( self.server.register_event_handler(
"server:gcode_response", self.handle_gcode_response) "server:gcode_response", self.handle_gcode_response
)
self.server.register_remote_method( self.server.register_remote_method("paneldue_beep", self.paneldue_beep)
"paneldue_beep", self.paneldue_beep)
# These commands are directly executued on the server and do not to # These commands are directly executued on the server and do not to
# make a request to Klippy # make a request to Klippy
@ -271,8 +268,7 @@ class PanelDue:
while retries: while retries:
try: try:
printer_info = await self.klippy_apis.get_klippy_info() printer_info = await self.klippy_apis.get_klippy_info()
cfg_status = await self.klippy_apis.query_objects( cfg_status = await self.klippy_apis.query_objects({'configfile': None})
{'configfile': None})
except self.server.error: except self.server.error:
logging.exception("PanelDue initialization request failed") logging.exception("PanelDue initialization request failed")
retries -= 1 retries -= 1
@ -282,10 +278,8 @@ class PanelDue:
continue continue
break break
self.firmware_name = "Repetier | Klipper " + \ self.firmware_name = "Repetier | Klipper " + printer_info['software_version']
printer_info['software_version'] config: Dict[str, Any] = cfg_status.get('configfile', {}).get('config', {})
config: Dict[str, Any] = cfg_status.get(
'configfile', {}).get('config', {})
printer_cfg: Dict[str, Any] = config.get('printer', {}) printer_cfg: Dict[str, Any] = config.get('printer', {})
self.kinematics = printer_cfg.get('kinematics', "none") self.kinematics = printer_cfg.get('kinematics', "none")
@ -295,36 +289,35 @@ class PanelDue:
f"Kinematics: {self.kinematics}\n" f"Kinematics: {self.kinematics}\n"
f"Printer Config: {config}\n") f"Printer Config: {config}\n")
# Initalize printer state and make subscription request # Make subscription request
self.printer_state = { sub_args: Dict[str, Optional[List[str]]] = {
'gcode_move': {}, 'toolhead': {}, 'virtual_sdcard': {}, "motion_report": None,
'fan': {}, 'display_status': {}, 'print_stats': {}, "gcode_move": None,
'idle_timeout': {}, 'gcode_macro PANELDUE_BEEP': {}} "toolhead": None,
sub_args = {k: None for k in self.printer_state.keys()} "virtual_sdcard": None,
"fan": None,
"display_status": None,
"print_stats": None,
"idle_timeout": None,
"gcode_macro PANELDUE_BEEP": None
}
self.extruder_count = 0 self.extruder_count = 0
self.heaters = [] self.heaters = []
extruders = [] extruders = []
for cfg in config: for cfg in config:
if cfg.startswith("extruder"): if cfg.startswith("extruder"):
self.extruder_count += 1 self.extruder_count += 1
self.printer_state[cfg] = {}
extruders.append(cfg) extruders.append(cfg)
sub_args[cfg] = None sub_args[cfg] = None
elif cfg == "heater_bed": elif cfg == "heater_bed":
self.printer_state[cfg] = {}
self.heaters.append(cfg) self.heaters.append(cfg)
sub_args[cfg] = None sub_args[cfg] = None
extruders.sort() extruders.sort()
self.heaters.extend(extruders) self.heaters.extend(extruders)
try: try:
status: Dict[str, Any] await self.klippy_apis.subscribe_objects(sub_args)
status = await self.klippy_apis.subscribe_objects(
sub_args, self.handle_status_update
)
except self.server.error: except self.server.error:
logging.exception("Unable to complete subscription request") logging.exception("Unable to complete subscription request")
else:
self.printer_state.update(status)
self.is_shutdown = False self.is_shutdown = False
self.is_ready = True self.is_ready = True
@ -335,15 +328,9 @@ class PanelDue:
# Tell the PD that the printer is "off" # Tell the PD that the printer is "off"
self.write_response({'status': 'O'}) self.write_response({'status': 'O'})
self.last_printer_state = 'O' self.last_printer_state = 'O'
self.is_ready = False
self.is_shutdown = self.is_shutdown = False self.is_shutdown = self.is_shutdown = False
def handle_status_update(self, status: Dict[str, Any], _: float) -> None:
for obj, items in status.items():
if obj in self.printer_state:
self.printer_state[obj].update(items)
else:
self.printer_state[obj] = items
def paneldue_beep(self, frequency: int, duration: float) -> None: def paneldue_beep(self, frequency: int, duration: float) -> None:
duration = int(duration * 1000.) duration = int(duration * 1000.)
self.write_response( self.write_response(
@ -560,9 +547,9 @@ class PanelDue:
if self.is_shutdown: if self.is_shutdown:
return 'S' return 'S'
printer_state = self.printer_state p_state = self.printer_state
sd_state: str sd_state: str
sd_state = printer_state['print_stats'].get('state', "standby") sd_state = p_state.get("print_stats", {}).get("state", "standby")
if sd_state == "printing": if sd_state == "printing":
if self.last_printer_state == 'A': if self.last_printer_state == 'A':
# Resuming # Resuming
@ -570,8 +557,9 @@ class PanelDue:
# Printing # Printing
return 'P' return 'P'
elif sd_state == "paused": elif sd_state == "paused":
p_active = printer_state['idle_timeout'].get( p_active = (
'state', 'Idle') == "Printing" p_state.get("idle_timeout", {}).get("state", 'Idle') == "Printing"
)
if p_active and self.last_printer_state != 'A': if p_active and self.last_printer_state != 'A':
# Pausing # Pausing
return 'D' return 'D'
@ -617,25 +605,28 @@ class PanelDue:
response['axes'] = 3 response['axes'] = 3
p_state = self.printer_state p_state = self.printer_state
toolhead = p_state.get("toolhead", {})
gcode_move = p_state.get("gcode_move", {})
self.last_printer_state = self._get_printer_status() self.last_printer_state = self._get_printer_status()
response['status'] = self.last_printer_state response['status'] = self.last_printer_state
response['babystep'] = round(p_state['gcode_move'].get( response['babystep'] = round(
'homing_origin', [0., 0., 0., 0.])[2], 3) gcode_move.get('homing_origin', [0., 0., 0., 0.])[2], 3
)
# Current position # Current position
pos: List[float] pos: List[float]
homed_pos: str homed_pos: str
sfactor: float sfactor: float
pos = p_state['toolhead'].get('position', [0., 0., 0., 0.]) pos = p_state.get("motion_report", {}).get('live_position', [0., 0., 0., 0.])
response['pos'] = [round(p, 2) for p in pos[:3]] response['pos'] = [round(p, 2) for p in pos[:3]]
homed_pos = p_state['toolhead'].get('homed_axes', "") homed_pos = toolhead.get('homed_axes', "")
response['homed'] = [int(a in homed_pos) for a in "xyz"] response['homed'] = [int(a in homed_pos) for a in "xyz"]
sfactor = round(p_state['gcode_move'].get('speed_factor', 1.) * 100, 2) sfactor = round(gcode_move.get('speed_factor', 1.) * 100, 2)
response['sfactor'] = sfactor response['sfactor'] = sfactor
# Print Progress Tracking # Print Progress Tracking
sd_status = p_state['virtual_sdcard'] sd_status = p_state.get('virtual_sdcard', {})
print_stats = p_state['print_stats'] print_stats = p_state.get('print_stats', {})
fname: str = print_stats.get('filename', "") fname: str = print_stats.get('filename', "")
sd_print_state: Optional[str] = print_stats.get('state') sd_print_state: Optional[str] = print_stats.get('state')
if sd_print_state in ['printing', 'paused']: if sd_print_state in ['printing', 'paused']:
@ -663,8 +654,9 @@ class PanelDue:
obj_height: Optional[float] obj_height: Optional[float]
obj_height = self.file_metadata.get('object_height') obj_height = self.file_metadata.get('object_height')
if obj_height: if obj_height:
cur_height: float = p_state['gcode_move'].get( cur_height: float = gcode_move.get(
'gcode_position', [0., 0., 0., 0.])[2] 'gcode_position', [0., 0., 0., 0.]
)[2]
hpct = min(1., cur_height / obj_height) hpct = min(1., cur_height / obj_height)
times_left.append(int(est_time - est_time * hpct)) times_left.append(int(est_time - est_time * hpct))
else: else:
@ -678,13 +670,13 @@ class PanelDue:
self.current_file = "" self.current_file = ""
self.file_metadata = {} self.file_metadata = {}
fan_speed: Optional[float] = p_state['fan'].get('speed') fan_speed: Optional[float] = p_state.get('fan', {}).get('speed')
if fan_speed is not None: if fan_speed is not None:
response['fanPercent'] = [round(fan_speed * 100, 1)] response['fanPercent'] = [round(fan_speed * 100, 1)]
extruder_name: str = "" extruder_name: str = ""
if self.extruder_count > 0: if self.extruder_count > 0:
extruder_name = p_state['toolhead'].get('extruder', "") extruder_name = toolhead.get('extruder', "")
if extruder_name: if extruder_name:
tool = 0 tool = 0
if extruder_name != "extruder": if extruder_name != "extruder":
@ -692,12 +684,12 @@ class PanelDue:
response['tool'] = tool response['tool'] = tool
# Report Heater Status # Report Heater Status
efactor: float = round(p_state['gcode_move'].get( efactor: float = round(gcode_move.get('extrude_factor', 1.) * 100., 2)
'extrude_factor', 1.) * 100., 2)
for name in self.heaters: for name in self.heaters:
temp: float = round(p_state[name].get('temperature', 0.0), 1) htr_state = p_state.get(name, {})
target: float = round(p_state[name].get('target', 0.0), 1) temp: float = round(htr_state.get('temperature', 0.0), 1)
target: float = round(htr_state.get('target', 0.0), 1)
response.setdefault('heaters', []).append(temp) response.setdefault('heaters', []).append(temp)
response.setdefault('active', []).append(target) response.setdefault('active', []).append(target)
response.setdefault('standby', []).append(target) response.setdefault('standby', []).append(target)
@ -710,7 +702,7 @@ class PanelDue:
response.setdefault('hstat', []).append(2 if target else 0) response.setdefault('hstat', []).append(2 if target else 0)
# Display message (via M117) # Display message (via M117)
msg: str = p_state['display_status'].get('message', "") msg: str = p_state.get('display_status', {}).get('message', "")
if msg and msg != self.last_message: if msg and msg != self.last_message:
response['message'] = msg response['message'] = msg
# reset the message so it only shows once. The paneldue # reset the message so it only shows once. The paneldue