Skip to content

Commit

Permalink
klippy_connection: track connection state with an enum
Browse files Browse the repository at this point in the history
Signed-off-by:  Eric Callahan <[email protected]>
  • Loading branch information
Arksine committed Nov 20, 2023
1 parent f81e340 commit 05f3029
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 63 deletions.
12 changes: 6 additions & 6 deletions moonraker/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
APIDefinition,
APITransport,
TransportType,
RequestType
RequestType,
KlippyState
)
from .utils import json_wrapper as jsonw
from .websockets import (
Expand Down Expand Up @@ -1133,11 +1134,10 @@ async def get(self) -> None:
"The [authorization] section in moonraker.conf must be "
"configured to enable CORS."
)
kstate = self.server.get_klippy_state()
if kstate != "disconnected":
kinfo = self.server.get_klippy_info()
kmsg = kinfo.get("state_message", kstate)
summary.append(f"Klipper reports {kmsg.lower()}")
kconn: Klippy = self.server.lookup_component("klippy_connection")
kstate = kconn.state
if kstate != KlippyState.DISCONNECTED:
summary.append(f"Klipper reports {kstate.message.lower()}")
else:
summary.append(
"Moonraker is not currently connected to Klipper. Make sure "
Expand Down
31 changes: 31 additions & 0 deletions moonraker/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,37 @@ def aborted(self) -> bool:
def is_printing(self) -> bool:
return self.value in [2, 4]

class KlippyState(ExtendedEnum):
DISCONNECTED = 1
STARTUP = 2
READY = 3
ERROR = 4
SHUTDOWN = 5

@classmethod
def from_string(cls, enum_name: str, msg: str = ""):
str_name = enum_name.upper()
for name, member in cls.__members__.items():
if name == str_name:
instance = cls(member.value)
if msg:
instance.set_message(msg)
return instance
raise ValueError(f"No enum member named {enum_name}")


def set_message(self, msg: str) -> None:
self._state_message: str = msg

@property
def message(self) -> str:
if hasattr(self, "_state_message"):
return self._state_message
return ""

def startup_complete(self) -> bool:
return self.value > 2

class Subscribable:
def send_status(
self, status: Dict[str, Any], eventtime: float
Expand Down
6 changes: 3 additions & 3 deletions moonraker/components/job_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Dict,
List,
)
from ..common import JobEvent
from ..common import JobEvent, KlippyState
if TYPE_CHECKING:
from ..confighelper import ConfigHelper
from .klippy_apis import KlippyAPI
Expand All @@ -27,8 +27,8 @@ def __init__(self, config: ConfigHelper) -> None:
self.server.register_event_handler(
"server:klippy_started", self._handle_started)

async def _handle_started(self, state: str) -> None:
if state != "ready":
async def _handle_started(self, state: KlippyState) -> None:
if state != KlippyState.READY:
return
kapis: KlippyAPI = self.server.lookup_component('klippy_apis')
sub: Dict[str, Optional[List[str]]] = {"print_stats": None}
Expand Down
5 changes: 3 additions & 2 deletions moonraker/components/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
Subscribable,
WebRequest,
APITransport,
JsonRPC
JsonRPC,
KlippyState
)
from ..utils import json_wrapper as jsonw

Expand Down Expand Up @@ -372,7 +373,7 @@ async def component_init(self) -> None:
self._do_reconnect(first=True)
)

async def _handle_klippy_started(self, state: str) -> None:
async def _handle_klippy_started(self, state: KlippyState) -> None:
if self.status_objs:
args = {'objects': self.status_objs}
try:
Expand Down
16 changes: 9 additions & 7 deletions moonraker/components/octoprint_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from __future__ import annotations
import logging
from ..common import RequestType, TransportType
from ..common import RequestType, TransportType, KlippyState

# Annotation imports
from typing import (
Expand All @@ -16,6 +16,7 @@
List,
)
if TYPE_CHECKING:
from ..klippy_connection import KlippyConnection
from ..confighelper import ConfigHelper
from ..common import WebRequest
from .klippy_apis import KlippyAPI as APIComp
Expand Down Expand Up @@ -153,10 +154,11 @@ def _handle_status_update(self, status: Dict[str, Any]) -> None:
data.update(status[heater_name])

