klippy_apis: allow subscription requests from transports
The default behavior of the subscribe API shares all subscription requests. API Transports require their own subscription. Add a method to facilitate this request. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
bfeb096f31
commit
eed759e111
|
@ -100,10 +100,11 @@ class KlippyAPI(APITransport):
|
||||||
self,
|
self,
|
||||||
method: str,
|
method: str,
|
||||||
params: Dict[str, Any],
|
params: Dict[str, Any],
|
||||||
default: Any = Sentinel.MISSING
|
default: Any = Sentinel.MISSING,
|
||||||
|
transport: Optional[APITransport] = None
|
||||||
) -> Any:
|
) -> Any:
|
||||||
try:
|
try:
|
||||||
req = WebRequest(method, params, transport=self)
|
req = WebRequest(method, params, transport=transport or self)
|
||||||
result = await self.klippy.request(req)
|
result = await self.klippy.request(req)
|
||||||
except self.server.error:
|
except self.server.error:
|
||||||
if default is Sentinel.MISSING:
|
if default is Sentinel.MISSING:
|
||||||
|
@ -227,6 +228,7 @@ class KlippyAPI(APITransport):
|
||||||
callback: Optional[SubCallback] = None,
|
callback: Optional[SubCallback] = None,
|
||||||
default: Union[Sentinel, _T] = Sentinel.MISSING
|
default: Union[Sentinel, _T] = Sentinel.MISSING
|
||||||
) -> Union[_T, Dict[str, Any]]:
|
) -> Union[_T, Dict[str, Any]]:
|
||||||
|
# The host transport shares subscriptions amongst all components
|
||||||
for obj, items in objects.items():
|
for obj, items in objects.items():
|
||||||
if obj in self.host_subscription:
|
if obj in self.host_subscription:
|
||||||
prev = self.host_subscription[obj]
|
prev = self.host_subscription[obj]
|
||||||
|
@ -237,9 +239,8 @@ class KlippyAPI(APITransport):
|
||||||
self.host_subscription[obj] = uitems
|
self.host_subscription[obj] = uitems
|
||||||
else:
|
else:
|
||||||
self.host_subscription[obj] = items
|
self.host_subscription[obj] = items
|
||||||
params = {'objects': dict(self.host_subscription)}
|
params = {"objects": dict(self.host_subscription)}
|
||||||
result = await self._send_klippy_request(
|
result = await self._send_klippy_request(SUBSCRIPTION_ENDPOINT, params, default)
|
||||||
SUBSCRIPTION_ENDPOINT, params, default)
|
|
||||||
if isinstance(result, dict) and "status" in result:
|
if isinstance(result, dict) and "status" in result:
|
||||||
if callback is not None:
|
if callback is not None:
|
||||||
self.subscription_callbacks.append(callback)
|
self.subscription_callbacks.append(callback)
|
||||||
|
@ -248,6 +249,22 @@ class KlippyAPI(APITransport):
|
||||||
return default
|
return default
|
||||||
raise self.server.error("Invalid response received from Klippy", 500)
|
raise self.server.error("Invalid response received from Klippy", 500)
|
||||||
|
|
||||||
|
async def subscribe_from_transport(
|
||||||
|
self,
|
||||||
|
objects: Mapping[str, Optional[List[str]]],
|
||||||
|
transport: APITransport,
|
||||||
|
default: Union[Sentinel, _T] = Sentinel.MISSING,
|
||||||
|
) -> Union[_T, Dict[str, Any]]:
|
||||||
|
params = {"objects": dict(objects)}
|
||||||
|
result = await self._send_klippy_request(
|
||||||
|
SUBSCRIPTION_ENDPOINT, params, default, transport
|
||||||
|
)
|
||||||
|
if isinstance(result, dict) and "status" in result:
|
||||||
|
return result["status"]
|
||||||
|
if default is not Sentinel.MISSING:
|
||||||
|
return default
|
||||||
|
raise self.server.error("Invalid response received from Klippy", 500)
|
||||||
|
|
||||||
async def subscribe_gcode_output(self) -> str:
|
async def subscribe_gcode_output(self) -> str:
|
||||||
template = {'response_template':
|
template = {'response_template':
|
||||||
{'method': "process_gcode_response"}}
|
{'method': "process_gcode_response"}}
|
||||||
|
|
|
@ -37,8 +37,8 @@ from typing import (
|
||||||
)
|
)
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..confighelper import ConfigHelper
|
from ..confighelper import ConfigHelper
|
||||||
from ..klippy_connection import KlippyConnection as Klippy
|
|
||||||
from ..common import JsonRPC, APIDefinition
|
from ..common import JsonRPC, APIDefinition
|
||||||
|
from .klippy_apis import KlippyAPI
|
||||||
FlexCallback = Callable[[bytes], Optional[Coroutine]]
|
FlexCallback = Callable[[bytes], Optional[Coroutine]]
|
||||||
RPCCallback = Callable[..., Coroutine]
|
RPCCallback = Callable[..., Coroutine]
|
||||||
|
|
||||||
|
@ -251,7 +251,6 @@ class MQTTClient(APITransport):
|
||||||
def __init__(self, config: ConfigHelper) -> None:
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
self.server = config.get_server()
|
self.server = config.get_server()
|
||||||
self.eventloop = self.server.get_event_loop()
|
self.eventloop = self.server.get_event_loop()
|
||||||
self.klippy: Klippy = self.server.lookup_component("klippy_connection")
|
|
||||||
self.address: str = config.get('address')
|
self.address: str = config.get('address')
|
||||||
self.port: int = config.getint('port', 1883)
|
self.port: int = config.getint('port', 1883)
|
||||||
user = config.gettemplate('username', None)
|
user = config.gettemplate('username', None)
|
||||||
|
@ -321,13 +320,13 @@ class MQTTClient(APITransport):
|
||||||
self.klipper_status_topic = f"{self.instance_name}/klipper/status"
|
self.klipper_status_topic = f"{self.instance_name}/klipper/status"
|
||||||
self.klipper_state_prefix = f"{self.instance_name}/klipper/state"
|
self.klipper_state_prefix = f"{self.instance_name}/klipper/state"
|
||||||
self.moonraker_status_topic = f"{self.instance_name}/moonraker/status"
|
self.moonraker_status_topic = f"{self.instance_name}/moonraker/status"
|
||||||
status_cfg: Dict[str, Any] = config.getdict("status_objects", {},
|
status_cfg: Dict[str, str] = config.getdict(
|
||||||
allow_empty_fields=True)
|
"status_objects", {}, allow_empty_fields=True
|
||||||
self.status_objs: Dict[str, Any] = {}
|
)
|
||||||
|
self.status_objs: Dict[str, Optional[List[str]]] = {}
|
||||||
for key, val in status_cfg.items():
|
for key, val in status_cfg.items():
|
||||||
if val is not None:
|
if val is not None:
|
||||||
self.status_objs[key] = [v.strip() for v in val.split(',')
|
self.status_objs[key] = [v.strip() for v in val.split(',') if v.strip()]
|
||||||
if v.strip()]
|
|
||||||
else:
|
else:
|
||||||
self.status_objs[key] = None
|
self.status_objs[key] = None
|
||||||
if status_cfg:
|
if status_cfg:
|
||||||
|
@ -368,13 +367,10 @@ class MQTTClient(APITransport):
|
||||||
|
|
||||||
async def _handle_klippy_started(self, state: KlippyState) -> None:
|
async def _handle_klippy_started(self, state: KlippyState) -> None:
|
||||||
if self.status_objs:
|
if self.status_objs:
|
||||||
args = {'objects': self.status_objs}
|
kapi: KlippyAPI = self.server.lookup_component("klippy_apis")
|
||||||
try:
|
await kapi.subscribe_from_transport(
|
||||||
await self.klippy.request(
|
self.status_objs, self, default=None,
|
||||||
WebRequest("objects/subscribe", args, transport=self)
|
|
||||||
)
|
)
|
||||||
except self.server.error:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_message(self,
|
def _on_message(self,
|
||||||
client: str,
|
client: str,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import logging.handlers
|
||||||
import tempfile
|
import tempfile
|
||||||
from queue import SimpleQueue
|
from queue import SimpleQueue
|
||||||
from ..loghelper import LocalQueueHandler
|
from ..loghelper import LocalQueueHandler
|
||||||
from ..common import APITransport, WebRequest, JobEvent, KlippyState
|
from ..common import APITransport, JobEvent, KlippyState
|
||||||
from ..utils import json_wrapper as jsonw
|
from ..utils import json_wrapper as jsonw
|
||||||
|
|
||||||
from typing import (
|
from typing import (
|
||||||
|
@ -580,16 +580,9 @@ class SimplyPrint(APITransport):
|
||||||
if not sub_objs:
|
if not sub_objs:
|
||||||
return
|
return
|
||||||
# Create our own subscription rather than use the host sub
|
# Create our own subscription rather than use the host sub
|
||||||
args = {'objects': sub_objs}
|
status: Dict[str, Any] = await self.klippy_apis.subscribe_from_transport(
|
||||||
klippy: KlippyConnection
|
sub_objs, self, default={}
|
||||||
klippy = self.server.lookup_component("klippy_connection")
|
|
||||||
try:
|
|
||||||
resp: Dict[str, Dict[str, Any]] = await klippy.request(
|
|
||||||
WebRequest("objects/subscribe", args, transport=self)
|
|
||||||
)
|
)
|
||||||
status: Dict[str, Any] = resp.get("status", {})
|
|
||||||
except self.server.error:
|
|
||||||
status = {}
|
|
||||||
if status:
|
if status:
|
||||||
logging.debug(f"SimplyPrint: Got Initial Status: {status}")
|
logging.debug(f"SimplyPrint: Got Initial Status: {status}")
|
||||||
self.printer_status = status
|
self.printer_status = status
|
||||||
|
|
Loading…
Reference in New Issue