From 108b66efe941c624f2d713c4c37de49fdae54282 Mon Sep 17 00:00:00 2001 From: Arksine Date: Wed, 28 Oct 2020 08:37:12 -0400 Subject: [PATCH] webhooks: Add "register_remote_method" endpoint This allows clients to register methods that can be called from Klipper. Signed-off-by: Eric Callahan --- klippy/webhooks.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/klippy/webhooks.py b/klippy/webhooks.py index 1e8022e4..09efbaec 100644 --- a/klippy/webhooks.py +++ b/klippy/webhooks.py @@ -275,8 +275,11 @@ class WebHooks: def __init__(self, printer): self.printer = printer self._endpoints = {"list_endpoints": self._handle_list_endpoints} + self._remote_methods = {} self.register_endpoint("info", self._handle_info_request) self.register_endpoint("emergency_stop", self._handle_estop_request) + self.register_endpoint("register_remote_method", + self._handle_rpc_registration) self.sconn = ServerSocket(self, printer) def register_endpoint(self, path, callback): @@ -305,6 +308,14 @@ class WebHooks: def _handle_estop_request(self, web_request): self.printer.invoke_shutdown("Shutdown due to webhooks request") + def _handle_rpc_registration(self, web_request): + template = web_request.get_dict('response_template') + method = web_request.get_str('remote_method') + new_conn = web_request.get_client_connection() + logging.info("webhooks: registering remote method '%s' " + "for connection id: %d" % (method, id(new_conn))) + self._remote_methods.setdefault(method, {})[new_conn] = template + def get_connection(self): return self.sconn @@ -320,6 +331,24 @@ class WebHooks: state_message, state = self.printer.get_state_message() return {'state': state, 'state_message': state_message} + def call_remote_method(self, method, **kwargs): + if method not in self._remote_methods: + raise self.printer.command_error( + "Remote method '%s' not registered" % (method)) + conn_map = self._remote_methods[method] + valid_conns = {} + for conn, template in conn_map.items(): + if not conn.is_closed(): + valid_conns[conn] = template + out = {'params': kwargs} + out.update(template) + conn.send(out) + if not valid_conns: + del self._remote_methods[method] + raise self.printer.command_error( + "No active connections for method '%s'" % (method)) + self._remote_methods[method] = valid_conns + class GCodeHelper: def __init__(self, printer): self.printer = printer