mirror of
https://github.com/smittix/intercept.git
synced 2026-05-03 02:50:01 -07:00
Add signal activity timeline visualization for TSCM mode
New lightweight timeline component that shows RF signal presence over time without heavy waterfall rendering: - Horizontal swimlanes for each frequency/signal source - Bars show transmission duration with height = signal strength - Status colors: blue=new, gray=baseline, orange=burst, red=flagged - Pattern detection for regular interval transmissions - Click to expand and see individual transmission ticks - Right-click to flag signals for investigation - Auto-annotations for new signals, bursts, and patterns - Tooltip with signal details on hover - Time window selector (5m to 2h) - Filter controls (hide baseline, show only new/burst) Integrated into TSCM mode: - Timeline created when TSCM mode is selected - WiFi, Bluetooth, and RF signals feed into timeline - Clears on new sweep start Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/modes/aprs.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/modes/tscm.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/components/signal-cards.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/components/signal-timeline.css') }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -1456,6 +1457,9 @@
|
||||
<!-- Sweep Summary (shown after sweep completes) -->
|
||||
<div id="tscmSweepSummary" style="display: none; margin-bottom: 16px;"></div>
|
||||
|
||||
<!-- Signal Activity Timeline -->
|
||||
<div id="tscmTimelineContainer" style="margin-bottom: 16px;"></div>
|
||||
|
||||
<!-- Cross-Protocol Correlations (shown when correlations found) -->
|
||||
<div id="tscmCorrelationsContainer" style="display: none;"></div>
|
||||
|
||||
@@ -1588,6 +1592,7 @@
|
||||
<script src="{{ url_for('static', filename='js/core/audio.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/components/radio-knob.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/components/signal-cards.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/components/signal-timeline.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modes/listening-post.js') }}"></script>
|
||||
|
||||
<script>
|
||||
@@ -2057,6 +2062,10 @@
|
||||
if (mode === 'tscm') {
|
||||
loadTscmBaselines();
|
||||
refreshTscmDevices();
|
||||
// Initialize signal timeline if not already created
|
||||
if (!document.getElementById('signalTimeline')) {
|
||||
SignalTimeline.create('tscmTimelineContainer');
|
||||
}
|
||||
}
|
||||
|
||||
// Show/hide Device Intelligence for modes that use it (not for satellite/aircraft/tscm)
|
||||
@@ -7782,7 +7791,7 @@
|
||||
];
|
||||
|
||||
function renderSatelliteList() {
|
||||
const list = document.getElementById('satelliteList');
|
||||
const list = document.getElementById('satTrackingList');
|
||||
if (!list) return;
|
||||
|
||||
list.innerHTML = trackedSatellites.map((sat, idx) => `
|
||||
@@ -7894,14 +7903,15 @@
|
||||
if (data.status === 'success' && data.satellites) {
|
||||
let added = 0;
|
||||
data.satellites.forEach(sat => {
|
||||
if (!trackedSatellites.find(s => s.norad === sat.norad)) {
|
||||
const noradStr = String(sat.norad);
|
||||
if (!trackedSatellites.find(s => s.norad === noradStr)) {
|
||||
trackedSatellites.push({
|
||||
id: sat.id,
|
||||
id: sat.name.replace(/[^a-zA-Z0-9-]/g, '-'),
|
||||
name: sat.name,
|
||||
norad: sat.norad,
|
||||
norad: noradStr,
|
||||
builtin: false,
|
||||
checked: false, // Don't auto-select
|
||||
tle: sat.tle
|
||||
tle: [sat.name, sat.tle1, sat.tle2]
|
||||
});
|
||||
added++;
|
||||
}
|
||||
@@ -8171,6 +8181,9 @@
|
||||
document.getElementById('startTscmBtn').style.display = 'none';
|
||||
document.getElementById('stopTscmBtn').style.display = 'block';
|
||||
document.getElementById('tscmProgress').style.display = 'flex';
|
||||
|
||||
// Clear and reset the signal timeline for new sweep
|
||||
SignalTimeline.clear();
|
||||
document.getElementById('tscmReportBtn').style.display = 'none';
|
||||
|
||||
// Show warnings if any devices unavailable
|
||||
@@ -8864,6 +8877,10 @@
|
||||
body: JSON.stringify(device)
|
||||
}).catch(e => console.error('Baseline feed error:', e));
|
||||
}
|
||||
// Add to signal timeline
|
||||
const freq = device.channel <= 14 ? '2400' : '5000';
|
||||
const strength = Math.min(5, Math.max(1, Math.ceil((device.signal + 100) / 20)));
|
||||
SignalTimeline.addEvent(freq, strength, 2000, device.ssid || 'Hidden WiFi');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8886,6 +8903,9 @@
|
||||
body: JSON.stringify(device)
|
||||
}).catch(e => console.error('Baseline feed error:', e));
|
||||
}
|
||||
// Add to signal timeline
|
||||
const strength = device.rssi ? Math.min(5, Math.max(1, Math.ceil((device.rssi + 100) / 20))) : 3;
|
||||
SignalTimeline.addEvent('2450', strength, 1500, device.name || 'Bluetooth Device');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8913,6 +8933,13 @@
|
||||
body: JSON.stringify(signal)
|
||||
}).catch(e => console.error('Baseline feed error:', e));
|
||||
}
|
||||
// Add to signal timeline
|
||||
const strength = signal.power_dbm ? Math.min(5, Math.max(1, Math.ceil((signal.power_dbm + 60) / 15))) : 3;
|
||||
SignalTimeline.addEvent(String(signal.frequency), strength, 1000, signal.classification || 'RF Signal');
|
||||
} else {
|
||||
// Update existing signal on timeline (show recurring transmission)
|
||||
const strength = signal.power_dbm ? Math.min(5, Math.max(1, Math.ceil((signal.power_dbm + 60) / 15))) : 3;
|
||||
SignalTimeline.addEvent(String(signal.frequency), strength, 500, signal.classification || 'RF Signal');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user