Настройка OctoPrint для работы с несколькими принтерами

kerbetos
Идет загрузка
Загрузка
07.09.2018
4618
38
печатает на Prusa Mendel 2
Техничка

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых постах.

Отписаться от уведомлений вы всегда сможете в профиле автора.

27
В этой статье я расскажу, как настроить OctoPrint Raspberry Pi 3 (малинка) для нескольких принтеров.
Для начала скачиваем с официальной страницы образ 2018-04-18-octopi-stretch-lite-0.15.1.img который с помощью win32diskimager записываем на Micro SD карту. Сразу скажу по поводу карты я использовал карту Kingston на 4 Гб, пробовал перед этим карты Mirex причем несколько разных - с ними были ошибки при загрузке и малинка висла, а с kingston проблем нет.

Если Raspberry будет общаться с внешним миром через wi-fi то на флешке правим файл octopi-wpa-supplicant.txt

убираем перед текстом знаки # и вписываем имя своей сети и пароль например так:
network={

ssid='SSID'

psk='WI_FI_PASS'

}
Сначала мы настраиваем OctoPrint только для одного принтера, а после этого - для нескольких принтеров и веб-камер.

Вставляем в малинку SD карту, подключаем к с ней монитор или телевизор с клавиатурой. и подаем питание.

после загрузки на экране будет виден IP адрес который получила малинка от роутера и приглашение ввести логин

в моем случае 192.168.1.5. Стандартный логин: pi пароль: raspberry

Далее настраиваем подключение к одному из принтеров зайдя с любого компьютера на сервер Octorint через web браузер в моем случае по адресу http://192.168.1.5

Для каждого принтера необходимо запустить отдельный экземпляр OctoPrint с другим портом. Если вы хотите использовать более одной веб-камеры, вам также необходимо запустить отдельные экземпляры MJPG-Streamer для каждой веб-камеры.

Дальнейшую настройку можно производить с клавиатуры и монитора gодключенного к Raspberry PI или подключившись через SSH с другого компьютера например с помощью PuTTY.
выбрав протокол SSH, вводим IP адрес Octoprint нажимаем Connect

В открывшемся окне вводим логин и пароль
Следующим шагом будет подключение нескольких принтеров к Raspberry PI

При подключении принтеров порты именуются как /dev/ttyUSB0, /dev/ttyUSB1 и так далее

Причем порты будут именоваться в порядке их подключения и не факт что после следующей загрузки принтер не поменяем имя порта. для этого мы выполним привязку порта и создадим именованные линки к ним

даем в консоли команду
pi@octopi:~ $ ls -al /dev/tty* | grep USB
у меня нашелся для начала один порт

crw-rw---- 1 root dialout 188, 0 Sep 6 18:27 /dev/ttyUSB0

найдем его уникальный идентификатор командами
pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB0 --attribute-walk|grep idVendor

ATTRS{idVendor}=='0403'

ATTRS{idVendor}=='0424'

ATTRS{idVendor}=='1d6b'
pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB0 --attribute-walk|grep idProduct

ATTRS{idProduct}=='6001'

ATTRS{idProduct}=='2514'

ATTRS{idProduct}=='0002'
pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB0 --attribute-walk|grep devpath

Udevadm info starts with the device specified by the devpath and then

ATTRS{devpath}=='1.2'

ATTRS{devpath}=='1'

ATTRS{devpath}=='0'
Получили необходимые значения для одного порта

idVendor=='0403'

idProduct=='6001'

devpath=='1.2'

аналогично для других принтеров и портов
pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB1 --attribute-walk|grep idVendor

ATTRS{idVendor}=='1a86'

ATTRS{idVendor}=='0424'

ATTRS{idVendor}=='1d6b'

pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB1 --attribute-walk|grep idProduct

ATTRS{idProduct}=='7523'

ATTRS{idProduct}=='2514'

ATTRS{idProduct}=='0002'

pi@octopi:~ $ udevadm info -q all -n /dev/ttyUSB1 --attribute-walk|grep devpath

Udevadm info starts with the device specified by the devpath and then

