-
Click a device to view details
+
+
+
-
-
-
🔵 Discovered Devices (0)
-
-
Start scanning to discover devices...
-
-
-
-
📍 Tracker Detection
-
-
Monitoring for AirTags, Tiles, and other trackers...
+
+
+ Start scanning to discover Bluetooth devices
+
@@ -2333,7 +2370,7 @@
};
document.getElementById('activeModeIndicator').innerHTML = '
' + modeNames[mode];
document.getElementById('wifiLayoutContainer').style.display = mode === 'wifi' ? 'flex' : 'none';
- document.getElementById('btVisuals').style.display = mode === 'bluetooth' ? 'grid' : 'none';
+ document.getElementById('btLayoutContainer').style.display = mode === 'bluetooth' ? 'flex' : 'none';
// Respect the "Show Radar Display" checkbox for aircraft mode
const showRadar = document.getElementById('adsbEnableMap').checked;
document.getElementById('aircraftVisuals').style.display = (mode === 'aircraft' && showRadar) ? 'grid' : 'none';
@@ -6408,69 +6445,164 @@
}).join('');
}
- // Add Bluetooth device card to output
+ // Add Bluetooth device card to device list panel
function addBtDeviceCard(device, isNew) {
- const output = document.getElementById('output');
- const placeholder = output.querySelector('.placeholder');
- if (placeholder) placeholder.remove();
+ // Add to new device list panel
+ const deviceList = document.getElementById('btDeviceListContent');
+ if (deviceList) {
+ // Remove placeholder if present
+ const placeholder = deviceList.querySelector('div[style*="text-align: center"]');
+ if (placeholder && placeholder.textContent.includes('Start scanning')) {
+ placeholder.remove();
+ }
- let card = document.getElementById('bt_' + device.mac.replace(/:/g, ''));
-
- if (!card) {
- card = document.createElement('div');
- card.id = 'bt_' + device.mac.replace(/:/g, '');
- card.className = 'sensor-card' + (device.findmy ? ' findmy-device' : '');
+ let card = document.getElementById('btcard_' + device.mac.replace(/:/g, ''));
const devType = device.device_type || device.type || 'other';
- card.style.borderLeftColor = device.findmy ? '#007aff' :
- device.tracker ? 'var(--accent-red)' :
- devType === 'phone' ? 'var(--accent-cyan)' :
- devType === 'audio' ? 'var(--accent-green)' :
- 'var(--accent-orange)';
- output.insertBefore(card, output.firstChild);
+
+ if (!card) {
+ card = document.createElement('div');
+ card.id = 'btcard_' + device.mac.replace(/:/g, '');
+ card.className = 'sensor-card bt-device-card' +
+ (device.findmy ? ' findmy' : '') +
+ (device.tracker && !device.findmy ? ' tracker' : '');
+ card.style.cursor = 'pointer';
+ card.onclick = () => selectBtDevice(device.mac);
+ deviceList.insertBefore(card, deviceList.firstChild);
+
+ // Update device count
+ const countEl = document.getElementById('btDeviceListCount');
+ if (countEl) countEl.textContent = Object.keys(btDevices).length;
+ }
+
+ const typeIcon = {
+ 'phone': '📱', 'audio': '🎧', 'wearable': '⌚', 'tracker': '📍',
+ 'computer': '💻', 'input': '⌨️', 'other': '📶'
+ }[devType] || '📶';
+
+ // Handle signal strength
+ const rssi = device.rssi || -100;
+ const signalBars = Math.max(0, Math.min(5, Math.floor((rssi + 100) / 15)));
+ const signalDisplay = rssi > -100 ? `${rssi} dBm` : 'N/A';
+
+ const findMyBadge = device.findmy
+ ? `
${device.findmy.network.toUpperCase()}`
+ : '';
+
+ const trackerBadge = device.tracker && !device.findmy
+ ? `
TRACKER`
+ : '';
+
+ card.innerHTML = `
+
+
+
+
MAC
+
${escapeHtml(device.mac)}
+
+
+
Manufacturer
+
${escapeHtml(device.manufacturer || 'Unknown')}
+
+
+
Signal
+
${signalDisplay} ${'█'.repeat(signalBars)}${'░'.repeat(5-signalBars)}
+
+
+
+
+
+
+ `;
}
- const devType = device.device_type || device.type || 'other';
- const typeIcon = {
- 'phone': '📱', 'audio': '🎧', 'wearable': '⌚', 'tracker': '📍',
- 'computer': '💻', 'input': '⌨️', 'other': '📶'
- }[devType] || '📶';
+ // Update statistics panels
+ updateBtStatsPanels();
+ }
- const findMyBadge = device.findmy
- ? `
${device.findmy.icon || '📍'} ${device.findmy.network.toUpperCase()}`
- : '';
+ // Select a Bluetooth device
+ function selectBtDevice(mac) {
+ selectedBtDevice = mac;
+ const device = btDevices[mac];
+ if (device) {
+ updateBtSelectedDevice(device);
+ }
+ }
- card.innerHTML = `
-
-
-
-
MAC
-
${escapeHtml(device.mac)}
-
-
-
Manufacturer
-
${escapeHtml(device.manufacturer || 'Unknown')}
-
- ${device.findmy ? `
-
-
Find My
-
${escapeHtml(device.findmy.type)}
-
` : ''}
- ${device.tracker && !device.findmy ? `
-
-
Tracker
-
${escapeHtml(device.tracker.name)}
-
` : ''}
-
-
-
-
-
- `;
+ // Update Bluetooth statistics panels
+ function updateBtStatsPanels() {
+ const devices = Object.values(btDevices);
- if (autoScroll) output.scrollTop = 0;
+ // Device type counts
+ let phones = 0, computers = 0, audio = 0, wearables = 0, other = 0;
+ let strong = 0, medium = 0, weak = 0;
+
+ devices.forEach(d => {
+ const devType = d.device_type || d.type || 'other';
+ if (devType === 'phone') phones++;
+ else if (devType === 'computer') computers++;
+ else if (devType === 'audio') audio++;
+ else if (devType === 'wearable') wearables++;
+ else other++;
+
+ const rssi = d.rssi || -100;
+ if (rssi >= -50) strong++;
+ else if (rssi >= -70) medium++;
+ else weak++;
+ });
+
+ // Update type counts
+ const phoneEl = document.getElementById('btPhoneCount');
+ const compEl = document.getElementById('btComputerCount');
+ const audioEl = document.getElementById('btAudioCount');
+ const wearEl = document.getElementById('btWearableCount');
+ const otherEl = document.getElementById('btOtherCount');
+ if (phoneEl) phoneEl.textContent = phones;
+ if (compEl) compEl.textContent = computers;
+ if (audioEl) audioEl.textContent = audio;
+ if (wearEl) wearEl.textContent = wearables;
+ if (otherEl) otherEl.textContent = other;
+
+ // Update signal distribution
+ const total = devices.length || 1;
+ const strongBar = document.getElementById('btSignalStrong');
+ const mediumBar = document.getElementById('btSignalMedium');
+ const weakBar = document.getElementById('btSignalWeak');
+ const strongCount = document.getElementById('btSignalStrongCount');
+ const mediumCount = document.getElementById('btSignalMediumCount');
+ const weakCount = document.getElementById('btSignalWeakCount');
+
+ if (strongBar) strongBar.style.width = (strong / total * 100) + '%';
+ if (mediumBar) mediumBar.style.width = (medium / total * 100) + '%';
+ if (weakBar) weakBar.style.width = (weak / total * 100) + '%';
+ if (strongCount) strongCount.textContent = strong;
+ if (mediumCount) mediumCount.textContent = medium;
+ if (weakCount) weakCount.textContent = weak;
+
+ // Update FindMy list
+ updateBtFindMyList();
+ }
+
+ // Update FindMy device list
+ function updateBtFindMyList() {
+ const listEl = document.getElementById('btFindMyList');
+ if (!listEl) return;
+
+ const findMyDevices = Object.values(btDevices).filter(d => d.findmy);
+
+ if (findMyDevices.length === 0) {
+ listEl.innerHTML = '
Scanning for FindMy-compatible devices...
';
+ return;
+ }
+
+ listEl.innerHTML = findMyDevices.map(d => `
+
+ ${d.findmy.icon || '📍'} ${escapeHtml(d.name || d.findmy.type)}
+ ${d.rssi || '--'} dBm
+
+ `).join('');
}
// Target a Bluetooth device