Fix HA toggle (Rocket Loader) and network map cleanup

HA toggle broken after modularization: separate <script src> files are
deferred by Cloudflare Rocket Loader, so inline onchange handlers fire
before toggleHA() is defined. Fix: add data-cfasync="false" to all
four JARVIS script tags to prevent Rocket Loader interference.

Network map cleanup:
- Deduplicate agent devices by hostname — two homeassistant agents
  (10.48.200.97 and 172.30.32.1) now show as one node; prefer online
  over offline, then most-recently-seen
- Offline agents excluded from inner rings — jellyfin (offline June 3)
  and mini_it12 (offline June 12) no longer appear on the map
- DB-pinned devices (Yealink phones) unaffected; still show in devices ring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 03:20:37 +00:00
parent b2aa3280e1
commit b014fd96ab
2 changed files with 31 additions and 5 deletions
+27 -1
View File
@@ -144,7 +144,33 @@ function _nmBuild(devices){
_nmNodes.push({id:'jarvis',label:'JARVIS',sub:'165.22.1.228',online:true,agent:true,ringIdx:0,angle:0,r:NM_RINGS[0].nodeR,pulse:0});
// Bucket
var buckets={proxmox:[],services:[],agents:[],devices:[],network:[]};
for(var i=0;i<devices.length;i++) buckets[_nmClassify(devices[i])].push(devices[i]);
// Deduplicate agent devices by hostname (same logical host registered twice)
var _seenNames={};
var _dedupedDevices=[];
for(var i=0;i<devices.length;i++){
var d=devices[i];
if(d.source!=='agent'){_dedupedDevices.push(d);continue;}
var nk=(d.name||d.ip||'').toLowerCase();
if(!nk){_dedupedDevices.push(d);continue;}
if(!_seenNames[nk]){
_seenNames[nk]={idx:_dedupedDevices.length,d:d};
_dedupedDevices.push(d);
} else {
var prev=_seenNames[nk].d;
var prevOn=prev.alive||prev.status==='online';
var curOn=d.alive||d.status==='online';
if(curOn&&!prevOn){_dedupedDevices[_seenNames[nk].idx]=d;_seenNames[nk].d=d;}
else if(!curOn&&prevOn){/* keep prev */}
else if((d.last_seen||'')>(prev.last_seen||'')){_dedupedDevices[_seenNames[nk].idx]=d;_seenNames[nk].d=d;}
}
}
// Bucket: offline agents are excluded from inner rings (keep DB/netscan as-is)
for(var i=0;i<_dedupedDevices.length;i++){
var d=_dedupedDevices[i];
var isOffline=!(d.alive||d.status==='online');
if(d.source==='agent'&&isOffline) continue; // hide offline agents from map
buckets[_nmClassify(d)].push(d);
}
// Sort netscan devices: online first, then those with meaningful hostnames
buckets.network.sort(function(a,b){
var sa=a.alive?1:0, sb=b.alive?1:0;
+4 -4
View File
@@ -404,10 +404,10 @@
style="position:fixed;top:-9999px;left:-9999px;width:320px;height:240px"></video>
<script src="https://cdn.jsdelivr.net/npm/face-api.js@0.22.2/dist/face-api.min.js" crossorigin="anonymous"></script>
<script src="assets/js/jarvis-effects.js"></script>
<script src="assets/js/jarvis-overlays.js"></script>
<script src="assets/js/jarvis-app.js"></script>
<script src="assets/js/jarvis-protocols.js"></script>
<script data-cfasync="false" src="assets/js/jarvis-effects.js"></script>
<script data-cfasync="false" src="assets/js/jarvis-overlays.js"></script>
<script data-cfasync="false" src="assets/js/jarvis-app.js"></script>
<script data-cfasync="false" src="assets/js/jarvis-protocols.js"></script>
<!-- VISION LIGHTBOX -->
<div id="vision-lightbox">