From 627790b5fcbff132f1bdfdf653187edf8065c122 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Wed, 4 Mar 2026 12:03:39 +0100 Subject: [PATCH] Javascript cleanup --- README | 8 +- README.de | 10 +- extra_post.py | 13 +- platformio.ini | 4 +- src/main.cpp | 3 + src/webserver.cpp | 1 + web/index.js | 295 +--------------------------------------------- 7 files changed, 31 insertions(+), 303 deletions(-) diff --git a/README b/README index 67cc52b..93dd7ee 100644 --- a/README +++ b/README @@ -149,16 +149,16 @@ Bill of materials (WIP) 1x buzzer 12V, passive 1x MOSFET 2N7000 1x resistor 150 Ω - 1x wiring set for buttons, 0.25 mm², 15cm each - 8x black (GND) - 7x colored (signal) + 1x wiring set for buttons, 0.25 mm² + 7x black (GND), 10cm each + 7x colored (signal), 15cm each 1x screw terminal block 2pol. 2.54mm 1x 3D enclosure consisting of front and back 1x nut tool, 3D-printed 4x mounting screws M4 countersunk 4x enclosure screws M2.5, long 8x PCB screws M2.5, short - 1x silicone sealing cord 2 mm + 1x silicone sealing cord 2 mm, l=380mm 1x SHT31 I²C module 1x female header 2.54 mm 1x pin header 2.54mm diff --git a/README.de b/README.de index 2236a30..f3ff1c9 100644 --- a/README.de +++ b/README.de @@ -157,22 +157,22 @@ Bauteilliste (WIP) 1x Buzzer 12V, passiv 1x MOSFET 2N7000 1x Widerstand 150 Ω - 1x Kabelsatz für Tasten, 0,25 mm², je 15cm lang - 8x schwarz (GND) - 7x farbig (Signal) + 1x Kabelsatz für Tasten, 0,25 mm² + 7x schwarz (GND), je 10cm lang + 7x farbig (Signal), je 15cm lang 1x Terminalblock 2pol. 2,54mm schraubbar 1x 3D-Gehäuse bestehend auf Front- und Rückseite 1x Mutternwerkzeug 3D-Druck 4x Befestigungsschraube M4 Senkkopf 4x Gehäuseschraube M2,5, lang 8x Platinenschraube M2,5, kurz - 1x Silikondichtschnur 2mm + 1x Silikondichtschnur 2mm, l=380mm 1x SHT31 I²C-Modul 1x Buchsenleiste 2,54 mm 1x Stiftleiste 2,54mm 2x Jumper 1x Polyfuse - 1x Schrumpfschlauch + 1x Schrumpfschlauch Konfiguration ------------- diff --git a/extra_post.py b/extra_post.py index 867cff3..b1a45f9 100644 --- a/extra_post.py +++ b/extra_post.py @@ -53,6 +53,15 @@ def postbuild(source, target, env): firmware = env.subst("$BUILD_DIR/${PROGNAME}.bin") (fwname, fwversion) = getFirmwareInfo(firmware) + pcbvers = "unknown" + for x in env["BUILD_FLAGS"]: + if not x.startswith('-D'): + continue + opt = x[2:].strip() + if opt.startswith("HARDWARE_"): + pcbvers = x.split('_')[1].lower() + print(f"compiled for pcb version {pcbvers}") + esptool = env.get('UPLOADER') uploaderflags = env.subst("${UPLOADERFLAGS}") base = env.subst("$PIOENV") @@ -91,9 +100,9 @@ def postbuild(source, target, env): env.Execute(' '.join(cmd), "#merging bin files") # Create symlinks to better identify firmware - fw_update = os.path.join(outdir, f"{base}-{fwversion}-update.bin") + fw_update = os.path.join(outdir, f"{base}_{pcbvers}-{fwversion}-update.bin") os.symlink(firmware, fw_update) - fw_full = os.path.join(outdir, f"{base}-{fwversion}-all.bin") + fw_full = os.path.join(outdir, f"{base}_{pcbvers}-{fwversion}-all.bin") os.symlink(outfile, fw_full) env.AddPostAction( diff --git a/platformio.ini b/platformio.ini index e8ead7c..fc7ad65 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,7 +29,6 @@ extra_scripts = post:extra_post.py lib_ldf_mode = chain monitor_speed = 115200 -# monitor_raw = yes build_flags = -DPIO_ENV_BUILD=$PIOENV -DBOARD_HAS_PSRAM @@ -43,13 +42,12 @@ build_flags = build_unflags = -std=gnu++11 -custom_version = 0.1.1 +custom_version = 0.2.0 custom_versionformat = DEVELOP # Version format switch: e.g.DEVELOP=dev|RELEASE=1.0.0 [env:obpkp61] build_type = release # debug | release board = esp32_s3_nano -#board = arduino_nano_esp32 # ATTENTION! Pin numbering scheme changes board_upload.flash_size = 16MB board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash upload_port = /dev/ttyACM0 diff --git a/src/main.cpp b/src/main.cpp index dc501ac..439c0a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -282,8 +282,10 @@ void setup() { pinMode(KEY_6, INPUT_PULLUP); pinMode(KEY_DST, INPUT_PULLUP); +#ifdef HARDWARE_V2 // Light sensor input pinMode(LDR, INPUT); +#endif // Early signal system activity, red while booting digitalWrite(RGBLED_R, HIGH); @@ -738,6 +740,7 @@ void loop() { case BUTTON_5: // reset LOGI(TAG, "Device reset"); esp_rom_uart_tx_wait_idle(0); + ledcWrite(LEDC_RGBLED_B, 0); // blue config light off led_blink(LEDC_RGBLED_G, 3, 4095, 500); ESP.restart(); break; diff --git a/src/webserver.cpp b/src/webserver.cpp index 7f3aa8b..558d39d 100644 --- a/src/webserver.cpp +++ b/src/webserver.cpp @@ -164,6 +164,7 @@ void webserver_init() { String out; serializeJson(doc, out); request->send(200, "application/json", out); + ledcWrite(LEDC_RGBLED_B, 0); // blue config light off led_blink(LEDC_RGBLED_G, 3, 4095, 500); esp_rom_uart_tx_wait_idle(0); ESP.restart(); diff --git a/web/index.js b/web/index.js index 639d3bf..996333f 100644 --- a/web/index.js +++ b/web/index.js @@ -95,35 +95,11 @@ let even = true; //first counter if (statusPage){ for (let k in jsonData) { - if (typeof (jsonData[k]) === 'object') { - if (k.indexOf('count') == 0) { - createCounterDisplay(statusPage, k.replace("count", "").replace(/in$/, " in").replace(/out$/, " out"), k, even); - even = !even; - for (let sk in jsonData[k]) { - let key = k + "." + sk; - if (typeof (jsonData[k][sk]) === 'object') { - //msg details - updateMsgDetails(key, jsonData[k][sk]); - } - else { - let el = document.getElementById(key); - if (el) el.textContent = jsonData[k][sk]; - } - } - } - if (k.indexOf("ch") == 0) { - //channel def - let name = k.substring(2); - channelList[name] = jsonData[k]; - } - } - else { - let el = document.getElementById(k); - if (el) el.textContent = jsonData[k]; - forEl('.status-' + k, function (el) { - el.textContent = jsonData[k]; - }); - } + let el = document.getElementById(k); + if (el) el.textContent = jsonData[k]; + forEl('.status-' + k, function (el) { + el.textContent = jsonData[k]; + }); } } lastUpdate = (new Date()).getTime(); @@ -341,33 +317,6 @@ }) .catch(function (e) { }); } - function createCounterDisplay(parent, label, key, isEven) { - if (parent.querySelector("#" + key)) { - return; - } - let clazz = "row icon-row counter-row"; - if (isEven) clazz += " even"; - let row = addEl('div', clazz, parent); - row.setAttribute("id", key); - let icon = addEl('span', 'icon icon-more', row); - addEl('span', 'label', row, label); - let value = addEl('span', 'value', row, '---'); - value.setAttribute('id', key + ".sumOk"); - let display = addEl('div', clazz + " msgDetails hidden", parent); - display.setAttribute('id', key + ".ok"); - row.addEventListener('click', function (ev) { - let rs = display.classList.toggle('hidden'); - if (rs) { - icon.classList.add('icon-more'); - icon.classList.remove('icon-less'); - } - else { - icon.classList.remove('icon-more'); - icon.classList.add('icon-less'); - } - }); - callListeners(api.EVENTS.counterDisplayCreated,row); - } function validKey(key) { if (!key) return; return key.replace(/[^a-z_:A-Z0-9-]/g, ''); @@ -470,7 +419,6 @@ if (!(condition instanceof Array)) condition = [condition]; return condition; } - function conditionOk(name){ let condition = getConditions(name); if (!condition) return true; @@ -504,97 +452,6 @@ else row.classList.add('hidden'); } let caliv = 0; - function createCalSetInput(configItem, frame, clazz) { - let el = addEl('input', clazz, frame); - let cb = addEl('button', '', frame, 'C'); - //el.disabled=true; - cb.addEventListener('click', (ev) => { - let cs = document.getElementById("calset").cloneNode(true); - cs.classList.remove("hidden"); - cs.querySelector(".heading").textContent = configItem.label || configItem.name; - let vel = cs.querySelector(".val"); - if (caliv != 0) window.clearInterval(caliv); - caliv = window.setInterval(() => { - if (document.body.contains(cs)) { - fetch(apiPrefix + "/api/calibrate?name=" + encodeURIComponent(configItem.name)) - .then((r) => r.text()) - .then((txt) => { - if (txt != vel.textContent) { - vel.textContent = txt; - } - }) - .catch((e) => { - alert(e); - hideOverlay(); - window.clearInterval(caliv); - }) - } - else { - window.clearInterval(caliv); - } - }, 200); - showOverlay(cs, false, [{ - label: 'Set', click: () => { - el.value = vel.textContent; - let cev = new Event('change'); - el.dispatchEvent(cev); - } - }]); - }) - el.setAttribute('name', configItem.name) - return el; - } - function createCalValInput(configItem, frame, clazz) { - let el = addEl('input', clazz, frame); - let cb = addEl('button', '', frame, 'C'); - //el.disabled=true; - cb.addEventListener('click', (ev) => { - const sv = function (val, cfg) { - if (configItem.eval) { - let v = parseFloat(val); - let c = parseFloat(cfg); - return (eval(configItem.eval)); - } - return v; - }; - let cs = document.getElementById("calval").cloneNode(true); - cs.classList.remove("hidden"); - cs.querySelector(".heading").textContent = configItem.label || configItem.name; - let vel = cs.querySelector(".val"); - let vinp = cs.querySelector("input"); - vinp.value = el.value; - if (caliv != 0) window.clearInterval(caliv); - caliv = window.setInterval(() => { - if (document.body.contains(cs)) { - fetch(apiPrefix + "/api/calibrate?name=" + encodeURIComponent(configItem.name)) - .then((r) => r.text()) - .then((txt) => { - txt = sv(txt, vinp.value); - if (txt != vel.textContent) { - vel.textContent = txt; - } - }) - .catch((e) => { - alert(e); - hideOverlay(); - window.clearInterval(caliv); - }) - } - else { - window.clearInterval(caliv); - } - }, 200); - showOverlay(cs, false, [{ - label: 'Set', click: () => { - el.value = vinp.value; - let cev = new Event('change'); - el.dispatchEvent(cev); - } - }]); - }) - el.setAttribute('name', configItem.name) - return el; - } function createInput(configItem, frame, clazz) { let el; if (configItem.type === 'boolean' || configItem.type === 'list') { @@ -628,9 +485,6 @@ el.setAttribute('name', configItem.name); return el; } - if (configItem.type === 'filter') { - return createFilterInput(configItem, frame, clazz); - } el = addEl('input', clazz, frame); if (configItem.readOnly) el.setAttribute('disabled', true); el.setAttribute('name', configItem.name) @@ -684,54 +538,6 @@ } } - function createFilterInput(configItem, frame) { - let el = addEl('div', 'filter', frame); - let ais = createInput({ - type: 'list', - name: configItem.name + "_ais", - list: ['aison', 'aisoff'], - readOnly: configItem.readOnly - }, el); - let mode = createInput({ - type: 'list', - name: configItem.name + "_mode", - list: ['whitelist', 'blacklist'], - readOnly: configItem.readOnly - }, el); - let sentences = createInput({ - type: 'text', - name: configItem.name + "_sentences", - readOnly: configItem.readOnly - }, el); - let data = addEl('input', undefined, el); - data.setAttribute('type', 'hidden'); - let changeFunction = function () { - let cv = data.value || ""; - let parts = cv.split(":"); - ais.value = (parts[0] == '0') ? "aisoff" : "aison"; - mode.value = (parts[1] == '0') ? "whitelist" : "blacklist"; - sentences.value = parts[2] || ""; - } - let updateFunction = function () { - let nv = (ais.value == 'aison') ? "1" : "0"; - nv += ":"; - nv += (mode.value == 'blacklist') ? "1" : "0"; - nv += ":"; - nv += sentences.value; - data.value = nv; - let chev = new Event('change'); - data.dispatchEvent(chev); - } - mode.addEventListener('change', updateFunction); - ais.addEventListener("change", updateFunction); - sentences.addEventListener("change", updateFunction); - data.addEventListener('change', function (ev) { - changeFunction(); - }); - data.setAttribute('name', configItem.name); - if (configItem.readOnly) data.setAttribute('disabled', true); - return data; - } let moreicons = ['icon-more', 'icon-less']; function collapseCategories(parent, expand) { @@ -1270,41 +1076,6 @@ return s + parts[0].substr(parts[0].length - dig); } let valueFormatters = { - formatCourse: { - f: function (v) { - let x = parseFloat(v); - let rt = x * 180.0 / Math.PI; - if (rt > 360) rt -= 360; - if (rt < 0) rt += 360; - return rt.toFixed(0); - }, - u: '°' - }, - formatKnots: { - f: function (v) { - let x = parseFloat(v); - x = x * 3600.0 / 1852.0; - return x.toFixed(2); - }, - u: 'kn' - }, - formatWind: { - f: function (v) { - let x = parseFloat(v); - x = x * 180.0 / Math.PI; - if (x > 180) x = -1 * (360 - x); - return x.toFixed(0); - }, - u: '°' - }, - mtr2nm: { - f: function (v) { - let x = parseFloat(v); - x = x / 1852.0; - return x.toFixed(2); - }, - u: 'nm' - }, kelvinToC: { f: function (v) { let x = parseFloat(v); @@ -1320,46 +1091,6 @@ }, u: '' }, - formatDepth: { - f: function (v) { - let x = parseFloat(v); - return x.toFixed(1); - }, - u: 'm' - }, - formatLatitude: { - f: function (v) { - let x = parseFloat(v); - if (isNaN(x)) return '-----'; - return formatLonLatsDecimal(x, 'lat'); - }, - u: '' - }, - formatLongitude: { - f: function (v) { - let x = parseFloat(v); - if (isNaN(x)) return '-----'; - return formatLonLatsDecimal(x, 'lon'); - }, - u: '' - }, - formatRot: { - f: function (v) { - let x = parseFloat(v); - if (isNaN(x)) return '---'; - x = x * 180.0 / Math.PI; - return x.toFixed(2); - }, - u: '°/s' - }, - formatXte: { - f: function (v) { - let x = parseFloat(v); - if (isNaN(x)) return '---'; - return x.toFixed(0); - }, - u: 'm' - }, formatDate: { f: function (v) { v = parseFloat(v); @@ -1388,8 +1119,6 @@ }, u: '' } - - } Object.freeze(valueFormatters); for (let k in valueFormatters){ @@ -1412,17 +1141,6 @@ } return u; } - function sourceName(v) { - if (v == 0) return "N2K"; - for (let n in channelList) { - if (v == channelList[n].id) return n; - if (v >= channelList[n].id && v <= channelList[n].max) { - return n; - } - } - if (v < minUser) return "---"; - return "USER[" + v + "]"; - } let lastSelectList = []; buttonHandlers.uploadBin=function(ev) { let el = document.getElementById("uploadFile"); @@ -1686,8 +1404,7 @@ config: 2, //called when the config data is loaded,data is the config object dataItemCreated: 4, //data is an object with // name: the item name, element: the frame item of the boat data display - status: 5, //status received, data is the status object - counterDisplayCreated: 6 //data is the row for the display + status: 5 //status received, data is the status object } }; function callListeners(event,data){