ATTRS{devpath}=='1.3'

ATTRS{devpath}=='1'

ATTRS{devpath}=='0'
получаем для второго принтера значения

idVendor=='1a86'

idProduct=='7523'

devpath=='1.3'

теперь мы знаем идентификаторы портов принтеров и сделаем link для портов с привязкой к его идентификатору

командой открываем файл /etc/udev/rules.d/95-ads7846.rule для редактирования
sudo nano /etc/udev/rules.d/95-ads7846.rules
и добавляем строки вписав полученные идентификаторы со звездочкой в начале и на конце, и новые имена портов. У меня это порты ttyUSBPrusa и ttyUSBHBotBIG
SUBSYSTEM=='tty', ATTRS{idVendor}=='0403', ATTRS{idProduct}=='6001', ATTRS{devpath}=='1.2', SYMLINK+='ttyUSBPrusa'

SUBSYSTEM=='tty', ATTRS{idVendor}=='1a86', ATTRS{idProduct}=='7523', ATTRS{devpath}=='1.3', SYMLINK+='ttyUSBHBotBIG'
Важно давать имена портам начинающиеся с ttyUSB иначе Octoprint может их не видеть в web интерфейсе

сохраняем файл и даем команду
pi@octopi:~ $ ls -al /dev/tty* | grep USB

lrwxrwxrwx 1 root root 7 Sep 6 22:58 /dev/ttyUSBHBotBIG -> ttyUSB1

lrwxrwxrwx 1 root root 7 Sep 6 22:58 /dev/ttyUSBPrusa -> ttyUSB0

crw-rw---- 1 root dialout 188, 0 Sep 6 22:58 /dev/ttyUSB0

crw-rw---- 1 root dialout 188, 1 Sep 6 22:58 /dev/ttyUSB1
если все нормально то видим новые порты
lrwxrwxrwx 1 root root 7 Sep 6 22:58 /dev/ttyUSBHBotBIG -> ttyUSB1

lrwxrwxrwx 1 root root 7 Sep 6 22:58 /dev/ttyUSBPrusa -> ttyUSB0
Теперь порты не потеряются и будут иметь понятный для нас вид

Настраиваем еще экземпляры Octoprint

Копируем каталог Octoprint
cp -R /home/pi/.octoprint /home/pi/.octoprint2
Копируем конфигурацию Octoprint
sudo cp /etc/default/octoprint /etc/default/octoprint2
Меняем настройки в файле конфигурации
sudo nano /etc/default/octoprint2
Необходимо поправить пару строк
HOST=0.0.0.0

PORT=5001

DAEMON_ARGS='--host=$HOST --port=$PORT --basedir /home/pi/.octoprint2/'
Копируем скрипт запуска
sudo cp /etc/init.d/octoprint /etc/init.d/octoprint2
И правим его
sudo nano /etc/init.d/octoprint2
В верхней части этого файла должны быть вносим изменения!

Измените каждое имя от «octoprint» до «octoprint2» и «OctoPrint» до «OctoPrint2»,

но оставьте строку «DAEMON=/usr/bin/octoprint» нетронутой!!!!!

Примерно так:
#!/bin/sh

### BEGIN INIT INFO

# Provides: octoprint2

# Required-Start: $local_fs networking

# Required-Stop:

# Should-Start:

# Should-Stop:

# Default-Start: 2 3 4 5

# Default-Stop: 0 1 6

# Short-Description: OctoPrint2 daemon

# Description: Starts the OctoPrint2 daemon with the user specified in

# /etc/default/octoprint2.

### END INIT INFO

# Author: Sami Olmari

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

DESC='OctoPrint2 Daemon'

NAME='OctoPrint2'

DAEMON=/usr/bin/octoprint

PIDFILE=/var/run/$NAME.pid

PKGNAME=octoprint2

SCRIPTNAME=/etc/init.d/$PKGNAME
Перезапускаем демона
sudo systemctl daemon-reload
Чтобы все автоматически запускалось обновляем rc.d
sudo update-rc.d octoprint2 defaults
Запускаем новый экземпляр Octoprint
sudo /etc/init.d/octoprint2 start
Проверяем был ли успешно добавлен сервис
systemctl status octoprint2.service
Все должно работать как надо статус должен быть Active. (Для выхода жмем Ctrl+C)

