diff --git a/moonraker/components/klippy_connection.py b/moonraker/components/klippy_connection.py index 31b1ef8..40030eb 100644 --- a/moonraker/components/klippy_connection.py +++ b/moonraker/components/klippy_connection.py @@ -60,6 +60,8 @@ LOG_ATTEMPT_INTERVAL = int(2. / INIT_TIME + .5) MAX_LOG_ATTEMPTS = 10 * LOG_ATTEMPT_INTERVAL UNIX_BUFFER_LIMIT = 20 * 1024 * 1024 SVC_INFO_KEY = "klippy_connection.service_info" +SRC_PATH_KEY = "klippy_connection.path" +PY_EXEC_KEY = "klippy_connection.executable" class KlippyConnection: def __init__(self, config: ConfigHelper) -> None: @@ -84,6 +86,8 @@ class KlippyConnection: self._missing_reqs: Set[str] = set() self._peer_cred: Dict[str, int] = {} self._service_info: Dict[str, Any] = {} + self._path = pathlib.Path("~/klipper").expanduser() + self._executable = pathlib.Path("~/klippy-env/bin/python").expanduser() self.init_attempts: int = 0 self._state: KlippyState = KlippyState.DISCONNECTED self._state.set_message("Klippy Disconnected") @@ -138,10 +142,25 @@ class KlippyConnection: unit_name = svc_info.get("unit_name", "klipper.service") return unit_name.split(".", 1)[0] + @property + def path(self) -> pathlib.Path: + return self._path + + @property + def executable(self) -> pathlib.Path: + return self._executable + + def load_saved_state(self) -> None: + db: Database = self.server.lookup_component("database") + sync_provider = db.get_provider_wrapper() + kc_info: Dict[str, Any] + kc_info = sync_provider.get_item("moonraker", "klippy_connection", {}) + self._path = pathlib.Path(kc_info.get("path", str(self._path))) + self._executable = pathlib.Path(kc_info.get("executable", str(self.executable))) + self._service_info = kc_info.get("service_info", {}) + async def component_init(self) -> None: - db: Database = self.server.lookup_component('database') machine: Machine = self.server.lookup_component("machine") - self._service_info = await db.get_item("moonraker", SVC_INFO_KEY, {}) if self._service_info: machine.log_service_info(self._service_info) @@ -266,7 +285,7 @@ class KlippyConnection: fut.set_result(self.is_connected()) return fut self.connection_task = self.event_loop.create_task(self._do_connect()) - return self.connection_task + return self.connection_task # type: ignore async def _do_connect(self) -> bool: async with self.connection_mutex: @@ -296,7 +315,7 @@ class KlippyConnection: self.writer = writer if self._get_peer_credentials(writer): await self._get_service_info(self._peer_cred["process_id"]) - self.event_loop.create_task(self._read_stream(reader)) + self.event_loop.create_task(self._read_stream(reader)) return await self._init_klippy_connection() async def open_klippy_connection( @@ -330,6 +349,19 @@ class KlippyConnection: self._service_info = svc_info machine.log_service_info(svc_info) + def _save_path_info(self) -> None: + kpath = pathlib.Path(self._klippy_info["klipper_path"]) + kexec = pathlib.Path(self._klippy_info["python_path"]) + db: Database = self.server.lookup_component("database") + if kpath != self.path: + self._path = kpath + db.insert_item("moonraker", SRC_PATH_KEY, str(kpath)) + logging.info(f"Updated Stored Klipper Source Path: {kpath}") + if kexec != self.executable: + self._executable = kexec + db.insert_item("moonraker", PY_EXEC_KEY, str(kexec)) + logging.info(f"Updated Stored Klipper Python Path: {kexec}") + async def _init_klippy_connection(self) -> bool: self._klippy_identified = False self._klippy_started = False @@ -417,6 +449,7 @@ class KlippyConnection: return if send_id: self._klippy_identified = True + self._save_path_info() await self.server.send_event("server:klippy_identified") # Request initial endpoints to register info, emergency stop APIs await self._request_endpoints() diff --git a/moonraker/server.py b/moonraker/server.py index 86c2cba..456de39 100755 --- a/moonraker/server.py +++ b/moonraker/server.py @@ -260,6 +260,10 @@ class Server: cfg_sections = set([s.split()[0] for s in config.sections()]) cfg_sections.remove('server') + # load database to initialize saved state + self.load_component(config, "database") + self.klippy_connection.load_saved_state() + # load core components for component in CORE_COMPONENTS: self.load_component(config, component)