Fix discovery scan button integration and add debugging

- Add event binding for discovery scan button
- Implement startDiscoveryScan method with proper UI updates
- Add comprehensive debug logging to track discovery flow
- Fix discovery results container detection
- Improve error handling and user feedback

Now the discovery workflow should work properly:
1. Click 'Start Discovery Scan' button
2. See progress status and results
3. Click 'Use This Signal' to populate form
4. Click 'Apply All as Protocol Signals' to create all
This commit is contained in:
openhands 2025-11-09 14:30:50 +00:00
parent a639e3159a
commit 698c114609
3 changed files with 277 additions and 1 deletions

View File

@ -12,6 +12,14 @@ class SimplifiedProtocolDiscovery {
} }
bindDiscoveryEvents() { bindDiscoveryEvents() {
// Discovery scan button
const startScanBtn = document.getElementById('start-discovery-scan');
if (startScanBtn) {
startScanBtn.addEventListener('click', () => {
this.startDiscoveryScan();
});
}
// Auto-fill signal form from discovery // Auto-fill signal form from discovery
document.addEventListener('click', (e) => { document.addEventListener('click', (e) => {
if (e.target.classList.contains('use-discovered-endpoint')) { if (e.target.classList.contains('use-discovered-endpoint')) {
@ -123,6 +131,45 @@ class SimplifiedProtocolDiscovery {
} }
} }
// Start discovery scan
async startDiscoveryScan() {
console.log('Starting discovery scan...');
// Update UI
const startBtn = document.getElementById('start-discovery-scan');
const stopBtn = document.getElementById('stop-discovery-scan');
const statusDiv = document.getElementById('discovery-status');
if (startBtn) startBtn.disabled = true;
if (stopBtn) stopBtn.disabled = false;
if (statusDiv) {
statusDiv.innerHTML = '<div class="alert alert-info"><i class="fas fa-search"></i> Discovery scan in progress...</div>';
}
try {
// Run discovery
const results = await this.discoverAndSuggestSignals();
// Update status
if (statusDiv) {
statusDiv.innerHTML = `<div class="alert alert-success"><i class="fas fa-check"></i> Discovery complete. Found ${results.length} devices.</div>`;
}
this.showNotification(`Discovery complete. Found ${results.length} devices.`, 'success');
} catch (error) {
console.error('Discovery scan failed:', error);
if (statusDiv) {
statusDiv.innerHTML = '<div class="alert alert-error"><i class="fas fa-exclamation-triangle"></i> Discovery scan failed</div>';
}
this.showNotification('Discovery scan failed', 'error');
} finally {
// Reset UI
if (startBtn) startBtn.disabled = false;
if (stopBtn) stopBtn.disabled = true;
}
}
// Advanced discovery features // Advanced discovery features
async discoverAndSuggestSignals(networkRange = '192.168.1.0/24') { async discoverAndSuggestSignals(networkRange = '192.168.1.0/24') {
console.log(`Starting discovery scan on ${networkRange}`); console.log(`Starting discovery scan on ${networkRange}`);
@ -187,8 +234,13 @@ class SimplifiedProtocolDiscovery {
} }
displayDiscoveryResults(suggestedSignals) { displayDiscoveryResults(suggestedSignals) {
console.log('Displaying discovery results:', suggestedSignals);
const resultsContainer = document.getElementById('discovery-results'); const resultsContainer = document.getElementById('discovery-results');
if (!resultsContainer) return; if (!resultsContainer) {
console.error('Discovery results container not found!');
this.showNotification('Discovery results container not found', 'error');
return;
}
resultsContainer.innerHTML = '<h3>Discovery Results</h3>'; resultsContainer.innerHTML = '<h3>Discovery Results</h3>';

View File

@ -257,6 +257,7 @@ function autoPopulateSignalForm(discoveryData) {
console.log('Auto-populating signal form with:', discoveryData); console.log('Auto-populating signal form with:', discoveryData);
// First, open the "Add New Signal" modal // First, open the "Add New Signal" modal
console.log('Opening Add Signal modal...');
showAddSignalModal(); showAddSignalModal();
// Wait for modal to be fully loaded and visible // Wait for modal to be fully loaded and visible

View File

@ -0,0 +1,223 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Discovery Integration Test</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-section {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 6px;
}
button {
background: #007acc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background: #005a9e;
}
.log {
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px;
margin-top: 10px;
font-family: monospace;
font-size: 12px;
max-height: 200px;
overflow-y: auto;
}
.success { color: green; }
.error { color: red; }
.info { color: blue; }
</style>
</head>
<body>
<div class="container">
<h1>Discovery Integration Test</h1>
<div class="test-section">
<h2>Test 1: Check if Functions are Available</h2>
<button onclick="testFunctionAvailability()">Check Function Availability</button>
<div id="function-test" class="log"></div>
</div>
<div class="test-section">
<h2>Test 2: Simulate Discovery Results</h2>
<button onclick="simulateDiscovery()">Simulate Discovery Scan</button>
<div id="discovery-results" class="log"></div>
</div>
<div class="test-section">
<h2>Test 3: Test Auto-Population</h2>
<button onclick="testAutoPopulation()">Test Auto-Population</button>
<div id="auto-population-test" class="log"></div>
</div>
<div class="test-section">
<h2>Test 4: Test API Endpoints</h2>
<button onclick="testAPIEndpoints()">Test API Endpoints</button>
<div id="api-test" class="log"></div>
</div>
</div>
<script>
function logMessage(elementId, message, type = 'info') {
const element = document.getElementById(elementId);
const timestamp = new Date().toLocaleTimeString();
element.innerHTML += `<div class="${type}">[${timestamp}] ${message}</div>`;
element.scrollTop = element.scrollHeight;
}
function testFunctionAvailability() {
const logElement = 'function-test';
logMessage(logElement, 'Testing function availability...', 'info');
const functions = [
'autoPopulateSignalForm',
'loadAllSignals',
'showAddSignalModal',
'saveSignal'
];
functions.forEach(funcName => {
const isAvailable = typeof window[funcName] === 'function';
const status = isAvailable ? '✓ AVAILABLE' : '✗ NOT AVAILABLE';
const type = isAvailable ? 'success' : 'error';
logMessage(logElement, `${funcName}: ${status}`, type);
});
}
function simulateDiscovery() {
const logElement = 'discovery-results';
logMessage(logElement, 'Simulating discovery scan...', 'info');
// Simulate discovered device
const discoveredDevice = {
device_id: 'test_device_001',
protocol_type: 'modbus_tcp',
device_name: 'Test Water Pump',
address: '192.168.1.200',
port: 502,
data_point: 'Speed',
protocol_address: '40001'
};
logMessage(logElement, `Discovered device: ${discoveredDevice.device_name}`, 'success');
logMessage(logElement, `Protocol: ${discoveredDevice.protocol_type} at ${discoveredDevice.protocol_address}`, 'info');
// Convert to signal format
const signalData = convertEndpointToSignal(discoveredDevice);
logMessage(logElement, 'Converted to signal format:', 'info');
logMessage(logElement, ` Signal Name: ${signalData.signal_name}`, 'info');
logMessage(logElement, ` Tags: ${signalData.tags.join(', ')}`, 'info');
logMessage(logElement, ` Protocol: ${signalData.protocol_type}`, 'info');
logMessage(logElement, ` Address: ${signalData.protocol_address}`, 'info');
logMessage(logElement, ` DB Source: ${signalData.db_source}`, 'info');
// Store for later use
window.testSignalData = signalData;
logMessage(logElement, 'Signal data stored in window.testSignalData', 'success');
}
function convertEndpointToSignal(endpoint) {
const signalName = `${endpoint.device_name} ${endpoint.data_point}`;
const tags = [
`device:${endpoint.device_name.toLowerCase().replace(/[^a-z0-9]/g, '_')}`,
`protocol:${endpoint.protocol_type}`,
`data_point:${endpoint.data_point.toLowerCase().replace(/[^a-z0-9]/g, '_')}`,
'discovered:true',
'test:true'
];
const dbSource = `measurements.${endpoint.device_name.toLowerCase().replace(/[^a-z0-9]/g, '_')}_${endpoint.data_point.toLowerCase().replace(/[^a-z0-9]/g, '_')}`;
return {
signal_name: signalName,
tags: tags,
protocol_type: endpoint.protocol_type,
protocol_address: endpoint.protocol_address,
db_source: dbSource
};
}
function testAutoPopulation() {
const logElement = 'auto-population-test';
if (!window.testSignalData) {
logMessage(logElement, 'No test signal data available. Run Test 2 first.', 'error');
return;
}
logMessage(logElement, 'Testing auto-population...', 'info');
// Check if autoPopulateSignalForm is available
if (typeof window.autoPopulateSignalForm !== 'function') {
logMessage(logElement, 'ERROR: autoPopulateSignalForm function not available!', 'error');
logMessage(logElement, 'This means the protocol_mapping.js file is not loaded or has errors.', 'error');
return;
}
logMessage(logElement, 'Calling autoPopulateSignalForm with test data...', 'info');
try {
window.autoPopulateSignalForm(window.testSignalData);
logMessage(logElement, '✓ autoPopulateSignalForm called successfully', 'success');
logMessage(logElement, 'The "Add New Signal" modal should open with pre-filled data.', 'info');
} catch (error) {
logMessage(logElement, `✗ Error calling autoPopulateSignalForm: ${error.message}`, 'error');
logMessage(logElement, `Stack trace: ${error.stack}`, 'error');
}
}
async function testAPIEndpoints() {
const logElement = 'api-test';
logMessage(logElement, 'Testing API endpoints...', 'info');
const endpoints = [
'/api/v1/dashboard/protocol-signals',
'/api/v1/dashboard/discovery/scan',
'/api/v1/dashboard/discovery/status'
];
for (const endpoint of endpoints) {
try {
logMessage(logElement, `Testing ${endpoint}...`, 'info');
const response = await fetch(endpoint);
const status = response.status;
const statusText = response.statusText;
if (response.ok) {
logMessage(logElement, `✓ ${endpoint}: ${status} ${statusText}`, 'success');
} else {
logMessage(logElement, `✗ ${endpoint}: ${status} ${statusText}`, 'error');
}
} catch (error) {
logMessage(logElement, `✗ ${endpoint}: ${error.message}`, 'error');
}
}
}
</script>
</body>
</html>