После данных манипуляций у нас будет два сервиса Octoprint работающих на портах 5000 и 5001 к которым можно обратиться по IP адресу в моем случае

http://192.168.1.5:5000/

http://192.168.1.5:5001/

и в каждом выбрав для работы соответствующий порт

Для более удобного обращения к принтерам я рекомендую настроить HaProxy

В этом случае можно будет обращаться не по портам а по именам каталогов к соотвеnствующему экземпляру Octoprint

Например сделаем два экземпляра для наших принтеров с обращением

http://192.168.1.5/prusa/

http://192.168.1.5/bighbot/

Остановим службу haproxy
sudo /etc/init.d/haproxy stop
На всякий случай сделаем резервную копию конфига haproxy
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.old
Поправим конфиг
sudo nano /etc/haproxy/haproxy.cfg
нам нужно добавить в секцию конфига записи

в
frontend public
добавляем
use_backend bighbot if { path_beg /bighbot/ }

use_backend prusa if { path_beg /prusa/ }
и для каждого принтера свою секцию с описанием настроек
backend bighbot

reqrep ^([^ :]*) /bighbot/(.*) 1 /2

option forwardfor

server octoprint1 127.0.0.1:5000

acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

reqadd X-Scheme: https if needs_scheme { ssl_fc }

reqadd X-Scheme: http if needs_scheme !{ ssl_fc }

reqadd X-Script-Name: /bighbot

backend prusa

reqrep ^([^ :]*) /prusa/(.*) 1 /2

option forwardfor

server octoprint1 127.0.0.1:5001

acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

reqadd X-Scheme: https if needs_scheme { ssl_fc }

reqadd X-Scheme: http if needs_scheme !{ ssl_fc }

reqadd X-Script-Name: /prusa
должен получиться примерно такой конфиг
global

maxconn 4096

user haproxy

group haproxy

log 127.0.0.1 local1 debug

defaults

log global

mode http

option httplog

option dontlognull

retries 3

option redispatch

option http-server-close

option forwardfor

maxconn 2000

timeout connect 5s

timeout client 15min

timeout server 15min

frontend public

bind :::80 v4v6

bind :::443 v4v6 ssl crt /etc/ssl/snakeoil.pem

option forwardfor except 127.0.0.1

use_backend bighbot if { path_beg /bighbot/ }

use_backend prusa if { path_beg /prusa/ }

use_backend webcam if { path_beg /webcam/ }

default_backend webcam

backend bighbot

reqrep ^([^ :]*) /bighbot/(.*) 1 /2

option forwardfor

server octoprint1 127.0.0.1:5000

acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

reqadd X-Scheme: https if needs_scheme { ssl_fc }

reqadd X-Scheme: http if needs_scheme !{ ssl_fc }

reqadd X-Script-Name: /bighbot

backend prusa

reqrep ^([^ :]*) /prusa/(.*) 1 /2

option forwardfor

server octoprint1 127.0.0.1:5001

acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

reqadd X-Scheme: https if needs_scheme { ssl_fc }

reqadd X-Scheme: http if needs_scheme !{ ssl_fc }

reqadd X-Script-Name: /prusa

backend webcam

reqrep ^([^ :]*) /webcam/(.*) 1 /2

server webcam1 127.0.0.1:8080

errorfile 503 /etc/haproxy/errors/503-no-webcam.http
Сохраняем и запускаем
sudo /etc/init.d/haproxy stop
На этом настройка завершена и у нас доступны несколько именованных экземпляров Octorint
Всем желающим могу оперативно ответить на своей странице в ВКhttps://vk.com/kerbetosПри первоначальной настройке использовались материалы из статьи http://thomas-messmer.com/index.php/14-free-knowledge/howtos/79-setting-up-octoprint-for-multiple-printers

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых постах.

Отписаться от уведомлений вы всегда сможете в профиле автора.

27
Комментарии к статье

