Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / assets / arch-arm32-m4-mt7697-usi.svg
Author[]google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.c...> 2025-12-27 10:59 UTC
Committer[]Andy Green <andy@warmcat.com> 2025-12-27 11:00 UTC
Tree55abff2a9ce538e4a3624005eb169fe644ff6d43   Raw Patch
 
Fix PCON startup behavior, UI sync, and data persistence
Fix PCON startup behavior, UI sync, and data persistence

- Backend: Disable "Rule 1" (Discovery) power-on in `src/power/p-sai.c` to prevent unwanted power toggling on `sai-power` restart.
- Backend: Implement change detection in `sul_pcon_check_cb` to notify `sai-server` via `saip_queue_stay_info` when PCON state actually changes, fixing UI desynchronization.
- Frontend: Add `pcon_energy_cache` in `assets/sai.js` to persist energy data across builder list redraws, preventing data flickering/loss.
- Frontend: Ensure explicit queuing of `pcon_control` messages in `src/web/w-ws-browser.c` to resolve potential forwarding issues.
diff --git a/assets/sai.js b/assets/sai.js index 7d976c9..7889afc 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -401,6 +401,7 @@ var logs = "", redpend = 0, gitohashi_integ = 0, authd = 0, exptimer, auth_user /* Global caches for reconcilation */ var pcon_topology = {}; +var pcon_energy_cache = {}; var last_builder_list = []; function createPconDiv(pcon) { @@ -1406,6 +1407,18 @@ function createPconDiv(pcon) { let type = pcon.type ? `(${pcon.type})` : ""; header.innerHTML = `<span class="${stateClass}">&#x23FB;</span> <b>${hsanitize(pcon.name)}</b> <span class="pcon-type">${hsanitize(type)}</span>`; + + if (pcon_energy_cache[pcon.name]) { + const d = pcon_energy_cache[pcon.name]; + let stats = document.createElement("span"); + stats.className = "pcon-stats"; + stats.style.marginLeft = "10px"; + stats.style.fontSize = "0.9em"; + stats.style.color = "#666"; + stats.textContent = `${d.voltage_v}V ${d.active_power_w}W ${d.current_ma}mA today:${(d.energy_today_wh/1000).toFixed(3)}kWh`; + header.appendChild(stats); + } + pconDiv.appendChild(header); /* Context menu for PCON */ @@ -1733,6 +1746,7 @@ function ws_open_sai() case "com.warmcat.sai.pcon_energy": if (jso.items) { jso.items.forEach(item => { + pcon_energy_cache[item.name] = item; const pconDiv = document.getElementById("pcon-" + item.name); if (pconDiv) { let header = pconDiv.querySelector(".pcon-header"); diff --git a/src/power/p-sai.c b/src/power/p-sai.c index ad7d4ff..2bd5c67 100644 --- a/src/power/p-sai.c +++ b/src/power/p-sai.c @@ -197,6 +197,8 @@ static const struct lws_protocols *pprotocols[] = { void sul_pcon_check_cb(lws_sorted_usec_list_t *sul) { + int any_changed = 0; + /* Iterate all PCONs */ lws_start_foreach_dll(struct lws_dll2 *, p, power.sai_pcon_owner.head) { saip_pcon_t *pc = lws_container_of(p, saip_pcon_t, list); @@ -204,11 +206,12 @@ sul_pcon_check_cb(lws_sorted_usec_list_t *sul) /* Rule 1: No builders registered -> Turn ON (Cold start / Discovery) */ if (!pc->registered_builders_owner.count) { - target_on = 1; - lwsl_info("%s: PCON %s has 0 builders -> Force ON\n", __func__, pc->name); + /* target_on = 1; */ + /* lwsl_info("%s: PCON %s has 0 builders -> Force ON\n", __func__, pc->name); */ } + /* Rule 2: User Keep On -> Turn ON */ - else if (pc->user_keep_on) { + if (pc->user_keep_on) { target_on = 1; lwsl_info("%s: PCON %s has user keep on -> Force ON\n", __func__, pc->name); } @@ -223,14 +226,28 @@ sul_pcon_check_cb(lws_sorted_usec_list_t *sul) lwsl_notice("%s: PCON %s ON (target=1, current=%d)\n", __func__, pc->name, pc->on); pc->on = 1; saip_switch(pc, 1); + any_changed = 1; } else if (!target_on && pc->on) { lwsl_notice("%s: PCON %s OFF (target=0, current=%d)\n", __func__, pc->name, pc->on); pc->on = 0; saip_switch(pc, 0); + any_changed = 1; } } lws_end_foreach_dll(p); + if (any_changed) { + lws_start_foreach_dll_safe(struct lws_dll2 *, mp, mp1, + power.sai_server_owner.head) { + saip_server_t *sps = lws_container_of(mp, struct saip_server, list); + saip_queue_stay_info(sps); + if (sps->ss) { + if (lws_ss_request_tx(sps->ss)) + lwsl_warn("%s: failed to request tx\n", __func__); + } + } lws_end_foreach_dll_safe(mp, mp1); + } + /* Schedule next check */ lws_sul_schedule(power.context, 0, &power.sul_pcon_check, sul_pcon_check_cb, 5 * LWS_US_PER_SEC); }
Page fetched 0s ago, creation time: 3ms (vhost etag hits: 0%, cache hits: 0%)