Spoolman: учёт катушек филамента для Klipper и OctoPrint
Как поднять Spoolman на малине или на своём сервере: docker compose, подключение к Moonraker и OctoPrint, механика списания веса, QR-этикетки, известные ограничения и разбор расхождений с весами.
Spoolman — бесплатный веб-сервис учёта катушек филамента, который вы поднимаете у себя: база данных, REST API и веб-интерфейс в одном контейнере. Он не управляет принтером — расход ему присылают Moonraker (для Klipper) или плагин OctoPrint, а сам Spoolman хранит остаток по каждой катушке в граммах и метрах и обновляет его прямо во время печати. Проект пишет разработчик под ником Donkie с 1 апреля 2023 года, лицензия MIT, на 9 августа 2026 года — 2692 звезды на GitHub и свежий релиз v0.26.1 от 7 августа 2026.
Зачем нужен учёт филамента, если есть весы и глазомер
Пока катушка одна, вопрос «хватит ли» решается взглядом. Проблемы начинаются с третьей-четвёртой: три чёрных PLA от разных производителей, две из них початые, одна сушилась, другая нет. Слайсер честно пишет, сколько граммов уйдёт на модель, но он не знает, сколько осталось именно на той катушке, что сейчас стоит на держателе.
Весы отвечают на этот вопрос, но каждый раз вручную: снять катушку, взвесить, вычесть вес пустой шпули (у Prusament это 193 г, у ELEGOO — 154 г, у Bambu Lab — 250 г, у каждого производителя своё), записать. Через месяц записи разъезжаются с реальностью. Программный учёт делает то же самое, но сам: принтер выдавил 14 077 мм прутка — с катушки списалось 43 г.
- Остаток в реальном времени. Пока идёт печать, число в интерфейсе уменьшается — не после, а прямо сейчас.
- Проверка перед стартом. Fluidd и плагин OctoPrint не дадут запустить задание молча: если на катушке 1,6 г, а нужно 18,4 г — вы увидите предупреждение до того, как принтер прогреется.
- История по каждой катушке. Когда куплена, когда открыта, когда сушилась, сколько печатала, в какой коробке лежит.
- Цена материала в детали. В карточке катушки есть поле цены — расход в граммах превращается в рубли без отдельной таблицы.
- Общий склад на несколько принтеров. Один сервис принимает отчёты сразу от нескольких Moonraker и OctoPrint.
Что такое Spoolman и как он устроен
Внутри — сервер на Python и FastAPI, база данных и веб-клиент на React. По умолчанию база лежит в одном файле SQLite (spoolman.db), но при желании подключается PostgreSQL, MySQL или CockroachDB. Всё вместе занимает один контейнер: ghcr.io/donkie/spoolman:latest (зеркало на Docker Hub — donkieyo/spoolman:latest).
Ключевая мысль, которую стоит уложить сразу: Spoolman не разговаривает с принтером. Он вообще не знает, что где-то печатается. Его задача — хранить данные и отвечать на запросы по HTTP. Кто-то другой должен посчитать расход и прислать его.
| Кто | Что делает в этой связке |
|---|---|
| Klipper | Двигает экструдер и хранит текущую позицию оси E в объекте toolhead |
| Moonraker | Подписан на позицию E, считает прирост в миллиметрах и отправляет его в Spoolman |
| OctoPrint + плагин | Делает то же самое для принтеров на Marlin и других прошивках без Klipper |
| Spoolman | Хранит катушки, переводит миллиметры в граммы, отдаёт остаток по API |
| Fluidd / Mainsail / KlipperScreen | Показывают текущую катушку и дают её выбрать; своей базы катушек у них нет |
Проект развивается очень активно: релиз v0.26.1 вышел 7 августа 2026 года и собрал 18 изменений — переопределение веса на уровне отдельной катушки, смена филамента и производителя у уже заведённой катушки, исправление небезопасного разбора JSON в настройках. До него были v0.26.0 (31 июля 2026), v0.25.0 (22 июля) и v0.24.0 (7 июля) — то есть примерно релиз в неделю-две. Веб-клиент переведён на 18 языков — русский среди них.
Второй экран после библиотеки — дашборд, где катушки разложены по локациям: «Dry Box 1», «Shelf A», «Prusa MK4S», «Bambu X1C». Перетащили карточку — катушка переехала в другое место. Это удобнее, чем кажется: когда катушек больше двадцати, вопрос «а где та серая PETG» становится не риторическим.
Что понадобится до установки
- Любая машина в вашей сети с Docker: та же Raspberry Pi с Klipper, мини-ПК, домашний сервер, NAS. Отдельного железа под Spoolman не нужно.
- Свободный порт — в примерах из документации это 7912.
- Доступ по SSH к принтеру или к машине, где стоит Moonraker, чтобы поправить
moonraker.confиprinter.cfg(в Fluidd и Mainsail это делается прямо из редактора конфигов в браузере). - Данные ваших катушек: производитель, материал, плотность, диаметр, вес пустой шпули. Большую часть подтянет встроенный каталог, остальное — из характеристик материалов.
- 10–15 минут, если ставите в Docker, и понимание, что база должна лежать в смонтированной папке, а не внутри контейнера.
Установка Spoolman в Docker: пошагово
Docker — рекомендованный способ по официальной документации: образ несёт в себе нужную версию Python и всё окружение, так что версия Python на хосте роли не играет.
Шаг 1: папка для данных и права на неё
Внутри контейнера Spoolman работает от пользователя с UID 1000. Если папку не подготовить заранее, контейнер стартует, но не сможет создать базу — и вы получите пустой интерфейс, который забывает всё при перезапуске.
mkdir -p ~/spoolman/data
cd ~/spoolman
chown 1000:1000 dataШаг 2: docker-compose.yml
services:
spoolman:
image: ghcr.io/donkie/spoolman:latest
restart: unless-stopped
volumes:
- type: bind
source: ./data # где данные лежат на хосте
target: /home/app/.local/share/spoolman # эту строку не менять
ports:
- "7912:8000" # порт хоста : порт внутри контейнера
environment:
- TZ=Europe/Moscow # иначе время в логах и интерфейсе будет UTC
- PUID=1000
- PGID=1000Внутри контейнера сервис всегда слушает порт 8000 — наружу его можно вывести на любой. В документации и во всех интеграциях по традиции фигурирует 7912, и лучше не отступать от этой привычки: половина инструкций в сообществе написана именно под него.
Шаг 3: запуск и проверка, что база создалась
docker compose up -d
docker compose logs --tail 30
ls -la data/ # здесь обязан появиться spoolman.dbИнтерфейс открывается по адресу http://адрес-машины:7912. Пароля нет и не будет — к этому вернёмся в разделе про безопасность.
Шаг 4: первая катушка
Заводить катушку с нуля не нужно. Spoolman тянет общий каталог SpoolmanDB — на 9 августа 2026 года в нём 6957 записей филамента от 53 производителей: Polymaker (1201 запись), Formfutura (1056), Extrudr (986), eSUN и Protopasta (по 315), Bambu Lab (269). По материалам: 3502 записи PLA, 1202 PETG, 563 ASA, 529 ABS, 179 TPU. Из каталога подтягиваются плотность, диаметр, вес шпули и температуры — ровно те поля, по которым потом считается расход.
Иерархия из трёх уровней: производитель → филамент (условно «eSUN PLA+ чёрный», с плотностью и температурами) → катушка (конкретная физическая бобина с остатком, местом хранения и датой вскрытия). Одному филаменту соответствует сколько угодно катушек — три чёрных PLA+ будут тремя катушками одного филамента, каждая со своим номером.
Шаг 5: обновление и что при этом происходит с базой
cd ~/spoolman
docker compose pull && docker compose up -dБаза остаётся в смонтированной папке, поэтому образ можно менять сколько угодно. Схема базы мигрирует автоматически при первом запуске новой версии — а вот откатиться назад после миграции уже не получится, о чём документация честно предупреждает в разделе про сборку из исходников.
Установка без Docker: standalone на Linux
Если Docker на машине нет и ставить его не хочется (частый случай на самом принтере с ограниченным местом), есть установочный скрипт. Нужны curl и unzip.
mkdir -p ./Spoolman && \
curl -s https://api.github.com/repos/Donkie/Spoolman/releases/latest | \
grep -o 'https://[^"]*spoolman.zip' | \
xargs curl -sSL -o temp.zip && \
unzip -o temp.zip -d ./Spoolman && \
rm temp.zip && \
cd ./Spoolman && \
bash ./scripts/install.shСкрипт создаёт файл .env с настройками и systemd-юнит Spoolman. Порт по умолчанию здесь 7912, а не 8000. Управление обычное: sudo systemctl restart Spoolman, sudo systemctl status Spoolman, логи — sudo journalctl -u Spoolman -f. База в этом варианте лежит в ~/.local/share/spoolman/spoolman.db, то есть вне папки установки, поэтому обновление её не трогает.
Переменные окружения, которые действительно пригодятся
Своего формата конфигурации у Spoolman нет — всё задаётся переменными окружения: в секции environment: для Docker или строками КЛЮЧ=значение в .env для standalone. Полный список всегда лежит в файле .env.example в репозитории; ниже — то, что чаще всего меняют.
| Переменная | По умолчанию | Зачем нужна |
|---|---|---|
| SPOOLMAN_DB_TYPE | sqlite | Тип базы: sqlite, postgres, mysql, cockroachdb |
| SPOOLMAN_DB_HOST / _PORT / _NAME | — | Адрес внешней базы. С SQLite задавать _NAME нельзя — сервис откажется стартовать |
| SPOOLMAN_DB_USERNAME / _PASSWORD | — | Учётные данные внешней базы |
| SPOOLMAN_DB_PASSWORD_FILE | — | Путь к файлу с паролем — для Docker secrets, приоритетнее обычного пароля |
| SPOOLMAN_DIR_DATA | ~/.local/share/spoolman | Где лежит база. В Docker это путь внутри контейнера |
| SPOOLMAN_DIR_BACKUPS | <каталог данных>/backups | Куда складывать ночные копии. По умолчанию — внутри каталога данных |
| SPOOLMAN_AUTOMATIC_BACKUP | TRUE | Ночная копия SQLite, хранятся последние 5. На другие базы не действует |
| SPOOLMAN_HOST | 0.0.0.0 | На каком интерфейсе слушать |
| SPOOLMAN_PORT | 8000 в Docker, 7912 в standalone | Порт. В Docker лучше менять маппинг в ports, а не эту переменную |
| SPOOLMAN_BASE_PATH | — | Подпуть за реверс-прокси, например /spoolman |
| SPOOLMAN_CORS_ORIGIN | — | Источники браузерных клиентов на других адресах, со схемой: http://mainsail.local:8080 |
| SPOOLMAN_ALLOWED_HOSTS | выключено | Имена хостов, на которые отвечает сервис — защита от подмены DNS |
| EXTERNAL_DB_URL | https://donkie.github.io/SpoolmanDB/ | Адрес общего каталога филаментов. Пустое значение отключает функцию |
| EXTERNAL_DB_SYNC_INTERVAL | 3600 | Как часто перечитывать каталог, в секундах. 0 — только при старте |
| SPOOLMAN_METRICS_ENABLED | FALSE | Включает метрики Prometheus на /metrics |
| SPOOLMAN_LEGACY_CLIENT | FALSE | Возврат к прежнему веб-клиенту, если новый ведёт себя странно |
| SPOOLMAN_LOGGING_LEVEL | INFO | DEBUG дополнительно пишет каждый SQL-запрос — это то, что прикладывают к отчёту об ошибке |
| PUID / PGID | 1000 / 1000 | От какого пользователя работать внутри контейнера. Ноль недопустим |
| TZ | UTC | Часовой пояс для времени в логах и интерфейсе |
И ещё одна тонкость, на которой легко потерять полчаса: опечатка в названии переменной проходит молча — настройка просто не применяется. А вот опечатка в значении роняет старт с внятным сообщением, где названа переменная. Так что если параметр «не работает», сначала сверьте написание с .env.example, а потом уже ищите проблему глубже. Что именно применилось, Spoolman перечисляет в логе при запуске.
Подключение Spoolman к Klipper через Moonraker
Сам Klipper про Spoolman ничего не знает. Всю работу делает Moonraker — в нём есть штатный компонент spoolman, который включается тремя строчками в конфиге. Отдельно ничего доустанавливать не нужно, если у вас не экзотическая прошивка от производителя (об этом отдельный раздел ниже).
Шаг 1: секция [spoolman] в moonraker.conf
# moonraker.conf
[spoolman]
server: http://192.168.0.123:7912
# Адрес Spoolman. Параметр обязателен.
sync_rate: 5
# Интервал синхронизации в секундах. По умолчанию 5.Вместо 192.168.0.123 подставьте адрес машины со Spoolman. Если он крутится на той же малине, что и Klipper — это http://localhost:7912. Параметр sync_rate задаёт, как часто Moonraker отправляет накопленный расход: раз в 5 секунд по умолчанию, минимально допустимое значение — 1.
Шаг 2: макросы SET_ACTIVE_SPOOL и CLEAR_ACTIVE_SPOOL
Компонент регистрирует у Klipper удалённый метод spoolman_set_active_spool. Чтобы дёргать его из G-кода и макросов, в printer.cfg добавляют пару макросов из официальной документации Moonraker:
# printer.cfg
[gcode_macro SET_ACTIVE_SPOOL]
gcode:
{% if params.ID %}
{% set id = params.ID|int %}
{action_call_remote_method(
"spoolman_set_active_spool",
spool_id=id
)}
{% else %}
{action_respond_info("Parameter 'ID' is required")}
{% endif %}
[gcode_macro CLEAR_ACTIVE_SPOOL]
gcode:
{action_call_remote_method(
"spoolman_set_active_spool",
spool_id=None
)}После этого команда SET_ACTIVE_SPOOL ID=1 назначает текущей катушку №1, а CLEAR_ACTIVE_SPOOL снимает выбор — например, при выгрузке филамента, чтобы расход больше никуда не списывался. Эти же вызовы срабатывают, когда вы выбираете катушку мышью в Fluidd, Mainsail или на экране KlipperScreen: интерфейсы просто дёргают тот же метод.
Шаг 3: перезапуск и проверка связи
# перезапустить Moonraker после правки конфига
sudo systemctl restart moonraker
# проверить, что связь установлена
curl -s http://localhost:7125/server/spoolman/status
# ответ выглядит так:
# {"result": {"spoolman_connected": true,
# "pending_reports": [],
# "spool_id": 1}}Поле spoolman_connected — главный индикатор: Moonraker держит со Spoolman постоянное соединение по WebSocket и сразу видит, что тот пропал. В pending_reports лежит расход, который посчитан, но ещё не доставлен. Если связь оборвалась посреди печати, миллиметры копятся именно здесь и уезжают в базу, когда сервис вернётся — короткий обрыв сети данные не теряет.
Кроме статуса Moonraker отдаёт ещё два адреса API: GET/POST /server/spoolman/spool_id — узнать или задать текущую катушку (передача null снимает выбор), и POST /server/spoolman/proxy — проксировать произвольный запрос к API Spoolman через Moonraker, чтобы интерфейсу не нужно было ходить на второй адрес напрямую. Выбранная катушка запоминается в базе самого Moonraker и переживает его перезапуск.
Что умеют Fluidd, Mainsail и KlipperScreen из коробки
Ни у Fluidd, ни у Mainsail нет своей базы катушек — они целиком опираются на Spoolman и секцию [spoolman] в Moonraker. Без поднятого сервиса в них попросту нечего выбирать. Зато как только он появился, интерфейс подхватывает его сам, без плагинов.
| Возможность | Fluidd 1.37 | Mainsail 2.18 | KlipperScreen |
|---|---|---|---|
| Выбор катушки при старте печати | Модальное окно, отключается в настройках | Есть | Есть, панель spoolman |
| Сканирование QR-кода веб-камерой | Да, прямо в окне выбора | Нет | Нет |
| Карточка текущей катушки на экране | Да, с кнопкой смены по ходу печати | Да | Отдельная панель Spoolman |
| Проверка «хватит ли материала» | Да | Да | Нет |
| Проверка совпадения типа филамента со слайсером | Да | Да | Нет |
| Отдельная катушка на каждый инструмент | Да, через переменные макросов T0/T1 | Да, с версии 2.13.0 | Нет |
| Запоминание выбора после перезагрузки | Да, через [save_variables] | Да, через [save_variables] | Нет |
Окно выбора появляется при каждом старте задания, и его можно выключить в настройках Fluidd, если катушка меняется редко. Проверки перед печатью здесь три: катушка выбрана; на ней хватает материала на задание; тип филамента совпадает с тем, что выбран в слайсере. Последнее ловит классическую ошибку «нарезал под PETG, а на принтере стоит PLA».
Несколько экструдеров и тулченджеры
Тут стоит развеять устаревшее убеждение: до начала 2024 года поддержки нескольких катушек одновременно действительно не было, из-за чего в трекере Fluidd висел популярный запрос. Его закрыли 3 февраля 2024 года, а 18 февраля сопровождающий проекта написал в том же обсуждении, что в версии 1.28.1 всё заработало. Сегодня катушка назначается каждому инструменту отдельно.
Чтобы инструменты попали в этот список, макросы смены головы должны объявлять переменную spool_id и вызывать назначение катушки:
# printer.cfg
[gcode_macro T0]
variable_spool_id: None
gcode:
...
SET_ACTIVE_SPOOL ID={ printer['gcode_macro T0'].spool_id }
...В Mainsail то же самое появилось позже — мультиинструментальная поддержка вошла в версию 2.13.0 (изменение смёржено 1 декабря 2024 года) и устроена так же: ID катушки хранится в переменной макроса. Запрос на «правильную» реализацию через отдельное API Moonraker, где катушка привязывается к инструменту на уровне сервера, закрыли 29 июня 2026 года со статусом «не планируется»: автор запроса написал, что со стороны Moonraker идея поддержки не нашла, и пока этого не произойдёт, делать в Mainsail нечего. Так что вариант с переменными макросов — не временный костыль, а текущая штатная схема. Заодно Mainsail умеет назначать катушки каналам (lane) автоматических сменщиков филамента: в диалоге смены он отправляет команду SET_SPOOL_ID LANE=<номер> SPOOL_ID=<id>.
Чтобы выбор катушки пережил перезагрузку принтера
Активная катушка хранится в базе Moonraker, а вот привязка катушек к инструментам живёт в переменных макросов и обнуляется при рестарте прошивки. Fluidd и Mainsail умеют это чинить: если в конфигурации есть секция [save_variables], интерфейс сохраняет выбор при каждой смене, а восстановить его можно отложенным макросом.
# printer.cfg
[delayed_gcode RESTORE_SELECTED_SPOOLS]
initial_duration: 0.1
gcode:
{% set svv = printer.save_variables.variables %}
{% for object in printer %}
{% if object.startswith('gcode_macro ') and printer[object].spool_id is defined %}
{% set macro = object.replace('gcode_macro ', '') %}
{% set var = (macro + '__SPOOL_ID')|lower %}
{% if svv[var] is defined %}
SET_GCODE_VARIABLE MACRO={macro} VARIABLE=spool_id VALUE={svv[var]}
{% endif %}
{% endif %}
{% endfor %}Подключение к OctoPrint
У принтеров без Klipper — на Marlin и родственных прошивках — роль Moonraker играет OctoPrint. Своего плагина автор Spoolman не пишет, но есть сторонний, зато живой: плагин Spoolman от Michał Dziekoński, в каталоге OctoPrint с 27 апреля 2024 года, лицензия AGPLv3. Актуальная версия 1.4.0 от 18 октября 2025 года, требуется OctoPrint 1.9.0 и новее. По статистике каталога плагин стоит минимум на 538 установках OctoPrint — для нишевого инструмента это приличное число.
Ставится через встроенный менеджер плагинов или по прямой ссылке на архив github.com/mdziekon/octoprint-spoolman/archive/master.zip. После установки в настройках указывают адрес своего Spoolman.
- Выбор и снятие катушек по инструментам и экструдерам — на мультиматериальных сборках у каждого инструмента своя катушка.
- Фильтрация списка; архивные катушки по умолчанию не показываются.
- Проверка перед печатью: подтверждение выбранной катушки, предупреждение, если катушка не выбрана, если материала не хватит на модель, если тип материала не совпадает с профилем PrusaSlicer или OrcaSlicer.
- Поддержка HTTPS с самоподписанным сертификатом — путь к цепочке сертификатов указывается в настройках плагина.
- Повтор отправки расхода при сбое связи: до трёх попыток при ошибках сервера и таймаутах.
Как в реальности взаимодействуют Spoolman и Klipper: механика списания
Это самая полезная часть для тех, кто потом будет разбираться, почему цифры не сходятся. Разберём по шагам, что происходит между Klipper и базой.
| Этап | Что происходит |
|---|---|
| 1. Klipper | Двигает экструдер; текущая позиция оси E лежит в объекте toolhead, поле position |
| 2. Moonraker | Подписан на toolhead.position и toolhead.extruder, запоминает максимум пройденной E-координаты |
| 3. Moonraker | Прирост координаты в миллиметрах копит для текущей катушки; при смене инструмента счётчик сбрасывается на текущую позицию, чтобы расход не задвоился |
| 4. Moonraker | Раз в sync_rate секунд отправляет запрос PUT /api/v1/spool/<id>/use с телом {"use_length": длина_в_мм} |
| 5. Spoolman | Переводит миллиметры в граммы по плотности и диаметру филамента из карточки и уменьшает остаток |
| 6. Spoolman | Рассылает обновление по WebSocket — интерфейсы обновляют цифру, не перезагружая страницу |
Отсюда два важных следствия. Первое: Moonraker передаёт длину, а в граммы её превращает Spoolman — значит, любая ошибка в плотности или диаметре сразу превращается в ошибку веса. Второе: считается фактическая экструзия, а не оценка слайсера, поэтому отменённая на середине печать спишет ровно то, что успело выдавиться.
Есть и приятная мелочь: Moonraker записывает использованные катушки в историю печати отдельным полем — по завершённому заданию видно, с какой катушки оно печаталось. Если вы считаете себестоимость деталей, это ровно та цифра, которой не хватает в обычном расчёте стоимости печати.
Что делать, если учёт расходится с реальным весом
Официальный FAQ задаёт планку: расхождение больше примерно 10% — уже повод разбираться, меньше — нормальный разброс, филамент неоднороден, а влажность меняет вес. Порядок проверки такой:
- Плотность и диаметр в карточке филамента. Для PLA плотность около 1,24 г/см³, самый ходовой диаметр — 1,75 мм. Ошибка здесь даёт систематический перекос на всех печатях сразу.
- Калибровка подачи экструдера (E-step). Если принтер выдавливает не столько, сколько думает, Spoolman получит неверную длину — виноват не он.
- Логи того, кто шлёт расход. Moonraker или OctoPrint — там видно, уходили ли запросы и с какими ошибками.
- Логи Spoolman. В Docker это
docker compose logs, в standalone —sudo journalctl -u Spoolman; файл лога лежит рядом с базой.
Плотность у разных материалов отличается заметно, и подставлять «как у PLA» ко всему подряд нельзя: у PETG она выше, у TPU своя, у наполненных углеволокном составов — тоже. Проще всего брать материал из встроенного каталога, где эти поля уже заполнены производителем.
Можно ли задать номер катушки прямо в слайсере
Логичное желание: раз в профиле филамента уже указано, чем печатаем, пусть слайсер сам подставит номер катушки. Штатно это не решено, и обсуждение в трекере проекта (тема от 29 июня 2025 года) до сих пор без единого ответа.
Автор темы описал, чем это кончается на практике. Он вписал SET_ACTIVE_SPOOL SPOOL_ID=<номер> (в его схеме параметр назван SPOOL_ID, а не ID, как в макросе из документации) в стартовый G-код профиля филамента, а вызов этого блока поставил первой строкой в стартовом G-коде принтера. Слайсер всё равно вставляет перед ним свои команды — EXCLUDE_OBJECT, M73, M106. Хуже другое: при печати файлом, загруженным через веб-интерфейс, окно выбора катушки в Fluidd всплывает раньше, чем Klipper успевает разобрать G-код. Проверяется это просто — контрольное сообщение M118 из макроса попадает в лог уже после того, как окно появилось. А вот при печати напрямую из OrcaSlicer окно не появляется вовсе.
Spoolman на QIDI Q2 и Q1 Pro: прошивки с форком Moonraker
Принтеры QIDI работают на Klipper, но прошивка у них своя, с изменённым и заметно более старым Moonraker. Из-за этого штатная инструкция «допишите секцию [spoolman]» упирается в то, что нужного компонента в прошивке просто нет. Разбор для QIDI Q1 Pro на прошивке V4.4.24 показывает, что именно приходится делать руками — и та же логика применима к линейке Q2, построенной на той же программной основе.
- Зайти на принтер по SSH: логин
mks, парольmakerbase; IP смотрят на экране принтера в Settings → Network (сеть). - Положить компонент
spoolman.pyв/home/mks/moonraker/moonraker/components/— причём именно старой ревизии: свежая версия несовместима со штатным Moonraker этой прошивки. - Перезапустить Moonraker:
sudo service moonraker restart. - Откатить Fluidd на версию 1.28.0 — более новые сборки на этой прошивке не запускаются. Старую папку сохраняют рядом как резервную копию.
- Через редактор конфигов в Fluidd дописать секцию
[spoolman]вmoonraker.confи макросыSET_ACTIVE_SPOOL/CLEAR_ACTIVE_SPOOLвprinter.cfg. - Полностью выключить и включить принтер кнопкой питания.
Отдельный приём из того же разбора: у QIDI смена филамента делается с экрана принтера макросами M603 (выгрузка) и M604 (загрузка), а Spoolman об этом ничего не узнаёт и продолжает списывать расход на старую катушку. Лечится дописыванием CLEAR_ACTIVE_SPOOL в конец обоих макросов в gcode_macro.cfg — после смены филамента выбор сбрасывается, и интерфейс попросит указать катушку заново.
Логика применима не только к QIDI. Ровно та же история встречается на рутованных Anycubic Kobra 3: в трекере Spoolman есть обращение владельца такого принтера, которому пришлось править компонент под форк Klipper от производителя, потому что команды назначения катушки в прошивке нет вовсе — её заменили на M555. Общее правило простое: чем сильнее производитель переписал Moonraker, тем больше ручной работы и тем меньше смысла ждать, что «просто заработает».
Этикетки с QR-кодом: чтобы не путать три чёрных катушки
В веб-клиент встроен дизайнер этикеток. Вы задаёте размер (в примере — 50×25 мм), кидаете на макет QR-код, текстовые поля, образец цвета и прямоугольники, а в поля подставляете шаблоны вида {filament.name} или {Temp: {filament.nozzleTemp}°C} — во втором случае строка исчезнет, если температура не заполнена. Печатать можно на листах наклеек или на этикеточном принтере, макеты сохраняются на сервере.
Этикетки бывают двух типов: на катушку (QR ведёт на конкретную бобину) и на филамент (QR ведёт на материал, поля, специфичные для отдельной катушки, в макет не попадают). Первый вариант — для наклейки на шпулю, второй удобен для коробок и полок.
Особенно выручает с материалами, которые внешне неразличимы, но печатаются по-разному: шелковистый PLA от обычного на глаз не отличить, а температура и поведение на мостах у них разные. Наклейка с цветовой полосой и температурой решает вопрос без открывания интерфейса.
История расхода: Prometheus и Grafana
Сам Spoolman хранит текущий остаток, а не график его изменения. Если хочется видеть, как таял пластик по часам, включается переменная SPOOLMAN_METRICS_ENABLED=TRUE — сервис начинает отдавать метрики на /metrics в формате Prometheus. Дальше их забирает Prometheus, а рисует Grafana.
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'spoolman'
static_configs:
- targets: ['localhost:7912']Смысл появляется, если стек Prometheus и Grafana у вас уже есть под другие задачи — например, для мониторинга домашнего сервера. Разворачивать их ради одного графика расхода — работа ради работы: те же данные видны в карточке катушки.
Spoolman в Home Assistant
Официальной интеграции у Spoolman нет, но есть популярная интеграция от сообщества (237 звёзд, лицензия MIT, последние изменения — 8 августа 2026 года, то есть проект живой). Ставится как пользовательский репозиторий через HACS; последняя стабильная версия — 1.4.0 от 10 мая 2026 года.
Интеграция создаёт устройство на каждую катушку и на каждое место хранения, а в атрибуты складывает буквально всё: даты регистрации, первой и последней печати, цену, плотность, диаметр, остаток в граммах и метрах, процент израсходованного. Есть событие о том, что остаток упал ниже порога — на нём вешают автоматизацию «напомнить купить, когда останется меньше 200 г».
Bambu Lab: почему Spoolman тут почти бесполезен
Запрос на поддержку принтеров Bambu Lab висит в трекере проекта с 9 декабря 2023 года и остаётся открытым. Причина не в лени разработчика: у Klipper есть Moonraker, у Marlin — OctoPrint, а закрытая прошивка Bambu не даёт ни того ни другого. Списывать расход просто некому.
Сторонние решения от сообщества существуют и развиваются. Один проект подключается к принтеру по MQTT, скачивает G-код задания и обновляет расход послойно, привязывая катушки по идентификатору лотка AMS (41 звезда, обновлялся 7 марта 2026 года). Второй, покрупнее — 233 звезды, обновление 26 июня 2026 года, GPL-3.0, есть готовый Docker-образ — синхронизирует лотки AMS с катушками Spoolman.
Оценивайте трезво: это надстройки над закрытой экосистемой, они зависят от того, что производитель не поменяет протокол. Если вам нужен именно бескомпромиссный контроль над своим Bambu, смотрите в сторону своего сервера для Bambu Lab — задача там решается на другом уровне.
Когда хватает малины, а когда нужен отдельный сервер
Скажем прямо: для одного принтера дома Spoolman ставят на ту же Raspberry Pi, где уже крутится Klipper. Это официально поддерживаемый и самый разумный вариант — сервис лёгкий, лишнего сетевого прыжка нет, денег стоит ноль. Документация начинается ровно с этого сценария, и если он ваш — дальше можно не читать, поставьте по инструкции выше и пользуйтесь.
Сначала — самый простой способ дотянуться до базы издалека
Если единственное, чего не хватает — посмотреть остаток катушек, стоя в магазине, то поднимать сервер не нужно. Достаточно частной сети между своими устройствами: Tailscale или ZeroTier ставятся клиентом на малину и на телефон, после чего телефон видит домашний адрес http://192.168.х.х:7912 так, будто он дома. Ни портов пробрасывать, ни прокси настраивать не надо.
Но частная сеть решает ровно одну задачу — «дотянуться до своей малины». Всё остальное она не покрывает, и вот тут появляется смысл в отдельном сервере:
- Несколько принтеров и один общий склад. Spoolman умеет принимать отчёты сразу от нескольких Moonraker и OctoPrint — это заявленная возможность, а не хитрость. Но если сервис живёт на малине первого принтера, то выключенный первый принтер оставляет без учёта все остальные. Когда принтеры стоят в разных комнатах или у разных людей, нейтральная точка нужна почти сразу.
- Сканер QR-кодов с телефона. Камера в браузере работает только по HTTPS. Сертификат нужен на нормальное доменное имя, а значит — реверс-прокси и машина, до которой этот домен доходит.
- Данные переживают смерть карты памяти. Если Spoolman стоит там же, где Klipper, база и прошивка лежат на одной SD-карте. Умерла карта или вы переставили систему ради обновления Klipper — вместе с ней уехал весь склад катушек за два года.
- Доступность, когда принтер выключен. Заказывать пластик и разбирать инвентарь удобно и тогда, когда печатать нечего.
- PostgreSQL под несколько клиентов и длинную историю. SQLite тянет домашние объёмы спокойно, но если вы уже держите Postgres, Spoolman к нему подключается штатно.
Требования к серверу скромные. Spoolman — лёгкий сервис на FastAPI поверх SQLite: ни распознавания брака нейросетью, ни перекодирования видео, ни тяжёлого рендера. Официальных минимумов по памяти и процессору документация не публикует, и это само по себе показательно — сообщество гоняет его на тех же одноплатниках, где живёт Klipper. На практике: 2 ГБ памяти хватает на Spoolman вместе с реверс-прокси и сертификатом, а свободное место нужно скорее под бэкапы, чем под саму базу.
Принтер под контролем из любой точки
Удалённый доступ к Klipper и OctoPrint, ИИ-мониторинг печати и своя библиотека моделей — на VPS от 172 ₽ в первый месяц.
- NVMe-диски
- Анти-DDoS
- Поддержка 24/7
- 🇷🇺 🇩🇪 🇳🇱 7 локаций
Первый месяц по промокоду, дальше от 429 ₽/мес — тариф Promo: 2 ГБ RAM, 30 ГБ NVMe, бэкапы включены.
Покупка по ссылке поддерживает Printer Hub 🤝
Схема разворачивания та же, что и для остальных сервисов, которые вы держите у себя вокруг принтера: контейнер со Spoolman, реверс-прокси с сертификатом перед ним, доменное имя. Если такой сервер у вас уже поднят под Obico и библиотеку моделей, Spoolman добавляется туда одним сервисом в тот же docker-compose.yml и лишних ресурсов почти не просит.
Безопасность: у Spoolman нет пароля
Отсюда правило, которое документация выделяет отдельно: если сервис доступен снаружи домашней сети, перед ним обязан стоять реверс-прокси с авторизацией — Authelia, Authentik или хотя бы basic-аутентификация самого прокси. Пробрасывать порт напрямую нельзя ни при каких условиях, и никакие настройки ниже этого не заменяют. Как поднимать такой прокси — подробно в материале про удалённый доступ к 3D-принтеру.
При этом кое-что Spoolman закрывает сам, без настройки: запись со сторонних сайтов и подключения по WebSocket с чужих страниц он отклоняет — то есть открытая в соседней вкладке страница не сможет тихо прочитать ваш склад. Запросы без заголовка источника (Moonraker, OctoPrint, Home Assistant, curl) под это не подпадают и работают как раньше.
| Настройка | Когда нужна | Формат |
|---|---|---|
| SPOOLMAN_CORS_ORIGIN | Браузерный интерфейс (Fluidd, Mainsail, свой дашборд) живёт на другом адресе | Со схемой: https://fluidd.local,http://mainsail.local:8080. Порт различает источники, без http:// правило молча не сработает |
| SPOOLMAN_ALLOWED_HOSTS | Защита от подмены DNS, когда доступ идёт по настоящему домену | Имена хостов без схемы и порта: spoolman.mydomain.com, поддерживается *.mydomain.com |
| Заголовок Host на прокси | Всегда, если стоит nginx или Apache | proxy_set_header Host $host; либо ProxyPreserveHost On. Traefik, Caddy и HAProxy делают это сами |
| SPOOLMAN_CORS_ORIGIN=* | Никогда на машине, которая вам дорога | Полностью выключает проверку источника; Spoolman пишет предупреждение в лог при старте |
Отдельно про метрики: включённый /metrics отдаёт названия производителей и филаментов, цвета и цены каждой катушки — без всякой проверки. Если Prometheus у вас снаружи, закрывайте этот адрес авторизацией на прокси.
Известные ограничения и что с ними делать
Все проблемы ниже сверены в трекере проекта 9 августа 2026 года — с датами и текущими статусами, а не по памяти.
Расход не доходит через туннель OctoEverywhere
Обращение открыто 23 ноября 2025 года и на 9 августа 2026 остаётся без ответа. Симптом коварный: проверка связи проходит успешно, интерфейс Spoolman через туннель открывается, а запросы на списание расхода до сервиса не доходят вообще — в логах соответствующий вызов не появляется ни разу за печать. Вывод практический: держите Spoolman в одной сети с Moonraker или OctoPrint, а туннель используйте для просмотра, а не как транспорт для учёта.
Нет поддержки Bambu Lab
Запрос открыт 9 декабря 2023 года, 38 комментариев, статус не менялся. Ждать штатной поддержки не стоит — упирается в закрытую прошивку. Рабочие варианты только сторонние, разобраны выше.
На форках прошивки расход начинает приходить только после перезапуска
Обращение от 15 января 2025 года, открыто. Владелец рутованной Anycubic Kobra 3 правил компонент под форк Klipper от производителя: в логе видно, что после старта печати запросы уходят не того типа, и только перезапуск контейнера переводит связку в рабочее состояние. Штатной связки Klipper с Moonraker это не касается, но хорошо показывает цену самодельных патчей: сломается — чинить будете сами.
«Выбор катушки не работает в Mainsail»
Классика жанра: обращение висит открытым с 1 января 2024 года, 37 комментариев, но последняя активность — 7 января того же года. В обсуждении участник собрал чистую MainsailOS и standalone Spoolman на той же малине и получил рабочий результат сразу после обновления всех компонентов во вкладке Machine. Практический вывод: почти всегда причина в рассинхроне версий Mainsail, Moonraker и Spoolman либо в пропущенном шаге установки. Перед тем как искать баг, обновите всё и перезапустите Moonraker.
И то, чего в этом списке нет. В сообществе иногда пересказывают историю про двойное списание расхода при ошибках печати. Обращение действительно было заведено 27 января 2025 года — и закрыто автором в тот же день с комментарием «orca seems to agree with spoolman spend» — расчёт слайсера сошёлся со списанием. Как самостоятельная проблема оно не подтвердилось, и единственный задокументированный сценарий задвоения — повторные отправки при сбоях связи в плагине OctoPrint, который выключается галочкой в настройках.
Экономика: сколько стоит держать Spoolman на своём сервере
Сам Spoolman бесплатен, лицензия MIT, никаких платных функций и лимитов у него нет. Платить приходится только за место, где он живёт, — и только если вы решили вынести его с малины. Цены на 9 августа 2026 года, тарифы AdminVPS в России:
| Тариф | Цена в месяц | Процессор | Память | Диск | Бэкапы |
|---|---|---|---|---|---|
| Lite | 299 ₽ | 1 × 3,6 ГГц | 1 ГБ | 15 ГБ NVMe | платные, промокоды не действуют |
| Promo | 429 ₽ | 1 × 3,6 ГГц | 2 ГБ | 30 ГБ NVMe | бесплатные |
| Micro | 799 ₽ | 2 × 3,6 ГГц | 4 ГБ | 60 ГБ NVMe | бесплатные |
Рабочий выбор — Promo за 429 ₽ в месяц: двух гигабайт памяти хватает на Spoolman с реверс-прокси и сертификатом с большим запасом, а бэкапы сервера здесь включены — это важно, потому что ночная копия базы по умолчанию складывается в ту же папку с данными, и потеря диска унесла бы её вместе с базой. Тариф Lite за 299 ₽ формально тоже потянет сервис, но резервные копии там платные, а промокоды на него не действуют — экономия выходит мнимой.
| Промокод | Скидка | Период оплаты |
|---|---|---|
| ph-60 | 60% на первый месяц | 1 месяц |
| ph-30 | 30% на первый месяц | 1 месяц |
| ph-3-20 | 20% на первые 3 месяца | 3 месяца |
| ph-6-15 | 15% на первые 6 месяцев | 6 месяцев |
| ph-1-5 | 5% на первый год | 12 месяцев |
Промокоды применяются к одному серверу в заказе, складываются со скидками сайта и активируются один раз — каждый под свой период оплаты. Самый выгодный вход — ph-60: первый месяц Promo обойдётся в 172 ₽ вместо 429 ₽, чего с запасом хватает, чтобы понять, нужен вам вынесенный учёт или достаточно малины. На тариф Lite промокоды не действуют.
Принтер под контролем из любой точки
Удалённый доступ к Klipper и OctoPrint, ИИ-мониторинг печати и своя библиотека моделей — на VPS от 172 ₽ в первый месяц.
- NVMe-диски
- Анти-DDoS
- Поддержка 24/7
- 🇷🇺 🇩🇪 🇳🇱 7 локаций
Первый месяц по промокоду, дальше от 429 ₽/мес — тариф Promo: 2 ГБ RAM, 30 ГБ NVMe, бэкапы включены.
Покупка по ссылке поддерживает Printer Hub 🤝
Сравните с ценой вопроса: 429 ₽ в месяц — это меньше, чем стоит одна испорченная печать, которая встала посреди детали из-за закончившегося пластика. Впрочем, честности ради: для одного принтера этот расход не нужен вовсе — вернитесь на два раздела выше и поставьте Spoolman на малину.
Альтернативы Spoolman
| Решение | Состояние | С чем работает | Вывод |
|---|---|---|---|
| Spoolman | Релиз 7 августа 2026, разработка активная | Moonraker/Klipper, OctoPrint, Home Assistant | Фактический стандарт |
| FilamentManager (плагин OctoPrint) | Последний релиз 15 ноября 2021 года | Только OctoPrint | Не развивается почти пять лет |
| Fluidd / Mainsail | Активны | Только интерфейс поверх Spoolman | Своей базы катушек нет вообще |
| Учёт в таблице или на бумаге | Вечно | Ни с чем | Работает ровно до третьей катушки |
| AMS и облако Bambu Lab | Активно | Только Bambu Lab | Закрытая экосистема, к Spoolman отношения не имеет |
Про FilamentManager стоит сказать подробнее, потому что его до сих пор советуют в старых обсуждениях. Плагин ведёт учёт по длине выдавленного прутка внутри OctoPrint и даже умеет работать с PostgreSQL для нескольких принтеров. Но последний релиз вышел 15 ноября 2021 года, а у исходного репозитория, от которого пошёл этот форк, последняя версия датирована и вовсе 2018 годом. Живой синхронизации с Moonraker там нет, поэтому связка «Klipper без OctoPrint» им не покрывается никак. Ставить его в 2026 году смысла нет.
Что стоит сделать в первый же день
Частые вопросы
Источники
- Donkie/Spoolman — репозиторий проекта, релизы и трекер обращений
- Spoolman Wiki — установка, переменные окружения, резервные копии, безопасность, частые вопросы
- Документация Moonraker — секция
[spoolman]и макросы назначения катушки - Документация Fluidd — выбор катушки, проверки перед печатью, тулченджеры и сохранение выбора
- Каталог плагинов OctoPrint — карточка плагина Spoolman, версии и совместимость
- SpoolmanDB — общий каталог филаментов, из которого подтягиваются плотность и температуры
- Разбор установки на QIDI Q1 Pro — пошаговая инструкция для прошивки производителя
- Интеграция для Home Assistant — сенсоры катушек и события о низком остатке
Команда Printer Hub
Изучаем официальную документацию и инструкции производителей, тестируем моды на реальных принтерах и анализируем опыт сообщества Reddit, Telegram, Printables и YouTube.