def printer_state(self) -> str:
klippy_state = self.server.get_klippy_state()
if klippy_state in ["disconnected", "startup"]:
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
klippy_state = kconn.state
if not klippy_state.startup_complete():
return 'Offline'
elif klippy_state != 'ready':
elif klippy_state != KlippyState.READY:
return 'Error'
return {
'standby': 'Operational',
Expand Down Expand Up @@ -202,11 +204,11 @@ async def _get_server(self,
"""
Server status
"""
klippy_state = self.server.get_klippy_state()
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
klippy_state = kconn.state
return {
'server': OCTO_VERSION,
'safemode': (
None if klippy_state == 'ready' else 'settings')
'safemode': None if klippy_state == KlippyState.READY else 'settings'
}

async def _post_login_user(self,
Expand Down
14 changes: 8 additions & 6 deletions moonraker/components/power.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import time
from urllib.parse import quote, urlencode
from ..utils import json_wrapper as jsonw
from ..common import RequestType
from ..common import RequestType, KlippyState

# Annotation imports
from typing import (
Expand Down Expand Up @@ -262,11 +262,11 @@ def __init__(self, config: ConfigHelper) -> None:
'initial_state', None
)

def _schedule_firmware_restart(self, state: str = "") -> None:
def _schedule_firmware_restart(self, state: KlippyState) -> None:
if not self.need_scheduled_restart:
return
self.need_scheduled_restart = False
if state == "ready":
if state == KlippyState.READY:
logging.info(
f"Power Device {self.name}: Klipper reports 'ready', "
"aborting FIRMWARE_RESTART"
Expand Down Expand Up @@ -304,8 +304,9 @@ async def process_power_changed(self) -> None:
await self.process_bound_services()
if self.state == "on" and self.klipper_restart:
self.need_scheduled_restart = True
klippy_state = self.server.get_klippy_state()
if klippy_state in ["disconnected", "startup"]:
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
klippy_state = kconn.state
if not klippy_state.startup_complete():
# If klippy is currently disconnected or hasn't proceeded past
# the startup state, schedule the restart in the
# "klippy_started" event callback.
Expand Down Expand Up @@ -338,7 +339,8 @@ def process_klippy_shutdown(self) -> None:
self.off_when_shutdown_delay, self._power_off_on_shutdown)

def _power_off_on_shutdown(self) -> None:
if self.server.get_klippy_state() != "shutdown":
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
if kconn.state != KlippyState.SHUTDOWN:
return
logging.info(
f"Powering off device '{self.name}' due to klippy shutdown")
Expand Down
20 changes: 11 additions & 9 deletions moonraker/components/simplyprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import tempfile
from queue import SimpleQueue
from ..loghelper import LocalQueueHandler
from ..common import Subscribable, WebRequest, JobEvent
from ..common import Subscribable, WebRequest, JobEvent, KlippyState
from ..utils import json_wrapper as jsonw

from typing import (
Expand Down Expand Up @@ -640,20 +640,20 @@ def _on_websocket_removed(self, ws: BaseRemoteConnection) -> None:
self.cache.firmware_info.update(ui_data)
self.send_sp("machine_data", ui_data)

def _on_klippy_startup(self, state: str) -> None:
if state != "ready":
def _on_klippy_startup(self, state: KlippyState) -> None:
if state != KlippyState.READY:
self._update_state("error")
kconn: KlippyConnection
kconn = self.server.lookup_component("klippy_connection")
self.send_sp("printer_error", {"error": kconn.state_message})
self.send_sp("printer_error", {"error": kconn.state.message})
self.send_sp("connection", {"new": "connected"})
self._send_firmware_data()

def _on_klippy_shutdown(self) -> None:
self._update_state("error")
kconn: KlippyConnection
kconn = self.server.lookup_component("klippy_connection")
self.send_sp("printer_error", {"error": kconn.state_message})
self.send_sp("printer_error", {"error": kconn.state.message})

def _on_klippy_disconnected(self) -> None:
self._update_state("offline")
Expand Down Expand Up @@ -927,10 +927,11 @@ def _update_temps(self, eventtime: float) -> None:
self.send_sp("temps", temp_data)

def _update_state_from_klippy(self) -> None:
kstate = self.server.get_klippy_state()
if kstate == "ready":
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
klippy_state = kconn.state
if klippy_state == KlippyState.READY:
sp_state = "operational"
elif kstate in ["error", "shutdown"]:
elif klippy_state in [KlippyState.ERROR, KlippyState.SHUTDOWN]:
sp_state = "error"
else:
sp_state = "offline"
Expand Down Expand Up @@ -1613,7 +1614,8 @@ async def start_print(self) -> None:
self.simplyprint.send_sp("file_progress", data)

async def _check_can_print(self) -> bool:
if self.server.get_klippy_state() != "ready":
kconn: KlippyConnection = self.server.lookup_component("klippy_connection")
if kconn.state != KlippyState.READY:
return False
kapi: KlippyAPI = self.server.lookup_component("klippy_apis")
try:
Expand Down
Loading

0 comments on commit 05f3029

Please sign in to comment.