mirror of
https://github.com/rightup/pyMC_Repeater.git
synced 2026-03-28 17:43:06 +01:00
226 lines
11 KiB
HTML
226 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>pyMC Repeater - Configuration</title>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="/static/style.css">
|
|
</head>
|
|
<body>
|
|
<div class="layout">
|
|
<!-- Navigation Component -->
|
|
<!-- NAVIGATION_PLACEHOLDER -->
|
|
|
|
<!-- Main Content -->
|
|
<main class="content">
|
|
<header>
|
|
<h1>Configuration</h1>
|
|
<p>System configuration and settings</p>
|
|
</header>
|
|
|
|
<div class="info-box">
|
|
Configuration is read-only. To modify settings, edit the config file and restart the daemon.
|
|
</div>
|
|
|
|
<!-- CAD Calibration Tool -->
|
|
<div class="info-box" style="background: var(--accent-color); color: white; border: none;">
|
|
<strong>CAD Calibration Tool Available</strong>
|
|
<p style="margin: 8px 0 0 0;">
|
|
Optimize your Channel Activity Detection settings for better mesh performance.
|
|
<a href="/cad-calibration" style="color: white; text-decoration: underline;">Launch CAD Calibration Tool →</a>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Radio Configuration -->
|
|
<h2>Radio Settings</h2>
|
|
<div class="config-section">
|
|
<div class="config-item">
|
|
<div class="config-label">Frequency</div>
|
|
<div class="config-value" id="radio-freq">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Spreading Factor</div>
|
|
<div class="config-value" id="radio-sf">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Bandwidth</div>
|
|
<div class="config-value" id="radio-bw">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">TX Power</div>
|
|
<div class="config-value" id="radio-tx">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Coding Rate</div>
|
|
<div class="config-value" id="radio-cr">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Preamble Length</div>
|
|
<div class="config-value" id="radio-preamble">Loading...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Repeater Configuration -->
|
|
<h2>Repeater Settings</h2>
|
|
<div class="config-section">
|
|
<div class="config-item">
|
|
<div class="config-label">Node Name</div>
|
|
<div class="config-value" id="node-name">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Local Hash</div>
|
|
<div class="config-value" id="local-hash">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Public Key</div>
|
|
<div class="config-value" id="public-key" style="word-break: break-all; font-family: monospace; font-size: 0.9em;">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Latitude</div>
|
|
<div class="config-value" id="latitude">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Longitude</div>
|
|
<div class="config-value" id="longitude">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Mode</div>
|
|
<div class="config-value" id="repeater-mode">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Periodic Advertisement Interval</div>
|
|
<div class="config-value" id="send-advert-interval">Loading...</div>
|
|
<div class="config-help">How often the repeater sends an advertisement packet (0 = disabled)</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Duty Cycle -->
|
|
<h2>Duty Cycle</h2>
|
|
<div class="config-section">
|
|
<div class="config-item">
|
|
<div class="config-label">Max Airtime %</div>
|
|
<div class="config-value" id="duty-cycle">Loading...</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Enforcement</div>
|
|
<div class="config-value" id="duty-enforcement">Loading...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TX Delays -->
|
|
<h2>Transmission Delays</h2>
|
|
<div class="config-section">
|
|
<div class="config-item">
|
|
<div class="config-label">Flood TX Delay Factor</div>
|
|
<div class="config-value" id="tx-delay-factor">Loading...</div>
|
|
<div class="config-help">Multiplier for flood packet transmission delays (collision avoidance)</div>
|
|
</div>
|
|
<div class="config-item">
|
|
<div class="config-label">Direct TX Delay Factor</div>
|
|
<div class="config-value" id="direct-tx-delay-factor">Loading...</div>
|
|
<div class="config-help">Base delay for direct-routed packet transmission (seconds)</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<script>
|
|
let currentConfig = {};
|
|
|
|
function loadConfiguration() {
|
|
fetch('/api/stats')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
currentConfig = data;
|
|
const config = data.config || {};
|
|
const radio = config.radio || {};
|
|
const dutyCycle = config.duty_cycle || {};
|
|
const delays = config.delays || {};
|
|
|
|
// Update radio settings
|
|
if (radio.frequency) {
|
|
document.getElementById('radio-freq').textContent = (radio.frequency / 1000000).toFixed(3) + ' MHz';
|
|
}
|
|
if (radio.spreading_factor) {
|
|
document.getElementById('radio-sf').textContent = radio.spreading_factor;
|
|
}
|
|
if (radio.bandwidth) {
|
|
document.getElementById('radio-bw').textContent = (radio.bandwidth / 1000).toFixed(1) + ' kHz';
|
|
}
|
|
if (radio.tx_power !== undefined) {
|
|
document.getElementById('radio-tx').textContent = radio.tx_power + ' dBm';
|
|
}
|
|
if (radio.coding_rate) {
|
|
document.getElementById('radio-cr').textContent = '4/' + radio.coding_rate;
|
|
}
|
|
if (radio.preamble_length) {
|
|
document.getElementById('radio-preamble').textContent = radio.preamble_length + ' symbols';
|
|
}
|
|
|
|
// Update repeater settings
|
|
if (config.node_name) {
|
|
document.getElementById('node-name').textContent = config.node_name;
|
|
}
|
|
if (data.local_hash) {
|
|
document.getElementById('local-hash').textContent = data.local_hash;
|
|
}
|
|
if (data.public_key) {
|
|
document.getElementById('public-key').textContent = data.public_key;
|
|
} else {
|
|
document.getElementById('public-key').textContent = 'Not set';
|
|
}
|
|
if (config.repeater && config.repeater.latitude !== undefined) {
|
|
const lat = config.repeater.latitude;
|
|
document.getElementById('latitude').textContent = lat && lat !== 0 ? lat.toFixed(6) : 'Not set';
|
|
}
|
|
if (config.repeater && config.repeater.longitude !== undefined) {
|
|
const lng = config.repeater.longitude;
|
|
document.getElementById('longitude').textContent = lng && lng !== 0 ? lng.toFixed(6) : 'Not set';
|
|
}
|
|
if (config.repeater && config.repeater.mode) {
|
|
const mode = config.repeater.mode;
|
|
document.getElementById('repeater-mode').textContent =
|
|
mode.charAt(0).toUpperCase() + mode.slice(1);
|
|
}
|
|
if (config.repeater && config.repeater.send_advert_interval_hours !== undefined) {
|
|
const interval = config.repeater.send_advert_interval_hours;
|
|
if (interval === 0) {
|
|
document.getElementById('send-advert-interval').textContent = 'Disabled';
|
|
} else {
|
|
document.getElementById('send-advert-interval').textContent = interval + ' hour' + (interval !== 1 ? 's' : '');
|
|
}
|
|
}
|
|
|
|
// Update duty cycle
|
|
if (dutyCycle.max_airtime_percent !== undefined) {
|
|
document.getElementById('duty-cycle').textContent = dutyCycle.max_airtime_percent.toFixed(1) + '%';
|
|
}
|
|
document.getElementById('duty-enforcement').textContent =
|
|
dutyCycle.enforcement_enabled ? 'Enabled' : 'Disabled';
|
|
|
|
// Update delays
|
|
if (delays.tx_delay_factor !== undefined) {
|
|
document.getElementById('tx-delay-factor').textContent = delays.tx_delay_factor.toFixed(2) + 'x';
|
|
}
|
|
if (delays.direct_tx_delay_factor !== undefined) {
|
|
document.getElementById('direct-tx-delay-factor').textContent = delays.direct_tx_delay_factor.toFixed(2) + 's';
|
|
}
|
|
})
|
|
.catch(e => {
|
|
console.error('Error loading configuration:', e);
|
|
// Show error in UI
|
|
document.querySelectorAll('.config-value').forEach(el => {
|
|
if (el.textContent === 'Loading...') {
|
|
el.textContent = 'Error';
|
|
el.style.color = '#f48771';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Load configuration on page load
|
|
document.addEventListener('DOMContentLoaded', loadConfiguration);
|
|
</script>
|
|
</body>
|
|
</html>
|