diff --git a/static/js/modes/wifi.js b/static/js/modes/wifi.js index a386e85..3f94200 100644 --- a/static/js/modes/wifi.js +++ b/static/js/modes/wifi.js @@ -461,10 +461,15 @@ const WiFiMode = (function() { networks.set(ap.bssid, ap); }); - // Update channel stats + // Update channel stats (calculate from networks if not provided by API) channelStats = result.channel_stats || []; recommendations = result.recommendations || []; + // If no channel stats from API, calculate from networks + if (channelStats.length === 0 && networks.size > 0) { + channelStats = calculateChannelStats(); + } + // Update UI updateNetworkTable(); updateStats(); @@ -933,9 +938,47 @@ const WiFiMode = (function() { } } + function calculateChannelStats() { + // Calculate channel stats from current networks + const stats = {}; + const networksList = Array.from(networks.values()); + + // Initialize all channels + // 2.4 GHz: channels 1-13 + for (let ch = 1; ch <= 13; ch++) { + stats[ch] = { channel: ch, band: '2.4GHz', ap_count: 0, client_count: 0, utilization_score: 0 }; + } + // 5 GHz: common channels + [36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165].forEach(ch => { + stats[ch] = { channel: ch, band: '5GHz', ap_count: 0, client_count: 0, utilization_score: 0 }; + }); + + // Count APs per channel + networksList.forEach(net => { + const ch = parseInt(net.channel); + if (stats[ch]) { + stats[ch].ap_count++; + stats[ch].client_count += (net.client_count || 0); + } + }); + + // Calculate utilization score (0-1) + const maxAPs = Math.max(1, ...Object.values(stats).map(s => s.ap_count)); + Object.values(stats).forEach(s => { + s.utilization_score = s.ap_count / maxAPs; + }); + + return Object.values(stats).filter(s => s.ap_count > 0 || [1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165].includes(s.channel)); + } + function updateChannelChart(band = '2.4') { if (typeof ChannelChart === 'undefined') return; + // Recalculate channel stats from networks if needed + if (channelStats.length === 0 && networks.size > 0) { + channelStats = calculateChannelStats(); + } + // Filter stats by band const bandFilter = band === '2.4' ? '2.4GHz' : band === '5' ? '5GHz' : '6GHz'; const filteredStats = channelStats.filter(s => s.band === bandFilter); diff --git a/templates/index.html b/templates/index.html index 3bff886..609b8ff 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4401,6 +4401,48 @@ // NOTE: Browser Notifications code moved to static/js/core/audio.js + // Sync legacy WiFi data to v2 channel chart + function syncLegacyToChannelChart() { + if (typeof ChannelChart === 'undefined') return; + + const networksList = Object.values(wifiNetworks); + if (networksList.length === 0) return; + + // Calculate channel stats from legacy networks + const stats = {}; + + // Initialize 2.4 GHz channels + for (let ch = 1; ch <= 11; ch++) { + stats[ch] = { channel: ch, band: '2.4GHz', ap_count: 0, utilization_score: 0 }; + } + // Initialize 5 GHz channels + [36, 40, 44, 48, 149, 153, 157, 161, 165].forEach(ch => { + stats[ch] = { channel: ch, band: '5GHz', ap_count: 0, utilization_score: 0 }; + }); + + // Count APs per channel + networksList.forEach(net => { + const ch = parseInt(net.channel); + if (stats[ch]) { + stats[ch].ap_count++; + } + }); + + // Calculate utilization (0-1) + const maxAPs = Math.max(1, ...Object.values(stats).map(s => s.ap_count)); + Object.values(stats).forEach(s => { + s.utilization_score = s.ap_count / maxAPs; + }); + + // Get active band from tab + const activeTab = document.querySelector('.channel-band-tab.active'); + const band = activeTab ? activeTab.dataset.band : '2.4'; + const bandFilter = band === '2.4' ? '2.4GHz' : '5GHz'; + + const filteredStats = Object.values(stats).filter(s => s.band === bandFilter); + ChannelChart.update(filteredStats, []); + } + // Update visualizations periodically setInterval(() => { if (currentMode === 'wifi') { @@ -4408,6 +4450,7 @@ correlateDevices(); updateHiddenSsidDisplay(); updateProbeAnalysis(); + syncLegacyToChannelChart(); } }, 2000);