Комментарии

07.09.2018 в 08:14
0

Сказать что статья подкатила во время ни чего не сказать ) Только собирался заняться копирвоанием, а тут... ctrl+c ctrl+v ))) Большое спасибо.

07.09.2018 в 08:51
0

Для тех у кого в  /etc/init.d/octoprint2
# Author: Sami Olmari & Gina Häußge
Надо вручную определить демона:
DAEMON=/usr/bin/octoprint

Как пример:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          octoprint2
# Required-Start:    $local_fs networking
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: OctoPrint2 daemon
# Description:       Starts the OctoPrint daemon with the user specified in
#                    /etc/default/octoprint2.
### END INIT INFO
# Author: Sami Olmari & Gina Häußge
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC='OctoPrint2 Daemon'
NAME='OctoPrint2'
PKGNAME=octoprint2
PIDFILE=/var/run/$PKGNAME.pid
SCRIPTNAME=/etc/init.d/$PKGNAME
DEFAULTS=/etc/default/$PKGNAME
DAEMON=/usr/bin/octoprint
В мане ошибочка. Сохраняем и запускаем
sudo /etc/init.d/haproxy start

errorfile 503 /etc/haproxy/errors/503-no-webcam.http в /etc/haproxy/haproxy.cfg надо либо создать этот файлик, либо удалить эту строку. Второе - 443 порт в бинде. Его надо удалить, либо заиметь серт /etc/ssl/snakeoil.pem
Ну и все равно...
503 Service UnavailableNo server is available to handle this request.

07.09.2018 в 15:40
0

Пользуйте nginx ;) haproxy нужен определенный ответ от нижестоящего сервера, чтобы он мог на него направить траффик, не стоит оно этого геморроя.

07.09.2018 в 17:05
0

Пришли полный конфигурации хатпрокси

07.09.2018 в 12:06
0

Зачем городить целый haproxy для этого? Обычного nginx хватит с головой. И ссылки можно сделать просто http://prusa/

server {

    listen 80;
    server_name prusa;

    location / {
  proxy_pass http://localhost:5000/;
    }
}

07.09.2018 в 12:14
0

используем то что было в образе octoprint

07.09.2018 в 12:15
0

да и доступ по сети не нужно DNS прописывать

07.09.2018 в 12:38
0

А что, установить nginx разве нельзя? Просто haproxy для таких целей это из пушки по воробьям, не говоря уже о муторном конфиге. С nginx тоже не нужно, если охота каждый раз ип вбивать )

07.09.2018 в 12:44
0

поставить можно, но можете об этом отдельную статью написать

07.09.2018 в 12:48
0

На статью это не потянет. Две команды, примерный конфиг я уже написал выше.

https://www.raspberrypi.org/documentation/remote-access/web-server/nginx.md

07.09.2018 в 13:19
0

а при доступе с другого компа что с ДНС делать?

07.09.2018 в 14:03
1

Вариантов много:

Самый простой: оставить ссылку вида http://192.168.1.5/prusa

Правильный вариант: практически на всех современных домашних раутерах есть DHCP и DNS сервера, прописываем малине статический айпи по мак адресу и вешаем на него DNS имена всех принтеров.

Есть еще несколько, но они сложнее в реализации.

07.09.2018 в 14:32
0

это все танец с бубном, я использовал то что уже предустановлено в сборке Octoprint и что можно поправить пару строк в конфигах и этого подавляющему большенству пользователей достаточно. Если есть у пользователя знания в linux системах, то может настроить все что угодно, хоть на каждый принтер свой домен завести, это уже на любителя.
на малинке можно и иксы поставить с хромом и подключив к монитору пользоваться как обычным компом.
Цель статьи показать как просто запустить несколько экземпляров октопринта на одном хосте. 
мне это понадобилось когда перенес все принтера в отдельное помещение, и надоело бегать туда сюда с кучей флешек.
сейчас запустил октопринта на 4 принтера (usb разьемов всего 4) остальные чуть позже или к отдельной малинке прикручу или попробую поставить USB хаб. Печать запускаю из соседнего дома через инет и контролирую через камеру что там происходит

