Configuration
This content is for 1.1 (beta). Switch to the stable release docs.
Complete reference for HelixScreen configuration options.
Table of Contents
Section titled “Table of Contents”- Configuration File Location
- Configuration Structure
- Multi-Printer Configuration
- General Settings
- Sound Settings
- Sound Output
- Theme Settings
- Logging Settings
- Display Settings
- Appearance Settings
- Input Settings
- Motion Settings
- Output Settings
- Network Settings
- Printer Settings
- LED Settings
- Moonraker Settings
- Standard Macros (Quick Action Buttons)
- G-code Viewer Settings
- AMS Settings
- Panel Widget Settings
- Cache Settings
- Streaming Settings
- Safety Settings
- Notification Settings
- Filament Settings
- Filament Sensor Settings
- Security Settings
- Label Printer Settings
- Printer Switcher
- Telemetry Settings
- Update Settings
- Upgrade Nudge
- Safety Limits
- Capability Overrides
- Resetting Configuration
- Command-Line Options
- Environment Variables
Configuration File Location
Section titled “Configuration File Location”| Platform | Location |
|---|---|
| MainsailOS (Pi) | ~/helixscreen/config/settings.json (or /opt/helixscreen/config/ if no Klipper ecosystem) |
| AD5M Forge-X | /opt/helixscreen/config/settings.json |
| AD5M Klipper Mod | /root/printer_software/helixscreen/config/settings.json |
| K1 Simple AF | /usr/data/helixscreen/config/settings.json |
| Development | ./config/settings.json (in config/ directory) |
Note: On Pi, the installer auto-detects your Klipper ecosystem. If
~/klipper,~/moonraker, or~/printer_dataexists, HelixScreen installs to~/helixscreen. Otherwise it falls back to/opt/helixscreen. You can override withINSTALL_DIR=/path ./install.sh.
The configuration file is created automatically by the first-run wizard. You can also copy from the template:
cp config/settings.json.template config/settings.jsonNote: A settings.json sitting in the app root or at /opt/helixscreen/settings.json is moved to the location above on startup.
Configuration Structure
Section titled “Configuration Structure”The configuration file is JSON format with several top-level sections:
{ "config_version": 24, "dark_mode": false, "brightness": 80, "sounds_enabled": true, "ui_sounds_enabled": true, "sound_theme": "default", "disable_sound": false, "completion_alert": 1, "wizard_completed": false, "wifi_expected": false, "language": "en", "beta_features": false, "telemetry_enabled": false, "log_dest": "auto", "log_path": "", "log_level": "info",
"panel_widgets": { ... }, "theme": { ... }, "sounds": { ... }, "display": { ... }, "appearance": { ... }, "input": { ... }, "output": { ... }, "printer": { ... }, "standard_macros": { ... }, "gcode_viewer": { ... }, "ams": { ... }, "cache": { ... }, "streaming": { ... }, "safety": { ... }, "filament": { ... }, "filament_sensors": { ... }, "security": { ... }, "label_printer": { ... }, "printers": { ... }, "update": { ... }}Multi-Printer Configuration
Section titled “Multi-Printer Configuration”When multiple printers are configured, the config file uses a versioned schema with per-printer settings. config_version tracks the schema and HelixScreen migrates older files forward on load — leave it alone:
{ "config_version": 24, "active_printer_id": "voron-24", "printers": { "voron-24": { "printer_name": "Voron 2.4", "moonraker_host": "192.168.1.100", "moonraker_port": 7125, "wizard_completed": true, "printer_image": "shipped:voron-v2", ...per-printer settings... }, "ender-3": { "printer_name": "Workshop Ender", "moonraker_host": "192.168.1.101", "moonraker_port": 7125, "wizard_completed": true, ...per-printer settings... } }, "wifi": { ... }, "display": { ... }}Each printer entry contains all printer-specific settings (connection details, hardware selections, LED config, filament sensors, etc.). Device-level settings like WiFi and display preferences remain at the root level and are shared across all printers.
Note: You don’t need to edit the config file manually — use the Settings > Connection > Printers UI to add and manage printers. The config file is shown here for reference.
Looking for a walkthrough of each setting? See the detailed guides: Display · Appearance · Touch & Input · Sound · Printing · Devices · LED Settings · Safety & Alerts · Connection · Language & Time · System · Updates · Help & About
General Settings
Section titled “General Settings”dark_mode
Section titled “dark_mode”Type: boolean
Default: false
Description: Use dark theme (true) or light theme (false). Can also be set via Settings panel or --dark/--light CLI flags.
brightness
Section titled “brightness”Type: integer
Default: 80
Range: 1 - 100
Description: Screen brightness percentage. Adjustable via Settings panel.
sounds_enabled
Section titled “sounds_enabled”Type: boolean
Default: false
Description: Master switch for all sound effects. When false, no sounds play (UI or event). This is the “mute” toggle — it silences playback but still initializes the audio backend (see disable_sound to prevent initialization entirely).
ui_sounds_enabled
Section titled “ui_sounds_enabled”Type: boolean
Default: true
Description: Enable UI interaction sounds specifically (button taps, navigation clicks). Independent of event sounds like the print-complete chime, so you can keep alerts while silencing tap feedback. Has no effect when sounds_enabled is false. Adjustable via Settings > Sound.
sound_theme
Section titled “sound_theme”Type: string
Default: "default"
Values: "default", "minimal"
Description: The active sound theme, loaded from config/sounds/<name>.json. "default" uses the full set of tones; "minimal" uses a sparser, quieter set.
completion_alert
Section titled “completion_alert”Type: integer
Default: 2
Values: 0 (Off), 1 (Notification), 2 (Alert)
Description: How HelixScreen notifies you when a print completes or is cancelled (while you’re on a different screen):
0— Off: No notification (sound still plays if sounds are enabled)1— Notification: Brief toast message at the top of the screen2— Alert: Full-screen modal with print stats (duration, layers, filament used) and confetti for successful prints
Errors always show the full alert regardless of this setting. To change this in the UI, go to Settings > Safety & Alerts > Print Completion Alert and select from the dropdown.
disable_sound
Section titled “disable_sound”Type: boolean
Default: false
Description: Disable all sound output entirely. Prevents the audio backend from initializing, which avoids CPU overhead on hardware where audio drivers are present but unusable (e.g., Artillery M1 Pro). Also available as the --no-sound CLI flag.
This is different from sounds_enabled — that toggle mutes playback but still initializes the audio backend. disable_sound prevents initialization altogether.
wizard_completed
Section titled “wizard_completed”Type: boolean
Default: false
Description: Whether the setup wizard has been completed. Set automatically after first-run wizard. Set to false to re-trigger the wizard on next startup.
wifi_expected
Section titled “wifi_expected”Type: boolean
Default: false
Description: Whether WiFi connectivity is expected. When true, HelixScreen shows connection warnings if WiFi is unavailable. Set during the wizard based on your network configuration choice.
language
Section titled “language”Type: string
Default: "en"
Values: "en", "de", "es", "fr", "it", "ja", "pt", "ru", "zh"
Description: UI language code. Nine languages are supported (English, German, Spanish, French, Italian, Japanese, Portuguese, Russian, Chinese). Change via Settings > Language & Time > Language.
beta_features
Section titled “beta_features”Type: boolean
Default: false
Description: Enable beta features that are still under testing. Gates rows that are still being proven on real hardware (in the Advanced panel: Tool Offsets, Belt Tension; on the Controls panel: the Tool Offsets button on tool-changing printers), the prompt that offers to install the HelixPrint Moonraker plugin, and the Dev entry in the Update Channel selector (Stable and Beta are offered without it). Always enabled automatically when running in --test mode. Can also be toggled by tapping the version button 7 times in Settings > Help & About > About. See the Beta Features guide for the full list.
Sound Settings
Section titled “Sound Settings”Located in the sounds section:
{ "sounds": { "volume": 80 }}sounds.volume
Section titled “sounds.volume”Type: integer
Default: 80
Range: 0 - 100
Description: Master playback volume as a percentage. 0 is silent, 100 is full volume. Adjustable via Settings > Sound. This scales the level of all sounds; the sounds_enabled and ui_sounds_enabled toggles decide whether sounds play at all.
Sound Output
Section titled “Sound Output”Located in the sound section. Both keys pick where sound goes; leave them out to let HelixScreen choose.
{ "sound": { "output_device": "plughw:CARD=vc4hdmi0,DEV=0", "pwm_channel": "0:0" }}sound.output_device
Section titled “sound.output_device”Type: string
Default: "" (the system’s default sound card)
Description: Which Linux sound card plays HelixScreen’s sounds, for example an HDMI screen’s built-in speaker. Set it from Settings > Sound > Output Device; editing it by hand is only needed when that row isn’t shown. List the cards with aplay -l.
sound.pwm_channel
Section titled “sound.pwm_channel”Type: string, "<chip>:<channel>"
Default: "" (off)
Description: Plays sounds on a small buzzer wired to one of the board’s PWM pins, instead of a sound card. "0:0" means /sys/class/pwm/pwmchip0/pwm0. When set, it takes priority over every sound card, since a headphone jack (a Raspberry Pi’s, for example) always looks available even with nothing plugged in. There is no menu for it, because choosing the wrong channel could drive something else on the same chip, such as a screen backlight. Works on any Linux board whose pin can output hardware PWM. Setup steps are in Sound: buzzer on a PWM pin. Restart HelixScreen after changing it.
Theme Settings
Section titled “Theme Settings”Located in the theme section:
{ "theme": { "preset": 0 }}preset
Section titled “preset”Type: integer
Default: 0
Description: Theme accent color preset. Requires restart to take effect.
Note:
presetis a legacy dropdown-index field, and index0maps to Ayu — it does not reflect the effective default theme. The out-of-the-box default theme is HelixScreen. The active theme is set by the/display/themestring (a theme name), not by this numeric index.
| Value | Theme |
|---|---|
| 0 | Ayu |
| 1 | Catppuccin |
| 2 | ChatGPT |
| 3 | Cupertino |
| 4 | Dracula |
| 5 | Everforest |
| 6 | Gruvbox |
| 7 | Hazard |
| 8 | HelixScreen (default) |
| 9 | Kanagawa |
| 10 | Material Design |
| 11 | Midnight |
| 12 | Nord |
| 13 | One Dark |
| 14 | Rose Pine |
| 15 | Solarized |
| 16 | Tokyo Night |
| 17 | Yami |
Tip: You can also browse and apply themes visually in Settings > Appearance > Theme Colors.
Logging Settings
Section titled “Logging Settings”log_dest
Section titled “log_dest”Type: string
Default: "auto"
Values: "auto", "journal", "syslog", "file", "console"
Description: Log destination:
auto- Detect best option (journal on systemd, console otherwise)journal- systemd journal (view withjournalctl -u helixscreen)syslog- Traditional syslogfile- Write to log fileconsole- Print to stdout/stderr
log_path
Section titled “log_path”Type: string
Default: ""
Description: Path for log file when log_dest is "file". Empty uses default location:
/var/log/helix-screen.log(if writable)~/.local/share/helix-screen/helix.log(fallback)
The path must be an absolute *.log path under /tmp, /var/log or the
install directory; a subdirectory of those must be owned by root or the
HelixScreen user with no group or world write bit, and the path may not
contain .. or be a symlink. Anything else is refused with a warning and the
default location is used, since settings.json is editable from the web UI
and must not aim the log at arbitrary files.
log_level
Section titled “log_level”Type: string
Default: "info"
Values: "warn", "info", "debug", "trace"
Description: Log verbosity level:
warn- Quiet, only warnings and errorsinfo- General operational information (default)debug- Detailed debugging informationtrace- Extremely verbose, all internal operations
Note: This can also be changed at runtime via Settings > System > Log Level without restarting. CLI -v flags override this setting (-v=info, -vv=debug, -vvv=trace).
Display Settings
Section titled “Display Settings”Located in the display section:
{ "display": { "animations_enabled": true, "time_format": 0, "timezone": "UTC", "theme": "helixscreen", "rotate": 0, "sleep_sec": 1200, "sleep_while_printing": true, "dim_sec": 600, "dim_brightness": 30, "drm_device": "", "gcode_render_mode": 2, "gcode_3d_enabled": true, "bed_mesh_render_mode": 0, "bed_mesh_show_zero_plane": true, "page_scroll_buttons": false, "speed_flow_physical_units": false, "ui_scale_percent": 0, "printer_image": "" }}Touch calibration data lives under
input.calibration, notdisplay.calibration. See the Input Configuration section below and the Touch Calibration Guide. Older configs that placed it underdisplayare automatically migrated on first load.
animations_enabled
Section titled “animations_enabled”Type: boolean
Default: true
Description: Enable UI animations and transitions. Disable for better performance on slow devices.
time_format
Section titled “time_format”Type: integer
Default: 0
Values: 0 (12-hour), 1 (24-hour)
Description: Time display format. 0 shows “2:30 PM”, 1 shows “14:30”.
timezone
Section titled “timezone”Type: string
Default: "UTC"
Example: "America/New_York", "Europe/London"
Description: IANA timezone ID used for all displayed clocks and print time estimates. Set this so times shown on screen match your local time instead of UTC. Change via Settings > Language & Time > Timezone.
Type: string
Default: "helixscreen"
Description: Active color theme by name (e.g., "nord", "dracula", "gruvbox"). This is the string that actually determines the effective theme — the numeric theme.preset index is a legacy field. Requires restart to take effect. Easiest to change via Settings > Appearance > Theme Colors, which writes this value for you.
layout
Section titled “layout”Type: string
Default: "auto"
Values: auto, standard, ultrawide, portrait, micro, micro-portrait, tiny, tiny-portrait
Description: Override the auto-detected screen layout. Leave this at auto unless you are testing — HelixScreen picks the layout from your display’s aspect ratio: wider than about 2.5:1 is ultrawide, narrower than about 0.8:1 is portrait, and anything in between is standard. Displays whose longest side is 480px or less get micro (480x272 class) or tiny instead, with -portrait variants when the screen is taller than wide.
Ultrawide and portrait are alpha at best. Detection, navigation-bar sizing, and grid sizing all work, and both orientations get their own home dashboard layout. Portrait goes further: Print Status, Print Tune, Motion, Bed Mesh, the temperature graph, and the Advanced panel’s E-stop bar rearrange for a tall screen as well. Ultrawide has the home dashboard and nothing else. Every other panel falls back to the standard landscape layout, so expect stretched, cramped, or clipped screens outside that set. Neither orientation has been tested much on real hardware. Forcing one of these is useful for contributing layouts, not for daily use.
rotate
Section titled “rotate”Type: integer
Default: 0
Values: 0, 90, 180, 270
Description: Rotate the entire display by the specified degrees. Touch coordinates are automatically adjusted to match. Change via Settings > Display > Screen Rotation (applies after restart).
Automatic detection: On first boot, HelixScreen checks the kernel for panel orientation (e.g., panel_orientation=upside_down in the kernel command line). If detected, the rotation is applied immediately and saved here — no manual configuration needed. On framebuffer displays only (e.g., AD5M — not Raspberry Pi), an interactive rotation wizard runs instead if no kernel hint is found.
Raspberry Pi and other DRM displays rotate by any angle. Where the display hardware cannot do the rotation itself - which is the case for every panel HelixScreen ships to - the app switches itself to the framebuffer backend, which rotates in software. This happens automatically and in-process: nothing needs reinstalling, no setting needs changing, and both binaries are already present. The cost is a full-screen redraw each frame rather than only the changed regions, typically under 1ms per frame on a Pi 5.
To avoid that cost entirely, rotate the panel in the kernel instead with a video=...,rotate=90 parameter on the kernel command line. That applies before HelixScreen starts, so the app renders unrotated at native speed.
Framebuffer displays (AD5M, K1, K2, CC1, AD5X) rotate by any angle with no meaningful performance impact, using a more efficient partial update.
rotation_probed
Section titled “rotation_probed”Type: boolean
Default: false
Description: Set to true after automatic rotation detection runs. Remove this key (along with rotate) to re-trigger automatic detection on next startup.
sleep_sec
Section titled “sleep_sec”Type: integer
Default: 1200
Description: Seconds of inactivity before screen turns OFF. Set to 0 to disable sleep. Default is 20 minutes.
sleep_while_printing
Section titled “sleep_while_printing”Type: boolean
Default: true
Description: Whether the screen is allowed to dim and sleep during an active print. When true, the normal dim_sec/sleep_sec timers apply while printing. Set to false to keep the display on for the whole print so you can glance at progress without touching the screen. Adjustable via Settings > Display.
dim_sec
Section titled “dim_sec”Type: integer
Default: 600
Description: Seconds of inactivity before screen dims. Set to 0 to disable dimming. Must be less than sleep_sec. Default is 10 minutes.
dim_brightness
Section titled “dim_brightness”Type: integer
Default: 30
Range: 1 - 100
Description: Brightness percentage when screen is dimmed.
sleep_backlight_off
Section titled “sleep_backlight_off”Type: boolean
Default: true
Description: Whether going to sleep switches the backlight off, rather than only dimming it to zero. Leave this on. It exists for panels where cutting the backlight leaves the screen in a state it cannot wake from; if your display goes dark and stays dark after sleeping, and a touch does not bring it back, set this to false and restart.
backlight_enable_ioctl
Section titled “backlight_enable_ioctl”Type: boolean
Default: true
Description: Whether to use the kernel’s backlight enable/disable call in addition to setting a brightness level. A few panels wire this signal backwards, so enabling the backlight turns it off. If your screen is inverted — dark when it should be lit, lit when it should be asleep — set this to false so brightness alone controls it.
backlight_floor_percent
Section titled “backlight_floor_percent”Type: integer
Default: 0 (20 on K2 builds, for sysfs backlights only)
Range: 0 - 100
Description: Lowest brightness level the panel can still show, as a percentage of its raw brightness range. With a floor set, the brightness slider’s minimum lands exactly on the floor and 100% on full brightness, so the dimmest setting dims instead of blacking out; turning the screen off is unaffected. 0 disables the floor.
The K2 build default applies only when the backlight is a sysfs device (/sys/class/backlight), as on community K2 firmware. Stock K2 firmware drives its panel through /dev/disp, stays visible almost down to zero, and takes no floor. A value you set here applies to every kind of backlight. Set it if your panel goes black before the slider reaches its minimum: raise it until the dimmest setting stays visible. Takes effect after a restart.
panel_power_off
Section titled “panel_power_off”Type: integer
Default: -1 (automatic)
Values: -1 = automatic, 0 = never, 1 = always
Description: Whether display sleep powers the screen panel down or just turns its backlight off. Automatic powers the panel down only when the screen has no brightness control; on every other screen, sleep turns the backlight off. Set 1 if your screen goes black at sleep but the backlight stays lit. Set 0 if at sleep your screen flashes colours, glows at the edges, or does not come back on when you wake it. Takes effect after a restart. See Troubleshooting.
screensaver_type
Section titled “screensaver_type”Type: integer
Default: 1
Values: 0 = Off, 1 = Flying Toasters, 2 = Starfield, 3 = 3D Pipes, 4 = Bouncing Printer, 5 = Fireworks
Description: Which screensaver plays when the screen has been idle. Choose it in Settings > Display. It starts at the dim_sec mark, alongside dimming, and stops when sleep_sec takes the display down. On a panel with no backlight control the screensaver is the only idle indication you get. A fresh install selects Flying Toasters on every device that has screensavers. Each screensaver checks its own cost on your device and lowers its frame rate or detail, or shows a plain black screen, if it would slow the printer (see screensaver_levels).
screensaver_levels
Section titled “screensaver_levels”Type: object Default: absent Description: Written by HelixScreen; do not edit it. Each screensaver measures how much processor time it uses while it plays. If it would slow the printer, it lowers its frame rate or detail, and if even its lowest setting is too much it shows a plain black screen instead. The result is kept here for each screensaver, with the HelixScreen version and a description of the screen hardware, and is measured again after an update or on different hardware. Delete this entry to have every screensaver measured again.
drm_device
Section titled “drm_device”Type: string
Default: "" (auto-detect)
Example: "/dev/dri/card1"
Description: Override DRM device for display output. Leave empty for auto-detection.
Pi 5 DRM devices:
/dev/dri/card0- v3d (3D only, no display output)/dev/dri/card1- DSI touchscreen/dev/dri/card2- HDMI (vc4)
Auto-detection finds the first device with dumb buffer support and a connected display.
gcode_render_mode
Section titled “gcode_render_mode”Type: integer
Default: 0
Values: 0 (Auto), 1 (3D View), 2 (2D Layers), 3 (Thumbnail Only)
Description: G-code visualization mode for the active print:
0- Auto: interactive 3D on hardware with a working GLES renderer, 2D layers everywhere else (also the mode HelixScreen drops to if 3D has to bail mid-print)1- 3D View: interactive 3D rendering of the toolpath2- 2D Layers: flat per-layer view, lighter on the GPU than 3D3- Thumbnail Only: shows just the slicer-embedded thumbnail, no live toolpath rendering - the lightest option
Adjustable from the UI at Settings > Printing > G-code Preview.
The mode can be overridden per launch without touching settings. Precedence is command line > HELIX_GCODE_MODE env var > this setting:
helix-screen --render-2dforces 2D Layers and--render-3dforces 3D View for that session. Launching with--render-2dis the quick way to force 2D on hardware that struggles with 3D rendering.HELIX_GCODE_MODE=3D(or2D) - only those exact, case-sensitive values are honored; anything else falls back to 2D, and leaving it unset means Auto.
gcode_3d_enabled
Section titled “gcode_3d_enabled”Type: boolean
Default: true
Description: Enable 3D G-code preview capability. When false, only 2D layer view is available.
bed_mesh_render_mode
Section titled “bed_mesh_render_mode”Type: integer
Default: 0
Values: 0 (3D surface), 1 (2D heatmap)
Description: Bed mesh visualization mode. 3D surface shows the mesh as a 3D plot, 2D heatmap shows it as a flat color grid.
bed_mesh_show_zero_plane
Section titled “bed_mesh_show_zero_plane”Type: boolean
Default: true
Description: Show translucent reference plane at Z=0 in bed mesh 3D view. Helps visualize where the nozzle touches the bed.
page_scroll_buttons
Section titled “page_scroll_buttons”Type: boolean
Default: false
Description: Show up/down scroll buttons on long lists throughout the app. Useful on small screens or displays where drag-to-scroll feels unresponsive. See Touch & Input Settings for details.
speed_flow_physical_units
Section titled “speed_flow_physical_units”Type: boolean
Default: false
Description: Show speed and flow as the live toolhead speed in mm/s and the live volumetric flow in mm³/s instead of percentages, on the Print Status screen and as the leading value in the Print Tune overlay. Tapping the Speed / Flow line on Print Status, or either readout in the Tune overlay, flips it. See Print Tune Overlay.
ui_scale_percent
Section titled “ui_scale_percent”Added in 1.1.
Type: integer
Default: 0 (Automatic)
Values: 0, or 100-200
Description: Size of the whole interface. 0 means Automatic: HelixScreen works the scale out from the panel’s physical pixel density, which leaves every supported printer at exactly 100 and only grows the UI on very high-density screens such as a phone. Any other value is an explicit percentage that overrides the measurement — useful if the interface comes out too small or too large on your display. A value outside the range is ignored and treated as Automatic.
Takes effect on the next start. HelixScreen sizes fonts and layout once, while the screen is being set up, so changing this mid-session cannot re-scale what is already drawn. See Display Settings.
printer_image
Section titled “printer_image”Type: string
Default: "" (auto-detect)
Description: Printer image displayed on the Home Panel and in the Printer Manager. The value determines which image is used:
""(empty string or absent) — Auto-detect: HelixScreen selects an image based on the printer type reported by Klipper"shipped:voron-v2"— Use a specific shipped image by name (seeassets/images/printers/for available images)"custom:my-printer"— Use a custom image that was imported fromconfig/custom_images/
Custom images are PNG or JPEG files placed in config/custom_images/. They are automatically converted to optimized LVGL binary format (300px and 150px variants) when the Printer Image picker overlay is opened. Maximum file size is 5MB, maximum resolution is 2048x2048 pixels.
This setting can also be changed via the Printer Manager overlay (tap the printer image on the Home Panel).
calibration
Section titled “calibration”Type: object
Default: {"valid": false}
Description: Touch calibration coefficients. Set by the calibration wizard or manually. Contains calibration matrix values (a through f) when valid. If the wizard detects that the touchscreen’s X/Y axes are swapped relative to the display, it bakes that correction directly into the a–f coefficients — there is no separate setting to configure.
Appearance Settings
Section titled “Appearance Settings”Located in the appearance section:
{ "appearance": { "toolhead_style": 0, "show_widget_labels": false }}toolhead_style
Section titled “toolhead_style”Type: integer
Default: 0
Values: 0 (Default), 1 (Creality K1), 2 (Creality K2)
Description: Which toolhead illustration is drawn on the temperature panel. Normally auto-detected from your printer type, so you rarely need to set it by hand. Override only if the wrong toolhead graphic is shown.
show_widget_labels
Section titled “show_widget_labels”Type: boolean
Default: false
Description: Show text labels beneath the Home panel widget icons. Leave false for a cleaner icon-only look, or set true if you prefer captions under each widget. Adjustable via the Home panel’s Edit Mode.
Input Settings
Section titled “Input Settings”Located in the input section:
{ "input": { "scroll_throw": 25, "scroll_limit": 10, "long_press_time": 500, "scroll_guard": false, "home_edit_mode_enabled": true, "keypad_layout": 0, "touch_device": "", "device_blacklist": [], "force_calibration": false, "calibration": { "valid": false, "a": 1.0, "b": 0.0, "c": 0.0, "d": 1.0, "e": 1.0, "f": 0.0 } }}Tuning touch feel:
scroll_throwandscroll_limitinteract. See Touch Feel — Which Setting Do I Tune? in the troubleshooting guide for a symptom → setting map.Touch calibration (
input.calibration) is set automatically by the wizard — don’t edit thea–fcoefficients by hand. See the Touch Calibration Guide for the full reference.
scroll_throw
Section titled “scroll_throw”Type: integer
Default: 25 (35 on ESP32 screens such as the BTT K-Touch)
Range: 5 - 50 (UI-clamped)
Description: Scroll momentum decay rate — how quickly a flicked list coasts to a stop. Higher values = faster decay (less “throw”). LVGL’s native default is 10; we use 25 because touchscreens feel sluggish with long coasting. Lower it if lists feel too “sticky” at the end of a flick.
scroll_limit
Section titled “scroll_limit”Type: integer
Default: 10
Range: 1 - 20 (UI-clamped)
Description: Pixels of finger movement required before a gesture is treated as a scroll instead of a tap. Below this threshold LVGL still thinks you’re pressing a widget, and releasing will fire a click. Above it, the press is cancelled and scroll engages.
- Lower = scroll engages sooner. Fixes phantom clicks that fire when scrolling a list with a short, slow swipe.
- Higher = more deliberate gesture required. Reduces accidental scrolls when you meant to tap, but makes short-travel scrolls feel unresponsive.
Matches LVGL’s native default of 10.
long_press_time
Section titled “long_press_time”Type: integer
Default: 500
Range: 300 - 1500 (UI-clamped)
Description: How long (in milliseconds) a finger must hold before a press registers as a long-press. Governs every long-press in the app — home-screen Edit Mode entry, file-card delete, macro edit mode, and others. Raise this if long-press actions trigger when a finger simply rests on the glass (common on a tablet lying flat). Applied live — no restart needed.
home_edit_mode_enabled
Section titled “home_edit_mode_enabled”Type: boolean
Default: true
Description: Whether a long-press on the home grid enters Edit Mode (the drag-and-drop layout editor). When false, the long-press is suppressed entirely. Turn off if Edit Mode triggers by accident and you don’t need to rearrange widgets, or pair with a higher long_press_time to make accidental entry harder while keeping the feature available. Applied live — no restart needed.
keypad_layout
Section titled “keypad_layout”Type: integer
Default: 0
Description: Digit order of the number pad. 0 = phone (1 2 3 on top, backspace bottom left, and a confirm key bottom right on whole-number fields); 1 = calculator (7 8 9 on top). Set it from Touch & Input Settings. Applied live — no restart needed.
touch_device
Section titled “touch_device”Type: string
Default: "" (auto-detect)
Example: "/dev/input/event1"
Description: Override touch/pointer input device. Leave empty for auto-detection. Auto-detection finds touch or pointer capable devices.
device_blacklist
Section titled “device_blacklist”Type: array of strings
Default: [] (no blacklist)
Example: ["002c:261a"]
Description: USB input devices that HelixScreen ignores entirely for keyboard and barcode-scanner input. Each entry is a "vid:pid" pair of lowercase 4-digit hex IDs. Use this when a USB barcode scanner enumerates as a plain HID keyboard and HelixScreen keeps claiming it — for example when an external tool like afc-spool-scan needs exclusive access to the scanner. A blacklisted device is skipped by both the persistent keyboard binding and the in-app scan overlay, but still appears in the Barcode Scanner settings device list so you can identify it.
Finding a device’s VID:PID: Open Settings > Devices > Spoolman > Barcode Scanner — the device list shows each device’s VID:PID. Alternatively, run lsusb over SSH and read the ID pair after ID (e.g. ID 002c:261a). See Sharing a scanner with another tool for the full walkthrough.
scroll_guard
Section titled “scroll_guard”Type: boolean
Default: false (true in the AD5M and AD5X presets)
Description: Ignore the stray click some touch controllers send when you lift your finger at the end of a scroll: a press that starts within scroll_guard_cooldown_ms (default 80 ms, range 20 to 500) of a scroll does not count as a click. Shown as the Scroll Guard toggle under Settings > Touch & Input. The AD5M and AD5X presets set it to true. Takes effect after a restart. Applies only to built-in touchscreens (DRM/fbdev); the desktop (SDL) and Android builds ignore it. HELIX_SCROLL_GUARD and HELIX_SCROLL_GUARD_COOLDOWN_MS override the saved values. For clicks that fire while you are still scrolling, the setting that helps is scroll_limit (see Touch Feel).
force_calibration
Section titled “force_calibration”Type: boolean
Default: false
Description: Force the calibration wizard to run on next startup, even if the device doesn’t normally require it. After successful calibration, this flag is automatically cleared. Mainly useful when touch is too far off to reach Settings at all — the Settings entry point itself is offered for any touchscreen, so you rarely need this just to find the option.
Motion Settings
Section titled “Motion Settings”Added in 1.1.
Located in the motion section. These back the jog pad; set them from the screen at Settings > Printing > Motion (or the cog icon in the Motion screen’s header) rather than by hand.
{ "motion": { "jog_speed_xy": 6000, "jog_speed_z": 600, "fine_inner": 0.1, "fine_outer": 1.0, "coarse_inner": 1.0, "coarse_outer": 10.0, "turbo_inner": 10.0, "turbo_outer": 50.0, "show_actual_position": false }}jog_speed_xy
Section titled “jog_speed_xy”Type: integer
Default: 6000
Range: 60 - 60000
Description: Jog pad feedrate for X and Y moves, in mm/min.
jog_speed_z
Section titled “jog_speed_z”Type: integer
Default: 600
Range: 60 - 60000
Description: Jog pad feedrate for Z moves, in mm/min.
fine_inner, fine_outer, coarse_inner, coarse_outer, turbo_inner, turbo_outer
Section titled “fine_inner, fine_outer, coarse_inner, coarse_outer, turbo_inner, turbo_outer”Type: number
Range: 0.01 - 200
Description: Distance in mm moved per tap, for each jog mode’s inner and outer ring. Defaults: Fine 0.1/1, Coarse 1/10, Turbo 10/50. The ring labels on the jog pad show whatever you set.
show_actual_position
Section titled “show_actual_position”Type: boolean
Default: false
Description: What the X/Y/Z coordinates on the Motion screen show when it opens: the commanded position (false) or the actual measured position (true). Tapping the Target / Actual chip next to the coordinates flips it, so this is normally set from the screen rather than by hand. Remembered per printer.
Output Settings
Section titled “Output Settings”Located in the output section:
{ "output": { "led_on_at_start": false }}led_on_at_start
Section titled “led_on_at_start”Type: boolean
Default: false
Description: Automatically turn on the configured LED strip when Klipper becomes ready. Useful for printers with chamber lights that should always be on. Set this under printer.leds.led_on_at_start instead — that is where HelixScreen writes it and where per-printer settings belong. A value here is still read, but it applies to every printer.
Network Settings
Section titled “Network Settings”Nothing about the network connection is stored in settings.json. The connection type, SSID and IP address shown in Settings > Connection > Network Settings are read live from the printer’s operating system, and the setup wizard configures the actual network through the printer, not through this file.
Printer Settings
Section titled “Printer Settings”Located in the printer section:
{ "printer": { "name": "Unnamed Printer", "type": "Unknown", "moonraker_host": "192.168.1.100", "moonraker_port": 7125, "moonraker_api_key": false, "heaters": { "bed": "heater_bed", "hotend": "extruder" }, "temp_sensors": { "bed": "temperature_sensor bed", "hotend": "temperature_sensor extruder" }, "fans": { "hotend": "heater_fan hotend_fan", "part": "fan", "chamber": "", "exhaust": "" }, "chamber_heater": "auto", "chamber_sensor": "auto", "leds": { "strip": "", "selected_strips": [], "led_on_at_start": false, "last_color": 16777215, "last_brightness": 100, "color_presets": [16777215, 16711680, 65280, 255, 16776960, 16711935, 65535], "auto_state": { ... }, "macro_devices": [] }, "extra_sensors": {}, "hardware": { "optional": [], "expected": [], "last_snapshot": {} }, "default_macros": { ... }, "capability_overrides": { ... } }}Breaking Change (Jan 2026): The config schema changed from singular keys (
heater,sensor,fan,led) to plural keys (heaters,temp_sensors,fans,leds). If upgrading from an older version, delete your config file and re-run the first-run wizard.
Type: string
Default: "Unnamed Printer"
Description: Display name for your printer.
Type: string
Default: "Unknown"
Description: Printer model/type for feature detection (e.g., “Voron 2.4”, “AD5M”, “K1”).
heaters.hotend
Section titled “heaters.hotend”Type: string
Default: "extruder"
Description: Klipper heater name for hotend.
heaters.bed
Section titled “heaters.bed”Type: string
Default: "heater_bed"
Description: Klipper heater name for heated bed.
temp_sensors.hotend
Section titled “temp_sensors.hotend”Type: string Description: Temperature sensor for hotend (may differ from heater name if using separate sensor).
temp_sensors.bed
Section titled “temp_sensors.bed”Type: string Description: Temperature sensor for bed (may differ from heater name if using separate sensor).
fans.part
Section titled “fans.part”Type: string
Default: "fan"
Description: Klipper fan name for part cooling.
fans.hotend
Section titled “fans.hotend”Type: string Description: Klipper fan name for hotend cooling.
fans.chamber
Section titled “fans.chamber”Type: string
Default: "" (none)
Description: Klipper fan name for chamber fan (e.g., "fan_generic chamber_fan"). Leave empty if not available.
fans.exhaust
Section titled “fans.exhaust”Type: string
Default: "" (none)
Description: Klipper fan name for exhaust fan (e.g., "fan_generic exhaust_fan"). Leave empty if not available.
chamber_heater
Section titled “chamber_heater”Type: string
Default: "auto"
Values: "auto", "none", or a Klipper object name
Description: Which heater warms the enclosure/chamber. "auto" lets HelixScreen pick it by name heuristics, "none" disables chamber-heater controls, or you can name the Klipper object explicitly (e.g., "heater_generic chamber"). Most printers work fine on "auto".
chamber_sensor
Section titled “chamber_sensor”Type: string
Default: "auto"
Values: "auto", "none", or a Klipper object name
Description: Which temperature sensor reports the enclosure/chamber temperature. "auto" detects it by name heuristics, "none" disables chamber-temperature display, or name the Klipper object explicitly (e.g., "temperature_sensor enclosure_bme"). Set this if your chamber temperature reads from the wrong sensor or isn’t detected.
enclosure_style
Section titled “enclosure_style”Type: integer
Default: 0
Values: 0 = Auto, 1 = Enclosed, 2 = Open frame
Description: Whether the printer counts as enclosed, which decides whether drying filament on the heated bed is offered. Auto treats a printer as enclosed when its model is known to ship enclosed or a chamber heater is configured. Set it from Settings > Printing > Enclosure.
z_offset.step_index
Section titled “z_offset.step_index”Added in 1.1.
Type: integer
Default: 2
Values: 0 = 0.05 mm, 1 = 0.025 mm, 2 = 0.01 mm, 3 = 0.005 mm
Description: The Z-offset step size the print Tune overlay’s nudge buttons use, remembered between prints. Picking a size on the overlay writes this; there is nothing to gain from editing it by hand.
LED Settings
Section titled “LED Settings”Located in the printer.leds section. Startup and Automatic LED Control are configured via Settings > Devices > LED Settings; which light each Home Panel Light button controls is set from that button’s own gear icon in Edit Mode (see Panel Widget Settings below and Home Panel > LED Controls).
leds.strip
Section titled “leds.strip”Type: string
Default: "" (empty)
Description: A single LED strip name, from a version of HelixScreen that only supported one strip at all. Like leds.selected_strips below, it is legacy — folded into that key on load and otherwise unused.
leds.selected_strips
Section titled “leds.selected_strips”Type: array of strings
Default: []
Description: A legacy key. It used to be the list of lights every light button, Automatic LED Control, and LED on at Start all shared. It is read once, the first time HelixScreen finds your lights with no leds.auto_state.strips saved yet, to give each of those now-separate settings a starting point. Automatic LED Control starts on the lights you had selected. Your Home Panel Light buttons start on that light if you had selected one, on All lights if you had selected every light, and on the chamber light otherwise. Nothing reads this key as “the lights HelixScreen controls” any more; editing it by hand does nothing.
leds.light_button_pending
Section titled “leds.light_button_pending”Type: string Default: absent Description: Written once by the migration above (or by the first-run wizard’s LED step) and consumed the first time a Home Panel Light button with no light of its own picks one up. You should not need to set this by hand — it clears itself once a button has adopted it.
leds.led_on_at_start
Section titled “leds.led_on_at_start”Type: boolean
Default: false
Description: Automatically turn on your lights when Klipper becomes ready — every light your Home Panel Light buttons control, or the chamber light if you haven’t placed one. A WLED strip gets up to 5 seconds to answer before HelixScreen falls back to the chamber light. A copy of this key under output is also honoured if you have one; printer.leds is where HelixScreen writes it.
leds.startup_brightness
Section titled “leds.startup_brightness”Type: integer
Default: 80
Range: 0 - 100
Description: Brightness the lights come up at when leds.led_on_at_start switches them on. Independent of leds.last_brightness, so the lights can start at a fixed level regardless of where you left the slider.
leds.last_color
Section titled “leds.last_color”Type: string (or integer)
Default: "#FFFFFF" (white)
Description: Last used LED color as a #RRGGBB hex string (e.g., "#FFFFFF" = white, "#FF0000" = red, "#00FF00" = green). Plain integer RGB values (e.g., 16777215) are also accepted. Remembered between sessions.
leds.last_brightness
Section titled “leds.last_brightness”Type: integer
Default: 100
Range: 0 - 100
Description: Last used brightness percentage. Remembered between sessions.
leds.color_presets
Section titled “leds.color_presets”Type: array of strings (or integers)
Default: ["#FFFFFF", "#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"]
Description: Preset colors shown in the color picker as #RRGGBB hex strings. Plain integer RGB values are also accepted. Default presets are white, red, green, blue, yellow, magenta, and cyan.
leds.auto_state
Section titled “leds.auto_state”Type: object
Description: Automatic state-based LED lighting configuration. When enabled, the lights in strips change automatically based on printer state — its own list, independent of what any Home Panel Light button controls.
{ "auto_state": { "enabled": false, "strips": ["neopixel toolhead_leds"], "mappings": { "idle": { "action": "brightness", "brightness": 50, "color": "#000000" }, "heating": { "action": "color", "color": "#FF0000", "brightness": 100 }, "printing": { "action": "brightness", "brightness": 100, "color": "#000000" }, "paused": { "action": "effect", "effect_name": "breathing", "color": "#000000", "brightness": 100 }, "error": { "action": "color", "color": "#FF0000", "brightness": 100 }, "complete": { "action": "color", "color": "#00FF00", "brightness": 100 } } }}enabled— Boolean, enable/disable automatic state-based lightingstrips— Array of light ids Automatic LED Control acts on (the “Applies to” row in Settings)mappings— Object mapping printer state keys (idle,heating,printing,paused,error,complete) to actions- Each mapping has an
actiontype:"off","brightness","color","effect","wled_preset", or"macro" - Additional fields depend on the action:
brightness(0-100),color(#RRGGBBhex string, or a plain integer RGB),effect_name(string),wled_preset(integer),macro(string)
leds.macro_devices
Section titled “leds.macro_devices”Type: array of objects
Default: []
Description: Custom LED macro devices, each shown as its own tab in the LEDs overlay. Each device object:
{ "name": "Chamber Light", "type": "on_off", "on_macro": "LIGHTS_ON", "off_macro": "LIGHTS_OFF", "toggle_macro": "", "presets": []}name— Display name for the device cardtype— Device type:"on_off"(separate on/off macros),"toggle"(single toggle macro), or"preset"(multiple named presets)on_macro/off_macro— Macro names for on/off typetoggle_macro— Macro name for toggle typepresets— Array of{"name": "...", "macro": "..."}objects for preset type
Configured via Settings > Devices > LED Settings > Macro Devices.
extra_sensors
Section titled “extra_sensors”Type: object
Default: {}
Description: Additional temperature sensors to monitor (beyond hotend/bed). Keys are display names, values are Klipper sensor names.
hardware
Section titled “hardware”Type: object Description: Hardware tracking information (managed automatically by the wizard):
optional- List of optional hardware detectedexpected- List of expected hardware based on printer typelast_snapshot- Last hardware state snapshot for change detection
default_macros
Section titled “default_macros”Type: object
Description: G-code HelixScreen runs for built-in buttons. Each entry can be a plain G-code string or an object with label and gcode fields. Only cooldown is read today: the Filament panel’s Load and Unload follow the standard macros, and the Controls panel’s quick buttons follow quick_button_1 … quick_button_4. The other keys are still written with their defaults and are ignored.
Default values:
{ "default_macros": { "cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0", "load_filament": { "label": "Load", "gcode": "LOAD_FILAMENT" }, "unload_filament": { "label": "Unload", "gcode": "UNLOAD_FILAMENT" }, "macro_1": { "label": "Clean Nozzle", "gcode": "HELIX_CLEAN_NOZZLE" }, "macro_2": { "label": "Bed Level", "gcode": "HELIX_BED_LEVEL_IF_NEEDED" } }}| Key | Format | Where it’s used |
|---|---|---|
cooldown |
G-code string | Preheat widget (auto-shows “Cool Down” when heaters are on), Filament panel cooldown button |
load_filament, unload_filament, macro_1, macro_2 |
{ "label", "gcode" } |
Not read |
Customizing cooldown for enclosed printers:
If your printer has a chamber heater, bed fans, or recirculation fans that should turn off during cooldown, override the cooldown macro:
{ "cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0\nSET_HEATER_TEMPERATURE HEATER=chamber_heater TARGET=0\nSET_FAN_SPEED FAN=bed_fan SPEED=0"}Multi-line G-code is separated by \n. You can also reference a Klipper macro by name (e.g., "cooldown": "MY_COOLDOWN_MACRO").
Configured via Settings > Printing > Macro Buttons, or by editing settings.json directly.
Moonraker Settings
Section titled “Moonraker Settings”Connection settings are in the printer section:
{ "printer": { "moonraker_host": "192.168.1.100", "moonraker_port": 7125, "moonraker_api_key": false, "moonraker_connection_timeout_ms": 10000, "moonraker_request_timeout_ms": 30000, "moonraker_keepalive_interval_ms": 10000, "moonraker_reconnect_min_delay_ms": 200, "moonraker_reconnect_max_delay_ms": 2000, "moonraker_timeout_check_interval_ms": 2000 }}moonraker_host
Section titled “moonraker_host”Type: string
Default: "127.0.0.1" (the value in config/settings.json.template)
Description: Moonraker hostname or IP address.
moonraker_port
Section titled “moonraker_port”Type: integer
Default: 7125
Description: Moonraker port number.
moonraker_api_key
Section titled “moonraker_api_key”Type: string or false
Default: false
Description: API key if Moonraker authentication is enabled. Set to false if no authentication.
moonraker_connection_timeout_ms
Section titled “moonraker_connection_timeout_ms”Type: integer
Default: 10000
Description: Connection timeout in milliseconds.
moonraker_request_timeout_ms
Section titled “moonraker_request_timeout_ms”Type: integer
Default: 30000
Description: Request timeout for Moonraker API calls.
moonraker_keepalive_interval_ms
Section titled “moonraker_keepalive_interval_ms”Type: integer
Default: 10000
Description: Interval for WebSocket keepalive pings.
moonraker_reconnect_min_delay_ms
Section titled “moonraker_reconnect_min_delay_ms”Type: integer
Default: 200
Description: Minimum delay before reconnection attempt.
moonraker_reconnect_max_delay_ms
Section titled “moonraker_reconnect_max_delay_ms”Type: integer
Default: 2000
Description: Maximum delay before reconnection attempt (exponential backoff cap).
moonraker_timeout_check_interval_ms
Section titled “moonraker_timeout_check_interval_ms”Type: integer
Default: 2000
Description: Interval for checking request timeouts.
Standard Macros (Quick Action Buttons)
Section titled “Standard Macros (Quick Action Buttons)”Located in the standard_macros section. These pick which built-in actions appear as the four quick-action buttons on the Controls panel:
{ "standard_macros": { "quick_button_1": "clean_nozzle", "quick_button_2": "bed_level", "quick_button_3": "", "quick_button_4": "" }}quick_button_1 … quick_button_4
Section titled “quick_button_1 … quick_button_4”Type: string
Default: "clean_nozzle" (button 1), "bed_level" (button 2), "" (buttons 3 and 4)
Values: any standard action name ("load_filament", "unload_filament", "purge", "pause", "resume", "cancel", "bed_mesh", "bed_level", "screws_tilt", "clean_nozzle", "heat_soak", "park_toolhead"), "builtin:light" (the printer light toggle), or "" (empty = hide the button)
Description: Assigns an action to each of the four Controls-panel quick buttons. A standard action runs the macro assigned to it (auto-detected from your Klipper config unless you override it below). "builtin:light" makes the button a light switch, hidden while no light is controllable. An empty string hides the button.
A key that is absent is different from one set to "". While a light is controllable and no button is set to "builtin:light", the first button whose key is absent and that would otherwise show nothing becomes the light switch. A button set to "" is never filled that way. Configured most easily via Settings > Printing > Macro Buttons rather than by editing JSON.
load_filament, unload_filament, purge, pause, resume, cancel, bed_mesh, bed_level, clean_nozzle, heat_soak
Section titled “load_filament, unload_filament, purge, pause, resume, cancel, bed_mesh, bed_level, clean_nozzle, heat_soak”Type: string
Default: "" (empty = use auto-detection)
Description: Overrides which macro HelixScreen runs for each standard action. An empty
string means “auto-detect from your Klipper config”; a macro name pins that slot to your
choice. Written by Settings > Printing > Macro Buttons, which is the easier way to set them
because it lists the macros your printer actually defines.
{ "standard_macros": { "unload_filament": "MY_UNLOAD_ROUTINE" }}On a printer with a multi-filament system, load_filament and unload_filament also decide
who performs the operation. Left empty, the filament system does it. Set to a macro, your
macro does it instead and the filament system’s own handling is skipped for that operation —
see Customizing which macro runs.
Note: This is separate from
printer.default_macros, which customizes the Load/Unload/cooldown/custom-macro buttons elsewhere in the UI. See Printer Settings › default_macros.
G-code Viewer Settings
Section titled “G-code Viewer Settings”Located in the gcode_viewer section:
{ "gcode_viewer": { "tube_sides": 4, "streaming_mode": "auto", "streaming_threshold_percent": 40, "layers_per_frame": 0, "adaptive_layer_target_ms": 16 }}tube_sides
Section titled “tube_sides”Type: integer
Default: 4
Values: 4, 8, 16
Description: Cross-section detail for filament paths:
4- Diamond shape, fastest rendering8- Octagonal, balanced quality16- Circular, matches OrcaSlicer quality
streaming_mode
Section titled “streaming_mode”Type: string
Default: "auto"
Values: "auto", "on", "off"
Description: Large G-code file handling:
auto- Stream files that would use too much RAMon- Always stream (lowest memory)off- Always load full file (fastest viewing)
Can be overridden via HELIX_GCODE_STREAMING env var.
streaming_threshold_percent
Section titled “streaming_threshold_percent”Type: integer
Default: 40
Range: 1 - 90
Description: Percent of available RAM that triggers streaming mode. Lower values stream smaller files. Only used when streaming_mode is "auto". On boards with 2GB of RAM or less this is capped at 15.
layers_per_frame
Section titled “layers_per_frame”Type: integer
Default: 0 (auto)
Range: 0 - 100
Description: Number of layers to render per frame during progressive 2D visualization:
0- Auto (adaptive based on render time, default)1-100- Fixed value
Higher values = faster caching, but may cause UI stutter on slow devices.
adaptive_layer_target_ms
Section titled “adaptive_layer_target_ms”Type: integer
Default: 16
Description: Target render time in milliseconds when using adaptive layers_per_frame (only used when layers_per_frame=0). Lower = smoother UI, higher = faster caching. Default 16ms targets ~60 FPS.
AMS Settings
Section titled “AMS Settings”Located in the ams section:
{ "ams": { "spool_style": "3d" }}spool_style
Section titled “spool_style”Type: string
Default: "3d"
Values: "3d", "flat"
Description: Filament spool visualization style:
3d- Bambu-style pseudo-3D canvas with gradientsflat- Simple concentric rings
Per-printer AMS settings
Section titled “Per-printer AMS settings”The remaining AMS settings are per printer, so they live under the printer’s own section rather than the top-level ams block:
{ "printers": { "default": { "ams": { "force_bypass_controls": false, "always_show_bypass_spool": false, "keep_spool_info_on_eject": true, "afc_unload_after_print": false } } }}All four have UI equivalents in Settings > Devices > Multi-Filament System Management - edit them there rather than by hand.
force_bypass_controls
Section titled “force_bypass_controls”Type: boolean
Default: false
Description: Show the bypass controls and the external spool on the filament path even when the firmware reports no bypass position. Applies to Anycubic ACE Pro, Snapmaker U1, tool changers, QIDI Box, and Happy Hare configs where [mmu_machine] has_bypass is 0. The matching UI row is hidden whenever the firmware does report a bypass - including the Creality CFS, whose bypass always works.
On Happy Hare, MMU_SELECT_BYPASS ignores has_bypass and works either way, so this setting makes the bypass usable on mmu_vendor: Other setups and on uncalibrated type-A selectors. On the other systems there is no bypass command to send: the Bypass toggle reports that the operation is not supported, and the setting controls only whether the external spool is displayed and tracked.
See Filament → When Bypass Doesn’t Appear.
always_show_bypass_spool
Section titled “always_show_bypass_spool”Type: boolean
Default: false
Description: Keep the external spool visible on the filament path while bypass is disengaged. Applies to AFC systems (Box Turtle, OpenAMS) only, which publish a virtual bypass sensor whether or not one is physically wired; without this, the node is drawn only while bypass is actually engaged.
keep_spool_info_on_eject
Section titled “keep_spool_info_on_eject”Type: boolean
Default: true
Description: Keep a lane’s spool details after it empties, so reloading the same spool after maintenance needs no re-selection. Turn it off to start fresh whenever a lane empties. Applies only to spools selected in HelixScreen; a spool assigned elsewhere (such as Mainsail) clears with the lane. To have every assigned spool remembered no matter where it was picked, use the firmware’s own retention instead (AFC: remember_spool in AFC.cfg) - HelixScreen follows the spool the firmware reports. When that firmware retention covers every lane, it takes precedence and the matching toggle shows as disabled. The toggle (Keep Spool Info on Eject, in the AMS Management overlay) is shown only on systems whose firmware tracks spool ids per lane (AFC, Happy Hare); systems that detect spool swaps by tag always refresh on a swap regardless of this setting.
afc_unload_after_print
Section titled “afc_unload_after_print”Type: boolean
Default: false
Description: On AFC systems, retract filament back to its lane when a print finishes.
Panel Widget Settings
Section titled “Panel Widget Settings”Located under the panel_widgets key, grouped by panel ID. The Home panel uses a multi-page format with explicit grid positions:
{ "panel_widgets": { "home": { "pages": [ { "id": "main", "widgets": [ {"id": "printer_image", "enabled": true, "col": 0, "row": 0, "colspan": 4, "rowspan": 4}, {"id": "print_status", "enabled": true, "col": 0, "row": 4, "colspan": 8, "rowspan": 4}, {"id": "temperature", "enabled": true, "col": 4, "row": 0, "colspan": 2, "rowspan": 2}, {"id": "fan_stack", "enabled": true, "col": 4, "row": 2, "colspan": 2, "rowspan": 2} ] }, { "id": "page_1", "widgets": [ {"id": "temp_graph", "enabled": true, "col": 0, "row": 0, "colspan": 8, "rowspan": 6}, {"id": "camera", "enabled": true, "col": 8, "row": 0, "colspan": 8, "rowspan": 6} ] } ], "main_page_index": 0, "next_page_id": 2 } }}Positions and spans are counted in half cells, not cells. The grid is laid out in half-cell tracks so that a few widgets can sit on half-cell boundaries, and these numbers are in those tracks. A one-cell widget is
"colspan": 2, "rowspan": 2; the two-by-two Printer Image above is4by4. Multiply by two when translating a size you read off the Widget Catalog badge or the Home Panel guide, which are both written in whole cells.
panel_widgets.home
Section titled “panel_widgets.home”Type: object Description: Controls the Home Panel’s pages and widgets. Contains:
pages— Array of page objects. Each page has:id— Unique page identifier (e.g.,"main","page_1")widgets— Array of widget objects on this page (see below)
main_page_index— Which page is the “main” page (shown on first connect and when double-tapping Home).0= first page.next_page_id— Internal counter for generating unique page IDs. Do not modify manually.
Each widget object has:
id— Widget identifier (see table below)enabled— Whether the widget is shown (true/false). A widget withenabled: falsesits in the Widget Catalog waiting for you to add it backcol— Grid column position in half cells (0-based, left to right).-1means “no position yet”row— Grid row position in half cells (0-based, top to bottom).-1means “no position yet”colspan— Width in half cells (2= one cell wide)rowspan— Height in half cells (2= one cell tall)
What
col: -1/row: -1means. The widget is switched on but has nowhere to sit right now, usually because the grid was full when HelixScreen last laid out the page. It is not disabled: as soon as a cell frees up - you remove another widget, unplug the hardware another widget needed, or view the same layout on a screen with a bigger grid - it places itself again automatically. You do not need to re-add it from the catalog.
config— (optional) Per-widget settings object, written by the gear button in Edit Mode. Which keys apply depends on the widget:
| Key | Widgets | Values |
|---|---|---|
display_mode |
temp_stack, fan_stack, thermistor |
"stack" (default) or "carousel" |
layout_style |
print_status |
"detailed" for the expanded card, otherwise the compact one |
fan |
fan |
Name of the fan to monitor |
sensor |
thermistor |
Name of the sensor to display |
sensors |
thermistor, temp_graph |
Array of sensor names to include |
macro, color, require_confirmation |
favorite_macro |
Macro to run, icon tint, and whether tapping prompts before it runs |
device |
power_device |
Name of the Moonraker power device to bind |
icon |
favorite_macro, power_device, temp_stack, fan_stack, tool_switcher |
Icon name override |
rotation, flip_h, flip_v |
camera |
0/90/180/270, and booleans |
source |
camera |
Name of the webcam to show, exactly as Moonraker lists it; empty or omitted picks the camera automatically |
source, danger_threshold |
clog_detection |
Detection source and danger-zone percentage |
source |
filament |
Which sensor role the tile follows: "auto" (default), "runout", "toolhead", or "entry" |
material_index |
preheat |
Which material profile the buttons preheat to |
led |
led |
Which light this button controls: a light id (e.g. "neopixel chamber_light"), "all" for every light, or omitted for the chamber light |
require_confirmation is the one worth spelling out: omitted (the default) means tapping the button prompts first - a parameter form when the macro takes parameters, otherwise the Settings > Safety & Alerts confirmation dialog. false runs the macro on a single tap with no parameters and no dialog. Dangerous macros confirm regardless. Set it from the widget’s Options tab; see Macro Button confirmation.
Configs written before
config_version23 stored the inverse of this asskip_param_prompt, which suppressed only the parameter form. HelixScreen rewrites it torequire_confirmationon first launch.
Setting these through Edit Mode is far easier than editing them here, and it is the only way that validates the value against your printer.
Available widget IDs:
For what each widget does and how big it can get, see the Home Panel guide. This table is just the ID-to-widget mapping you need when editing the JSON.
| ID | Widget | On by default | Hardware-gated |
|---|---|---|---|
printer_image |
Printer Image | Yes | No |
print_status |
Print Status | Yes | No |
control_buttons |
Print Controls | No | No |
print_stats |
Print Stats | No | No |
job_queue |
Job Queue | No | No |
camera |
Camera | No | Webcam configured |
temperature |
Nozzle Temperature | Yes | No |
nozzle_temps |
Nozzle Temperatures | No | No |
bed_temperature |
Bed Temperature | Yes | No |
chamber_temperature |
Chamber Temperature | No | Chamber sensor or heater |
temp_stack |
Temperatures | No | No |
thermistor |
Temperature Sensors | No | Extra temperature sensors |
temp_graph |
Temperature Graph | No | No |
preheat |
Preheat | No | No |
fan_stack |
Fan Speeds | Yes | No |
fan |
Fan | No | No |
ams |
Multi-Filament System Status | No | AMS/MMU detected |
active_spool |
Active Spool | No | No |
filament |
Filament Sensor | Yes | Filament sensor |
humidity |
Humidity | No | Humidity sensor |
width_sensor |
Width Sensor | No | Width sensor |
clog_detection |
Clog Detection | No | Clog detection hardware |
favorite_macro |
Macro Button | No | No |
macros |
Macros | No | No |
gcode_console |
G-code Console | No | No |
motion |
Motion | No | No |
tool_switcher |
Tool Switcher | No | No |
power_device |
Power | No | Moonraker power device |
led |
LED Light | Yes | LEDs configured |
led_controls |
LED Controls | No | LEDs configured |
network |
Network | No | No |
notifications |
Notifications | Yes | No |
clock |
Digital Clock | No | No |
tips |
Tips | Yes | No |
shutdown |
Shutdown/Reboot | No | No |
firmware_restart |
Firmware Restart | No | No |
lock |
Lock Screen | No | No |
power_device, fan, thermistor, favorite_macro, temp_graph, and led can appear more than once. Extra copies get an ID like favorite_macro:2.
Notes:
- Widget grid positions (
col,row,colspan,rowspan) determine where each widget appears on its page, in half cells - Hardware-gated widgets are hidden on the Home Panel if their hardware isn’t detected, even when enabled
- New widgets are appended automatically with their default enabled state
- Widget IDs that HelixScreen doesn’t recognise are ignored
- Up to 8 pages are supported
This is best configured via Edit Mode on the Home Panel (long-press the widget grid) rather than editing the JSON directly. See the Home Panel guide for details on adding pages and arranging widgets.
Cache Settings
Section titled “Cache Settings”Located in the cache section:
{ "cache": { "thumbnail_max_mb": 20, "disk_critical_mb": 5, "disk_low_mb": 20 }}thumbnail_max_mb
Section titled “thumbnail_max_mb”Type: integer
Default: 20
Description: Maximum thumbnail cache size in MB. Cache auto-sizes to 5% of available disk, capped at this limit.
disk_critical_mb
Section titled “disk_critical_mb”Type: integer
Default: 5
Description: Stop caching when available disk falls below this threshold (MB). Prevents filling filesystem.
disk_low_mb
Section titled “disk_low_mb”Type: integer
Default: 20
Description: Evict cache aggressively when available disk falls below this threshold (MB). Reduces cache to half normal limit.
Streaming Settings
Section titled “Streaming Settings”Located in the streaming section:
{ "streaming": { "threshold_mb": 0, "force_streaming": false }}threshold_mb
Section titled “threshold_mb”Type: integer
Default: 0 (no size ceiling)
Description: Files larger than this many MB always stream, even when available RAM would allow loading them whole. 0 leaves the decision to the RAM-based rule in streaming_threshold_percent. A value here can only add streaming; it never loads a larger file whole.
force_streaming
Section titled “force_streaming”Type: boolean
Default: false
Description: Always stream, regardless of file size. Same as gcode_viewer.streaming_mode: "on" or HELIX_GCODE_STREAMING=on; an explicit streaming_mode of "off" or "on" takes precedence.
Safety Settings
Section titled “Safety Settings”Located in the safety section:
{ "safety": { "estop_require_confirmation": true, "cancel_escalation_enabled": false, "cancel_escalation_timeout_seconds": 30 }}estop_require_confirmation
Section titled “estop_require_confirmation”Type: boolean
Default: true
Description: Require confirmation dialog before emergency stop. When false, E-Stop triggers immediately. Default is true to prevent accidental emergency stops.
cancel_escalation_enabled
Section titled “cancel_escalation_enabled”Type: boolean
Default: false
Description: When enabled, a cancel that doesn’t complete within the configured timeout will automatically escalate to an emergency stop (M112). When false (the default), cancel waits indefinitely for the printer to finish its cancel routine. Leave this off if your printer has a long cancel macro (e.g., toolchangers that need to park tools).
cancel_escalation_timeout_seconds
Section titled “cancel_escalation_timeout_seconds”Type: integer
Default: 30
Options: 15, 30, 60, 120
Description: How long to wait (in seconds) after sending a cancel before escalating to emergency stop. Only applies when cancel_escalation_enabled is true.
Notification Settings
Section titled “Notification Settings”Located in the notifications section:
{ "notifications": { "min_toast_severity": 0 }}min_toast_severity
Section titled “min_toast_severity”Type: integer
Default: 0
Values: 0 (all toasts), 1 (warnings & errors), 2 (errors only)
Description: The lowest notification level allowed to interrupt with a toast. Below-the-line notifications still land in the notification history; full-screen error dialogs always show. Change via Settings > Safety & Alerts > On-screen Alerts.
Filament Settings
Section titled “Filament Settings”Located in the filament section:
{ "filament": { "auto_cooldown": true, "cooldown_delay_seconds": 120 }}auto_cooldown
Section titled “auto_cooldown”Type: boolean
Default: true
UI: Settings > Printing > Cool nozzle after filament ops
Description: Whether HelixScreen turns the extruder heater off after a filament load or unload completes. Turn this off if your filament system runs its own post-operation cooldown — AFC does, in recent versions — so the two aren’t both driving the same heater.
cooldown_delay_seconds
Section titled “cooldown_delay_seconds”Type: integer
Default: 120
Description: How long to wait, in seconds, after a filament load or unload before automatically turning the extruder heater off. This lets you run several filament operations back-to-back without the nozzle cooling down between them. Default is 120 (2 minutes). Setting this to 0 also disables auto-cooldown, but prefer auto_cooldown — it’s the one the UI toggle writes.
favorite_ids
Section titled “favorite_ids”Added in 1.1.
Type: array of strings
Default: []
Description: The filament types you have starred, in star order. Written whenever you tap a star in a filament selector; each entry is the filament’s product id. Edit it only to reorder or clear: a hand-added id that matches nothing simply never shows.
Filament Sensor Settings
Section titled “Filament Sensor Settings”Located in the filament_sensors section:
{ "filament_sensors": { "master_enabled": true, "sensors": [] }}master_enabled
Section titled “master_enabled”Type: boolean
Default: true
Description: Global toggle to enable/disable all filament sensor monitoring. When false, sensor states are ignored and no runout detection occurs.
sensors
Section titled “sensors”Type: array
Default: []
Description: Array of sensor configurations. Sensors are auto-discovered from Moonraker. Each sensor object has:
klipper_name- Full Klipper object name (e.g.,"filament_switch_sensor fsensor")role- Sensor role:"none","runout","toolhead","entry"enabled- Boolean to enable/disable individual sensorlane- Optional. The filament slot or toolhead (0-based) this sensor watches, for printers with one sensor per head. Each head can then have its ownrunoutsensor, and the check before a print reads the sensors of the heads the file uses.
Example:
{ "sensors": [ { "klipper_name": "filament_switch_sensor fsensor", "role": "runout", "enabled": true } ]}Security Settings
Section titled “Security Settings”Located in the security section. Controls the optional PIN lock screen:
{ "security": { "pin_hash": "", "auto_lock": false }}security.pin_hash
Section titled “security.pin_hash”Type: string
Default: "" (empty = lock screen disabled)
Description: A SHA-256 hash of your lock-screen PIN. HelixScreen stores only this hash, never the PIN itself. Do not edit this value by hand — set, change, or clear your PIN through Settings > System > Security, which computes and writes the hash for you. An empty string means no PIN and no lock screen.
security.auto_lock
Section titled “security.auto_lock”Type: boolean
Default: false
Description: When true, the screen automatically locks whenever the display sleeps and wakes, requiring your PIN to get back in. Has no effect unless pin_hash is set (with no PIN there is nothing to lock). Toggle via Settings > System > Security.
Label Printer Settings
Section titled “Label Printer Settings”Located in the label_printer section. Configures the thermal label printer used to print filament spool labels. This is best set up through Settings > Devices > Spoolman > Label Printer — scanning and selecting a printer fills these fields in for you. The keys are documented here for reference. See the Label Printing guide for the full walkthrough.
{ "label_printer": { "type": "network", "address": "", "port": 9100, "protocol": "raw", "label_size": 0, "preset": 0, "label_count": 1, "usb_vid": 0, "usb_pid": 0, "usb_serial": "", "bt_address": "", "bt_name": "", "bt_transport": "spp" }}Type: string
Default: "network"
Values: "network", "usb", "bluetooth"
Description: How the label printer connects — Network (Brother QL over Ethernet/WiFi), USB (Phomemo over cable), or Bluetooth (any supported printer paired over Bluetooth). Bluetooth is only offered when your device has Bluetooth hardware.
address
Section titled “address”Type: string
Default: ""
Description: IP address or hostname of a network label printer. Only used when type is "network".
Type: integer
Default: 9100
Description: TCP port for a network label printer. 9100 is the standard RAW/JetDirect port used by Brother QL. Only used when type is "network".
protocol
Section titled “protocol”Type: string
Default: "raw"
Values: "raw", "ipp"
Description: Network print protocol. "raw" (JetDirect, port 9100) works for most printers; "ipp" is used by some networked models.
label_size
Section titled “label_size”Type: integer
Default: 0
Description: Index of the label/tape size preset for your printer. 0 selects that model’s default size. The available sizes depend on the detected printer (a Niimbot D11 offers different sizes than a B21), so pick yours from the size list in the Label Printer settings overlay rather than guessing an index.
preset
Section titled “preset”Type: integer
Default: 0
Description: Label content layout preset. 0 = Standard (full label: spool name, material, color, temperatures, and QR code); other indices select the Compact or QR Only layouts. Choose it in the Label Printer settings overlay.
label_count
Section titled “label_count”Type: integer
Default: 1
Description: Number of copies to print per label job.
usb_vid / usb_pid / usb_serial
Section titled “usb_vid / usb_pid / usb_serial”Type: integer / integer / string
Default: 0 / 0 / ""
Description: USB vendor ID, product ID, and serial number identifying a USB label printer. 0 (and an empty serial) means auto-detect — you normally never set these by hand. Only used when type is "usb".
bt_address / bt_name / bt_transport
Section titled “bt_address / bt_name / bt_transport”Type: string / string / string
Default: "" / "" / "spp"
Description: Bluetooth MAC address, advertised name, and transport of a Bluetooth label printer. bt_transport is "spp" (Bluetooth Classic / RFCOMM — used by Brother PT, Phomemo, and MakeID) or "ble" (Bluetooth Low Energy — used by Niimbot). These are filled in automatically when you scan and select a printer; you don’t normally type the MAC address by hand. Only used when type is "bluetooth".
Printer Switcher
Section titled “Printer Switcher”Located in the printers section:
{ "printers": { "show_printer_switcher": false }}printers.show_printer_switcher
Section titled “printers.show_printer_switcher”Type: boolean
Default: false
Description: Show a printer-switcher button on the Home panel for quickly jumping between configured printers. Off by default since single-printer setups don’t need it; turn it on when you manage more than one printer. See Multi-Printer Configuration above.
Telemetry Settings
Section titled “Telemetry Settings”telemetry_enabled
Section titled “telemetry_enabled”Type: boolean
Default: false
Description: Enables anonymous usage telemetry. This is a top-level key (not nested in a section). OFF by default — you must opt in, either during the setup wizard or via Settings > System > Share Usage Data. While false, nothing is collected, queued, or transmitted. For a full breakdown of exactly what is and isn’t collected, and how the data is anonymized, see the Telemetry documentation.
Update Settings
Section titled “Update Settings”channel lives in the update section of settings.json. The URL overrides
(dev_url, r2_url) live in a separate root-owned file,
/var/lib/helixscreen/update_urls.json, because the updater installs whatever
those URLs serve and settings.json is editable from the web UI:
{ "update": { "channel": 0 }}{ "r2_url": "", "dev_url": ""}The override file only takes effect when it is owned by root or the user
HelixScreen runs as and has no group or world write bit. /var/lib/helixscreen
is created by the systemd unit or the init script on every platform; on a device
where it is missing yet:
sudo mkdir -p /var/lib/helixscreen && sudo chown root:root /var/lib/helixscreen && sudo chmod 755 /var/lib/helixscreensudo install -o root -g root -m 644 update_urls.json /var/lib/helixscreen/update_urls.jsonchannel
Section titled “channel”Type: integer
Default: 0
Values: 0 (Stable), 1 (Beta), 2 (Dev)
Description: Update channel selection:
0- Stable: Tries R2 CDN first ({r2_url}/stable/manifest.json), falls back to GitHub releases API1- Beta: Tries R2 CDN first ({r2_url}/beta/manifest.json), falls back to GitHub pre-releases API2- Dev: Usesdev_urlfrom the trusted override file if set, otherwise uses R2 CDN ({r2_url}/dev/manifest.json)
Can also be changed from the Settings panel. Stable and Beta are offered on any
install; Dev appears only when beta_features is enabled.
dev_url
Section titled “dev_url”Where: /var/lib/helixscreen/update_urls.json
Type: string
Default: "" (empty)
Example: "https://releases.helixscreen.org/dev"
Description: Explicit base URL for the dev update channel. When set and channel is 2, HelixScreen fetches {dev_url}/manifest.json directly, bypassing R2. When empty, the dev channel uses the R2 CDN path ({r2_url}/dev/manifest.json). Must use http:// or https:// scheme. Primarily used for local development servers or self-hosted setups that predate R2 support.
r2_url
Section titled “r2_url”Where: /var/lib/helixscreen/update_urls.json
Type: string
Default: "" (uses built-in https://releases.helixscreen.org)
Example: "https://my-cdn.example.com"
Description: Base URL for R2/CDN update manifests. All channels (Stable, Beta, Dev) fetch manifests from {r2_url}/{channel}/manifest.json. When empty, uses the compiled-in default (https://releases.helixscreen.org). Self-hosters can override this to point to their own CDN or R2 bucket. Trailing slashes are automatically stripped.
Upgrade Nudge
Section titled “Upgrade Nudge”Located in the top-level upgrade_nudge section. Controls how insistently HelixScreen tells you an update is waiting.
{ "upgrade_nudge": { "intensity": "off", "dismissed_version": "" }}upgrade_nudge.intensity
Section titled “upgrade_nudge.intensity”Type: string
Default: "off"
Values: "off", "normal", "aggressive"
Description: How visible the update prompt is.
"off"— nothing. An available update is only visible in Settings > Help & About"normal"— a red dot on the Settings icon"aggressive"— the red dot, plus a banner across the top of the screen that stays until you dismiss it
No nudge of any kind appears while a print is running.
upgrade_nudge.dismissed_version
Section titled “upgrade_nudge.dismissed_version”Type: string
Default: "" (empty)
Description: The version whose banner you dismissed. Set for you when you close the banner, and only suppresses that exact version — the next release brings the banner back. Clear it to see the banner again for a version you already dismissed.
Safety Limits
Section titled “Safety Limits”HelixScreen checks every temperature, move, and fan command it sends against a set of safety limits: a temperature ceiling for each heater, axis travel limits, a maximum feedrate, and fan speed bounds.
The limits are read automatically from your printer’s own Klipper configuration:
- Each heater is capped at its own
max_temp, so a 290 °C nozzle and a 120 °C heated bed are each limited correctly - Axis travel limits come from your steppers’
position_minandposition_max - The maximum feedrate comes from your printer’s
max_velocity
Generous built-in defaults apply where your configuration is silent. Where your Klipper configuration states a value, that value governs, so a high-temperature hotend or a very large build volume is picked up automatically with no setting to change.
Safety limits are not settable in settings.json. If a limit is wrong for your printer, change the value in printer.cfg: that is the one source every tool respects, including Mainsail, Fluidd, and your slicer. Editing a curated set of those values directly from HelixScreen is proposed in issue #1699.
Capability Overrides
Section titled “Capability Overrides”Located in printer.capability_overrides:
{ "printer": { "capability_overrides": { "bed_mesh": "auto", "qgl": "auto", "z_tilt": "auto", "nozzle_clean": "auto", "heat_soak": "auto", "chamber": "auto", "speaker": "auto" } }}Values for each setting:
"auto"- Use Moonraker detection"enable"- Force feature on"disable"- Force feature off
Use cases:
- Enable
heat_soakwhen you have a chamber but no chamber heater (soak macro works without) - Disable
qglon a printer where it’s defined but not used - Enable
bed_meshif detection failed - Disable
speakeron a board whose buzzer is detected but not wired, so HelixScreen stops trying to play M300 beeps through it
Resetting Configuration
Section titled “Resetting Configuration”Full Reset
Section titled “Full Reset”Delete the config file and restart (use your actual install path):
# Pi with Klipper ecosystem:rm ~/helixscreen/config/settings.json# Pi without ecosystem (or if installed to /opt):sudo rm /opt/helixscreen/config/settings.json
sudo systemctl restart helixscreenThis triggers the first-run wizard.
Partial Reset
Section titled “Partial Reset”Edit the config file directly:
nano ~/helixscreen/config/settings.jsonOr copy fresh from template:
cp ~/helixscreen/config/settings.json.template ~/helixscreen/config/settings.jsonConfig Safety & Recovery
Section titled “Config Safety & Recovery”HelixScreen protects your configuration against corruption and data loss:
Atomic Saves
Section titled “Atomic Saves”Configuration writes use atomic file operations — data is written to a temporary file first, then renamed into place. This prevents partial writes from corrupting your config if power is lost during a save.
Corruption Detection
Section titled “Corruption Detection”If settings.json contains invalid JSON (e.g., from manual editing errors),
HelixScreen detects the parse failure and:
- Renames the corrupt file to
settings.json.corrupt(preserved for diagnosis) - Loads safe defaults
- Logs the error with details about what went wrong
Rolling Backups
Section titled “Rolling Backups”Every successful config save maintains rolling backups in two locations:
/var/lib/helixscreen/settings.json.backup(primary — survives app reinstalls)~/.helixscreen/settings.json.backup(fallback)
If settings.json is missing at startup (e.g., after a Moonraker update wipe),
HelixScreen automatically restores from the most recent backup.
Recovery Steps
Section titled “Recovery Steps”If your config is lost or corrupted:
- Automatic: HelixScreen restores from rolling backup on next launch
- Manual: Check for
settings.json.corruptin your config directory — this contains your previous (invalid) config that you can manually fix - Fresh start: delete
settings.jsonand the backup copies (see Reset HelixScreen or re-run the setup wizard), or use Settings > System > Factory Reset. A template copy alone is replaced from the rolling backup on the next start
If you have a helixconfig.json
Section titled “If you have a helixconfig.json”Installing or updating HelixScreen renames it to settings.json. Until then
HelixScreen still reads it when it is the symlink into printer_data that older
Raspberry Pi installs made. A plain helixconfig.json comes from a release older
than v0.99.4, too old to migrate, so HelixScreen starts from defaults.
Command-Line Options
Section titled “Command-Line Options”HelixScreen accepts command-line options for overriding configuration and debugging.
Display Options
Section titled “Display Options”| Option | Description |
|---|---|
-s, --size <size> |
Screen size: tiny (480×320), small (480×400), medium (800×480), large (1024×600) |
--layout <type> |
Override auto-detected layout: auto, standard, ultrawide, portrait, micro, micro-portrait, tiny, tiny-portrait. ultrawide and all portrait variants are alpha — see the layout setting |
--dpi <n> |
Display DPI (50-500, default: 160) |
--dark |
Use dark theme |
--light |
Use light theme |
--skip-splash |
Skip splash screen on startup |
--no-sound |
Disable all sound output (prevents audio backend initialization) |
Navigation Options
Section titled “Navigation Options”| Option | Description |
|---|---|
-w, --wizard |
Force first-run configuration wizard |
--skip-wizard |
Suppress the first-run wizard (for automation/screenshots) |
Developers: to drive the UI to a specific panel or overlay, see
docs/devel/HELIXCTL.md(thehelix-screen ctlremote-control client). The control server it talks to is auto-enabled in--testmode, or opt-in with--remote(and--remote-socket <path>to override the socket location).
Connection Options
Section titled “Connection Options”| Option | Description |
|---|---|
--moonraker <url> |
Override Moonraker URL (e.g., ws://192.168.1.100:7125) |
Logging Options
Section titled “Logging Options”| Option | Description |
|---|---|
-v, --verbose |
Increase verbosity (-v=info, -vv=debug, -vvv=trace) |
--log-dest <dest> |
Log destination: auto, journal, syslog, file, console |
--log-file <path> |
Log file path (when --log-dest=file) |
Debugging Options
Section titled “Debugging Options”| Option | Description |
|---|---|
--debug-touches |
Draw ripple effects at each touch point for diagnosing touch accuracy |
--calibrate-touch |
Force touch calibration on startup |
Utility Options
Section titled “Utility Options”| Option | Description |
|---|---|
--screenshot [sec] |
Take screenshot after delay (default: 2 seconds) |
-t, --timeout <sec> |
Auto-quit after specified seconds (1-3600) |
-h, --help |
Show help message |
-V, --version |
Show version information |
Examples
Section titled “Examples”# Start in dark mode, skipping the splash screenhelix-screen --dark --skip-splash
# Override Moonraker connectionhelix-screen --moonraker ws://192.168.1.50:7125
# Enable debug logginghelix-screen -vv
# Take screenshot after 5 secondshelix-screen --screenshot 5Note: Test mode options (
--test,--real-*) are for development only and not documented here.
Environment Variables
Section titled “Environment Variables”These belong in your helixscreen.env file (typically ~/helixscreen/config/helixscreen.env),
or in the environment before running the binary by hand. Do not put them in
/etc/systemd/system/helixscreen.service: that unit is rewritten from the install-dir
template on every start, so edits to it are discarded before the app launches.
Values in helixscreen.env are plain text. Surrounding quotes are removed and nothing is
expanded or run: a line whose value holds $VAR, $(...), ${...} or a backtick is
ignored, so write the final value itself. Only the settings on this page and in the file’s own comments
are read from it; any other line is ignored and noted in the log.
Display & Input:
| Variable | Description |
|---|---|
HELIX_DRM_DEVICE |
Override DRM device path (e.g., /dev/dri/card1) |
HELIX_DISPLAY_BACKEND |
Override display backend (drm, fbdev, sdl) |
HELIX_DISPLAY_ROTATION |
Override display rotation in degrees (0, 90, 180, 270) |
HELIX_COLOR_SWAP_RB |
Swap red/blue channels (1 to enable) — fixes inverted colors on some displays |
HELIX_BACKLIGHT_DEVICE |
Force the backlight control method: sysfs, allwinner, brightness (Creality Sonic Pad), or none to disable. Fixes a brightness slider that does nothing |
HELIX_DPI |
Override the panel’s DPI (50-500). Above 225 it enlarges the UI (1.1 and later; 500 is about 188%); at or below 225 it changes nothing, and it never shrinks the UI. The ui_scale_percent setting overrides it unless set to Automatic |
HELIX_SCREEN_SIZE |
Force screen resolution (micro, tiny, small, medium, large, xlarge, or WxH) — persistent equivalent of -s. Despite the name this is a resolution, not a UI scale; use ui_scale_percent to scale the interface |
HELIX_TOUCH_DEVICE |
Override touch input device (e.g., /dev/input/event1) |
HELIX_TOUCH_SWAP_AXES |
Swap X/Y touch axes (1 to enable) |
HELIX_TOUCH_CALIBRATE |
Force touch calibration on next launch (1 to enable) |
HELIX_MOUSE_DEVICE |
Override USB mouse device (e.g., /dev/input/event4) |
HELIX_KEYBOARD_DEVICE |
Override USB keyboard device (e.g., /dev/input/event5) |
HELIX_SCROLL_GUARD |
Override scroll_guard post-scroll tap suppression (1 to enable) |
HELIX_SCROLL_GUARD_COOLDOWN_MS |
Override scroll_guard_cooldown_ms window in milliseconds |
Theme & Rendering:
| Variable | Description |
|---|---|
HELIX_THEME |
Override theme (e.g., dracula, nord, gruvbox) |
HELIX_GCODE_MODE |
Override G-code render mode (3D or 2D, exact case-sensitive; unset = Auto, any other value = 2D) |
HELIX_GCODE_STREAMING |
Override G-code streaming mode |
Example in service file:
[Service]Environment="HELIX_DRM_DEVICE=/dev/dri/card1"Environment="HELIX_TOUCH_DEVICE=/dev/input/event0"Note: Most users won’t need environment variables. The config file options are preferred. Environment variables are mainly for debugging when the config file isn’t accessible.
For a comprehensive list of all environment variables (including mock/testing, touch calibration, UI automation, and more), see the Environment Variables Reference.
Example Complete Configuration
Section titled “Example Complete Configuration”{ "config_version": 24, "dark_mode": true, "brightness": 70, "sounds_enabled": true, "completion_alert": 1, "wizard_completed": true, "wifi_expected": true, "language": "en", "log_dest": "journal", "log_path": "", "log_level": "info",
"theme": { "preset": 0 },
"display": { "animations_enabled": true, "time_format": 0, "rotate": 0, "sleep_sec": 1200, "dim_sec": 600, "dim_brightness": 30, "drm_device": "", "gcode_render_mode": 2, "gcode_3d_enabled": true, "bed_mesh_render_mode": 0, "bed_mesh_show_zero_plane": true, "page_scroll_buttons": false, "speed_flow_physical_units": false, "printer_image": "" },
"input": { "scroll_throw": 25, "scroll_limit": 10, "scroll_guard": false, "scroll_guard_cooldown_ms": 80, "touch_device": "", "device_blacklist": [], "force_calibration": false, "calibration": { "valid": false, "a": 1.0, "b": 0.0, "c": 0.0, "d": 0.0, "e": 1.0, "f": 0.0 } },
"output": { "led_on_at_start": false },
"printer": { "name": "Voron 2.4 350", "type": "Voron 2.4", "moonraker_host": "localhost", "moonraker_port": 7125, "moonraker_api_key": false, "moonraker_connection_timeout_ms": 10000, "moonraker_request_timeout_ms": 30000, "moonraker_keepalive_interval_ms": 10000, "moonraker_reconnect_min_delay_ms": 200, "moonraker_reconnect_max_delay_ms": 2000, "moonraker_timeout_check_interval_ms": 2000, "heaters": { "hotend": "extruder", "bed": "heater_bed" }, "temp_sensors": { "hotend": "extruder", "bed": "heater_bed" }, "fans": { "part": "fan", "hotend": "heater_fan hotend_fan", "chamber": "", "exhaust": "" }, "leds": { "strip": "", "selected_strips": ["neopixel caselight"], "led_on_at_start": false, "last_color": 16777215, "last_brightness": 100, "color_presets": [16777215, 16711680, 65280, 255, 16776960, 16711935, 65535], "auto_state": { "enabled": false, "mappings": { "idle": { "action": "brightness", "brightness": 50, "color": 0 }, "heating": { "action": "color", "color": 16711680, "brightness": 100 }, "printing": { "action": "brightness", "brightness": 100, "color": 0 }, "paused": { "action": "off" }, "error": { "action": "color", "color": 16711680, "brightness": 100 }, "complete": { "action": "color", "color": 65280, "brightness": 100 } } }, "macro_devices": [] }, "extra_sensors": {}, "hardware": { "optional": [], "expected": [], "last_snapshot": {} }, "default_macros": { "cooldown": "SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0\nSET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0", "load_filament": { "label": "Load", "gcode": "LOAD_FILAMENT" }, "unload_filament": { "label": "Unload", "gcode": "UNLOAD_FILAMENT" }, "macro_1": { "label": "Clean Nozzle", "gcode": "HELIX_CLEAN_NOZZLE" }, "macro_2": { "label": "Bed Level", "gcode": "HELIX_BED_LEVEL_IF_NEEDED" } }, "capability_overrides": { "bed_mesh": "auto", "qgl": "auto", "z_tilt": "auto", "nozzle_clean": "auto", "heat_soak": "auto", "chamber": "auto" } },
"gcode_viewer": { "tube_sides": 8, "streaming_mode": "auto", "streaming_threshold_percent": 40, "layers_per_frame": 0, "adaptive_layer_target_ms": 16 },
"panel_widgets": { "home": { "pages": [ { "id": "main", "widgets": [ {"id": "printer_image", "enabled": true, "col": 0, "row": 0, "colspan": 2, "rowspan": 2}, {"id": "print_status", "enabled": true, "col": 0, "row": 2, "colspan": 2, "rowspan": 2}, {"id": "temperature", "enabled": true, "col": 2, "row": 0, "colspan": 1, "rowspan": 1}, {"id": "fan_stack", "enabled": true, "col": 3, "row": 0, "colspan": 1, "rowspan": 1} ] } ], "main_page_index": 0, "next_page_id": 1 } },
"ams": { "spool_style": "3d" },
"cache": { "thumbnail_max_mb": 20, "disk_critical_mb": 5, "disk_low_mb": 20 },
"streaming": { "threshold_mb": 0, "force_streaming": false },
"safety": { "estop_require_confirmation": true },
"filament_sensors": { "master_enabled": true, "sensors": [] },
"update": { "channel": 0 }}Back to: User Guide | Troubleshooting