diff --git a/.github/workflows/fluidd_multiarch.yml b/.github/workflows/fluidd_multiarch.yml deleted file mode 100644 index 5490b21..0000000 --- a/.github/workflows/fluidd_multiarch.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Fluidd Multiarch Image CI - -on: - push: - branches: - - main - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Prepare - id: prep - run: | - DOCKER_IMAGE=${{ secrets.DOCKER_USERNAME }}/fluidd - VERSION=latest - SHORTREF=${GITHUB_SHA::8} - - # If this is git tag, use the tag name as a docker tag - if [[ $GITHUB_REF == refs/tags/* ]]; then - VERSION=${GITHUB_REF#refs/tags/v} - fi - TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:${SHORTREF}" - - # If the VERSION looks like a version number, assume that - # this is the most recent version of the image and also - # tag it 'latest'. - if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then - TAGS="$TAGS,${DOCKER_IMAGE}:latest" - fi - - # Set output parameters. - echo ::set-output name=tags::${TAGS} - echo ::set-output name=docker_image::${DOCKER_IMAGE} - - - name: Set up QEMU - uses: docker/setup-qemu-action@master - with: - platforms: all - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@master - - - name: Login to DockerHub - if: github.event_name != 'pull_request' - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Build - uses: docker/build-push-action@v2 - with: - builder: ${{ steps.buildx.outputs.name }} - context: frontend - file: frontend/Dockerfile - platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: true - tags: ${{ steps.prep.outputs.tags }} - build-args: | - FRONTEND_ZIP_URL=https://github.com/cadriel/fluidd/releases/latest/download/fluidd.zip diff --git a/.github/workflows/klipper_moonraker_multiarch.yml b/.github/workflows/klipper_moonraker_multiarch.yml index d4b2e9e..1ceb0e6 100644 --- a/.github/workflows/klipper_moonraker_multiarch.yml +++ b/.github/workflows/klipper_moonraker_multiarch.yml @@ -4,6 +4,8 @@ on: push: branches: - main + schedule: + - cron: '42 12 * * SUN' jobs: docker: diff --git a/.github/workflows/mainsail_multiarch.yml b/.github/workflows/mainsail_multiarch.yml index 35c9256..3c163ba 100644 --- a/.github/workflows/mainsail_multiarch.yml +++ b/.github/workflows/mainsail_multiarch.yml @@ -4,6 +4,8 @@ on: push: branches: - main + schedule: + - cron: '24 12 * * SUN' jobs: docker: diff --git a/README.md b/README.md index fdbd01e..1c57313 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -![Fluidd Multiarch Image CI](https://github.com/dimalo/klipper-web-control-docker/workflows/Fluidd%20Multiarch%20Image%20CI/badge.svg) ![Mainsail Multiarch Image CI](https://github.com/dimalo/klipper-web-control-docker/workflows/Mainsail%20Multiarch%20Image%20CI/badge.svg) ![Klipper Moonraker Multiarch Image CI](https://github.com/dimalo/klipper-web-control-docker/workflows/Klipper%20Moonraker%20Multiarch%20Image%20CI/badge.svg) # klipper-web-control-docker __Klipper with Moonraker shipped with Fluidd and/or Mainsail__ +- get your printer to the next level! - Docker Compose config and Dockerfiles provided! - Build with Github actions and deployed to https://hub.docker.com/u/dimalo - Docker multiarch builds with best practices @@ -27,7 +27,13 @@ __Klipper with Moonraker shipped with Fluidd and/or Mainsail__ Example for PrusaSlicer start gcode: - ```START_PRINT T_BED=[first_layer_bed_temperature] T_EXTRUDER=[first_layer_temperature]``` + ``` + ; Making sure PrusaSlicer doesn't inject heatup gcode... + M104 S0 + M190 S0 + ; Run START_PRINT macro + START_PRINT T_BED=[first_layer_bed_temperature] T_EXTRUDER=[first_layer_temperature] + ``` - several versions of pause/cancel/end, to either present the toolhead or the print (and get the toolhead out of the way) - ___check the defaults!___ @@ -36,6 +42,7 @@ __Klipper with Moonraker shipped with Fluidd and/or Mainsail__ - support delay with display output with ```COUNTDOWN``` ___Please be careful to not run the macros without making sure they work with your printer!___ +- collection of calibration macros (for example manual bed leveling) [see calibration_macros.cfg](./config/calibration_macros.cfg) - complete Klipper setup with web control client - supports [Fluidd](https://github.com/cadriel/fluidd) - supports [Mainsail](https://github.com/meteyou/mainsail) @@ -58,7 +65,7 @@ ___Prerequisites:___ 1. modify docker-compose.yml to your needs - set serial port of your printer - mount printer.cfg if already prepared (else you will be able to set it up later as well...) -1. run ```docker-compose up``` +1. run ```docker-compose pull && docker-compose up``` if you want to use the provided dockerhub images, else run ```docker-compose up``` to first build them on your host 1. watch the services being set up - make sure you have no port conflicts on 7125, 8010 and 8011 - make sure klipper and moonraker started @@ -91,10 +98,9 @@ Run ```docker-compose build``` After build run ```docker-compose up -d``` and see if it works. ## Features not implemented or not tested (yet) -- compiling klipper.bin for your printer -- setting up more than one klipper instance and connecting to all in the UI -- automatic updates for klipper/moonraker -- automatic updates for the frontend +- compiling klipper.bin for your printer (will need compile tools which bloat the image so this will likely not be implemented) +- automatic updates for klipper/moonraker (partly working as repos are getting updated but no dependency installs happen - update the container with ```docker-compose pull``` instead) +- automatic updates for the frontend (update the container with ```docker-compose pull``` instead) - CI pipeline to build images as upstream repos change ## Credits diff --git a/config/calibration_macros.cfg b/config/calibration_macros.cfg new file mode 100644 index 0000000..8e1fe72 --- /dev/null +++ b/config/calibration_macros.cfg @@ -0,0 +1,27 @@ +[gcode_macro down96] +gcode: + TESTZ Z=-0.96 + +[gcode_macro down24] +gcode: + TESTZ Z=-0.24 + +[gcode_macro down08] +gcode: + TESTZ Z=-0.08 + +[gcode_macro down04] +gcode: + TESTZ Z=-0.04 + +[gcode_macro down] +gcode: + TESTZ Z=- + +[gcode_macro up] +gcode: + TESTZ Z=+ + +[gcode_macro up04] +gcode: + TESTZ Z=0.04 diff --git a/config/client_macros.cfg b/config/client_macros.cfg index 028f418..f32b387 100755 --- a/config/client_macros.cfg +++ b/config/client_macros.cfg @@ -3,29 +3,34 @@ variable_parameter_T_BED: 60 variable_parameter_T_EXTRUDER: 215 gcode: - M117 Homing - # Use absolute coordinates + + M83 + # Use absolute coordinates but realative extrusions G90 G92 E0 ; reset extruder distance - # Reset the G-Code Z offset (adjust Z offset if needed) - SET_GCODE_OFFSET Z=0.0 - # Home the printer - G28 X Y - # Use the bed mesh - BED_MESH_PROFILE LOAD=default - M117 Waiting for temperature + M117 Preheating bed... # Start bed heating and continue M140 S{T_BED} {% if printer.heater_bed.temperature < params.T_BED|float*0.7 %} - M190 S{params.T_BED|float*0.7} # wait till 0.85 of bed temp is reached, then continue + M190 S{params.T_BED|float*0.7} # wait till 70% of target bed temp is reached, then continue {% endif %} - + + M117 Heating... + M140 S{T_BED} M109 S{T_EXTRUDER} M190 S{T_BED} + + M117 Homing... + G28 + + # Reset the G-Code Z offset (adjust Z offset if needed) + SET_GCODE_OFFSET Z=0.0 MOVE=1 + + # Use the bed mesh + BED_MESH_PROFILE LOAD=default - G28 Z # Prime line PRIME_LINE M117 Printing... @@ -33,12 +38,12 @@ gcode: [gcode_macro PRIME_LINE] gcode: M117 Priming the nozzle - G1 Z0.16 F240 - G1 X3 Y{ (range(1, 8) | random) * 0.6} F3000 - G1 X30 E6 F1200.0 ; intro line - G1 X95 Z0.32 E9 F1500.0 ; intro line + G1 Z0.2 F240 + G1 Y{ (range(0, 8) | random) * 0.64} F1200 ; Set random start Y between 0 and ~5mm + G1 X30 E6 F1200.0 ; pressure build up line + G1 X95 Z0.4 E9 F1500.0 ; intro line G1 Z2 F3000 ; Move Z Axis up little - G1 X100 Z0.2 F5000.0 ; Move over to prevent blob squish + G1 X100 Z0.2 F3000.0 ; Move over and stick remainings to the bed G92 E0 ; reset extruder distance [gcode_macro END_PRINT] @@ -60,9 +65,9 @@ gcode: [gcode_macro PAUSE] rename_existing: BASE_PAUSE -default_parameter_X: 5 #edit to your park position -default_parameter_Y: 5 #edit to your park position -default_parameter_Z: 10 #edit to your park position +default_parameter_X: 5 #edit to your pause position +default_parameter_Y: 5 #edit to your pause position +default_parameter_Z: 10 #edit to your pause position default_parameter_E: 5 #edit to your retract length gcode: SAVE_GCODE_STATE NAME=PAUSE_state @@ -74,10 +79,10 @@ gcode: G1 X{X} Y{Y} F6000 [gcode_macro CLEAR_PAUSE] -rename_existing: BASE_PAUSE -default_parameter_X: 5 #edit to your park position -default_parameter_Y: 205 #edit to your park position -default_parameter_Z: 10 #edit to your park position +rename_existing: BASE_CLEAR_PAUSE +default_parameter_X: 5 #edit to your clear pause position +default_parameter_Y: 205 #edit to your clear pause position +default_parameter_Z: 10 #edit to your clear pause position default_parameter_E: 5 #edit to your retract length gcode: SAVE_GCODE_STATE NAME=PAUSE_state @@ -106,6 +111,12 @@ gcode: SDCARD_RESET_FILE BASE_CANCEL_PRINT +[gcode_macro MAINTENANCE] +gcode: + SAVE_GCODE_STATE NAME=PAUSE_state + G1 X110 Y5 Z66.5 F600 + M84 + # Park toolhead [gcode_macro M125] gcode: @@ -117,7 +128,7 @@ gcode: G1 X25 Y0 F4000 # move to park position RESTORE_GCODE_STATE NAME=parking -# LOW_TEMP_CHECK checks if there is a setpoint for the extruder. Untested! +# LOW_TEMP_CHECK checks if there is a setpoint for the extruder. # - If this setpoint is reached, continue. # - If not, heat to setpoint. # - If no setpoint, heat to parameter T (default@200) @@ -137,8 +148,13 @@ gcode: {% endif %} -# load filament +# load filament alias [gcode_macro M701] +gcode: + LOAD_FILAMENT + +# load filament +[gcode_macro LOAD_FILAMENT] gcode: SAVE_GCODE_STATE NAME=loading_filament M117 Loading Filament @@ -150,19 +166,24 @@ gcode: G1 E25 F120 # some extra to prime the nozzle --> slower G92 E0.0 RESTORE_GCODE_STATE NAME=loading_filament - -# unload filament + + +# unload filament alias [gcode_macro M702] +gcode: + UNLOAD_FILAMENT + +# unload filament +[gcode_macro UNLOAD_FILAMENT] gcode: SAVE_GCODE_STATE NAME=unloading_filament - M125 # park M117 Unloading Filament LOW_TEMP_CHECK G91 # set relative G1 E8 F100 G1 E2 F300 G1 E-10 F1800 - G1 E-420 F1500 # the E is the length of the bowden tube (420mm) + 100 mm. + G1 E-420 F1500 # the E is the length of the bowden tube (420mm) G92 E0.0 RESTORE_GCODE_STATE NAME=unloading_filament @@ -171,24 +192,24 @@ gcode: gcode: M117 Filament Change SAVE_GCODE_STATE NAME=filament_change - PAUSE + BASE_PAUSE LOW_TEMP_CHECK G91 # relative G1 E-1 F300 # retract 1 M125 # park - M702 # unload + UNLOAD_FILAMENT # unload M117 New filament COUNTDOWN TIME=25 MSG="Switch" - M701 + LOAD_FILAMENT COUNTDOWN TIME=10 MSG="Clean" - RESUME + BASE_RESUME M117 Resuming RESTORE_GCODE_STATE NAME=filament_change M117 Printing.. [gcode_macro COUNTDOWN] -default_parameter_MSG: "Time: " +default_parameter_MSG: "Time:" default_parameter_TIME: 10 gcode: # countdown @@ -196,5 +217,5 @@ gcode: # dwell 1 second G4 P1000 # echo - M117 {params.MSG} {s}s + M117 {params.MSG} {s}sec {% endfor %} \ No newline at end of file diff --git a/config/klipper.cfg b/config/klipper.cfg index ccf695b..f50c06f 100644 --- a/config/klipper.cfg +++ b/config/klipper.cfg @@ -1,3 +1,4 @@ [include printer.cfg] [include client.cfg] [include client_macros.cfg] +[include calibration_macros.cfg] diff --git a/config/moonraker.conf b/config/moonraker.conf index 3fd2f5f..96f09a8 100755 --- a/config/moonraker.conf +++ b/config/moonraker.conf @@ -17,3 +17,5 @@ trusted_clients: 192.168.0.0/16 FE80::/10 ::1/128 + +[update_manager] diff --git a/docker-compose.yml b/docker-compose.yml index 612c2f6..9ba7019 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,26 +15,50 @@ services: restart: unless-stopped volumes: - gcode_files:/home/klippy/gcode_files + # be aware to create your own branch if you mount the config folder as it will be updated on the main branch + # that way you can merge upstream changes to your (developed) configs... + - ./config:/home/klippy/.config # - ./printer.cfg:/home/klippy/.config/printer.cfg # mount serial device - take care to grant sufficient permissions to the device: : # devices: # - /dev/ttyUSB0:/dev/ttyUSB0 - fluidd: - image: dimalo/fluidd + klipper_another_printer: + image: dimalo/klipper-moonraker build: - dockerfile: Dockerfile - context: frontend - args: - FRONTEND_ZIP_URL: https://github.com/cadriel/fluidd/releases/latest/download/fluidd.zip + dockerfile: ./klipper/Dockerfile + context: . + # args: + # DEVICE_GROUP: device + # DEVICE_GID: 987 + container_name: klipper_another_printer + ports: + - 7126:7125 + restart: unless-stopped + volumes: + - gcode_files:/home/klippy/gcode_files + # be aware to create your own branch if you mount the config folder as it will be updated on the main branch + # that way you can merge upstream changes to your (developed) configs... + - ./config_another_printer:/home/klippy/.config + # - ./another_printer.cfg:/home/klippy/.config/printer.cfg + + # mount serial device - take care to grant sufficient permissions to the device: : + # devices: + # - /dev/ttyACM0:/dev/ttyACM0 + + + fluidd: + image: cadriel/fluidd container_name: fluidd ports: - 8010:80 depends_on: - klipper + # - klipper_another_printer links: - klipper:klipper + # - klipper_another_printer:klipper_another_printer mainsail: image: dimalo/mainsail diff --git a/klipper/Dockerfile b/klipper/Dockerfile index ea20d39..6d2991e 100644 --- a/klipper/Dockerfile +++ b/klipper/Dockerfile @@ -1,4 +1,4 @@ -FROM python:buster as builder +FROM python:3.9-buster as builder ARG DEBIAN_FRONTEND=noninteractive @@ -34,13 +34,21 @@ RUN ${MOONRAKER_VENV_DIR}/bin/python -m pip install pip -U RUN ${MOONRAKER_VENV_DIR}/bin/pip install wheel gpiod RUN ${MOONRAKER_VENV_DIR}/bin/pip install -r moonraker/scripts/moonraker-requirements.txt -FROM python:slim-buster as image +FROM python:3.9-slim-buster as image ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get upgrade -y && \ - apt-get install git gcc locales supervisor -y && \ + apt-get install -y \ + git \ + gcc \ + locales \ + supervisor \ + libjpeg62-turbo \ + libtiff5 \ + gpiod \ + libopenjp2-7 && \ sed -i -e 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen && \ locale-gen && \ # Clean up @@ -61,19 +69,22 @@ ENV MOONRAKER_VENV_DIR=${HOME}/moonraker-env ARG DEVICE_GROUP=device ARG DEVICE_GID=987 -RUN useradd --user-group --no-log-init --shell /bin/false ${USER} && \ +RUN useradd --user-group --no-log-init --shell /bin/false -m -d ${HOME} ${USER} && \ groupadd -g ${DEVICE_GID} ${DEVICE_GROUP} && \ usermod -a -G ${DEVICE_GROUP} ${USER} && \ usermod -a -G tty ${USER} && \ usermod -a -G dialout ${USER} && \ mkdir -p /var/log/supervisor && \ - pip install --no-cache supervisord-dependent-startup + mkdir -p /var/log/klipper && chown ${USER}:${USER} /var/log/klipper && \ + pip install --no-cache supervisord-dependent-startup gpiod + +RUN mkdir -p /usr/lib/python3 && ln -s /usr/local/lib/python3.9/site-packages /usr/lib/python3/dist-packages USER ${USER} WORKDIR ${HOME} -RUN mkdir ${HOME}/gcode_files && \ - mkdir ${CONFIG_DIR} && \ +RUN mkdir -p ${HOME}/gcode_files && \ + mkdir -p ${CONFIG_DIR} && \ touch ${HOME}/.moonraker_api_key VOLUME ${HOME}/gcode_files VOLUME ${CONFIG_DIR} diff --git a/klipper/klipper.ini b/klipper/klipper.ini index b4e09e2..3a7257f 100644 --- a/klipper/klipper.ini +++ b/klipper/klipper.ini @@ -1,7 +1,7 @@ [program:klipper] user=klippy -command=/home/klippy/klippy-env/bin/python /home/klippy/klipper/klippy/klippy.py -a /tmp/klippy_uds /home/klippy/.config/klipper.cfg +command=/home/klippy/klippy-env/bin/python /home/klippy/klipper/klippy/klippy.py -a /tmp/klippy_uds -l /var/log/klipper/klipper.log /home/klippy/.config/klipper.cfg environment=USER=klippy,HOME=/home/klippy,PYTHONPATH=/home/klippy/klippy-env/lib/python2.7/site-packages stdout_logfile=/dev/fd/1 stdout_logfile_maxbytes = 0 diff --git a/klipper/moonraker.ini b/klipper/moonraker.ini index 6f60533..7ca77d9 100644 --- a/klipper/moonraker.ini +++ b/klipper/moonraker.ini @@ -1,6 +1,6 @@ [program:moonraker] user=klippy -command=/home/klippy/moonraker-env/bin/python /home/klippy/moonraker/moonraker/moonraker.py -c /home/klippy/.config/moonraker.conf +command=/home/klippy/moonraker-env/bin/python /home/klippy/moonraker/moonraker/moonraker.py -l /var/log/klipper/moonraker.log -c /home/klippy/.config/moonraker.conf environment=USER=klippy,HOME=/home/klippy,PYTHONPATH=/home/klippy/moonraker-env/lib/python3.7/site-packages stdout_logfile=/dev/fd/1 stdout_logfile_maxbytes = 0