Compare commits
13 Commits
59ed3a5726
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 34329e1550 | |||
| 25f2d354a9 | |||
| 1e7cd50df2 | |||
| 51ab8e0b10 | |||
| 7ebf9171cc | |||
| 02d184c7bf | |||
| 0d43916a83 | |||
| f29dc7c6ad | |||
| 2209c0e1f9 | |||
| a78afa3ec4 | |||
| 80d487b08d | |||
| d95eb40516 | |||
| 83e079c24e |
@@ -7,8 +7,5 @@ autocommit.sh
|
|||||||
moonraker-sql.db
|
moonraker-sql.db
|
||||||
moonraker-obico.cfg
|
moonraker-obico.cfg
|
||||||
moonraker-obico-update.cfg
|
moonraker-obico-update.cfg
|
||||||
KlipperScreen.conf
|
|
||||||
sonar.conf
|
|
||||||
moonraker.conf
|
|
||||||
telegram.conf
|
telegram.conf
|
||||||
.*.*.bkp
|
.*.*.bkp
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#
|
||||||
|
# MMU "Happy Hare edition" menus
|
||||||
|
#
|
||||||
|
[include mmu_klipperscreen.conf]
|
||||||
|
|
||||||
|
# To use this KlipperScreen panel, create a symlink:
|
||||||
|
# $MOONRAKER_OBICO_HOME/scripts/klipper_screen_obico_panel.py ->$KLIPPER_SCREEN_HOME/panels/obico.py
|
||||||
|
[menu __main more obico]
|
||||||
|
name: Obico
|
||||||
|
icon: network
|
||||||
|
panel: obico
|
||||||
|
|
||||||
|
#~# --- Do not edit below this line. This section is auto generated --- #~#
|
||||||
|
#~#
|
||||||
|
#~# [main]
|
||||||
|
#~# theme = colorized
|
||||||
|
#~# print_sort_dir = date_desc
|
||||||
|
#~# language = ru
|
||||||
|
#~#
|
||||||
|
#~# [graph Printer]
|
||||||
|
#~# extruder = False
|
||||||
|
#~#
|
||||||
+4
-5
@@ -41,14 +41,13 @@ no_proxy: false
|
|||||||
#v4l2ctl: # Add v4l2-ctl parameters to setup your camera, see Log what your cam is capable of.
|
#v4l2ctl: # Add v4l2-ctl parameters to setup your camera, see Log what your cam is capable of.
|
||||||
|
|
||||||
[cam head]
|
[cam head]
|
||||||
#mode: ustreamer
|
mode: ustreamer
|
||||||
mode: MJPG
|
|
||||||
port: 8080
|
port: 8080
|
||||||
#device: /dev/v4l/by-path/platform-5101000.usb-usb-0:1.1:1.0-video-index0
|
#device: /dev/v4l/by-path/platform-5101000.usb-usb-0:1.1:1.0-video-index0
|
||||||
device: /dev/v4l/by-id/usb-DSJ_UC60_Video_200901010001-video-index0
|
device: /dev/v4l/by-id/usb-DSJ_UC60_Video_200901010001-video-index0
|
||||||
resolution: 1280x960 #176x144, 320x240, 352x288, 640x480, 640x360, 640x400, 800x600, 1024x768, 1280x720, 1280x960, 1600x1200, 1920x1080, 2048x1536, 2560x1440, 2592x1944
|
resolution: 1600x1200 #176x144, 320x240, 352x288, 640x480, 640x360, 640x400, 800x600, 1024x768, 1280x720, 1280x960, 1600x1200, 1920x1080, 2048x1536, 2560x1440, 2592x1944
|
||||||
max_fps: 15
|
max_fps: 30
|
||||||
v4l2ctl: focus_auto=0 #brightness=-10, backlight_compensation=0
|
v4l2ctl: focus_automatic_continuous=0 #brightness=-10, backlight_compensation=0
|
||||||
|
|
||||||
#[cam bed_cam]
|
#[cam bed_cam]
|
||||||
#mode: ustreamer
|
#mode: ustreamer
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# CONFIG_LOW_LEVEL_OPTIONS is not set
|
||||||
|
# CONFIG_MACH_AVR is not set
|
||||||
|
# CONFIG_MACH_ATSAM is not set
|
||||||
|
# CONFIG_MACH_ATSAMD is not set
|
||||||
|
# CONFIG_MACH_LPC176X is not set
|
||||||
|
# CONFIG_MACH_STM32 is not set
|
||||||
|
# CONFIG_MACH_HC32F460 is not set
|
||||||
|
# CONFIG_MACH_RPXXXX is not set
|
||||||
|
# CONFIG_MACH_PRU is not set
|
||||||
|
# CONFIG_MACH_AR100 is not set
|
||||||
|
CONFIG_MACH_LINUX=y
|
||||||
|
# CONFIG_MACH_SIMU is not set
|
||||||
|
CONFIG_BOARD_DIRECTORY="linux"
|
||||||
|
CONFIG_CLOCK_FREQ=50000000
|
||||||
|
CONFIG_LINUX_SELECT=y
|
||||||
|
CONFIG_USB_VENDOR_ID=0x1d50
|
||||||
|
CONFIG_USB_DEVICE_ID=0x614e
|
||||||
|
CONFIG_USB_SERIAL_NUMBER="12345"
|
||||||
|
CONFIG_WANT_ADC=y
|
||||||
|
CONFIG_WANT_SPI=y
|
||||||
|
CONFIG_WANT_SOFTWARE_SPI=y
|
||||||
|
CONFIG_WANT_I2C=y
|
||||||
|
CONFIG_WANT_SOFTWARE_I2C=y
|
||||||
|
CONFIG_WANT_HARD_PWM=y
|
||||||
|
CONFIG_WANT_BUTTONS=y
|
||||||
|
CONFIG_WANT_TMCUART=y
|
||||||
|
CONFIG_WANT_NEOPIXEL=y
|
||||||
|
CONFIG_WANT_PULSE_COUNTER=y
|
||||||
|
CONFIG_WANT_ST7920=y
|
||||||
|
CONFIG_WANT_HD44780=y
|
||||||
|
CONFIG_WANT_ADXL345=y
|
||||||
|
CONFIG_WANT_LIS2DW=y
|
||||||
|
CONFIG_WANT_BMI160=y
|
||||||
|
CONFIG_WANT_MPU9250=y
|
||||||
|
CONFIG_WANT_ICM20948=y
|
||||||
|
CONFIG_WANT_THERMOCOUPLE=y
|
||||||
|
CONFIG_WANT_HX71X=y
|
||||||
|
CONFIG_WANT_ADS1220=y
|
||||||
|
CONFIG_WANT_LDC1612=y
|
||||||
|
CONFIG_WANT_SENSOR_ANGLE=y
|
||||||
|
CONFIG_NEED_SENSOR_BULK=y
|
||||||
|
CONFIG_WANT_TRIGGER_ANALOG=y
|
||||||
|
CONFIG_NEED_SOS_FILTER=y
|
||||||
|
CONFIG_CANBUS_FREQUENCY=1000000
|
||||||
|
CONFIG_INLINE_STEPPER_HACK=y
|
||||||
|
CONFIG_HAVE_GPIO=y
|
||||||
|
CONFIG_HAVE_GPIO_ADC=y
|
||||||
|
CONFIG_HAVE_GPIO_SPI=y
|
||||||
|
CONFIG_HAVE_GPIO_I2C=y
|
||||||
|
CONFIG_HAVE_GPIO_HARD_PWM=y
|
||||||
+309
-41
@@ -1,52 +1,320 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
# Сборка и прошивка Klipper на всех MCU принтера leo-voron:
|
||||||
#Полезные комманды
|
# host — linux-процесс klipper_mcu на CB2 (/usr/local/bin/klipper_mcu, сервис klipper-mcu)
|
||||||
#make menuconfig KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/config.manta723.CAN
|
# mcu — Octopus Pro 1.1 (stm32h723, USB-CAN bridge; прошивается по USB через katapult)
|
||||||
#make flash FLASH_DEVICE=0483:df11
|
# toolhead — EBB SB2209 (rp2040; прошивается по CAN через katapult)
|
||||||
#python3 flash_can.py -i can0 -u 6c3c86ee0b29 -f ~/firmware/octopus_klipper.bin
|
#
|
||||||
#python3 ~/katapult/scripts/flashtool.py -i can0 -q
|
# Использование:
|
||||||
#make flash FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_rp2040_45474E621A87A43A-if00 KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/hbb.cfg
|
# update_fw.sh [-h] [--build-only|--no-build] [--force] [host|mcu|toolhead ...]
|
||||||
|
# без целей — все три
|
||||||
#Toolheads
|
# --build-only — только собрать прошивки в ~/firmware, ничего не прошивать
|
||||||
|
# --no-build — не собирать, прошить уже собранные ~/firmware/<цель>_klipper.{bin,elf}
|
||||||
|
# --force — не останавливаться, если Moonraker недоступен для проверки печати
|
||||||
|
#
|
||||||
|
# Исходники Klipper НЕ обновляются (это делает Moonraker Update Manager).
|
||||||
|
# Скрипт интерактивный: пароль sudo спрашивается один раз в начале.
|
||||||
|
#
|
||||||
|
# Полезные команды:
|
||||||
|
# make menuconfig KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/octopus-pro.config
|
||||||
|
# make flash FLASH_DEVICE=0483:df11 # stm32 в DFU
|
||||||
|
# python3 ~/katapult/scripts/flashtool.py -i can0 -q # список узлов на CAN
|
||||||
|
# python3 ~/katapult/scripts/flashtool.py -i can0 -u <uuid> -r # запрос бутлоадера
|
||||||
|
# make flash FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_rp2040_45474E621A87A43A-if00 KCONFIG_CONFIG=.../hbb.cfg
|
||||||
|
#
|
||||||
|
# Старые тулхеды (UUID):
|
||||||
# rp_sb2209 = 350f10596216
|
# rp_sb2209 = 350f10596216
|
||||||
# sht36_v2 = 8ce295109ef0
|
# sht36_v2 = 8ce295109ef0
|
||||||
|
|
||||||
toolhead_name=ebb_rp2240
|
set -Eeuo pipefail
|
||||||
toolhead_uuid=d7e70bd38059
|
|
||||||
mcu_uuid=afcf80281237
|
|
||||||
mcu_path=/dev/serial/by-id/usb-katapult_stm32h723xx_320006001751313431393536-if00
|
|
||||||
config_path=/home/biqu/printer_data/config/firmware/
|
|
||||||
|
|
||||||
mkdir -p ~/firmware
|
# ---------- Константы ----------
|
||||||
|
MOONRAKER="http://127.0.0.1:7125"
|
||||||
|
KLIPPER="$HOME/klipper"
|
||||||
|
KATAPULT="$HOME/katapult/scripts/flashtool.py"
|
||||||
|
CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
OUT_DIR="$HOME/firmware"
|
||||||
|
KLIPPY_LOG="$HOME/printer_data/logs/klippy.log"
|
||||||
|
CAN_IF="can0"
|
||||||
|
JOBS=4
|
||||||
|
|
||||||
sudo service klipper stop
|
MCU_UUID="afcf80281237"
|
||||||
|
MCU_CFG="octopus-pro.config"
|
||||||
|
KATAPULT_SERIAL_GLOB='/dev/serial/by-id/usb-katapult_stm32h723xx_*'
|
||||||
|
|
||||||
cd ~/klipper
|
TOOLHEAD_UUID="d7e70bd38059"
|
||||||
make clean
|
TOOLHEAD_CFG="ebb_rp2240.CAN"
|
||||||
make -j4 KCONFIG_CONFIG="${config_path}octopus-pro.config"
|
|
||||||
mv ~/klipper/out/klipper.bin ~/firmware/octopus_klipper.bin
|
|
||||||
|
|
||||||
make clean
|
HOST_CFG="host_linux.config"
|
||||||
toolhead_config="${config_path}/${toolhead_name}.CAN"
|
HOST_BIN="/usr/local/bin/klipper_mcu"
|
||||||
make -j4 KCONFIG_CONFIG=$toolhead_config
|
|
||||||
mv ~/klipper/out/klipper.bin ~/firmware/toolhead_klipper.bin
|
|
||||||
|
|
||||||
cd ~/katapult/scripts
|
ALL_TARGETS=(host mcu toolhead)
|
||||||
# Update MCU Octopus Pro
|
|
||||||
echo "Start update MCU Octopus Pro"
|
|
||||||
python3 ~/katapult/scripts/flashtool.py -i can0 -u $mcu_uuid -r
|
|
||||||
python3 flash_can.py -f ~/firmware/octopus_klipper.bin -d $mcu_path
|
|
||||||
sleep 2
|
|
||||||
#read -p "MCU Manta M5P firmware flashed, please check above for any errors. Press [Enter] to continue, or [Ctrl+C] to abort"
|
|
||||||
#echo "Finish update MCU octopus"
|
|
||||||
|
|
||||||
# Update Toolhead MCU
|
# ---------- Разбор аргументов ----------
|
||||||
echo "Start update Toolhead MCU"
|
BUILD_ONLY=0
|
||||||
python3 flash_can.py -i can0 -u $toolhead_uuid -f ~/firmware/toolhead_klipper.bin
|
NO_BUILD=0
|
||||||
sleep 2
|
FORCE=0
|
||||||
#read -p "MCU EBB36 firmware flashed, please check above for any errors. Press [Enter] to continue, or [Ctrl+C] to abort"
|
TARGETS=()
|
||||||
#echo "Finish update MCU EBB36"
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
-h|--help) sed -n '2,16p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||||
|
--build-only) BUILD_ONLY=1 ;;
|
||||||
|
--no-build) NO_BUILD=1 ;;
|
||||||
|
--force) FORCE=1 ;;
|
||||||
|
host|mcu|toolhead) TARGETS+=("$arg") ;;
|
||||||
|
*) echo "Неизвестный аргумент: $arg (см. -h)" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
[ ${#TARGETS[@]} -eq 0 ] && TARGETS=("${ALL_TARGETS[@]}")
|
||||||
|
[ "$BUILD_ONLY" = 1 ] && [ "$NO_BUILD" = 1 ] && { echo "--build-only и --no-build несовместимы" >&2; exit 2; }
|
||||||
|
want() { local t; for t in "${TARGETS[@]}"; do [ "$t" = "$1" ] && return 0; done; return 1; }
|
||||||
|
|
||||||
python3 ~/katapult/scripts/flashtool.py -i can0 -q
|
# ---------- Лог и трапы ----------
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
LOG="$OUT_DIR/update_fw-$(date +%Y%m%d-%H%M).log"
|
||||||
|
exec > >(trap '' INT; exec tee -a "$LOG") 2>&1
|
||||||
|
START_TS=$(date +%s)
|
||||||
|
STAGE="инициализация"
|
||||||
|
KLIPPER_STOPPED=0
|
||||||
|
|
||||||
sudo service klipper start
|
on_err() {
|
||||||
|
echo
|
||||||
|
echo "!!! ОШИБКА на этапе: $STAGE (лог: $LOG)" >&2
|
||||||
|
}
|
||||||
|
on_exit() {
|
||||||
|
local rc=$?
|
||||||
|
rm -rf "${BUILD_TMP:-}"
|
||||||
|
if [ "$KLIPPER_STOPPED" = 1 ]; then
|
||||||
|
echo; echo "=== Запуск klipper ==="
|
||||||
|
sudo systemctl start klipper || echo "!!! Не удалось запустить klipper — запустите вручную: sudo systemctl start klipper" >&2
|
||||||
|
fi
|
||||||
|
[ $rc -ne 0 ] && echo "Завершено с ошибкой (код $rc)."
|
||||||
|
exit $rc
|
||||||
|
}
|
||||||
|
trap on_err ERR
|
||||||
|
trap on_exit EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
|
||||||
|
section() { echo; echo "=== $* ==="; }
|
||||||
|
die() { echo "!!! [$STAGE] $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
# Ждать, пока команда-условие не вернёт 0 (таймаут в секундах)
|
||||||
|
wait_for() {
|
||||||
|
local timeout=$1 msg=$2; shift 2
|
||||||
|
local deadline=$((SECONDS + timeout))
|
||||||
|
while [ "$SECONDS" -lt "$deadline" ]; do
|
||||||
|
if "$@" >/dev/null 2>&1; then return 0; fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "!!! Таймаут ($timeout с): $msg" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
# Klipper отвечает на запрос UUID только пока ему не назначен node id (canserial.c),
|
||||||
|
# поэтому -q годится лишь для узлов, только что перезагруженных после прошивки.
|
||||||
|
can_has_uuid() { local out; out=$(python3 "$KATAPULT" -i "$CAN_IF" -q 2>/dev/null) || return 1; grep -q "$1" <<< "$out"; }
|
||||||
|
katapult_serial() { local d; for d in $KATAPULT_SERIAL_GLOB; do [ -e "$d" ] && { echo "$d"; return 0; }; done; return 1; }
|
||||||
|
klippy_state() { curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.state // empty' 2>/dev/null; }
|
||||||
|
klippy_ready() { [ "$(klippy_state)" = "ready" ]; }
|
||||||
|
mcu_versions() {
|
||||||
|
curl -s --max-time 5 "$MOONRAKER/printer/objects/query?mcu&mcu%20EBBCan&mcu%20host" \
|
||||||
|
| jq -r '.result.status | to_entries[] | "\(.key)\t\(.value.mcu_version // "?")\t\(.value.mcu_constants.MCU // "?")"' 2>/dev/null \
|
||||||
|
|| echo "недоступно"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------- Preflight ----------
|
||||||
|
STAGE="предварительные проверки"
|
||||||
|
section "Preflight"
|
||||||
|
echo "Цели: ${TARGETS[*]} build-only=$BUILD_ONLY no-build=$NO_BUILD лог: $LOG"
|
||||||
|
|
||||||
|
[ -d "$KLIPPER" ] || die "Нет исходников Klipper: $KLIPPER"
|
||||||
|
[ -f "$KATAPULT" ] || die "Нет katapult flashtool: $KATAPULT"
|
||||||
|
want host && { [ -f "$CONFIG_DIR/$HOST_CFG" ] || die "Нет конфига $CONFIG_DIR/$HOST_CFG"; }
|
||||||
|
want mcu && { [ -f "$CONFIG_DIR/$MCU_CFG" ] || die "Нет конфига $CONFIG_DIR/$MCU_CFG"; }
|
||||||
|
want toolhead && { [ -f "$CONFIG_DIR/$TOOLHEAD_CFG" ] || die "Нет конфига $CONFIG_DIR/$TOOLHEAD_CFG"; }
|
||||||
|
|
||||||
|
KLIPPER_VER=$(git -C "$KLIPPER" describe --always --tags --long --dirty 2>/dev/null || echo unknown)
|
||||||
|
echo "Klipper в $KLIPPER: $KLIPPER_VER"
|
||||||
|
|
||||||
|
# Артефакт цели: ~/firmware/<цель>_klipper.<bin|elf> (симлинк на <цель>-<версия>.<ext>)
|
||||||
|
artifact() { case "$1" in host) echo "$OUT_DIR/host_klipper.elf" ;; *) echo "$OUT_DIR/$1_klipper.bin" ;; esac; }
|
||||||
|
|
||||||
|
if [ "$NO_BUILD" = 1 ]; then
|
||||||
|
echo "Без сборки — используются готовые прошивки:"
|
||||||
|
for t in "${TARGETS[@]}"; do
|
||||||
|
f=$(artifact "$t")
|
||||||
|
[ -s "$f" ] || die "Нет готовой прошивки $f (соберите: $0 --build-only $t)"
|
||||||
|
real=$(readlink -f "$f")
|
||||||
|
echo " $t: $(basename "$real") ($(stat -c %s "$real") байт)"
|
||||||
|
case "$(basename "$real")" in
|
||||||
|
*"-${KLIPPER_VER}."*) ;;
|
||||||
|
*) echo " !!! $t: прошивка собрана не из текущего $KLIPPER_VER" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
BEFORE=""
|
||||||
|
if [ "$BUILD_ONLY" = 0 ]; then
|
||||||
|
if want mcu || want toolhead; then
|
||||||
|
ip -br link show "$CAN_IF" 2>/dev/null | grep -q " UP " || die "$CAN_IF не поднят"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Печать не должна идти
|
||||||
|
KSTATE=$(klippy_state || true)
|
||||||
|
PRINT_STATE=$(curl -s --max-time 5 "$MOONRAKER/printer/objects/query?print_stats" \
|
||||||
|
| jq -r '.result.status.print_stats.state // empty' 2>/dev/null || true)
|
||||||
|
if [ -z "$KSTATE" ]; then
|
||||||
|
if [ "$FORCE" = 1 ]; then
|
||||||
|
echo "Moonraker недоступен, проверка печати пропущена (--force)"
|
||||||
|
else
|
||||||
|
die "Moonraker недоступен — не могу проверить, идёт ли печать (--force чтобы пропустить)"
|
||||||
|
fi
|
||||||
|
elif [ -z "$PRINT_STATE" ]; then
|
||||||
|
echo "klippy в состоянии '$KSTATE' (не ready) — печать не идёт, продолжаю"
|
||||||
|
else
|
||||||
|
echo "print_stats.state = $PRINT_STATE"
|
||||||
|
case "$PRINT_STATE" in
|
||||||
|
printing|paused) die "Идёт печать ($PRINT_STATE) — прошивка отменена" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Версии MCU до обновления:"
|
||||||
|
BEFORE=$(mcu_versions); echo "$BEFORE" | sed 's/^/ /'
|
||||||
|
|
||||||
|
# Пароль sudo — один раз, до остановки сервисов
|
||||||
|
sudo -v || die "Нужны права sudo"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------- Сборка ----------
|
||||||
|
BUILD_TMP=$(mktemp -d)
|
||||||
|
build() { # build <цель> <конфиг> <артефакт: bin|elf>
|
||||||
|
local name=$1 ext=$3
|
||||||
|
STAGE="сборка $name"
|
||||||
|
section "Сборка $name ($2)"
|
||||||
|
# Собираем из копии: olddefconfig переписывает конфиг и создаёт <конфиг>.old,
|
||||||
|
# а файлы в репозитории должны оставаться нетронутыми
|
||||||
|
local cfg="$BUILD_TMP/$2"
|
||||||
|
cp "$CONFIG_DIR/$2" "$cfg"
|
||||||
|
make -C "$KLIPPER" clean KCONFIG_CONFIG="$cfg" >/dev/null
|
||||||
|
make -C "$KLIPPER" olddefconfig KCONFIG_CONFIG="$cfg"
|
||||||
|
make -C "$KLIPPER" -j"$JOBS" KCONFIG_CONFIG="$cfg"
|
||||||
|
local src="$KLIPPER/out/klipper.$ext"
|
||||||
|
[ -s "$src" ] || die "Сборка $name не дала $src"
|
||||||
|
local dst="$OUT_DIR/${name}-${KLIPPER_VER}.$ext"
|
||||||
|
cp "$src" "$dst"
|
||||||
|
ln -sfn "$(basename "$dst")" "$(artifact "$name")"
|
||||||
|
echo "-> $dst ($(stat -c %s "$dst") байт)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$NO_BUILD" = 0 ]; then
|
||||||
|
want mcu && build mcu "$MCU_CFG" bin
|
||||||
|
want toolhead && build toolhead "$TOOLHEAD_CFG" bin
|
||||||
|
want host && build host "$HOST_CFG" elf
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BUILD_ONLY" = 1 ]; then
|
||||||
|
section "Готово (только сборка)"
|
||||||
|
ls -l "$OUT_DIR"/*_klipper.* 2>/dev/null
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------- Прошивка ----------
|
||||||
|
STAGE="остановка klipper"
|
||||||
|
section "Остановка klipper"
|
||||||
|
sudo systemctl stop klipper
|
||||||
|
KLIPPER_STOPPED=1
|
||||||
|
|
||||||
|
if want host; then
|
||||||
|
STAGE="прошивка host MCU"
|
||||||
|
section "Прошивка host (klipper-mcu)"
|
||||||
|
# flash-linux.sh <dir> копирует <dir>/klipper.elf в /usr/local/bin/klipper_mcu и перезапускает klipper-mcu.
|
||||||
|
# Подсовываем ему каталог с артефактом из ~/firmware, а не out/ (там может быть сборка другой цели)
|
||||||
|
mkdir -p "$BUILD_TMP/host"
|
||||||
|
cp "$(artifact host)" "$BUILD_TMP/host/klipper.elf"
|
||||||
|
HOST_PID_OLD=$(systemctl show -p ExecMainPID --value klipper-mcu)
|
||||||
|
sudo "$KLIPPER/scripts/flash-linux.sh" "$BUILD_TMP/host"
|
||||||
|
[ "$(stat -c %Y "$HOST_BIN")" -ge "$START_TS" ] || die "$HOST_BIN не обновился"
|
||||||
|
host_restarted() {
|
||||||
|
[ "$(systemctl show -p ExecMainPID --value klipper-mcu)" != "$HOST_PID_OLD" ] \
|
||||||
|
&& [ "$(systemctl show -p SubState --value klipper-mcu)" = "running" ] && [ -e /tmp/klipper_host_mcu ]
|
||||||
|
}
|
||||||
|
if ! wait_for 10 "klipper-mcu не перезапустился (PID $HOST_PID_OLD)" host_restarted; then
|
||||||
|
journalctl -u klipper-mcu -n 8 --no-pager -o cat || true
|
||||||
|
die "klipper-mcu не работает после прошивки (см. journalctl -u klipper-mcu)"
|
||||||
|
fi
|
||||||
|
# Убедиться, что процесс не падает в цикле перезапуска (Restart=always)
|
||||||
|
sleep 3
|
||||||
|
[ "$(systemctl show -p SubState --value klipper-mcu)" = "running" ] \
|
||||||
|
|| { journalctl -u klipper-mcu -n 8 --no-pager -o cat || true; die "klipper-mcu перезапускается в цикле"; }
|
||||||
|
echo "klipper-mcu перезапущен (PID $HOST_PID_OLD -> $(systemctl show -p ExecMainPID --value klipper-mcu)), $HOST_BIN обновлён"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if want mcu; then
|
||||||
|
STAGE="прошивка Octopus Pro"
|
||||||
|
section "Прошивка mcu (Octopus Pro, uuid $MCU_UUID)"
|
||||||
|
python3 "$KATAPULT" -i "$CAN_IF" -u "$MCU_UUID" -r
|
||||||
|
wait_for 20 "не появился katapult serial ($KATAPULT_SERIAL_GLOB). Проверьте USB или перезагрузите плату" katapult_serial
|
||||||
|
DEV=$(katapult_serial)
|
||||||
|
echo "katapult serial: $DEV"
|
||||||
|
sleep 1 # порт может быть ещё не готов сразу после появления симлинка
|
||||||
|
python3 "$KATAPULT" -d "$DEV" -f "$(artifact mcu)"
|
||||||
|
# После прошивки плата перезагружается в Klipper и снова поднимает USB-CAN мост
|
||||||
|
wait_for 30 "Octopus не вернулся на $CAN_IF после прошивки" can_has_uuid "$MCU_UUID"
|
||||||
|
echo "Octopus снова на $CAN_IF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if want toolhead; then
|
||||||
|
STAGE="прошивка тулхеда"
|
||||||
|
section "Прошивка toolhead (EBB SB2209, uuid $TOOLHEAD_UUID)"
|
||||||
|
# flashtool сам отправляет запрос бутлоадера по UUID и заливает прошивку
|
||||||
|
python3 "$KATAPULT" -i "$CAN_IF" -u "$TOOLHEAD_UUID" -f "$(artifact toolhead)"
|
||||||
|
wait_for 30 "тулхед не вернулся на $CAN_IF после прошивки" can_has_uuid "$TOOLHEAD_UUID"
|
||||||
|
echo "Тулхед снова на $CAN_IF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Узлы на $CAN_IF"
|
||||||
|
python3 "$KATAPULT" -i "$CAN_IF" -q || true
|
||||||
|
|
||||||
|
# ---------- Запуск и проверка ----------
|
||||||
|
STAGE="запуск klipper"
|
||||||
|
section "Запуск klipper"
|
||||||
|
sudo systemctl start klipper
|
||||||
|
KLIPPER_STOPPED=0
|
||||||
|
|
||||||
|
STAGE="проверка после прошивки"
|
||||||
|
if wait_for 90 "klippy не перешёл в ready" klippy_ready; then
|
||||||
|
echo "klippy: ready"
|
||||||
|
else
|
||||||
|
echo "klippy state: $(klippy_state)"
|
||||||
|
curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.state_message // empty' 2>/dev/null || true
|
||||||
|
echo "--- хвост $KLIPPY_LOG ---"
|
||||||
|
tail -n 40 "$KLIPPY_LOG" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Версии"
|
||||||
|
KLIPPY_VER=$(curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.software_version // "?"' 2>/dev/null || echo "?")
|
||||||
|
echo "klippy (хост): $KLIPPY_VER"
|
||||||
|
# klippy считает untracked-файлы в klippy/extras (autotune, Happy-Hare) как -dirty, прошивки — нет
|
||||||
|
KLIPPY_VER=${KLIPPY_VER%-dirty}
|
||||||
|
AFTER=$(mcu_versions)
|
||||||
|
MISMATCH=0
|
||||||
|
if [ -z "$AFTER" ] || [ "$AFTER" = "недоступно" ]; then
|
||||||
|
echo "!!! Версии MCU недоступны (klippy не ready)"; MISMATCH=1
|
||||||
|
else
|
||||||
|
printf '%-12s %-32s %s\n' "MCU" "было" "стало"
|
||||||
|
while IFS=$'\t' read -r name ver _; do
|
||||||
|
old=$(printf '%s\n' "$BEFORE" | awk -F'\t' -v n="$name" '$1==n{print $2}')
|
||||||
|
printf '%-12s %-32s %s\n' "$name" "${old:-?}" "$ver"
|
||||||
|
[ "$ver" = "$KLIPPY_VER" ] || { echo "!!! $name: версия $ver != klippy $KLIPPY_VER"; MISMATCH=1; }
|
||||||
|
done <<< "$AFTER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Только строки после последнего старта klippy, чтобы не ловить старые ошибки
|
||||||
|
if tac "$KLIPPY_LOG" 2>/dev/null | sed '/^Start printer at/q' | grep -E "Command format mismatch|Protocol error|Lost communication" | tail -5 | grep .; then
|
||||||
|
echo "!!! В klippy.log есть ошибки протокола (см. выше)"; MISMATCH=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$MISMATCH" = 0 ]; then
|
||||||
|
echo; echo "Готово: все MCU на $KLIPPY_VER. Дальше: QUAD_GANTRY_LEVEL и проверить TAP/z_offset."
|
||||||
|
else
|
||||||
|
echo; echo "Есть расхождения — проверьте вывод выше; при необходимости FIRMWARE_RESTART или повторить: $0 <цель>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|||||||
+112
@@ -0,0 +1,112 @@
|
|||||||
|
[server]
|
||||||
|
host: 0.0.0.0
|
||||||
|
port: 7125
|
||||||
|
klippy_uds_address: /home/biqu/printer_data/comms/klippy.sock
|
||||||
|
|
||||||
|
[authorization]
|
||||||
|
trusted_clients:
|
||||||
|
192.168.0.0/16
|
||||||
|
10.0.0.0/8
|
||||||
|
127.0.0.0/8
|
||||||
|
169.254.0.0/16
|
||||||
|
172.16.0.0/12
|
||||||
|
192.168.0.0/16
|
||||||
|
FC00::/7
|
||||||
|
FE80::/10
|
||||||
|
::1/128
|
||||||
|
cors_domains:
|
||||||
|
*.lan
|
||||||
|
*.local
|
||||||
|
*://localhost
|
||||||
|
*://localhost:*
|
||||||
|
*://my.mainsail.xyz
|
||||||
|
*://app.fluidd.xyz
|
||||||
|
|
||||||
|
[octoprint_compat]
|
||||||
|
|
||||||
|
[history]
|
||||||
|
|
||||||
|
[file_manager]
|
||||||
|
enable_object_processing: True
|
||||||
|
|
||||||
|
[update_manager]
|
||||||
|
channel: dev
|
||||||
|
refresh_interval: 168
|
||||||
|
|
||||||
|
[timelapse]
|
||||||
|
|
||||||
|
[update_manager mainsail]
|
||||||
|
path: /home/biqu/mainsail
|
||||||
|
repo: mainsail-crew/mainsail
|
||||||
|
channel: stable
|
||||||
|
type: web
|
||||||
|
|
||||||
|
[update_manager mainsail-config]
|
||||||
|
managed_services: klipper
|
||||||
|
origin: https://github.com/mainsail-crew/mainsail-config.git
|
||||||
|
path: /home/biqu/mainsail-config
|
||||||
|
primary_branch: master
|
||||||
|
type: git_repo
|
||||||
|
|
||||||
|
[update_manager KlipperScreen]
|
||||||
|
install_script: /home/biqu/KlipperScreen/scripts/KlipperScreen-install.sh
|
||||||
|
requirements: /home/biqu/KlipperScreen/scripts/KlipperScreen-requirements.txt
|
||||||
|
virtualenv: /home/biqu/.KlipperScreen-env
|
||||||
|
managed_services: KlipperScreen
|
||||||
|
origin: https://github.com/moggieuk/KlipperScreen-Happy-Hare-Edition.git
|
||||||
|
path: /home/biqu/KlipperScreen
|
||||||
|
type: git_repo
|
||||||
|
|
||||||
|
# Crowsnest update_manager entry
|
||||||
|
[update_manager crowsnest]
|
||||||
|
type: git_repo
|
||||||
|
path: ~/crowsnest
|
||||||
|
origin: https://github.com/mainsail-crew/crowsnest.git
|
||||||
|
managed_services: crowsnest
|
||||||
|
install_script: tools/pkglist.sh
|
||||||
|
|
||||||
|
# Sonar update_manager entry
|
||||||
|
[update_manager sonar]
|
||||||
|
type: git_repo
|
||||||
|
path: ~/sonar
|
||||||
|
origin: https://github.com/mainsail-crew/sonar.git
|
||||||
|
primary_branch: main
|
||||||
|
managed_services: sonar
|
||||||
|
system_dependencies: resources/system-dependencies.json
|
||||||
|
|
||||||
|
[update_manager timelapse]
|
||||||
|
type: git_repo
|
||||||
|
primary_branch: main
|
||||||
|
path: ~/moonraker-timelapse
|
||||||
|
origin: https://github.com/mainsail-crew/moonraker-timelapse.git
|
||||||
|
managed_services: klipper moonraker
|
||||||
|
|
||||||
|
[update_manager Klipper-Adaptive-Meshing-Purging]
|
||||||
|
type: git_repo
|
||||||
|
channel: dev
|
||||||
|
path: ~/Klipper-Adaptive-Meshing-Purging
|
||||||
|
origin: https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging.git
|
||||||
|
managed_services: klipper
|
||||||
|
primary_branch: main
|
||||||
|
|
||||||
|
[update_manager klipper_tmc_autotune]
|
||||||
|
type: git_repo
|
||||||
|
channel: dev
|
||||||
|
path: ~/klipper_tmc_autotune
|
||||||
|
origin: https://github.com/andrewmcgr/klipper_tmc_autotune.git
|
||||||
|
managed_services: klipper
|
||||||
|
primary_branch: main
|
||||||
|
install_script: install.sh
|
||||||
|
|
||||||
|
[update_manager happy-hare]
|
||||||
|
type: git_repo
|
||||||
|
path: ~/Happy-Hare
|
||||||
|
origin: https://github.com/moggieuk/Happy-Hare.git
|
||||||
|
primary_branch: main
|
||||||
|
managed_services: klipper
|
||||||
|
|
||||||
|
[mmu_server]
|
||||||
|
enable_file_preprocessor: True
|
||||||
|
enable_toolchange_next_pos: True
|
||||||
|
update_spoolman_location: True
|
||||||
|
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#### Sonar - A WiFi Keepalive daemon
|
||||||
|
####
|
||||||
|
#### Written by Stephan Wendel aka KwadFan <me@stephanwe.de>
|
||||||
|
#### Copyright 2022
|
||||||
|
#### https://github.com/mainsail-crew/sonar
|
||||||
|
####
|
||||||
|
#### This File is distributed under GPLv3
|
||||||
|
####
|
||||||
|
|
||||||
|
[sonar]
|
||||||
|
enable: false # false to disable till next reboot (will stop again if not set to true)
|
||||||
|
debug_log: false # if set to true, sonar will log every ping with triptime and date/time
|
||||||
|
persistent_log: false # If true logs in /var/log/sonar.log, false logs to systemd
|
||||||
|
target: auto # IP Address, URL or auto as ping target
|
||||||
|
count: 3 # How often should be pinged?
|
||||||
|
interval: 60 # Ping again after X seconds
|
||||||
|
restart_threshold: 10 # If failed, restart WiFi after X seconds
|
||||||
Reference in New Issue
Block a user