07.09.2018 в 15:36
0

Я понимаю, просто предлагаю другой вариант, потому что haproxy штука довольно сложная в настройке и отладке, и для таких вещей гораздо проще использовать nginx, как раз для этого предназначенный. Выше vasyna уже напоролся на грабли =)

07.09.2018 в 17:06
0

Чуть ниже также напоролся на nginx

07.09.2018 в 17:14
0

Вы видите разницу между вашим конфигом haproxy и моим конфигом nginx? И уж разобраться с nginx куда проще, чем с haproxy. Это я вам говорю, как системный администратор, работавший и с тем и с другим. Не говоря уже о том, что haproxy вообще не для этих задач придуман.

17.11.2019 в 03:39
0

Устройства потеряются если воткнуть в другой USB порт, но есть решения выкинуть все

    ATTRS{idVendor}=='{VendorID}',ATTRS{idProduct}=='{ProductID}

и сделать привязку к серийному номеру чипа

1 принтер

    SUBSYSTEM=="tty", ATTRS{serial}=="04FFF006AF291D295AA35837F50020C0", SYMLINK+="ttyACMsmail"

2 принтер

    SUBSYSTEM=="tty", ATTRS{serial}=="09003013AF2E94025B5159B2F50020C4", SYMLINK+="ttyACMbig"

после этого в какой либо порт USB вы не воткнули ваши принтеры они всегда привяжутся по серийнику правильно


20.11.2019 в 22:47
0

все верно, но не для китайских ардуин.

У ch340 нет поля serial и приходится мудрить так

07.09.2018 в 16:21
0

Давайте ман )

07.09.2018 в 16:28
1

Инструкция по установке nginx есть по ссылке выше, примерный конфиг еще выше.

Если не заморачиваться с днс, то будет выглядеть как-то так:

server {

listen 80;
server_name 192.168.1.5;

location /prusa {
proxy_pass [url]http://localhost:5000/;
}
}

Куда это вставить, зависит от расположения конфигов в распбиане. Обычно это где-то тут /etc/nginx/nginx.conf или /etc/nginx/conf.d/myserver.conf

07.09.2018 в 16:41
0

Ну взлетает сервис. не нравится конфиг.
точнее не конфиг

 nginx: [emerg] 'server' directive is not allowed here in /etc/nginx/nginx.conf:87
сен 07 16:39:37 sirota-MS-7865 nginx[32437]: nginx: configuration file /etc/nginx/nginx.conf test failed
сен 07 16:39:37 sirota-MS-7865 systemd[1]: nginx.service: Control process exited, code=exited status=1
сен 07 16:39:37 sirota-MS-7865 systemd[1]: nginx.service: Failed with result 'exit-code'.
сен 07 16:39:37 sirota-MS-7865 systemd[1]: Failed to start A high performance web server and a reverse proxy server.

что-то не то с правами. с понедельника почитаю.

07.09.2018 в 16:48
1

Это не с правами, это вы не туда вставили секцию. server должен быть внутри http секции.

07.09.2018 в 16:52
1

Понял. Переделал. результат ))

07.09.2018 в 16:55
0

А почему порт 4999? nginx должен слушать на 80, ссылка должна быть такая: http://192.168.0.224/tarantula

А конфиг

server {

listen 80;
server_name 192.168.0.224;

location /tarantula {
proxy_pass http://localhost:4999/;
}
}

Вы по ходу прямо на октопринт зашли )

07.09.2018 в 16:59
0

Да без разницы )

server {

                listen 80;
                server_name 192.168.0.224;

                location /kossel {
                        proxy_pass http://localhost:5000/;
                        }
        }

Все тоже самое. И почему должен? Он может любой слушать. Ну да не суть. Сделал 80, все равно.

07.09.2018 в 17:04
0

Ну вся идея в том, чтобы убрать номера портов из ссылки, чтобы меньше писать =) А если порт не указывать в ссылке, то подразумевается 80. Nginx принимает на 80 и проксирует на 4999. Так то можно вообще без nginx, просто на нужные порты ходить =)

