Theme changes, added DIY devices

This commit is contained in:
2026-03-18 16:51:54 +03:00
parent af9341ba41
commit 4c1beb7383

View File

@@ -16,7 +16,7 @@
<script src="./js/tailwindcss/tailwind-v3.4.3-forms-v0.5.7.js"></script>
<!-- vue js -->
<script src="./js/vue@3.4.26/dist/vue.global.js"></script>
<script src="./js/vue@3.4.26/dist/vue.global.prod.js"></script>
<script src="./js/crypto-js@3.9.1-1/core.js"></script>
<script src="./js/crypto-js@3.9.1-1/md5.js"></script>
@@ -83,6 +83,9 @@
<button @click="flash" :disabled="isFlashing" class="border border-gray-500 px-2 bg-gray-700 hover:bg-gray-600 rounded text-white">
Flash Now
</button>
<button @click="eraseEsp32" :disabled="isFlashing" class="border border-red-500 px-2 bg-red-700 hover:bg-red-600 rounded text-white ml-2">
Erase Flash
</button>
</div>
<div v-else>
@@ -481,7 +484,7 @@
<!-- setup esptool-js -->
<script type="module">
import { ESPLoader, Transport } from "./js/esptool-js@0.4.5/bundle.js";
import { ESPLoader, Transport } from "./js/esptool-js@0.5.6/bundle.js";
window.ESPLoader = ESPLoader;
window.Transport = Transport;
</script>
@@ -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() {