pycentauri 0.5.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pycentauri-0.5.0 → pycentauri-0.5.1}/CHANGELOG.md +21 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/PKG-INFO +25 -3
- {pycentauri-0.5.0 → pycentauri-0.5.1}/README.md +24 -2
- {pycentauri-0.5.0 → pycentauri-0.5.1}/pyproject.toml +1 -1
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/__init__.py +1 -1
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/cli.py +113 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/mcp/server.py +47 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/.gitignore +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/LICENSE +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/camera.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/client.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/discovery.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/mcp/__init__.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/mcp/__main__.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/models.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/py.typed +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/rtsp.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/sdcp.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/server.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/web/__init__.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/web/app.js +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/web/index.html +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/src/pycentauri/web/styles.css +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/__init__.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/integration/__init__.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/test_client.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/test_discovery.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/test_rtsp.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/test_sdcp.py +0 -0
- {pycentauri-0.5.0 → pycentauri-0.5.1}/tests/test_server.py +0 -0
|
@@ -6,6 +6,27 @@ Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.5.1] - 2026-06-17
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **CLI parity with the new live-adjust API.** Three new top-level
|
|
13
|
+
commands matching the library and HTTP surfaces shipped in 0.5.0:
|
|
14
|
+
- `centauri speed <silent|balanced|sport|ludicrous|50|100|130|160>`
|
|
15
|
+
- `centauri fan [--model N] [--aux N] [--chamber N]`
|
|
16
|
+
- `centauri temp [--nozzle N] [--bed N] [--chamber N]`
|
|
17
|
+
All require `--enable-control` and accept any subset of fan/heater
|
|
18
|
+
flags (omitted axes are left untouched).
|
|
19
|
+
- **MCP tool parity:** three new tools (only registered with
|
|
20
|
+
`--enable-control`) — `set_print_speed`, `set_fan_speed`,
|
|
21
|
+
`set_temperatures`. Same shapes as the HTTP endpoints; not marked
|
|
22
|
+
"DESTRUCTIVE" because live runtime adjustment is their entire
|
|
23
|
+
purpose.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- 0.5.0 shipped the live-adjust API to the library, HTTP server, and
|
|
27
|
+
web UI but missed the CLI and MCP server. This release closes that
|
|
28
|
+
parity gap — every surface now exposes the same control set.
|
|
29
|
+
|
|
9
30
|
## [0.5.0] - 2026-06-17
|
|
10
31
|
|
|
11
32
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycentauri
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Local-network toolkit for Elegoo Centauri Carbon 3D printers: async Python client, CLI, MCP server, REST/SSE HTTP server, web UI, and RTSP bridge
|
|
5
5
|
Project-URL: Homepage, https://github.com/bjan/pycentauri
|
|
6
6
|
Project-URL: Repository, https://github.com/bjan/pycentauri
|
|
@@ -109,8 +109,17 @@ centauri print start cube.gcode --host 192.168.1.209 --enable-control
|
|
|
109
109
|
centauri print pause --host 192.168.1.209 --enable-control
|
|
110
110
|
centauri print resume --host 192.168.1.209 --enable-control
|
|
111
111
|
centauri print stop --host 192.168.1.209 --enable-control
|
|
112
|
+
|
|
113
|
+
# Live adjust — speed mode, fans, heaters (only effective mid-print for speed)
|
|
114
|
+
centauri speed sport --host 192.168.1.209 --enable-control
|
|
115
|
+
centauri fan --model 100 --aux 60 --chamber 30 --host 192.168.1.209 --enable-control
|
|
116
|
+
centauri temp --nozzle 215 --bed 60 --host 192.168.1.209 --enable-control
|
|
112
117
|
```
|
|
113
118
|
|
|
119
|
+
The four speed modes (`silent`, `balanced`, `sport`, `ludicrous`) map to
|
|
120
|
+
the firmware's only-accepted `PrintSpeedPct` values (50, 100, 130, 160) —
|
|
121
|
+
arbitrary intermediate percentages are silently dropped by the firmware.
|
|
122
|
+
|
|
114
123
|
The host can also come from the `PYCENTAURI_HOST` environment variable.
|
|
115
124
|
If neither is set, every command auto-discovers via a 2.5 s UDP broadcast
|
|
116
125
|
and bails out if it finds zero or more than one printer.
|
|
@@ -136,8 +145,11 @@ async def main():
|
|
|
136
145
|
asyncio.run(main())
|
|
137
146
|
```
|
|
138
147
|
|
|
139
|
-
Control actions (`start_print`, `pause`, `resume`, `stop
|
|
140
|
-
`
|
|
148
|
+
Control actions (`start_print`, `pause`, `resume`, `stop`,
|
|
149
|
+
`set_print_speed`, `set_fan_speed`, `set_temperatures`) require
|
|
150
|
+
`Printer.connect(..., enable_control=True)`. The mode-to-value map for
|
|
151
|
+
print speed is also exposed as `Printer.PRINT_SPEED_MODES` for callers
|
|
152
|
+
that want to render their own picker.
|
|
141
153
|
|
|
142
154
|
## Quick start — HTTP server
|
|
143
155
|
|
|
@@ -166,6 +178,13 @@ centauri server --host 192.168.1.209 --bind 0.0.0.0 --port 8787 \
|
|
|
166
178
|
| `GET` | `/docs` / `/redoc` | Auto-generated OpenAPI docs |
|
|
167
179
|
| `POST` | `/print/start` | Body: `{"filename": "cube.gcode"}`. Requires `--enable-control`. |
|
|
168
180
|
| `POST` | `/print/{pause,resume,stop}` | Requires `--enable-control`. |
|
|
181
|
+
| `POST` | `/print/speed` | Body: `{"mode": "silent\|balanced\|sport\|ludicrous"}` (or `50\|100\|130\|160`). |
|
|
182
|
+
| `POST` | `/print/fan` | Body: `{"model": 50, "auxiliary": 30, "chamber": 0}` (any subset; 0..100). |
|
|
183
|
+
| `POST` | `/print/temperature` | Body: `{"nozzle": 215, "bed": 60, "chamber": 0}` (any subset; °C). |
|
|
184
|
+
|
|
185
|
+
The web UI's **ADJUST** panel exposes all three of the above as a
|
|
186
|
+
4-button speed-mode selector and per-fan/heater rows with auto-hydration
|
|
187
|
+
from live status.
|
|
169
188
|
|
|
170
189
|
The server holds a single long-lived WebSocket to the printer and reuses
|
|
171
190
|
it for every request — no per-request reconnect, and it won't bump into
|
|
@@ -226,6 +245,9 @@ the host is pinned at spawn time. Tools exposed:
|
|
|
226
245
|
| `pause_print` | only with `--enable-control` | Pauses the current print |
|
|
227
246
|
| `resume_print` | only with `--enable-control` | Resumes a paused print |
|
|
228
247
|
| `stop_print` | only with `--enable-control` | Stops the current print |
|
|
248
|
+
| `set_print_speed` | only with `--enable-control` | Sets speed mode (`silent`/`balanced`/`sport`/`ludicrous`) — only takes effect mid-print |
|
|
249
|
+
| `set_fan_speed` | only with `--enable-control` | Sets any subset of model/aux/chamber fan speeds (0..100%) |
|
|
250
|
+
| `set_temperatures` | only with `--enable-control` | Sets any subset of nozzle/bed/chamber heater targets (°C, 0 = off) |
|
|
229
251
|
|
|
230
252
|
Control tools aren't just gated — they're not *registered* without the
|
|
231
253
|
flag, so an LLM that wasn't given the `--enable-control` launch can't see
|
|
@@ -61,8 +61,17 @@ centauri print start cube.gcode --host 192.168.1.209 --enable-control
|
|
|
61
61
|
centauri print pause --host 192.168.1.209 --enable-control
|
|
62
62
|
centauri print resume --host 192.168.1.209 --enable-control
|
|
63
63
|
centauri print stop --host 192.168.1.209 --enable-control
|
|
64
|
+
|
|
65
|
+
# Live adjust — speed mode, fans, heaters (only effective mid-print for speed)
|
|
66
|
+
centauri speed sport --host 192.168.1.209 --enable-control
|
|
67
|
+
centauri fan --model 100 --aux 60 --chamber 30 --host 192.168.1.209 --enable-control
|
|
68
|
+
centauri temp --nozzle 215 --bed 60 --host 192.168.1.209 --enable-control
|
|
64
69
|
```
|
|
65
70
|
|
|
71
|
+
The four speed modes (`silent`, `balanced`, `sport`, `ludicrous`) map to
|
|
72
|
+
the firmware's only-accepted `PrintSpeedPct` values (50, 100, 130, 160) —
|
|
73
|
+
arbitrary intermediate percentages are silently dropped by the firmware.
|
|
74
|
+
|
|
66
75
|
The host can also come from the `PYCENTAURI_HOST` environment variable.
|
|
67
76
|
If neither is set, every command auto-discovers via a 2.5 s UDP broadcast
|
|
68
77
|
and bails out if it finds zero or more than one printer.
|
|
@@ -88,8 +97,11 @@ async def main():
|
|
|
88
97
|
asyncio.run(main())
|
|
89
98
|
```
|
|
90
99
|
|
|
91
|
-
Control actions (`start_print`, `pause`, `resume`, `stop
|
|
92
|
-
`
|
|
100
|
+
Control actions (`start_print`, `pause`, `resume`, `stop`,
|
|
101
|
+
`set_print_speed`, `set_fan_speed`, `set_temperatures`) require
|
|
102
|
+
`Printer.connect(..., enable_control=True)`. The mode-to-value map for
|
|
103
|
+
print speed is also exposed as `Printer.PRINT_SPEED_MODES` for callers
|
|
104
|
+
that want to render their own picker.
|
|
93
105
|
|
|
94
106
|
## Quick start — HTTP server
|
|
95
107
|
|
|
@@ -118,6 +130,13 @@ centauri server --host 192.168.1.209 --bind 0.0.0.0 --port 8787 \
|
|
|
118
130
|
| `GET` | `/docs` / `/redoc` | Auto-generated OpenAPI docs |
|
|
119
131
|
| `POST` | `/print/start` | Body: `{"filename": "cube.gcode"}`. Requires `--enable-control`. |
|
|
120
132
|
| `POST` | `/print/{pause,resume,stop}` | Requires `--enable-control`. |
|
|
133
|
+
| `POST` | `/print/speed` | Body: `{"mode": "silent\|balanced\|sport\|ludicrous"}` (or `50\|100\|130\|160`). |
|
|
134
|
+
| `POST` | `/print/fan` | Body: `{"model": 50, "auxiliary": 30, "chamber": 0}` (any subset; 0..100). |
|
|
135
|
+
| `POST` | `/print/temperature` | Body: `{"nozzle": 215, "bed": 60, "chamber": 0}` (any subset; °C). |
|
|
136
|
+
|
|
137
|
+
The web UI's **ADJUST** panel exposes all three of the above as a
|
|
138
|
+
4-button speed-mode selector and per-fan/heater rows with auto-hydration
|
|
139
|
+
from live status.
|
|
121
140
|
|
|
122
141
|
The server holds a single long-lived WebSocket to the printer and reuses
|
|
123
142
|
it for every request — no per-request reconnect, and it won't bump into
|
|
@@ -178,6 +197,9 @@ the host is pinned at spawn time. Tools exposed:
|
|
|
178
197
|
| `pause_print` | only with `--enable-control` | Pauses the current print |
|
|
179
198
|
| `resume_print` | only with `--enable-control` | Resumes a paused print |
|
|
180
199
|
| `stop_print` | only with `--enable-control` | Stops the current print |
|
|
200
|
+
| `set_print_speed` | only with `--enable-control` | Sets speed mode (`silent`/`balanced`/`sport`/`ludicrous`) — only takes effect mid-print |
|
|
201
|
+
| `set_fan_speed` | only with `--enable-control` | Sets any subset of model/aux/chamber fan speeds (0..100%) |
|
|
202
|
+
| `set_temperatures` | only with `--enable-control` | Sets any subset of nozzle/bed/chamber heater targets (°C, 0 = off) |
|
|
181
203
|
|
|
182
204
|
Control tools aren't just gated — they're not *registered* without the
|
|
183
205
|
flag, so an LLM that wasn't given the `--enable-control` launch can't see
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pycentauri"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.1"
|
|
8
8
|
description = "Local-network toolkit for Elegoo Centauri Carbon 3D printers: async Python client, CLI, MCP server, REST/SSE HTTP server, web UI, and RTSP bridge"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -323,6 +323,119 @@ def cmd_print_stop(host: HostOpt = None, enable_control: ControlOpt = False) ->
|
|
|
323
323
|
_run(run())
|
|
324
324
|
|
|
325
325
|
|
|
326
|
+
@app.command("speed")
|
|
327
|
+
def cmd_speed(
|
|
328
|
+
mode: Annotated[
|
|
329
|
+
str,
|
|
330
|
+
typer.Argument(
|
|
331
|
+
help="Speed mode: silent | balanced | sport | ludicrous "
|
|
332
|
+
"(or the integer 50 | 100 | 130 | 160).",
|
|
333
|
+
),
|
|
334
|
+
],
|
|
335
|
+
host: HostOpt = None,
|
|
336
|
+
enable_control: ControlOpt = False,
|
|
337
|
+
) -> None:
|
|
338
|
+
"""Set the print-speed mode. Only effective while a print is running."""
|
|
339
|
+
if not enable_control:
|
|
340
|
+
_echo_err("Refusing to send a write action without --enable-control.")
|
|
341
|
+
raise typer.Exit(code=2)
|
|
342
|
+
|
|
343
|
+
parsed: str | int = int(mode) if mode.lstrip("-").isdigit() else mode
|
|
344
|
+
|
|
345
|
+
async def run() -> None:
|
|
346
|
+
h, mid = await _resolve_target(host)
|
|
347
|
+
async with await Printer.connect(h, enable_control=True, mainboard_id=mid) as printer:
|
|
348
|
+
try:
|
|
349
|
+
await printer.set_print_speed(parsed)
|
|
350
|
+
except ValueError as err:
|
|
351
|
+
_echo_err(str(err))
|
|
352
|
+
raise typer.Exit(code=2) from err
|
|
353
|
+
typer.echo(f"speed mode set: {mode}")
|
|
354
|
+
|
|
355
|
+
_run(run())
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
@app.command("fan")
|
|
359
|
+
def cmd_fan(
|
|
360
|
+
model: Annotated[
|
|
361
|
+
int | None,
|
|
362
|
+
typer.Option("--model", help="Model (part-cooling) fan 0..100%."),
|
|
363
|
+
] = None,
|
|
364
|
+
auxiliary: Annotated[
|
|
365
|
+
int | None,
|
|
366
|
+
typer.Option("--aux", "--auxiliary", help="Auxiliary fan 0..100%."),
|
|
367
|
+
] = None,
|
|
368
|
+
chamber: Annotated[
|
|
369
|
+
int | None,
|
|
370
|
+
typer.Option("--chamber", help="Chamber/box fan 0..100%."),
|
|
371
|
+
] = None,
|
|
372
|
+
host: HostOpt = None,
|
|
373
|
+
enable_control: ControlOpt = False,
|
|
374
|
+
) -> None:
|
|
375
|
+
"""Set fan speeds. Pass any subset; omitted fans are left untouched."""
|
|
376
|
+
if not enable_control:
|
|
377
|
+
_echo_err("Refusing to send a write action without --enable-control.")
|
|
378
|
+
raise typer.Exit(code=2)
|
|
379
|
+
if model is None and auxiliary is None and chamber is None:
|
|
380
|
+
_echo_err("Specify at least one of --model, --aux, --chamber.")
|
|
381
|
+
raise typer.Exit(code=2)
|
|
382
|
+
|
|
383
|
+
async def run() -> None:
|
|
384
|
+
h, mid = await _resolve_target(host)
|
|
385
|
+
async with await Printer.connect(h, enable_control=True, mainboard_id=mid) as printer:
|
|
386
|
+
try:
|
|
387
|
+
await printer.set_fan_speed(model=model, auxiliary=auxiliary, chamber=chamber)
|
|
388
|
+
except ValueError as err:
|
|
389
|
+
_echo_err(str(err))
|
|
390
|
+
raise typer.Exit(code=2) from err
|
|
391
|
+
parts = [
|
|
392
|
+
f"{k}={v}%"
|
|
393
|
+
for k, v in (("model", model), ("aux", auxiliary), ("chamber", chamber))
|
|
394
|
+
if v is not None
|
|
395
|
+
]
|
|
396
|
+
typer.echo("fans set: " + ", ".join(parts))
|
|
397
|
+
|
|
398
|
+
_run(run())
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
@app.command("temp")
|
|
402
|
+
def cmd_temp(
|
|
403
|
+
nozzle: Annotated[
|
|
404
|
+
float | None, typer.Option("--nozzle", help="Nozzle target °C (0 = off).")
|
|
405
|
+
] = None,
|
|
406
|
+
bed: Annotated[float | None, typer.Option("--bed", help="Bed target °C (0 = off).")] = None,
|
|
407
|
+
chamber: Annotated[
|
|
408
|
+
float | None, typer.Option("--chamber", help="Chamber target °C (0 = off).")
|
|
409
|
+
] = None,
|
|
410
|
+
host: HostOpt = None,
|
|
411
|
+
enable_control: ControlOpt = False,
|
|
412
|
+
) -> None:
|
|
413
|
+
"""Set heater target temperatures. Pass any subset."""
|
|
414
|
+
if not enable_control:
|
|
415
|
+
_echo_err("Refusing to send a write action without --enable-control.")
|
|
416
|
+
raise typer.Exit(code=2)
|
|
417
|
+
if nozzle is None and bed is None and chamber is None:
|
|
418
|
+
_echo_err("Specify at least one of --nozzle, --bed, --chamber.")
|
|
419
|
+
raise typer.Exit(code=2)
|
|
420
|
+
|
|
421
|
+
async def run() -> None:
|
|
422
|
+
h, mid = await _resolve_target(host)
|
|
423
|
+
async with await Printer.connect(h, enable_control=True, mainboard_id=mid) as printer:
|
|
424
|
+
try:
|
|
425
|
+
await printer.set_temperatures(nozzle=nozzle, bed=bed, chamber=chamber)
|
|
426
|
+
except ValueError as err:
|
|
427
|
+
_echo_err(str(err))
|
|
428
|
+
raise typer.Exit(code=2) from err
|
|
429
|
+
parts = [
|
|
430
|
+
f"{k}={v}°C"
|
|
431
|
+
for k, v in (("nozzle", nozzle), ("bed", bed), ("chamber", chamber))
|
|
432
|
+
if v is not None
|
|
433
|
+
]
|
|
434
|
+
typer.echo("targets set: " + ", ".join(parts))
|
|
435
|
+
|
|
436
|
+
_run(run())
|
|
437
|
+
|
|
438
|
+
|
|
326
439
|
@app.command("server")
|
|
327
440
|
def cmd_server(
|
|
328
441
|
host: HostOpt = None,
|
|
@@ -196,6 +196,53 @@ def build_server(*, enable_control: bool = False) -> FastMCP:
|
|
|
196
196
|
result = await printer.stop()
|
|
197
197
|
return {"ok": True, "response": result.inner}
|
|
198
198
|
|
|
199
|
+
@mcp.tool()
|
|
200
|
+
async def set_print_speed(mode: str | int) -> dict[str, Any]:
|
|
201
|
+
"""Set the print-speed mode. Only effective while a print is running.
|
|
202
|
+
|
|
203
|
+
``mode`` is one of ``"silent"``, ``"balanced"``, ``"sport"``,
|
|
204
|
+
``"ludicrous"``, or the corresponding ``PrintSpeedPct`` value
|
|
205
|
+
(``50``, ``100``, ``130``, ``160``). Arbitrary intermediate
|
|
206
|
+
values are rejected by the firmware.
|
|
207
|
+
"""
|
|
208
|
+
host, mid = await _resolve_target()
|
|
209
|
+
async with await Printer.connect(host, enable_control=True, mainboard_id=mid) as printer:
|
|
210
|
+
result = await printer.set_print_speed(mode)
|
|
211
|
+
return {"ok": True, "response": result.inner}
|
|
212
|
+
|
|
213
|
+
@mcp.tool()
|
|
214
|
+
async def set_fan_speed(
|
|
215
|
+
model: int | None = None,
|
|
216
|
+
auxiliary: int | None = None,
|
|
217
|
+
chamber: int | None = None,
|
|
218
|
+
) -> dict[str, Any]:
|
|
219
|
+
"""Set fan speeds (0..100% each). Pass any subset; omitted fans are untouched.
|
|
220
|
+
|
|
221
|
+
``chamber`` is the chamber/box fan. At least one of the three must
|
|
222
|
+
be provided.
|
|
223
|
+
"""
|
|
224
|
+
host, mid = await _resolve_target()
|
|
225
|
+
async with await Printer.connect(host, enable_control=True, mainboard_id=mid) as printer:
|
|
226
|
+
result = await printer.set_fan_speed(model=model, auxiliary=auxiliary, chamber=chamber)
|
|
227
|
+
return {"ok": True, "response": result.inner}
|
|
228
|
+
|
|
229
|
+
@mcp.tool()
|
|
230
|
+
async def set_temperatures(
|
|
231
|
+
nozzle: float | None = None,
|
|
232
|
+
bed: float | None = None,
|
|
233
|
+
chamber: float | None = None,
|
|
234
|
+
) -> dict[str, Any]:
|
|
235
|
+
"""Set heater target temperatures in °C. Pass any subset.
|
|
236
|
+
|
|
237
|
+
``0`` turns the corresponding heater off. Safety caps applied:
|
|
238
|
+
nozzle 0..300, bed 0..110, chamber 0..60. Setting all heaters to
|
|
239
|
+
``0`` mid-print effectively kills the print.
|
|
240
|
+
"""
|
|
241
|
+
host, mid = await _resolve_target()
|
|
242
|
+
async with await Printer.connect(host, enable_control=True, mainboard_id=mid) as printer:
|
|
243
|
+
result = await printer.set_temperatures(nozzle=nozzle, bed=bed, chamber=chamber)
|
|
244
|
+
return {"ok": True, "response": result.inner}
|
|
245
|
+
|
|
199
246
|
return mcp
|
|
200
247
|
|
|
201
248
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|