notify: add server endpoints for notifier to list and test them

Signed-off-by: Pieter Willekens <me@pataar.nl>
This commit is contained in:
pataar 2022-10-17 09:57:04 +02:00 committed by Eric Callahan
parent f1c4d6b143
commit b981dc109d
2 changed files with 153 additions and 0 deletions

View File

@ -3375,6 +3375,65 @@ Returns: Test results in the following format
}
```
### Notifier APIs
The following APIs are available to view and tests notifiers.
#### List Notifiers
HTTP request:
```http
GET /server/notifiers/list
```
JSON-RPC request:
```json
{
"jsonrpc": "2.0",
"method": "server.notifiers.list",
"id": 4654
}
```
Returns:
A list of configured notifiers:
```json
{
"notifiers": [
{
"name": "print_start",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"started"
],
"body": "Your printer started printing '{event_args[1].filename}'",
"title": null,
"attach": null
},
{
"name": "print_complete",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"complete"
],
"body": "Your printer completed printing '{event_args[1].filename}",
"title": null,
"attach": "http://192.168.1.100/webcam/?action=snapshot"
},
{
"name": "print_error",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"error"
],
"body": "{event_args[1].message}",
"title": null,
"attach": "http://192.168.1.100/webcam/?action=snapshot"
}
]
}
```
### Update Manager APIs
The following endpoints are available when the `[update_manager]` component has
been configured:
@ -5064,6 +5123,46 @@ JSON-RPC request:
}
```
#### Test a notifier (debug)
You can trigger a notifier manually using this endpoint.
HTTP request:
```http
POST /server/notifiers/test?name=notifier_name
```
JSON-RPC request:
```json
{
"jsonrpc": "2.0",
"method": "server.notifiers.test",
"params": {
"name": "notifier_name"
},
"id": 4654
}
```
Parameters:
- `name`: The name of the notifier to test.
Returns: Test results in the following format
```json
{
"status": "success",
"stats": {
"print_duration": 0.0,
"total_duration": 0.0,
"filament_used": 0.0,
"filename": "notifier_test.gcode",
"state": "standby",
"message": ""
}
}
```
### Websocket notifications
Printer generated events are sent over the websocket as JSON-RPC 2.0
notifications. These notifications are sent to all connected clients

View File

@ -22,6 +22,8 @@ from typing import (
if TYPE_CHECKING:
from confighelper import ConfigHelper
from websockets import WebRequest
from .http_client import HttpClient
from . import klippy_apis
APIComp = klippy_apis.KlippyAPI
@ -54,6 +56,8 @@ class Notifier:
continue
self.notifiers[notifier.get_name()] = notifier
self.register_endpoints(config)
def register_remote_actions(self):
self.server.register_remote_method("notify", self.notify_action)
@ -96,6 +100,45 @@ class Notifier:
"job_state:resumed",
config)
def register_endpoints(self, config: ConfigHelper):
self.server.register_endpoint(
"/server/notifiers/list", ["GET"], self._handle_notifier_list
)
self.server.register_debug_endpoint(
"/debug/notifiers/test", ["POST"], self._handle_notifier_test
)
async def _handle_notifier_list(
self, web_request: WebRequest
) -> Dict[str, Any]:
return {"notifiers": self._list_notifiers()}
def _list_notifiers(self) -> List[Dict[str, Any]]:
return [notifier.as_dict() for notifier in self.notifiers.values()]
async def _handle_notifier_test(
self, web_request: WebRequest
) -> Dict[str, Any]:
name = web_request.get_str("name")
if name not in self.notifiers:
raise self.server.error(f"Notifier '{name}' not found", 404)
client: HttpClient = self.server.lookup_component("http_client")
notifier = self.notifiers[name]
kapis: APIComp = self.server.lookup_component('klippy_apis')
result: Dict[str, Any] = await kapis.query_objects(
{'print_stats': None}, default={})
print_stats = result.get('print_stats', {})
print_stats["filename"] = "notifier_test.gcode" # Mock the filename
await notifier.notify(notifier.events[0], [print_stats, print_stats])
return {
"status": "success",
"stats": print_stats
}
class NotifierEvent:
def __init__(self, identifier: str, event_name: str, config: ConfigHelper):
@ -156,9 +199,20 @@ class NotifierInstance:
self.apprise.add(self.url)
def as_dict(self):
return {
"name": self.name,
"url": self.config.get("url"),
"title": self.config.get("title", None),
"body": self.config.get("body", None),
"events": self.events,
"attach": self.attach
}
async def notify(
self, event_name: str, event_args: List, message: str = ""
) -> None:
context = {
"event_name": event_name,
"event_args": event_args,