CalejoControl/static/protocol_mapping.js

298 lines
11 KiB
JavaScript
Raw Normal View History

// Protocol Mapping Functions
let currentProtocolFilter = 'all';
let editingMappingId = null;
function selectProtocol(protocol) {
currentProtocolFilter = protocol;
// Update active button
document.querySelectorAll('.protocol-btn').forEach(btn => {
btn.classList.remove('active');
});
event.target.classList.add('active');
// Reload mappings with filter
loadProtocolMappings();
}
async function loadProtocolMappings() {
try {
const params = new URLSearchParams();
if (currentProtocolFilter !== 'all') {
params.append('protocol_type', currentProtocolFilter);
}
const response = await fetch(`/api/v1/dashboard/protocol-mappings?${params}`);
const data = await response.json();
if (data.success) {
displayProtocolMappings(data.mappings);
} else {
showProtocolMappingAlert('Failed to load protocol mappings', 'error');
}
} catch (error) {
console.error('Error loading protocol mappings:', error);
showProtocolMappingAlert('Error loading protocol mappings', 'error');
}
}
function displayProtocolMappings(mappings) {
const tbody = document.getElementById('protocol-mappings-body');
tbody.innerHTML = '';
if (mappings.length === 0) {
tbody.innerHTML = '<tr><td colspan="8" style="text-align: center; padding: 20px;">No protocol mappings found</td></tr>';
return;
}
mappings.forEach(mapping => {
const row = document.createElement('tr');
row.innerHTML = `
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.id}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.protocol_type}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.station_id || '-'}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.pump_id || '-'}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.data_type}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.protocol_address}</td>
<td style="padding: 10px; border: 1px solid #ddd;">${mapping.db_source}</td>
<td style="padding: 10px; border: 1px solid #ddd;">
<button onclick="editMapping('${mapping.id}')" style="background: #007acc; margin-right: 5px;">Edit</button>
<button onclick="deleteMapping('${mapping.id}')" style="background: #dc3545;">Delete</button>
</td>
`;
tbody.appendChild(row);
});
}
function showAddMappingModal() {
editingMappingId = null;
document.getElementById('modal-title').textContent = 'Add Protocol Mapping';
document.getElementById('mapping-form').reset();
document.getElementById('protocol_address_help').textContent = '';
document.getElementById('mapping-modal').style.display = 'block';
}
function showEditMappingModal(mapping) {
editingMappingId = mapping.id;
document.getElementById('modal-title').textContent = 'Edit Protocol Mapping';
document.getElementById('mapping_id').value = mapping.id;
document.getElementById('protocol_type').value = mapping.protocol_type;
document.getElementById('station_id').value = mapping.station_id || '';
document.getElementById('pump_id').value = mapping.pump_id || '';
document.getElementById('data_type').value = mapping.data_type;
document.getElementById('protocol_address').value = mapping.protocol_address;
document.getElementById('db_source').value = mapping.db_source;
updateProtocolFields();
document.getElementById('mapping-modal').style.display = 'block';
}
function closeMappingModal() {
document.getElementById('mapping-modal').style.display = 'none';
editingMappingId = null;
}
function updateProtocolFields() {
const protocolType = document.getElementById('protocol_type').value;
const helpText = document.getElementById('protocol_address_help');
switch (protocolType) {
case 'modbus_tcp':
helpText.textContent = 'Modbus address format: 40001 (holding register), 30001 (input register), 10001 (coil), 00001 (discrete input)';
break;
case 'opcua':
helpText.textContent = 'OPC UA NodeId format: ns=2;s=MyVariable or ns=2;i=1234';
break;
case 'modbus_rtu':
helpText.textContent = 'Modbus RTU address format: 40001 (holding register), 30001 (input register), 10001 (coil), 00001 (discrete input)';
break;
case 'rest_api':
helpText.textContent = 'REST API endpoint format: /api/v1/data/endpoint';
break;
default:
helpText.textContent = '';
}
}
async function validateMapping() {
const formData = getMappingFormData();
try {
const response = await fetch(`/api/v1/dashboard/protocol-mappings/${editingMappingId || 'new'}/validate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
const data = await response.json();
if (data.success) {
if (data.valid) {
showProtocolMappingAlert('Mapping validation successful!', 'success');
} else {
showProtocolMappingAlert(`Validation failed: ${data.errors.join(', ')}`, 'error');
}
} else {
showProtocolMappingAlert('Validation error', 'error');
}
} catch (error) {
console.error('Error validating mapping:', error);
showProtocolMappingAlert('Error validating mapping', 'error');
}
}
async function saveMapping(event) {
event.preventDefault();
const formData = getMappingFormData();
try {
let response;
if (editingMappingId) {
response = await fetch(`/api/v1/dashboard/protocol-mappings/${editingMappingId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
} else {
response = await fetch('/api/v1/dashboard/protocol-mappings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
}
const data = await response.json();
if (data.success) {
showProtocolMappingAlert(`Protocol mapping ${editingMappingId ? 'updated' : 'created'} successfully!`, 'success');
closeMappingModal();
loadProtocolMappings();
} else {
showProtocolMappingAlert(`Failed to save mapping: ${data.detail || 'Unknown error'}`, 'error');
}
} catch (error) {
console.error('Error saving mapping:', error);
showProtocolMappingAlert('Error saving mapping', 'error');
}
}
function getMappingFormData() {
return {
protocol_type: document.getElementById('protocol_type').value,
station_id: document.getElementById('station_id').value,
pump_id: document.getElementById('pump_id').value,
data_type: document.getElementById('data_type').value,
protocol_address: document.getElementById('protocol_address').value,
db_source: document.getElementById('db_source').value
};
}
async function editMapping(mappingId) {
try {
const response = await fetch(`/api/v1/dashboard/protocol-mappings?protocol_type=all`);
const data = await response.json();
if (data.success) {
const mapping = data.mappings.find(m => m.id === mappingId);
if (mapping) {
showEditMappingModal(mapping);
} else {
showProtocolMappingAlert('Mapping not found', 'error');
}
} else {
showProtocolMappingAlert('Failed to load mapping', 'error');
}
} catch (error) {
console.error('Error loading mapping:', error);
showProtocolMappingAlert('Error loading mapping', 'error');
}
}
async function deleteMapping(mappingId) {
if (!confirm(`Are you sure you want to delete mapping ${mappingId}?`)) {
return;
}
try {
const response = await fetch(`/api/v1/dashboard/protocol-mappings/${mappingId}`, {
method: 'DELETE'
});
const data = await response.json();
if (data.success) {
showProtocolMappingAlert('Mapping deleted successfully!', 'success');
loadProtocolMappings();
} else {
showProtocolMappingAlert(`Failed to delete mapping: ${data.detail || 'Unknown error'}`, 'error');
}
} catch (error) {
console.error('Error deleting mapping:', error);
showProtocolMappingAlert('Error deleting mapping', 'error');
}
}
function showProtocolMappingAlert(message, type) {
const alertsDiv = document.getElementById('protocol-mapping-alerts');
const alertDiv = document.createElement('div');
alertDiv.className = `alert ${type === 'error' ? 'error' : 'success'}`;
alertDiv.textContent = message;
alertsDiv.innerHTML = '';
alertsDiv.appendChild(alertDiv);
setTimeout(() => {
alertDiv.remove();
}, 5000);
}
async function exportProtocolMappings() {
try {
const response = await fetch('/api/v1/dashboard/protocol-mappings?protocol_type=all');
const data = await response.json();
if (data.success) {
const csvContent = convertToCSV(data.mappings);
downloadCSV(csvContent, 'protocol_mappings.csv');
} else {
showProtocolMappingAlert('Failed to export mappings', 'error');
}
} catch (error) {
console.error('Error exporting mappings:', error);
showProtocolMappingAlert('Error exporting mappings', 'error');
}
}
function convertToCSV(mappings) {
const headers = ['ID', 'Protocol', 'Station', 'Pump', 'Data Type', 'Protocol Address', 'Database Source'];
const rows = mappings.map(mapping => [
mapping.id,
mapping.protocol_type,
mapping.station_id || '',
mapping.pump_id || '',
mapping.data_type,
mapping.protocol_address,
mapping.db_source
]);
return [headers, ...rows].map(row => row.map(field => `"${field}"`).join(',')).join('\n');
}
function downloadCSV(content, filename) {
const blob = new Blob([content], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}
// Initialize form submission handler
document.addEventListener('DOMContentLoaded', function() {
const mappingForm = document.getElementById('mapping-form');
if (mappingForm) {
mappingForm.addEventListener('submit', saveMapping);
}
});