diff --git a/config/services/klipper.service b/config/services/klipper.service new file mode 100644 index 0000000..8d92e95 --- /dev/null +++ b/config/services/klipper.service @@ -0,0 +1,19 @@ +[Unit] +Description=Klipper 3D Printer Firmware - PRINTERNAME +Documentation=https://www.klipper3d.org/ +After=network-online.target +Before=moonraker.service +Wants=udev.target + +[Install] +WantedBy=multi-user.target + +[Service] +Type=simple +User=pi +RemainAfterExit=yes +WorkingDirectory=/home/pi/PRINTERNAME/klipper +EnvironmentFile=/home/pi/PRINTERNAME/printer_data/systemd/klipper.env +ExecStart=/home/pi/PRINTERNAME/klippy-env/bin/python $KLIPPER_ARGS +Restart=always +RestartSec=10 diff --git a/config/services/moonraker.service b/config/services/moonraker.service new file mode 100644 index 0000000..8dea823 --- /dev/null +++ b/config/services/moonraker.service @@ -0,0 +1,18 @@ +# systemd service file for moonraker +[Unit] +Description=API Server for Klipper - PRINTERNAME +Requires=network-online.target +After=network-online.target + +[Install] +WantedBy=multi-user.target + +[Service] +Type=simple +User=pi +SupplementaryGroups=moonraker-admin +RemainAfterExit=yes +EnvironmentFile=/home/pi/PRINTERNAME/printer_data/systemd/moonraker.env +ExecStart=/home/pi/PRINTERNAME/moonraker-env/bin/python $MOONRAKER_ARGS +Restart=always +RestartSec=10 diff --git a/dirs/printer_data/config/mainsail.cfg b/dirs/printer_data/config/mainsail.cfg deleted file mode 100644 index a378963..0000000 --- a/dirs/printer_data/config/mainsail.cfg +++ /dev/null @@ -1,294 +0,0 @@ -## Client klipper macro definitions -## -## Copyright (C) 2022 Alex Zellner -## -## This file may be distributed under the terms of the GNU GPLv3 license -## -## !!! This file is read-only. Maybe the used editor indicates that. !!! -## -## Customization: -## 1) copy the gcode_macro _CLIENT_VARIABLE (see below) to your printer.cfg -## 2) remove the comment mark (#) from all lines -## 3) change any value in there to your needs -## -## Use the PAUSE macro direct in your M600: -## e.g. with a different park position front left and a minimal height of 50 -## [gcode_macro M600] -## description: Filament change -## gcode: PAUSE X=10 Y=10 Z_MIN=50 -## Z_MIN will park the toolhead at a minimum of 50 mm above to bed to make it easier for you to swap filament. -## -## Client variable macro for your printer.cfg -#[gcode_macro _CLIENT_VARIABLE] -#variable_use_custom_pos : False ; use custom park coordinates for x,y [True/False] -#variable_custom_park_x : 0.0 ; custom x position; value must be within your defined min and max of X -#variable_custom_park_y : 0.0 ; custom y position; value must be within your defined min and max of Y -#variable_custom_park_dz : 2.0 ; custom dz value; the value in mm to lift the nozzle when move to park position -#variable_retract : 1.0 ; the value to retract while PAUSE -#variable_cancel_retract : 5.0 ; the value to retract while CANCEL_PRINT -#variable_speed_retract : 35.0 ; retract speed in mm/s -#variable_unretract : 1.0 ; the value to unretract while RESUME -#variable_speed_unretract : 35.0 ; unretract speed in mm/s -#variable_speed_hop : 15.0 ; z move speed in mm/s -#variable_speed_move : 100.0 ; move speed in mm/s -#variable_park_at_cancel : False ; allow to move the toolhead to park while execute CANCEL_PRINT [True/False] -#variable_park_at_cancel_x : None ; different park position during CANCEL_PRINT [None/Position as Float]; park_at_cancel must be True -#variable_park_at_cancel_y : None ; different park position during CANCEL_PRINT [None/Position as Float]; park_at_cancel must be True -## !!! Caution [firmware_retraction] must be defined in the printer.cfg if you set use_fw_retract: True !!! -#variable_use_fw_retract : False ; use fw_retraction instead of the manual version [True/False] -#variable_idle_timeout : 0 ; time in sec until idle_timeout kicks in. Value 0 means that no value will be set or restored -#variable_runout_sensor : "" ; If a sensor is defined, it will be used to cancel the execution of RESUME in case no filament is detected. -## Specify the config name of the runout sensor e.g "filament_switch_sensor runout". Hint use the same as in your printer.cfg -## !!! Custom macros, please use with care and review the section of the corresponding macro. -## These macros are for simple operations like setting a status LED. Please make sure your macro does not interfere with the basic macro functions. -## Only single line commands are supported, please create a macro if you need more than one command. -#variable_user_pause_macro : "" ; Everything inside the "" will be executed after the klipper base pause (PAUSE_BASE) function -#variable_user_resume_macro: "" ; Everything inside the "" will be executed before the klipper base resume (RESUME_BASE) function -#variable_user_cancel_macro: "" ; Everything inside the "" will be executed before the klipper base cancel (CANCEL_PRINT_BASE) function -#gcode: - -[virtual_sdcard] -path: ~/taz/printer_data_taz/gcodes -on_error_gcode: CANCEL_PRINT - -[pause_resume] -#recover_velocity: 50. -# When capture/restore is enabled, the speed at which to return to -# the captured position (in mm/s). Default is 50.0 mm/s. - -[display_status] - -[respond] - -[gcode_macro CANCEL_PRINT] -description: Cancel the actual running print -rename_existing: CANCEL_PRINT_BASE -gcode: - ##### get user parameters or use default ##### - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set allow_park = client.park_at_cancel|default(false)|lower == 'true' %} - {% set retract = client.cancel_retract|default(5.0)|abs %} - ##### define park position ##### - {% set park_x = "" if (client.park_at_cancel_x|default(none) is none) - else "X=" ~ client.park_at_cancel_x %} - {% set park_y = "" if (client.park_at_cancel_y|default(none) is none) - else "Y=" ~ client.park_at_cancel_y %} - {% set custom_park = park_x|length > 0 or park_y|length > 0 %} - ##### end of definitions ##### - # restore idle_timeout time if needed - {% if printer['gcode_macro RESUME'].restore_idle_timeout > 0 %} - SET_IDLE_TIMEOUT TIMEOUT={printer['gcode_macro RESUME'].restore_idle_timeout} - {% endif %} - {% if (custom_park or not printer.pause_resume.is_paused) and allow_park %} _TOOLHEAD_PARK_PAUSE_CANCEL {park_x} {park_y} {% endif %} - _CLIENT_RETRACT LENGTH={retract} - TURN_OFF_HEATERS - M106 S0 - {client.user_cancel_macro|default("")} - SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False - # clear pause_next_layer and pause_at_layer as preparation for next print - SET_PAUSE_NEXT_LAYER ENABLE=0 - SET_PAUSE_AT_LAYER ENABLE=0 LAYER=0 - CANCEL_PRINT_BASE - -[gcode_macro PAUSE] -description: Pause the actual running print -rename_existing: PAUSE_BASE -gcode: - ##### get user parameters or use default ##### - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set idle_timeout = client.idle_timeout|default(0) %} - {% set temp = printer[printer.toolhead.extruder].target if printer.toolhead.extruder != '' else 0 %} - {% set restore = False if printer.toolhead.extruder == '' - else True if params.RESTORE|default(1)|int == 1 else False %} - ##### end of definitions ##### - SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder_temp VALUE="{{'restore': restore, 'temp': temp}}" - # set a new idle_timeout value - {% if idle_timeout > 0 %} - SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=restore_idle_timeout VALUE={printer.configfile.settings.idle_timeout.timeout} - SET_IDLE_TIMEOUT TIMEOUT={idle_timeout} - {% endif %} - PAUSE_BASE - {client.user_pause_macro|default("")} - _TOOLHEAD_PARK_PAUSE_CANCEL {rawparams} - -[gcode_macro RESUME] -description: Resume the actual running print -rename_existing: RESUME_BASE -variable_last_extruder_temp: {'restore': False, 'temp': 0} -variable_restore_idle_timeout: 0 -variable_idle_state: False -gcode: - ##### get user parameters or use default ##### - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} - {% set sp_move = client.speed_move|default(velocity) %} - {% set runout_resume = True if client.runout_sensor|default("") == "" # no runout - else True if not printer[client.runout_sensor].enabled # sensor is disabled - else printer[client.runout_sensor].filament_detected %} # sensor status - {% set can_extrude = True if printer.toolhead.extruder == '' # no extruder defined in config - else printer[printer.toolhead.extruder].can_extrude %} # status of active extruder - {% set do_resume = False %} - {% set prompt_txt = [] %} - ##### end of definitions ##### - #### Printer comming from timeout idle state #### - {% if printer.idle_timeout.state|upper == "IDLE" or idle_state %} - SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False - {% if last_extruder_temp.restore %} - # we need to use the unicode (\u00B0) for the ° as py2 env's would throw an error otherwise - RESPOND TYPE=echo MSG='{"Restoring \"%s\" temperature to %3.1f\u00B0C, this may take some time" % (printer.toolhead.extruder, last_extruder_temp.temp) }' - M109 S{last_extruder_temp.temp} - {% set do_resume = True %} - {% elif can_extrude %} - {% set do_resume = True %} - {% else %} - RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}' - {% set _d = prompt_txt.append("\"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder) %} - {% endif %} - #### Printer comming out of regular PAUSE state #### - {% elif can_extrude %} - {% set do_resume = True %} - {% else %} - RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}' - {% set _d = prompt_txt.append("\"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder) %} - {% endif %} - {% if runout_resume %} - {% if do_resume %} - {% if restore_idle_timeout > 0 %} SET_IDLE_TIMEOUT TIMEOUT={restore_idle_timeout} {% endif %} # restore idle_timeout time - {client.user_resume_macro|default("")} - _CLIENT_EXTRUDE - RESUME_BASE VELOCITY={params.VELOCITY|default(sp_move)} - {% endif %} - {% else %} - RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" detects no filament, please load filament and press RESUME" % (client.runout_sensor.split(" "))[1]}' - {% set _d = prompt_txt.append("\"%s\" detects no filament, please load filament and press RESUME" % (client.runout_sensor.split(" "))[1]) %} - {% endif %} - ##### Generate User Information box in case of abort ##### - {% if not (runout_resume and do_resume) %} - RESPOND TYPE=command MSG="action:prompt_begin RESUME aborted !!!" - {% for element in prompt_txt %} - RESPOND TYPE=command MSG='{"action:prompt_text %s" % element}' - {% endfor %} - RESPOND TYPE=command MSG="action:prompt_footer_button Ok|RESPOND TYPE=command MSG=action:prompt_end|info" - RESPOND TYPE=command MSG="action:prompt_show" - {% endif %} - -# Usage: SET_PAUSE_NEXT_LAYER [ENABLE=[0|1]] [MACRO=] -[gcode_macro SET_PAUSE_NEXT_LAYER] -description: Enable a pause if the next layer is reached -gcode: - {% set pause_next_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer %} - {% set ENABLE = params.ENABLE|default(1)|int != 0 %} - {% set MACRO = params.MACRO|default(pause_next_layer.call, True) %} - SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ 'enable': ENABLE, 'call': MACRO }}" - -# Usage: SET_PAUSE_AT_LAYER [ENABLE=[0|1]] [LAYER=] [MACRO=] -[gcode_macro SET_PAUSE_AT_LAYER] -description: Enable/disable a pause if a given layer number is reached -gcode: - {% set pause_at_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer %} - {% set ENABLE = params.ENABLE|int != 0 if params.ENABLE is defined - else params.LAYER is defined %} - {% set LAYER = params.LAYER|default(pause_at_layer.layer)|int %} - {% set MACRO = params.MACRO|default(pause_at_layer.call, True) %} - SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ 'enable': ENABLE, 'layer': LAYER, 'call': MACRO }}" - -# Usage: SET_PRINT_STATS_INFO [TOTAL_LAYER=] [CURRENT_LAYER= ] -[gcode_macro SET_PRINT_STATS_INFO] -rename_existing: SET_PRINT_STATS_INFO_BASE -description: Overwrite, to get pause_next_layer and pause_at_layer feature -variable_pause_next_layer: { 'enable': False, 'call': "PAUSE" } -variable_pause_at_layer : { 'enable': False, 'layer': 0, 'call': "PAUSE" } -gcode: - {% if pause_next_layer.enable %} - RESPOND TYPE=echo MSG='{"%s, forced by pause_next_layer" % pause_next_layer.call}' - {pause_next_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE - SET_PAUSE_NEXT_LAYER ENABLE=0 - {% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER|int == pause_at_layer.layer %} - RESPOND TYPE=echo MSG='{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}' - {pause_at_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE - SET_PAUSE_AT_LAYER ENABLE=0 - {% endif %} - SET_PRINT_STATS_INFO_BASE {rawparams} - -##### internal use ##### -[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL] -description: Helper: park toolhead used in PAUSE and CANCEL_PRINT -gcode: - ##### get user parameters or use default ##### - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} - {% set use_custom = client.use_custom_pos|default(false)|lower == 'true' %} - {% set custom_park_x = client.custom_park_x|default(0.0) %} - {% set custom_park_y = client.custom_park_y|default(0.0) %} - {% set park_dz = client.custom_park_dz|default(2.0)|abs %} - {% set sp_hop = client.speed_hop|default(15) * 60 %} - {% set sp_move = client.speed_move|default(velocity) * 60 %} - ##### get config and toolhead values ##### - {% set origin = printer.gcode_move.homing_origin %} - {% set act = printer.gcode_move.gcode_position %} - {% set max = printer.toolhead.axis_maximum %} - {% set cone = printer.toolhead.cone_start_z|default(max.z) %} ; height as long the toolhead can reach max and min of an delta - {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch'] - else False %} - ##### define park position ##### - {% set z_min = params.Z_MIN|default(0)|float %} - {% set z_park = [[(act.z + park_dz), z_min]|max, (max.z - origin.z)]|min %} - {% set x_park = params.X if params.X is defined - else custom_park_x if use_custom - else 0.0 if round_bed - else (max.x - 5.0) %} - {% set y_park = params.Y if params.Y is defined - else custom_park_y if use_custom - else (max.y - 5.0) if round_bed and z_park < cone - else 0.0 if round_bed - else (max.y - 5.0) %} - ##### end of definitions ##### - _CLIENT_RETRACT - {% if "xyz" in printer.toolhead.homed_axes %} - G90 - G1 Z{z_park} F{sp_hop} - G1 X{x_park} Y{y_park} F{sp_move} - {% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %} - {% else %} - RESPOND TYPE=echo MSG='Printer not homed' - {% endif %} - -[gcode_macro _CLIENT_EXTRUDE] -description: Extrudes, if the extruder is hot enough -gcode: - ##### get user parameters or use default ##### - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set use_fw_retract = (client.use_fw_retract|default(false)|lower == 'true') and (printer.firmware_retraction is defined) %} - {% set length = params.LENGTH|default(client.unretract)|default(1.0)|float %} - {% set speed = params.SPEED|default(client.speed_unretract)|default(35) %} - {% set absolute_extrude = printer.gcode_move.absolute_extrude %} - ##### end of definitions ##### - {% if printer.toolhead.extruder != '' %} - {% if printer[printer.toolhead.extruder].can_extrude %} - {% if use_fw_retract %} - {% if length < 0 %} - G10 - {% else %} - G11 - {% endif %} - {% else %} - M83 - G1 E{length} F{(speed|float|abs) * 60} - {% if absolute_extrude %} - M82 - {% endif %} - {% endif %} - {% else %} - RESPOND TYPE=echo MSG='{"\"%s\" not hot enough" % printer.toolhead.extruder}' - {% endif %} - {% endif %} - -[gcode_macro _CLIENT_RETRACT] -description: Retracts, if the extruder is hot enough -gcode: - {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} - {% set length = params.LENGTH|default(client.retract)|default(1.0)|float %} - {% set speed = params.SPEED|default(client.speed_retract)|default(35) %} - - _CLIENT_EXTRUDE LENGTH=-{length|float|abs} SPEED={speed|float|abs} - diff --git a/dirs/printer_data/systemd/crowsnest.env b/dirs/printer_data/systemd/crowsnest.env index 17ad838..9c85575 100644 --- a/dirs/printer_data/systemd/crowsnest.env +++ b/dirs/printer_data/systemd/crowsnest.env @@ -1 +1 @@ -CROWSNEST_ARGS="-c /home/pi/printer_data_taz/config/crowsnest.conf" +CROWSNEST_ARGS="-c /home/pi/PRINTERNAME/printer_data/config/crowsnest.conf" diff --git a/dirs/printer_data/systemd/klipper.env b/dirs/printer_data/systemd/klipper.env index b92f121..3f1e125 100644 --- a/dirs/printer_data/systemd/klipper.env +++ b/dirs/printer_data/systemd/klipper.env @@ -1 +1 @@ -KLIPPER_ARGS="/home/pi/taz/klipper-taz/klippy/klippy.py /home/pi/taz/printer_data_taz/config/printer.cfg -l /home/pi/taz/printer_data_taz/logs/klippy.log -I /home/pi/taz/printer_data_taz/comms/klippy.serial -a /home/pi/taz/printer_data_taz/comms/klippy.sock" +KLIPPER_ARGS="/home/pi/PRINTERNAME/klipper/klippy/klippy.py /home/pi/PRINTERNAME/printer_data/onfig/printer.cfg -l /home/pi/taz/printer_data_taz/logs/klippy.log -I /home/pi/taz/printer_data_taz/comms/klippy.serial -a /home/pi/taz/printer_data_taz/comms/klippy.sock" diff --git a/dirs/printer_data/systemd/moonraker.env b/dirs/printer_data/systemd/moonraker.env index 3584b3e..e162f08 100644 --- a/dirs/printer_data/systemd/moonraker.env +++ b/dirs/printer_data/systemd/moonraker.env @@ -1,4 +1,4 @@ -MOONRAKER_DATA_PATH="/home/pi/taz/printer_data_taz" +MOONRAKER_DATA_PATH="/home/pi/PRINTERDATA/printer_data" MOONRAKER_ARGS="-m moonraker" -PYTHONPATH="/home/pi/taz/moonraker-taz" +PYTHONPATH="/home/pi/PRINTERNAME/moonraker" diff --git a/setup.sh b/setup.sh index c26710f..a505779 100755 --- a/setup.sh +++ b/setup.sh @@ -2,9 +2,6 @@ ROOT_DIR="$(dirname "$0")" cd $ROOT_DIR -# TODO: add CMD line args -# - skip makeconfig - # Pull Klipper git submodule update --init --recursive @@ -18,7 +15,7 @@ for f in ${CONFIG_FILES[@]}; do C+=($i $f) let i+=1 done -CONFIG_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "Printer Selection" --menu "Select Printer Config" --output-fd 1 40 0 1 ${C[@]}) +CONFIG_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "Printer Selection" --menu "Select Printer Config" --output-fd 1 40 0 1 ${C[@]} 3>&1 1>&2 2>&3) CONFIG_FILE=${CONFIG_FILES[$CONFIG_INDEX]} # Select Serial Device @@ -29,11 +26,17 @@ for f in ${DEVICES[@]}; do C+=($i $f) let i+=1 done -DEVICE_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "USB Device Selection" --menu "Select USB Device" --output-fd 1 40 0 1 ${C[@]}) +DEVICE_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "USB Device Selection" --menu "Select USB Device" --output-fd 1 40 0 1 ${C[@]} 3>&1 1>&2 2>&3) DEVICE=${DEVICES[$DEVICE_INDEX]} # Name Printer -PRINTER_NAME="$(dialog --backtitle \"drwho@hackers.town\" --title \"Printer Name\" --inputbox \"Name This Printer\" 8 40 3>&1 1>&2 2>&3)" +NAME_NOT_VALID=true +while $NAME_NOT_VALID ; do + PRINTER_NAME="$(dialog --backtitle 'drwho@hackers.town' --inputbox 'Name This Printer' 8 40 'Print' 3>&1 1>&2 2>&3)" + if [[ $PRINTER_NAME =~ ^[a-zA-Z0-9_-]+$ ]]; then + NAME_NOT_VALID=false + fi +done # Build Klipper cat ./config/$CONFIG_FILE | sed -e "s/^serial: .\+$/serial: \/dev\/serial\/by-id\/${DEVICE}/" > ./printer.cfg @@ -43,20 +46,52 @@ make -j$(nproc) make flash FLASH_DEVICE=/dev/serial/by-id/$DEVICE # Copy over printer config file -cd $ROOT_DIR -cp dirs/klipper/printer.cfg dirs/printer_data/config/printer.cfg +cd $ROOT_DIR/dirs +cat $ROOT_DIR/config/macros.gcode >> printer.cfg.tmp +cat klipper/printer.cfg >> printer.cfg.tmp +mv printer.cfg.tmp printer_data/config/printer.cfg # Apply Edits to Configs +cd $ROOT_DIR/dirs/print_data +cat config/moonraker.conf | sed -e "s/PRINTERNAME/$PRINTER_NAME/g" > config/moonraker.conf.tmp +mv config/moonraker.conf.tmp config/moonraker.conf -# Create Empty Dirs -mkdir -p ~/PRINTER/logs -mkdir -p ~/PRINTER/gcodes -mkdir -p ~/PRINTER/certs -mkdir -p ~/PRINTER/backup +cat mainsail-config/client.cfg | sed -e "s/~\/printer_data/~\/$PRINTER_NAME\/printer_data/g" > mainsail-config/client.cfg.tmp +mv mainsail-config/client.cfg.tmp mainsail-config/client.cfg + +FILES=(crowsnest moonraker klipper) +for f in ${FILES[@]}; do + cat systemd/$f.service | sed -e "s/PRINTERNAME/$PRINTER_NAME/g" > systemd/$f.service.tmp + mv systemd/$f.service.tmp systemd/$f.service +done # Download Mainsail cd $ROOT_DIR wget -q -O mainsail.zip https://github.com/mainsail-crew/mainsail/releases/latest/download/mainsail.zip unzip -o mainsail.zip -d dirs/mainsail +# Copy To Final Location +mkdir -p ~/$PRINTER_NAME +cp -r dirs/* ~/$PRINTER_NAME + +# Create Empty Dirs +DIRS=(logs gcodes certs backup mainsail-config) +for d in ${DIRS[@]}; do + mkdir -p "~/$PRINTER_NAME/$d" +done + +# Configure System Services +cd $ROOT_DIR/config/services +SERVICES=() +for f in *.service; do + SERVICES+=($f) + cat $f | sed -e "s/PRINTERNAME/$PRINTER_NAME/g" > /etc/systemd/system/$PRINTERNAME-$f +done + # Install System Services +sudo cp $ROOT_DIR/config/services/* /etc/systemd/system/ +sudo systemctl daemon-reload +for svc in ${SERVICES[@]}; do + sudo systemctl enable $PRINTER_NAME-$svc + sudo systemctl start $PRINTER_NAME-$svc +done