07.09.2018 в 14:14
3

И, кстати, idVendor=='1a86' и idProduct=='7523' это не идентификаторы порта, а идентификаторы устройства. И делается это все для того, чтобы при вставке принтера в другой физический порт он все равно получил нужный файл устройства /dev/ttyЧтоТоТам. Это так, для общего развития =) И devpath лучше выкинуть оттуда по той же причине, что устройство может быть подключено в другой физический порт.

07.09.2018 в 14:24
0

да верно идентификаторы usb порта устройства

07.09.2018 в 16:09
0

Нет, это идентификатор самого устройства, а не порта. idVendor это идентификатор производителя, он одинаков для всех устройств этого производителя. idProduct это код продукта, то есть конкретной модели устройства. Например, если запустить lspci -nn, то можно увидеть эти идентификаторы и для pci/pci-e устройств (00:19.0 Ethernet controller [0200]: Intel Corporation Ethernet Connection I217-V [8086:153b] (rev 04))

07.09.2018 в 17:35
0

devpath получился по причине дешевых ардуин. CH34X не имеет на борту памяти и различить их никак нельзя. грусть-печаль

07.09.2018 в 17:38
0

Да, в этом случае придется запоминать в какой порт кого втыкать =) И, в принципе, вся эта настройка тогда не имеет особого смысла.

07.09.2018 в 17:48
0

смысл есть в любом случае, как правило один раз настроил и работает годами никто провода не переключает

07.09.2018 в 17:51
0

Ну если один раз настроил и работает, можно настроить сразу на конкретный файл устройства, а не городить именованные ссылки на каждый принтер )

07.09.2018 в 18:00
1

Вот тут вы пропустили в статье часть смыла

При подключении принтеров порты именуются как /dev/ttyUSB0, /dev/ttyUSB1 и так далее
Причем порты будут именоваться в порядке их подключения и не факт что после следующей загрузки принтер не поменяем имя порта. для этого мы выполним привязку порта и создадим именованные линки к ним
даем в консоли команду
т.е. даже просто перезагрузив малинку /dev/ttyUSB0 подключенный например к прюше после следующей перезагрузки оказывается подключенным к другому принтеру хотя он был на порту dev/ttyUSB1
я это неоднократно наблюдал во время подготовки Octoprint к написанию статьи.

07.09.2018 в 18:02
0

Ага, тогда да, смысл есть )

07.09.2018 в 18:06
0

А вот еще есть любопытный плагин, говорят, умеет несколько принтеров https://github.com/donovan6000/M33-Fio

07.09.2018 в 18:55
1

У меня ферма настроена практически так же, как описано у автора статьи. Единственное отличие - доступ к принтерам по имени с помощью mDNS, т. е. сервиса avahi (aka Bonjour, Zeroconf), который тоже установлен по умолчанию.

Но чтобы работать с несколькими принтерами надо дополнительно поставить программку avahi-aliases и запустить ее как сервис.
Если интересно, напишу за выходные подробнее. Вариант с nginx прикольный, но и haproxy вроде бы для этих целей несложно настраивается, тем более, что он уже стоит.

09.09.2018 в 00:12
1

Спасибо за информацию, нашел для себя много нового, хотя давно куцый пост писал ))
Вот еще небольшое дополнение по самому Octopirint
В настройках каждого инстанса(вкладки) лучше указать каталог 'Upload', например, самого первого Octoprinta, тогда если вы загружаете на малинку файлы, то их будут видеть все принтеры(после жмакания кнопки обновить в меню Files).
Ну и вот еще удобная прога для подключения сетевого диска SFTP Net Drive

Для написания комментариев, пожалуйста, авторизуйтесь.

Читайте в блогах

Sirius Hardlight - Принтер который вы искали

Печатаем гибкую, эластичную, мягкую деталь полимерником

КОМПАС-3D v18 Home. Основы 3D-проектирования. Часть 16.3. Создание игрушечного паровоза. Крыша и тележка паровоза

Boot or not to boot или ректальная реанимация MKS TFT32.

Контейнеры для филамента, которые я использую.

Спасение новогодней елки