### Example Third-Party Package Configuration (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/design/third_party.md This example demonstrates the configuration variables for a third-party integration package, specifically the Tailscale VPN. It shows how the version, download URL, and SHA256 checksum are defined for verification and installation. ```bash VERSION=1.92.5 URL="https://pkgs.tailscale.com/stable/tailscale_${VERSION}_arm64.tgz" SHA256=13a59c3181337dfc9fdf9dea433b04c1fbf73f72ec059f64d87466b79a3a313c ``` -------------------------------- ### Install Firmware via USB Drive Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Instructions for installing the custom firmware using a USB drive. This involves downloading the .bin file, copying it to a FAT32 formatted USB, and initiating the update from the printer's touchscreen. Ensure the USB drive is correctly formatted and the file is placed in the root directory. ```bash # 1. Download the firmware .bin file from GitHub Releases # https://github.com/paxx12/SnapmakerU1/releases # 2. Copy to FAT32 USB drive root directory cp U1_extended_v1.1.1.bin /media/usb/ # 3. On printer touchscreen: # Navigate to: Settings > About > Firmware Version > Local Update # Select the .bin file and confirm installation # Wait for update to complete (printer will reboot automatically) ``` -------------------------------- ### Download Tailscale Package (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/vpn.md This command downloads the Tailscale package, which is a prerequisite for manual setup on the printer. It requires an active internet connection on the printer. ```bash tailscale-pkg download ``` -------------------------------- ### Download OctoEverywhere Package (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/cloud.md This command downloads the OctoEverywhere package to the printer. It requires SSH access to the printer and an active internet connection. This is the first step in the manual setup process. ```bash ssh root@ octoeverywhere-pkg download ``` -------------------------------- ### Start Tailscale VPN (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/vpn.md This command initiates the Tailscale VPN connection. It allows the printer to join your Tailnet and become accessible from anywhere. The `tailscale status` command can be used to verify the connection and retrieve the printer's Tailscale IP address. ```bash tailscale up # show your tailscale IP tailscale status | grep lava 100.95.6.132 lava username@ linux - ``` -------------------------------- ### Camera Streaming Configuration Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Guides on configuring hardware-accelerated camera streaming using WebRTC, MJPEG, or RTSP protocols for both internal MIPI and USB cameras. It includes accessing stream URLs, control interfaces, and enabling USB cameras via the `extended2.cfg` file. Specific configurations for Moonraker are also provided. ```ini # Access internal camera stream # URL: http:///webcam/ # Access USB camera stream (when enabled) # URL: http:///webcam2/ # Camera controls interface # URL: http:///webcam/control # URL: http:///webcam2/control # Enable USB camera in extended2.cfg: [camera] usb: paxx12 # Configure camera streaming mode in moonraker config # File: /home/lava/printer_data/config/extended/moonraker/02_internal_camera.cfg [webcam case] service: webrtc-camerastreamer stream_url: /webcam/webrtc snapshot_url: /webcam/snapshot.jpg aspect_ratio: 16:9 # Available streaming modes: # - webrtc-camerastreamer (best quality, stream_url: /webcam/webrtc) ``` -------------------------------- ### Test OpenSpool JSON Payloads with CLI (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/30-rfid-support/test/README.md Examples demonstrating how to use the RFID OpenSpool CLI Test Tool to parse various OpenSpool JSON filament payloads. These commands help verify the tool's ability to correctly interpret different filament types and properties. ```bash python3 -m app.cli openspool-pla-basic.json python3 -m app.cli openspool-petg-rapid.json python3 -m app.cli openspool-silk-multicolor.json python3 -m app.cli openspool-abs-transparent.json python3 -m app.cli openspool-tpu-flexible.json ``` -------------------------------- ### Configure VPN Provider (INI) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/vpn.md This configuration snippet sets the VPN provider to 'tailscale' within the extended firmware configuration file. It is part of the manual setup process. ```ini [remote_access] vpn: tailscale ``` -------------------------------- ### Enable Tailscale VPN Remote Access Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Configure secure remote access to your printer using Tailscale VPN, eliminating the need for port forwarding. This involves downloading the package, enabling it in the configuration, and starting the service. ```bash # Enable Tailscale via SSH # Step 1: Download Tailscale package ssh root@192.168.1.100 tailscale-pkg download # Step 2: Enable in config file cat << 'EOF' >> /home/lava/printer_data/config/extended/extended2.cfg [remote_access] vpn: tailscale EOF # Step 3: Start VPN service /etc/init.d/S99vpn restart # Step 4: Login to your Tailnet tailscale up # View your Tailscale IP tailscale status | grep lava # Output: 100.95.6.132 lava username@ linux - # Optional: Enable Tailscale SSH (passwordless access) tailscale up --ssh # Optional: Enable SSL certificates via Tailscale Serve tailscale serve --bg 80 # Access securely at: https://lava.your-tailnet.ts.net/ ``` -------------------------------- ### Custom Klipper Macro Example (CFG) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/klipper_includes.md This snippet demonstrates how to define a custom G-code macro in Klipper using a `.cfg` file. It shows the basic structure for creating a macro named 'CUSTOM_MACRO' that executes G28 (homing) and then moves the Z-axis. ```cfg [gcode_macro CUSTOM_MACRO] gcode: G28 G1 Z10 F600 ``` -------------------------------- ### Read Filament Detection Status Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/design/filament_detect.md This example demonstrates how to query the printer's status for filament detection information. It uses a `curl` command to access the `/printer/objects/query?filament_detect` endpoint. The response provides a detailed subset of the detected filament's properties, including its vendor, type, color, and temperature settings. ```bash curl -s 'http:///printer/objects/query?filament_detect' ``` ```json { "result": { "status": { "filament_detect": { "info": [ { "VENDOR": "Generic", "MAIN_TYPE": "PLA", "SUB_TYPE": "Basic", "RGB_1": 3368652, "ALPHA": 128, "ARGB_COLOR": 2150852300, "HOTEND_MIN_TEMP": 205, "HOTEND_MAX_TEMP": 225, "BED_TEMP": 55, "OFFICIAL": true } ] } } } } ``` -------------------------------- ### Initialize UI Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Initializes the user interface by performing an initial full refresh of all components upon page load. ```javascript refreshAll(); ``` -------------------------------- ### GET /printer/objects/query?filament_detect Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/design/filament_detect.md Queries the current filament detection status of the printer. This endpoint returns detailed information about the detected filament. ```APIDOC ## GET /printer/objects/query?filament_detect ### Description Queries the current filament detection status of the printer. This endpoint returns detailed information about the detected filament. ### Method GET ### Endpoint /printer/objects/query?filament_detect ### Response #### Success Response (200) - **result.status.filament_detect.info** (array) - An array of objects, where each object contains detailed information about a detected filament. - **VENDOR** (string) - The vendor of the filament. - **MAIN_TYPE** (string) - The main type of the filament. - **SUB_TYPE** (string) - The subtype of the filament. - **RGB_1** (integer) - The RGB color value. - **ALPHA** (integer) - The alpha value of the color. - **ARGB_COLOR** (integer) - The ARGB color value. - **HOTEND_MIN_TEMP** (integer) - The minimum hotend temperature. - **HOTEND_MAX_TEMP** (integer) - The maximum hotend temperature. - **BED_TEMP** (integer) - The bed temperature. - **OFFICIAL** (boolean) - Indicates if the filament is official. #### Response Example ```json { "result": { "status": { "filament_detect": { "info": [ { "VENDOR": "Generic", "MAIN_TYPE": "PLA", "SUB_TYPE": "Basic", "RGB_1": 3368652, "ALPHA": 128, "ARGB_COLOR": 2150852300, "HOTEND_MIN_TEMP": 205, "HOTEND_MAX_TEMP": 225, "BED_TEMP": 55, "OFFICIAL": true } ] } } } } ``` ``` -------------------------------- ### Upgrade Firmware to Printer (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/development.md Command to build and deploy firmware directly to a connected printer. Requires the printer's IP address and the profile name. An optional password can be provided. ```bash ./dev.sh ./scripts/dev/upgrade-firmware.sh root@ ``` ```bash PASSWORD=mypassword ./dev.sh ./scripts/dev/upgrade-firmware.sh root@192.168.1.100 extended ``` -------------------------------- ### Download Firmware Upgrade via URL (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Handles the process of downloading and applying a firmware upgrade from a specified URL. It includes user confirmation, asynchronous download, and logging of the upgrade process. Dependencies include DOM manipulation for input/output and an `apiFetch` function. ```javascript function downloadUpgrade() { const url = $('url-input').value.trim(); if (!url) return; showConfirmModal( 'Confirm Download & Upgrade', 'Download and upgrade from URL? System may reboot.', () => doDownloadUpgrade(url) ); } async function doDownloadUpgrade(url) { const btn = $('download-btn'); btn.disabled = true; btn.textContent = 'Processing...'; showActionModal('Download & Upgrade', 'Downloading and upgrading...'); $('action-log').classList.add('visible'); try { const resp = await apiFetch('api/upgrade/url', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url }) }); await streamResponse(resp); } catch (e) { appendLog(`\nERROR: ${e.message}`); setMessage('Failed', 'var(--error)'); } finally { enableCloseButton(); btn.disabled = false; btn.textContent = 'Download & Upgrade'; } } ``` -------------------------------- ### GET /printer/objects/query?filament_detect Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/design/filament_detect.md Queries the current state of filament detection across all channels. This endpoint returns detailed information about each filament, including both writable and read-only fields. ```APIDOC ## GET /printer/objects/query?filament_detect ### Description Queries the current state of filament detection across all channels. This endpoint returns detailed information about each filament, including both writable and read-only fields. ### Method GET ### Endpoint /printer/objects/query?filament_detect ### Parameters #### Query Parameters - **filament_detect** (string) - Required - Specifies the object to query. Must be set to `filament_detect`. ### Response #### Success Response (200) - **result.status.filament_detect.info** (object) - An object containing filament information for each channel. - **[channel]** (object) - Information for a specific filament channel. - **VENDOR** (string) - The manufacturer or vendor of the filament. - **MAIN_TYPE** (string) - The main type of the filament (e.g., `PLA`, `PETG`). - **SUB_TYPE** (string) - The subtype of the filament (e.g., `Basic`, `Matte`). - **RGB_1** (int) - The primary RGB color value. - **ALPHA** (int) - The alpha transparency value (0-255). - **HOTEND_MIN_TEMP** (int) - The minimum recommended hotend temperature. - **HOTEND_MAX_TEMP** (int) - The maximum recommended hotend temperature. - **BED_TEMP** (int) - The recommended bed temperature. - **CARD_UID** (list[int]) - An array of byte integers representing the RFID card UID. - **SKU** (int) - The Stock Keeping Unit identifier. - **ARGB_COLOR** (int) - Derived ARGB color value. - **OFFICIAL** (boolean) - Indicates if the filament information is officially recognized. - **MANUFACTURER** (string) - The manufacturer of the filament. - **VERSION** (string) - The version of the filament data. - **TRAY** (string) - The tray identifier. - **COLOR_NUMS** (list[int]) - Numerical representation of the color. - **RGB_2..RGB_5** (int) - Additional RGB color components. - **DIAMETER** (float) - The diameter of the filament. - **WEIGHT** (int) - The weight of the filament. - **LENGTH** (int) - The length of the filament. - **DRYING_TEMP** (int) - Recommended drying temperature. - **DRYING_TIME** (int) - Recommended drying time. - **BED_TYPE** (string) - Recommended bed type. - **FIRST_LAYER_TEMP** (int) - Recommended first layer temperature. - **OTHER_LAYER_TEMP** (int) - Recommended temperature for other layers. - **MF_DATE** (string) - Manufacturing date. - **RSA_KEY_VERSION** (string) - RSA key version. #### Response Example ```json { "result": { "status": { "filament_detect": { "info": { "0": { "VENDOR": "Generic", "MAIN_TYPE": "PLA", "SUB_TYPE": "Basic", "RGB_1": 16737792, "ALPHA": 255, "HOTEND_MIN_TEMP": 200, "HOTEND_MAX_TEMP": 220, "BED_TEMP": 55, "CARD_UID": [161, 178, 195, 212], "SKU": 12345, "ARGB_COLOR": -16711680, "OFFICIAL": true, "MANUFACTURER": "Snapmaker", "VERSION": "1.0", "TRAY": "A1", "COLOR_NUMS": [255, 102, 0], "RGB_2": 0, "RGB_3": 0, "RGB_4": 0, "RGB_5": 0, "DIAMETER": 1.75, "WEIGHT": 1000, "LENGTH": 200000, "DRYING_TEMP": 50, "DRYING_TIME": 60, "BED_TYPE": "Glass", "FIRST_LAYER_TEMP": 60, "OTHER_LAYER_TEMP": 55, "MF_DATE": "2023-01-01", "RSA_KEY_VERSION": "v1.2" } } } } } } ``` ``` -------------------------------- ### GET /printer/objects/query?print_task_config Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/design/filament_detect.md Queries the current print task configuration, including filament details. This endpoint provides information about the configured filament properties for printing tasks. ```APIDOC ## GET /printer/objects/query?print_task_config ### Description Queries the current print task configuration, including filament details. This endpoint provides information about the configured filament properties for printing tasks. ### Method GET ### Endpoint /printer/objects/query?print_task_config ### Response #### Success Response (200) - **result.status.print_task_config** (object) - An object containing print task configuration details. - **filament_vendor** (array) - An array of filament vendor names. - **filament_type** (array) - An array of filament types. - **filament_sub_type** (array) - An array of filament subtypes. - **filament_color_rgba** (array) - An array of filament color RGBA values. - **filament_official** (array) - An array of booleans indicating if the filament is official. #### Response Example ```json { "result": { "status": { "print_task_config": { "filament_vendor": ["Generic"], "filament_type": ["PLA"], "filament_sub_type": ["Basic"], "filament_color_rgba": ["3366CC80"], "filament_official": [true] } } } } ``` ``` -------------------------------- ### Fetch and Display Settings from API (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Fetches setting data from the 'api/settings' endpoint and dynamically renders it into an HTML container. It groups settings and allows users to select options from dropdowns, with confirmation prompts for changes. The settings card is hidden if no settings are found. ```javascript async function loadSettings() { const container = $('settings-container'); const card = container.closest('.card'); try { const grouped = await (await apiFetch('api/settings')).json(); const groups = Object.entries(grouped); if (groups.length === 0) { card.style.display = 'none'; return; } card.style.display = 'block'; container.innerHTML = groups.map(([_, group]) => `
${group.label}
${group.items.map(setting => { const options = Object.entries(setting.options).map(([optKey, optVal]) => { return ``; }).join(''); return `
${setting.label}${setting.help_url ? `` : ''} ${setting.description ? `${setting.description}` : ''}
`; }).join('')}
`).join(''); } catch (e) { container.innerHTML = `
Error: ${e.message}
`; } } ``` -------------------------------- ### Download Klipper Commit as Patch (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/development.md Demonstrates how to download a specific Klipper commit as a patch file from GitHub. This is a crucial step for integrating upstream changes into the extended firmware. ```bash wget https://github.com/Klipper3d/klipper/commit/16fc46fe5.patch -O 01_16fc46fe5.patch ``` -------------------------------- ### Execute Actions (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Provides functionality to run predefined actions identified by an ID. It supports optional confirmation prompts before execution and streams the action's output logs. Dependencies include DOM manipulation and an `apiFetch` function for server communication. ```javascript function runAction(id) { currentAction = id; const actionConfig = actionsData.find(a => a.id === id); const title = actionConfig?.label || id; if (actionConfig?.confirm) { const message = typeof actionConfig.confirm === 'string' ? actionConfig.confirm : `Are you sure you want to run "${title}"?`; showConfirmModal(title, message, () => doRunAction(id, title)); } else { doRunAction(id, title); } } function doRunAction(id, title) { showActionModal(title, 'Executing...'); $('action-log').classList.add('visible'); execAction(id); } async function execAction(id) { try { const resp = await apiFetch(`api/action/${id}`, { method: 'POST' }); await streamResponse(resp, id); } catch (e) { appendLog(`\nERROR: ${e.message}`); setMessage('Failed', 'var(--error)'); enableCloseButton(); } } async function streamResponse(resp, actionId = null) { const reader = resp.body.getReader(); const decoder = new TextDecoder(); let fullLog = ''; while (true) { const { done, value } = await reader.read(); if (done) break; const text = decoder.decode(value, { stream: true }); fullLog += text; appendLog(text); } // Parse last line for SUCCESS/ERROR status const lastLine = fullLog.trim().split('\n').pop() || ''; const isSuccess = lastLine.startsWith('SUCCESS:'); // ... rest of the function ``` -------------------------------- ### Enable Remote Screen Access (INI Configuration) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/remote_screen.md Configuration snippet to enable remote screen access by setting the 'remote_screen' parameter to true in the extended2.cfg file. This is part of the manual setup process for advanced users. ```ini [web] remote_screen: true ``` -------------------------------- ### Enable Tailscale Serve (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/vpn.md This command enables Tailscale Serve to generate Let's Encrypt SSL certificates for your printer, allowing secure HTTPS access. The `--bg 80` flag runs the service in the background and listens on port 80 for certificate challenges. To disable, use `tailscale serve reset`. ```bash tailscale serve --bg 80 # to disable: tailscale serve reset ``` -------------------------------- ### Download Action File Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Initiates the download of an action-related file. It makes a POST request to the API, retrieves the file as a blob, determines the filename from the 'content-disposition' header, and triggers the browser's download mechanism. Handles potential download failures. ```javascript async function downloadFile() { if (!currentAction) return; try { const resp = await apiFetch(`api/action/${currentAction}/download`, { method: 'POST' }); if (!resp.ok) throw new Error(resp.statusText); const blob = await resp.blob(); const contentDisposition = resp.headers.get('content-disposition'); let filename = 'download.bin'; if (contentDisposition) { const match = contentDisposition.match(/filename="?([^"]+)"?/); if (match) filename = match[1]; } const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); URL.revokeObjectURL(a.href); } catch (e) { alert('Download failed: ' + e.message); } } ``` -------------------------------- ### Apply Setting Change via API Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Asynchronously applies a setting change to the backend via an API call. It shows an 'Updating Setting' modal, streams the response, and refreshes all UI elements upon successful application. Errors are logged and displayed. ```javascript async function doUpdateSetting(key, value) { showActionModal('Updating Setting', 'Applying changes...'); $('action-log').classList.add('visible'); try { const resp = await apiFetch(`api/settings/${key}/${value}`, { method: 'POST' }); await streamResponse(resp); refreshAll(); } catch (e) { appendLog(`\nERROR: ${e.message}`); setMessage('Failed', 'var(--error)'); } } ``` -------------------------------- ### Fetch and Display Actions from API (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Fetches action data from the 'api/actions' endpoint and dynamically renders it into an HTML container. It groups actions by category and provides interactive elements for running each action. Error handling is included for API fetch failures. ```javascript async function loadActions() { const container = $('actions-container'); try { const grouped = await (await apiFetch('api/actions')).json(); actionsData = Object.values(grouped).flatMap(g => g.items); container.innerHTML = Object.entries(grouped).map(([_, group]) => `
${group.label}
${group.items.map(action => `
${action.label}${action.help_url ? `` : ''} ${action.description ? `${action.description}` : ''}
`).join('')}
`).join(''); } catch (e) { container.innerHTML = `
Error: ${e.message}
`; } } ``` -------------------------------- ### Access Firmware Configuration Web Interface Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Provides access to a web-based tool for managing firmware settings, upgrades, and troubleshooting without needing SSH. Advanced Mode must be enabled on the printer's touchscreen. The interface allows configuration of frontend, cameras, VPN, cloud services, Klipper tweaks, and RFID detection. ```bash # Access Firmware Config (requires Advanced Mode enabled on printer touchscreen) # URL: http:///firmware-config/ # Enable Advanced Mode on printer: # Touchscreen: Settings > Maintenance > Advanced Mode > Enable # Then restart the printer # Available settings via web interface: # - Frontend selection (Fluidd/Mainsail) # - Camera configuration (internal/USB) # - Remote screen access # - VPN provider (Tailscale) # - Cloud provider (OctoEverywhere) # - Klipper tweaks (TMC AutoTune, reduced current) # - RFID detection system selection # Firmware upgrade via URL: # 1. Enter firmware URL in web interface # 2. Click "Download & Upgrade" # System downloads, installs, and reboots automatically ``` -------------------------------- ### Upload Firmware Upgrade via File (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Manages the firmware upgrade process by uploading a local file. This function utilizes `XMLHttpRequest` for progress tracking and handles upload status, including success and error messages. It requires a `selectedFile` variable and JWT for authorization. ```javascript function uploadUpgrade() { if (!selectedFile) return; showConfirmModal( 'Confirm Upgrade', 'Upload and upgrade? System may reboot.', doUploadUpgrade ); } async function doUploadUpgrade() { if (!selectedFile) return; const btn = $('upload-btn'); btn.disabled = true; btn.textContent = 'Uploading...'; showActionModal('Upgrade', 'Uploading...'); $('action-log').classList.add('visible'); $('action-progress').classList.add('visible'); $('action-progress-info').classList.add('visible'); const formData = new FormData(); formData.append('file', selectedFile); const xhr = new XMLHttpRequest(); let lastIdx = 0; const startTime = performance.now(); xhr.open('POST', 'api/upgrade/upload'); const jwt = getJWT(); if (jwt) xhr.setRequestHeader('Authorization', `Bearer ${jwt}`); xhr.upload.onprogress = (e) => { if (e.lengthComputable) { const pct = (e.loaded / e.total) * 100; $('action-progress-fill').classList.remove('indeterminate'); $('action-progress-fill').style.width = pct.toFixed(1) + '%'; $('action-progress-text').textContent = `${pct.toFixed(1)}% (${formatSize(e.loaded)} / ${formatSize(e.total)})`; } else { $('action-progress-fill').classList.add('indeterminate'); $('action-progress-text').textContent = 'Uploading...'; } const elapsed = (performance.now() - startTime) / 1000; if (elapsed > 0) { const speedMbps = ((e.loaded * 8 / 1e6) / elapsed).toFixed(2); $('action-speed').textContent = speedMbps + ' Mbit/s'; } }; xhr.upload.onload = () => { setMessage('Installing firmware...'); btn.textContent = 'Upgrading...'; $('action-progress').classList.remove('visible'); $('action-progress-info').classList.remove('visible'); }; xhr.onprogress = () => { const newText = xhr.responseText.substring(lastIdx); if (newText) { appendLog(newText); lastIdx = xhr.responseText.length; } }; xhr.onload = () => { const newText = xhr.responseText.substring(lastIdx); if (newText) appendLog(newText); const lastLine = (xhr.responseText.trim().split('\n').pop() || ''); if (lastLine.startsWith('SUCCESS:')) { setMessage('Success - System will reboot', 'var(--success)'); } else if (lastLine.startsWith('ERROR:')) { setMessage('Upgrade failed', 'var(--error)'); } else { setMessage('Completed'); } enableCloseButton(); btn.disabled = false; btn.textContent = 'Upload & Upgrade'; }; xhr.onerror = () => { appendLog('\nERROR: Upload failed\n'); setMessage('Upload failed', 'var(--error)'); enableCloseButton(); btn.disabled = false; btn.textContent = 'Upload & Upgrade'; }; xhr.send(formData); } ``` -------------------------------- ### Action Modal Initialization and Control (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Handles the initialization and control of an action modal, used for displaying progress and logs of an ongoing operation. It sets titles, messages, and controls the visibility of progress indicators and log areas. The close button is initially disabled. ```javascript function showActionModal(title, message) { $('action-title').textContent = title; $('action-message').textContent = message; $('action-message').style.color = ''; $('action-log').textContent = ''; $('action-log').classList.remove('visible'); $('action-progress').classList.remove('visible'); $('action-progress-fill').style.width = '0%'; $('action-progress-fill').classList.remove('indeterminate'); $('action-progress-info').classList.remove('visible'); $('action-download-btn').style.display = 'none'; $('action-close-btn').disabled = true; $('action-modal').classList.add('visible'); } function hideActionModal() { $('action-modal').classList.remove('visible'); } function enableCloseButton() { $('action-close-btn').disabled = false; } function appendLog(text) { const el = $('action-l ``` -------------------------------- ### Configuration File Management Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/firmware_config.md Explanation of how default configuration files are managed. When a configuration file is customized, a corresponding '.default' file is created, containing the original default values. This aids in tracking changes and restoring defaults. ```text When you modify a configuration file, the system automatically creates a .default file alongside it containing the original default values. For example, if you customize extended2.cfg, you'll find extended2.cfg.default in the same directory. This makes it easy to: - See which files you have customized - Compare your changes against the defaults - Restore default values if needed The .default files are updated on each boot to reflect the current firmware defaults. ``` -------------------------------- ### Extract Base Firmware (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/development.md Command to extract and examine the base firmware. The extracted files will be placed in the `tmp/extracted/` directory. ```bash ./dev.sh make extract ``` -------------------------------- ### Enable OctoEverywhere Cloud Remote Access Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Set up cloud-based remote access using OctoEverywhere for features like AI failure detection and remote monitoring. This involves downloading the package, enabling it in the configuration, and linking your account. ```bash # Enable OctoEverywhere via SSH # Step 1: Download OctoEverywhere package ssh root@192.168.1.100 octoeverywhere-pkg download # Step 2: Enable in config file cat << 'EOF' >> /home/lava/printer_data/config/extended/extended2.cfg [remote_access] cloud: octoeverywhere EOF # Step 3: Start cloud service /etc/init.d/S99cloud restart # Step 4: Link your account # Download octoeverywhere.log from Mainsail/Fluidd Configuration tab # Find the account linking URL in the log and open in browser # Complete account linking on OctoEverywhere.com ``` -------------------------------- ### Update Setting with Confirmation Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Handles updating a specific setting. It prompts the user for confirmation before applying the change, displaying a warning about service restarts. If confirmed, it calls `doUpdateSetting`; otherwise, it reverts the selection. ```javascript function updateSetting(key, selectEl) { const value = selectEl.value; const prevValue = selectEl.dataset.prevValue || value; const selectedOption = selectEl.selectedOptions[0]; const optLabel = decodeURIComponent(selectedOption.dataset.label || value); const confirmMsg = decodeURIComponent(selectedOption.dataset.confirm || ''); const label = selectEl.parentElement.querySelector('.row-label').textContent; const message = confirmMsg || `Change ${label} to "${optLabel}"?`; const warning = '⚠️ Warning: Changing settings will restart services and may interrupt printing.'; showConfirmModal( `Update ${label}`, `${message}\n\n${warning}`, () => { selectEl.dataset.prevValue = value; doUpdateSetting(key, value); }, () => { selectEl.value = prevValue; } ); } ``` -------------------------------- ### JavaScript Authentication and API Fetching Functions Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Provides utility functions for handling authentication tokens and making API requests. It includes logic to retrieve JWT tokens from local storage and set authorization headers. The apiFetch function handles common HTTP errors like 401 (Unauthorized) and 502 (Bad Gateway), displaying relevant notices to the user. ```javascript // Helper function to get element by ID const $ = id => document.getElementById(id); // Auth functions for Moonraker/Fluidd token function getJWT() { const instanceKey = `user-token-${window.location.host.replace(/[^a-zA-Z0-9]/g, '_')}`; let token = localStorage.getItem(instanceKey); if (token) return token; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key && key.startsWith('user-token-')) { token = localStorage.getItem(key); if (token) return token; } } return null; } function getAuthHeaders() { const jwt = getJWT(); return jwt ? { 'Authorization': `Bearer ${jwt}` } : {}; } // Global state let selectedFile = null; let actionsData = []; let currentAction = ''; function showServiceNotice() { $('service-notice').classList.add('visible'); } function showServiceError() { $('service-error').classList.add('visible'); } function showAuthNotice() { $('auth-notice').classList.add('visible'); } function hideNotices() { $('service-notice').classList.remove('visible'); $('service-error').classList.remove('visible'); $('auth-notice').classList.remove('visible'); } async function apiFetch(url, options = {}) { options.headers = { ...getAuthHeaders(), ...options.headers }; const resp = await fetch(url, options); hideNotices(); if (resp.status === 401) { showAuthNotice(); throw new Error('Authentication required'); } else if (resp.status === 502) { showServiceNotice(); throw new Error('Service unavailable'); } else if (resp.status >= 500 && resp.status < 600) { showServiceError(); throw new Error(`Service unavailable (HTTP ${resp.status})`); } else if (!resp.ok) { throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); } return resp; } ``` -------------------------------- ### Monitoring Configuration (Klipper Exporter) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/firmware_config.md Enable the Klipper Prometheus metrics exporter and specify the host and port for metrics. The exporter can be enabled on a specific port (e.g., ':9101') or a custom host:port combination. If not set, the exporter is disabled. ```ini [monitoring] # Enable Klipper Prometheus exporter on specified address # klipper_exporter: :9101 ``` -------------------------------- ### JavaScript Data Loading Functions for Status and Links Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html These functions handle loading and displaying status information and quick links from the API. The loadStatus function fetches printer status details and renders them in a structured format. The loadLinks function retrieves a list of links with icons and labels, displaying them as clickable items. ```javascript // ======================================== // Data Loading Functions // ======================================== async function loadStatus() { const container = $('status-container'); try { const status = await (await apiFetch('api/status')).json(); container.innerHTML = Object.entries(status).map(([key, section]) => { const itemsHtml = section.items.map(item => `
${item.label}: ${item.value || 'N/A'}
`).join(''); return `
${section.title}
${itemsHtml}
`; }).join(''); } catch (e) { container.innerHTML = `
Error: ${e.message}
`; } } async function loadLinks() { const container = $('links-container'); try { const links = await (await apiFetch('api/links')).json(); container.innerHTML = links.map(link => ` ${link.icon} ${link.label} `).join(''); } catch (e) { container.innerHTML = `
Error: ${e.message}
`; } } async function loadActions() { const container = $('actions-container'); try { const grouped = await (aw ``` -------------------------------- ### File Input Handling and Display (JavaScript) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Handles file selection from an input element, updating a display value with the file name and size. It also enables an upload button upon file selection. A helper function 'formatSize' is used to format byte counts into human-readable KB or MB. ```javascript function handleFile(input) { if (input.files[0]) { selectedFile = input.files[0]; $('file-display').value = `${selectedFile.name} (${formatSize(selectedFile.size)})`; $('upload-btn').disabled = false; } } function formatSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / 1048576).toFixed(1) + ' MB'; } ``` -------------------------------- ### Enable System Persistence (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/data_persistence.md Enables system-level changes to persist across reboots by creating a .debug file. This affects configurations in /etc. To revert, remove the file and reboot. ```bash touch /oem/.debug ``` -------------------------------- ### Refresh All UI Components Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/10-firmware-config/root/usr/local/share/firmware-config/html/index.html Refreshes the entire user interface by sequentially loading status, links, settings, and actions. It displays a loading spinner on the refresh button and re-enables it once all data has been fetched. ```javascript async function refreshAll() { const btn = document.querySelector('h1 .btn'); btn.innerHTML = ' Refresh'; btn.disabled = true; try { await Promise.all([ loadStatus(), loadLinks(), loadSettings(), loadActions() ]); } finally { btn.innerHTML = '↻ Refresh'; btn.disabled = false; } } ``` -------------------------------- ### Restart Cloud Service (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/cloud.md This command restarts the cloud service on the printer, applying the configuration changes made in the previous step. It ensures that the newly configured cloud provider is active and ready to establish a connection. ```bash /etc/init.d/S99cloud restart ``` -------------------------------- ### Web Interface Configuration Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/firmware_config.md Configure the web interface frontend, firmware config availability, and remote screen access. The frontend can be set to 'fluidd' or 'mainsail'. Firmware config can be enabled or disabled. Remote screen access allows viewing and control in a web browser. ```ini [web] # Web interface frontend: fluidd, mainsail frontend: fluidd # Enable access at http:///firmware-config/: true, false firmware_config: true # Enable access at http:///screen/: true, false remote_screen: false ``` -------------------------------- ### Run RFID OpenSpool CLI Test Tool (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/overlays/firmware-extended/30-rfid-support/test/README.md This command executes the RFID OpenSpool CLI Test Tool using Python 3. It takes a file path as an argument, automatically detecting whether to parse it as an OpenSpool JSON payload or NDEF binary data. ```bash python3 -m app.cli ``` -------------------------------- ### Enable AFC-Lite Stub Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/afc-lite.md Enables the AFC-Lite stub by creating a symbolic link to the AFC configuration file and restarting the Klipper service. This allows AFC UI panels to be used with Fluidd/Mainsail. ```bash ln -sf /usr/local/share/firmware-config/tweaks/klipper/afc.cfg \ /oem/printer_data/config/extended/klipper/afc.cfg /etc/init.d/S60klipper restart ``` -------------------------------- ### Restart VPN Service (Bash) Source: https://github.com/paxx12/snapmakeru1-extended-firmware/blob/develop/docs/vpn.md This command restarts the VPN service, applying the configuration changes made in the extended firmware settings. It ensures the VPN daemon is running. ```bash /etc/init.d/S99vpn restart ``` -------------------------------- ### Configure Prometheus Klipper Metrics Exporter Source: https://context7.com/paxx12/snapmakeru1-extended-firmware/llms.txt Integrate Klipper metrics with monitoring systems like Prometheus, Grafana, Home Assistant, or DataDog by enabling the Klipper metrics exporter. This provides an endpoint to scrape metrics. ```ini # Enable Klipper Prometheus exporter in extended2.cfg: [monitoring] klipper_exporter: :9101 # Access metrics endpoint # URL: http://:9101/metrics # Sample Prometheus scrape config (prometheus.yml) scrape_configs: - job_name: 'snapmaker-u1' static_configs: - targets: ['192.168.1.100:9101'] scrape_interval: 15s # DataDog OpenMetrics integration # File: /etc/datadog-agent/conf.d/openmetrics.d/snapmaker_u1.yaml instances: - openmetrics_endpoint: http://192.168.1.100:9101/metrics namespace: snapmaker metrics: - klipper_* ```