diff --git a/led-driver b/led-driver index 044dd81..fb53f90 160000 --- a/led-driver +++ b/led-driver @@ -1 +1 @@ -Subproject commit 044dd815dce607ecce2ac42f9376ca7f03091293 +Subproject commit fb53f900fbcd6731431c890774cdda2dc57ea736 diff --git a/src/controllers/preset.py b/src/controllers/preset.py index e263af2..8fd142b 100644 --- a/src/controllers/preset.py +++ b/src/controllers/preset.py @@ -171,9 +171,13 @@ async def send_presets(request, session): if not sender: return json.dumps({"error": "Transport not configured"}), 503, {'Content-Type': 'application/json'} - async def send_chunk(chunk_presets): - # Include save flag so the led-driver can persist when desired. - msg = build_message(presets=chunk_presets, save=save_flag, default=default_id) + async def send_chunk(chunk_presets, is_last): + # Save/default should only be sent with the final presets chunk. + msg = build_message( + presets=chunk_presets, + save=save_flag and is_last, + default=default_id if is_last else None, + ) await sender.send(msg, addr=destination_mac) MAX_BYTES = 240 @@ -195,7 +199,7 @@ async def send_presets(request, session): last_msg = test_msg else: try: - await send_chunk(batch) + await send_chunk(batch, False) except Exception: return json.dumps({"error": "Send failed"}), 503, {'Content-Type': 'application/json'} await asyncio.sleep(send_delay_s) @@ -205,7 +209,7 @@ async def send_presets(request, session): if batch: try: - await send_chunk(batch) + await send_chunk(batch, True) except Exception: return json.dumps({"error": "Send failed"}), 503, {'Content-Type': 'application/json'} await asyncio.sleep(send_delay_s) diff --git a/src/static/presets.js b/src/static/presets.js index bc8fa75..2de75bb 100644 --- a/src/static/presets.js +++ b/src/static/presets.js @@ -132,7 +132,7 @@ const sendEspnowMessage = (obj) => { // Send a select message for a preset to all device names in the current tab. // Uses the preset ID as the select key. -const sendSelectForCurrentTabDevices = (presetId, sectionEl, saveToDevice = true) => { +const sendSelectForCurrentTabDevices = (presetId, sectionEl) => { const section = sectionEl || document.querySelector('.presets-section[data-tab-id]'); if (!section || !presetId) { return; @@ -155,9 +155,6 @@ const sendSelectForCurrentTabDevices = (presetId, sectionEl, saveToDevice = true v: '1', select, }; - if (saveToDevice) { - message.save = true; - } sendEspnowMessage(message); }; @@ -1325,9 +1322,8 @@ document.addEventListener('DOMContentLoaded', () => { // Build ESPNow messages for a single preset. // Send order: -// 1) preset payload (without save) -// 2) optional select for device names -// 3) optional save command +// 1) preset payload (optionally with save) +// 2) optional select for device names (never with save) // saveToDevice defaults to true. const sendPresetViaEspNow = async (presetId, preset, deviceNames, saveToDevice = true, setDefault = false) => { try { @@ -1394,11 +1390,13 @@ const sendDefaultPreset = (presetId, deviceNames) => { return; } // Default should only set startup preset, not trigger live selection. + // Save is attached to default messages. // When device names are provided, scope the default update to those devices. const targets = Array.isArray(deviceNames) ? deviceNames.map((n) => (n || '').trim()).filter((n) => n.length > 0) : []; const message = { v: '1', default: presetId }; + message.save = true; if (targets.length > 0) { message.targets = targets; } diff --git a/src/static/tabs.js b/src/static/tabs.js index 68c6d27..9434988 100644 --- a/src/static/tabs.js +++ b/src/static/tabs.js @@ -354,7 +354,7 @@ async function loadTabContent(tabId) { brightnessSendTimeout = setTimeout(() => { if (typeof window.sendEspnowRaw === 'function') { try { - window.sendEspnowRaw({ v: '1', b: val }); + window.sendEspnowRaw({ v: '1', b: val, save: true }); } catch (err) { console.error('Failed to send brightness via ESPNow:', err); }