From 4c1beb7383a23b0b55feddb9363688386a3fba51 Mon Sep 17 00:00:00 2001 From: Nickie Deuxyeux Date: Wed, 18 Mar 2026 16:51:54 +0300 Subject: [PATCH] Theme changes, added DIY devices --- index.html | 391 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 343 insertions(+), 48 deletions(-) diff --git a/index.html b/index.html index ad2acdd..e6baed3 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@ - + @@ -83,6 +83,9 @@ +
@@ -481,7 +484,7 @@ @@ -511,7 +514,7 @@ models: [ { id: ROM.MODEL_FE, - name: "433 MHz", + name: "470-510 MHz", }, ], firmware_filename: "rnode_firmware_aethernode.zip", @@ -527,6 +530,59 @@ }, }, }, + { + name: "MeshAdventurer-S3 (Classic RNode)", + id: ROM.PRODUCT_HMBRW, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_FE, + name: "470-510 MHz", + }, + { + id: ROM.MODEL_FE, + name: "863-928 MHz", + }, + ], + firmware_filename: "rnode_firmware_meshadventurer_s3.zip", + firmware_repo: "https://github.com/chrismyers2000/MeshAdventurer", + flash_config: { + flash_size: "16MB", + flash_files: { + "0xe000": "rnode_firmware_meshadventurer_s3.boot_app0", + "0x1000": "rnode_firmware_meshadventurer_s3.bootloader", + "0x10000": "rnode_firmware_meshadventurer_s3.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_meshadventurer_s3.partitions", + }, + }, + }, + { + name: "MeshAdventurer-S3 (Boundary Node)", + id: ROM.PRODUCT_HMBRW, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_FE, + name: "470-510 MHz", + }, + { + id: ROM.MODEL_FE, + name: "863-928 MHz", + }, + ], + firmware_filename: "rtnode_meshadventurer_s3.zip", + firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4", + flash_config: { + flash_size: "16MB", + flash_files: { + "0xe000": "boot_app0.bin", + "0x0": "bootloader.bin", + "0x10000": "firmware.bin", + "0x8000": "partitions.bin", + }, + }, + }, { name: "MeshAdventurer", id: ROM.PRODUCT_HMBRW, @@ -534,7 +590,11 @@ models: [ { id: ROM.MODEL_FE, - name: "868 MHz", + name: "470-510 MHz", + }, + { + id: ROM.MODEL_FE, + name: "863-928 MHz", }, ], firmware_filename: "rnode_firmware_meshadventurer.zip", @@ -550,6 +610,33 @@ }, }, }, + { + name: "DIY-V1", + id: ROM.PRODUCT_HMBRW, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_FE, + name: "470-510 MHz", + }, + { + id: ROM.MODEL_FE, + name: "863-928 MHz", + }, + ], + firmware_filename: "rnode_firmware_diy_v1.zip", + firmware_repo: "https://github.com/NanoVHF/Meshtastic-DIY", + flash_config: { + flash_size: "4MB", + flash_files: { + "0xe000": "rnode_firmware_diy_v1.boot_app0", + "0x1000": "rnode_firmware_diy_v1.bootloader", + "0x10000": "rnode_firmware_diy_v1.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_diy_v1.partitions", + }, + }, + }, { name: "FakeTec (Promicro)", id: ROM.PRODUCT_HMBRW, @@ -563,6 +650,100 @@ firmware_filename: "rnode_firmware_promicro.zip", firmware_repo: "https://github.com/gargomoma/fakeTec_pcb", }, + { + name: "Heltec V3 (Classic RNode)", + id: ROM.PRODUCT_H32_V3, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_C5, + name: "433 MHz", + }, + { + id: ROM.MODEL_CA, + name: "868 MHz / 915 MHz / 923 MHz", + }, + ], + firmware_filename: "rnode_firmware_heltec32v3.zip", + firmware_repo: "https://heltec.org/project/wifi-lora-32-v3/", + flash_config: { + flash_size: "8MB", + flash_files: { + "0xe000": "rnode_firmware_heltec32v3.boot_app0", + "0x0": "rnode_firmware_heltec32v3.bootloader", + "0x10000": "rnode_firmware_heltec32v3.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_heltec32v3.partitions", + }, + }, + }, + { + name: "Heltec V3 (Boundary Node)", + id: ROM.PRODUCT_H32_V3, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_C8, + name: "868 MHz / 915 MHz / 923 MHz with PA", + }, + ], + firmware_filename: "rtnode_heltec_V3.zip", + firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4", + flash_config: { + flash_size: "16MB", + flash_files: { + "0xe000": "boot_app0.bin", + "0x0": "bootloader.bin", + "0x10000": "firmware.bin", + "0x8000": "partitions.bin", + }, + }, + }, + { + name: "Heltec V4 (Classic RNode)", + id: ROM.PRODUCT_H32_V4, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_C8, + name: "868 MHz / 915 MHz / 923 MHz with PA", + }, + ], + firmware_filename: "rnode_firmware_heltec32v4pa.zip", + firmware_repo: "https://heltec.org/project/wifi-lora-32-v4/", + flash_config: { + flash_size: "16MB", + flash_files: { + "0xe000": "rnode_firmware_heltec32v4pa.boot_app0", + "0x0": "rnode_firmware_heltec32v4pa.bootloader", + "0x10000": "rnode_firmware_heltec32v4pa.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_heltec32v4pa.partitions", + }, + }, + }, + { + name: "Heltec V4 (Boundary Node)", + id: ROM.PRODUCT_H32_V4, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_C8, + name: "868 MHz / 915 MHz / 923 MHz with PA", + }, + ], + firmware_filename: "rtnode_heltec_V4.zip", + firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4", + flash_config: { + flash_size: "16MB", + flash_files: { + "0xe000": "boot_app0.bin", + "0x0": "bootloader.bin", + "0x10000": "firmware.bin", + "0x8000": "partitions.bin", + }, + }, + }, { name: "Heltec T114", id: ROM.PRODUCT_HELTEC_T114, @@ -579,6 +760,73 @@ ], firmware_filename: "rnode_firmware_heltec_t114.zip", firmware_repo: "https://heltec.org/project/mesh-node-t114/", + }, + { + name: "LilyGO T-Beam", + id: ROM.PRODUCT_TBEAM, + platform: ROM.PLATFORM_ESP32, + models: [ + { + id: ROM.MODEL_E4, + name: "433 MHz (with SX1278 chip)", + firmware_filename: "rnode_firmware_tbeam.zip", + flash_config: { + flash_size: "4MB", + flash_files: { + "0xe000": "rnode_firmware_tbeam.boot_app0", + "0x1000": "rnode_firmware_tbeam.bootloader", + "0x10000": "rnode_firmware_tbeam.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_tbeam.partitions", + }, + }, + }, + { + id: ROM.MODEL_E9, + name: "868/915/923 MHz (with SX1276 chip)", + firmware_filename: "rnode_firmware_tbeam.zip", + flash_config: { + flash_size: "4MB", + flash_files: { + "0xe000": "rnode_firmware_tbeam.boot_app0", + "0x1000": "rnode_firmware_tbeam.bootloader", + "0x10000": "rnode_firmware_tbeam.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_tbeam.partitions", + }, + }, + }, + { + id: ROM.MODEL_E3, + name: "433 MHz (with SX1268 chip)", + firmware_filename: "rnode_firmware_tbeam_sx1262.zip", + flash_config: { + flash_size: "4MB", + flash_files: { + "0xe000": "rnode_firmware_tbeam_sx1262.boot_app0", + "0x1000": "rnode_firmware_tbeam_sx1262.bootloader", + "0x10000": "rnode_firmware_tbeam_sx1262.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_tbeam_sx1262.partitions", + }, + }, + }, + { + id: ROM.MODEL_E8, + name: "868/915/923 MHz (with SX1262 chip)", + firmware_filename: "rnode_firmware_tbeam_sx1262.zip", + flash_config: { + flash_size: "4MB", + flash_files: { + "0xe000": "rnode_firmware_tbeam_sx1262.boot_app0", + "0x1000": "rnode_firmware_tbeam_sx1262.bootloader", + "0x10000": "rnode_firmware_tbeam_sx1262.bin", + "0x210000": "console_image.bin", + "0x8000": "rnode_firmware_tbeam_sx1262.partitions", + }, + }, + }, + ], }, ], @@ -747,7 +995,7 @@ } // close port - console.log("Closing serial port"); + console.log("Closing serial port..."); try { await serialPort.close(); } catch(e) { @@ -764,7 +1012,7 @@ return; } - // ensure flash config is known, use from selected model, or fallback to selected product + // ensure flash config is known const flashConfig = this.selectedModel?.flash_config ?? this.selectedProduct?.flash_config; if(!flashConfig){ alert("Flash config is not available for the selected device."); @@ -784,10 +1032,10 @@ return; } - // update progress this.isFlashing = true; this.flashingProgress = 0; + let transport; try { // read zip file @@ -795,48 +1043,32 @@ const zipReader = new window.zip.ZipReader(blobReader); const zipEntries = await zipReader.getEntries(); - // get files to flash const filesToFlash = []; for(const [address, filename] of Object.entries(flashConfig.flash_files)){ - - // find file inside zip - const file = zipEntries.find((zipEntry) => zipEntry.filename === filename); - if(!file){ - throw filename + " not found in firmware file!"; - } - - // get file data as binary string - const blob = await file.getData(new window.zip.BlobWriter()); - const data = await this.readAsBinaryString(blob); // fixme: deprecated, but works for now - - // add to files to flash - filesToFlash.push({ - "address": parseInt(address), - "data": data, - }); - + const zipEntry = zipEntries.find(e => e.filename === filename); + if(!zipEntry) throw filename + " not found in firmware file!"; + const blob = await zipEntry.getData(new window.zip.BlobWriter()); + const data = await this.readAsBinaryString(blob); // deprecated, works for now + filesToFlash.push({ address: parseInt(address), data }); } // init transport and esploader - const transport = new window.Transport(serialPort, true); + transport = new window.Transport(serialPort, true); const esploader = new window.ESPLoader({ - transport: transport, + transport, baudrate: 921600, debugLogging: false, enableTracing: false, terminal: { - clean() { - - }, - writeLine(data) { - console.log(data); - }, - write(data) { - console.log(data); - }, + clean() {}, + writeLine(data) { console.log(data); }, + write(data) { console.log(data); }, }, }); + // completely disable TRACE logging + transport.trace = () => {}; + // load device info await esploader.main(); @@ -850,34 +1082,97 @@ compress: true, calculateMD5Hash: (image) => CryptoJS.MD5(CryptoJS.enc.Latin1.parse(image)), reportProgress: (fileIndex, written, total) => { - const currentFilePercentage = (written / total) * 100; - this.flashingProgress = Math.floor(currentFilePercentage); + const percent = (written / total) * 100; + this.flashingProgress = Math.floor(percent); }, }); // reboot device await transport.setDTR(false); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise(resolve => setTimeout(resolve, 100)); await transport.setDTR(true); - // flashing successful alert("Firmware has been flashed!"); } catch(e) { alert("Firmware flashing failed: " + e); + console.error(e); + } finally { + this.isFlashing = false; + + // release reader/writer locks before closing port + try { + if(transport?.reader){ + await transport.reader.cancel(); + transport.reader.releaseLock(); + } + if(transport?.writer){ + transport.writer.releaseLock(); + } + + console.log("Closing serial port..."); + await serialPort.close(); + } catch(e) { + console.warn("Failed to close serial port, ignoring...", e); + } + } + }, + async eraseEsp32() { + if (!window.ESPLoader) { + alert("esptool-js could not be loaded."); + return; + } + + // ask for serial port + const serialPort = await this.askForSerialPort(); + if (!serialPort) return; + + this.isFlashing = true; + + let transport, esploader; + + try { + transport = new window.Transport(serialPort, true); + esploader = new window.ESPLoader({ + transport: transport, + baudrate: 921600, + debugLogging: false, + enableTracing: false, + terminal: { + clean() {}, + writeLine(data) { console.log(data); }, + write(data) { console.log(data); }, + }, + }); + + // completely disable TRACE logging + transport.trace = () => {}; + + await esploader.main(); + await esploader.eraseFlash(); + alert("Flash erase completed!"); + } catch (e) { + alert("Flash erase failed: " + e); console.log(e); } finally { this.isFlashing = false; - } - // close port - console.log("Closing serial port"); - try { - await serialPort.close(); - } catch(e) { - console.log("failed to close serial port, ignoring...", e); - } + // properly release streams before closing + try { + if (transport?.reader) { + await transport.reader.cancel(); + transport.reader.releaseLock(); + } + if (transport?.writer) { + transport.writer.releaseLock(); + } + console.log("Closing serial port..."); + await serialPort.close(); + } catch (e) { + console.warn("Failed to close serial port, ignoring...", e); + } + } }, async detect() {