mirror of
https://github.com/cjfranko/NTP-Timeturner.git
synced 2025-11-08 18:32:02 +00:00
PPM control for NDF fractional control
This commit is contained in:
parent
2e8bc9ac5e
commit
2295a29d75
11 changed files with 532 additions and 20 deletions
|
|
@ -95,11 +95,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<input type="checkbox" id="auto-ppm-enabled" name="auto-ppm-enabled" style="vertical-align: middle;">
|
||||
<label for="auto-ppm-enabled" style="vertical-align: middle;">Enable Fractional NDF Discipline (auto PPM)</label>
|
||||
<label for="ppm-target" style="margin-left: 10px;">Target PPM:</label>
|
||||
<input type="number" id="ppm-target" style="width: 80px;" step="1">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<button id="save-config">Save Timeturner Config</button>
|
||||
<button id="manual-sync">Send Manual Sync</button>
|
||||
<span id="sync-message"></span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<input type="checkbox" id="ppm-applied" disabled>
|
||||
<label for="ppm-applied">PPM Applied</label>
|
||||
<span id="fractional-ndf-badge" style="display:none; font-weight:bold; color:#28a745; margin-left: 10px;">Fractional NDF discipline active</span>
|
||||
</div>
|
||||
<div class="control-group" style="display: none;">
|
||||
<label>Nudge Clock (ms):</label>
|
||||
<button id="nudge-down">-</button>
|
||||
|
|
|
|||
|
|
@ -95,11 +95,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<input type="checkbox" id="auto-ppm-enabled" name="auto-ppm-enabled" style="vertical-align: middle;">
|
||||
<label for="auto-ppm-enabled" style="vertical-align: middle;">Enable Fractional NDF Discipline (auto PPM)</label>
|
||||
<label for="ppm-target" style="margin-left: 10px;">Target PPM:</label>
|
||||
<input type="number" id="ppm-target" style="width: 80px;" step="1">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<button id="save-config">Save Config</button>
|
||||
<button id="manual-sync">Manual Sync</button>
|
||||
<span id="sync-message"></span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<input type="checkbox" id="ppm-applied" disabled>
|
||||
<label for="ppm-applied">PPM Applied</label>
|
||||
<span id="fractional-ndf-badge" style="display:none; font-weight:bold; color:#28a745; margin-left: 10px;">Fractional NDF discipline active</span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label>Nudge Clock (ms):</label>
|
||||
<button id="nudge-down">-</button>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 0.125,
|
||||
jitter_status: 'GOOD',
|
||||
interfaces: ['192.168.1.100/24 (eth0)', '10.0.0.5/8 (wlan0)'],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -41,6 +42,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 0.075,
|
||||
jitter_status: 'GOOD',
|
||||
interfaces: ['192.168.1.100/24 (eth0)'],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -64,6 +66,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: -12.5,
|
||||
jitter_status: 'AVERAGE',
|
||||
interfaces: ['192.168.1.100/24 (eth0)'],
|
||||
fractional_ndf_discipline_active: true,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -87,6 +90,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 20,
|
||||
jitter_status: 'AVERAGE',
|
||||
interfaces: ['192.168.1.100/24 (eth0)'],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -110,6 +114,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 93076,
|
||||
jitter_status: 'GOOD',
|
||||
interfaces: ['192.168.1.100/24 (eth0)'],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -133,6 +138,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 0.25,
|
||||
jitter_status: 'BAD',
|
||||
interfaces: ['192.168.1.100/24 (eth0)'],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 10,
|
||||
|
|
@ -156,6 +162,7 @@ const mockApiDataSets = {
|
|||
timecode_delta_frames: 0,
|
||||
jitter_status: 'UNKNOWN',
|
||||
interfaces: [],
|
||||
fractional_ndf_discipline_active: false,
|
||||
},
|
||||
config: {
|
||||
hardwareOffsetMs: 0,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
const hwOffsetInput = document.getElementById('hw-offset');
|
||||
const autoSyncCheckbox = document.getElementById('auto-sync-enabled');
|
||||
const autoPpmCheckbox = document.getElementById('auto-ppm-enabled');
|
||||
const ppmTargetInput = document.getElementById('ppm-target');
|
||||
const ppmAppliedCheckbox = document.getElementById('ppm-applied');
|
||||
const offsetInputs = {
|
||||
h: document.getElementById('offset-h'),
|
||||
m: document.getElementById('offset-m'),
|
||||
|
|
@ -35,6 +38,7 @@
|
|||
const saveConfigButton = document.getElementById('save-config');
|
||||
const manualSyncButton = document.getElementById('manual-sync');
|
||||
const syncMessage = document.getElementById('sync-message');
|
||||
const fractionalNdfBadge = document.getElementById('fractional-ndf-badge');
|
||||
|
||||
const nudgeDownButton = document.getElementById('nudge-down');
|
||||
const nudgeUpButton = document.getElementById('nudge-up');
|
||||
|
|
@ -150,6 +154,18 @@
|
|||
} else {
|
||||
statusElements.interfaces.textContent = 'No active interfaces found.';
|
||||
}
|
||||
|
||||
// Show/hide fractional NDF discipline badge
|
||||
if (fractionalNdfBadge) {
|
||||
if (data.fractional_ndf_discipline_active) {
|
||||
fractionalNdfBadge.style.display = 'inline';
|
||||
} else {
|
||||
fractionalNdfBadge.style.display = 'none';
|
||||
}
|
||||
}
|
||||
if (ppmAppliedCheckbox) {
|
||||
ppmAppliedCheckbox.checked = !!data.fractional_ndf_discipline_active;
|
||||
}
|
||||
}
|
||||
|
||||
function animateClocks() {
|
||||
|
|
@ -238,6 +254,8 @@
|
|||
const data = mockApiDataSets[currentMockSetKey].config;
|
||||
hwOffsetInput.value = data.hardwareOffsetMs;
|
||||
autoSyncCheckbox.checked = data.autoSyncEnabled;
|
||||
if (autoPpmCheckbox) autoPpmCheckbox.checked = !!data.autoFractionalPpmEnabled;
|
||||
if (ppmTargetInput && typeof data.fractionalPpmTarget === 'number') ppmTargetInput.value = data.fractionalPpmTarget;
|
||||
offsetInputs.h.value = data.timeturnerOffset.hours;
|
||||
offsetInputs.m.value = data.timeturnerOffset.minutes;
|
||||
offsetInputs.s.value = data.timeturnerOffset.seconds;
|
||||
|
|
@ -252,6 +270,8 @@
|
|||
const data = await response.json();
|
||||
hwOffsetInput.value = data.hardwareOffsetMs;
|
||||
autoSyncCheckbox.checked = data.autoSyncEnabled;
|
||||
if (autoPpmCheckbox) autoPpmCheckbox.checked = !!data.autoFractionalPpmEnabled;
|
||||
if (ppmTargetInput && typeof data.fractionalPpmTarget === 'number') ppmTargetInput.value = data.fractionalPpmTarget;
|
||||
offsetInputs.h.value = data.timeturnerOffset.hours;
|
||||
offsetInputs.m.value = data.timeturnerOffset.minutes;
|
||||
offsetInputs.s.value = data.timeturnerOffset.seconds;
|
||||
|
|
@ -268,6 +288,8 @@
|
|||
hardwareOffsetMs: parseInt(hwOffsetInput.value, 10) || 0,
|
||||
autoSyncEnabled: autoSyncCheckbox.checked,
|
||||
defaultNudgeMs: parseInt(nudgeValueInput.value, 10) || 0,
|
||||
autoFractionalPpmEnabled: autoPpmCheckbox ? autoPpmCheckbox.checked : undefined,
|
||||
fractionalPpmTarget: ppmTargetInput ? (parseInt(ppmTargetInput.value, 10) || 0) : undefined,
|
||||
timeturnerOffset: {
|
||||
hours: parseInt(offsetInputs.h.value, 10) || 0,
|
||||
minutes: parseInt(offsetInputs.m.value, 10) || 0,
|
||||
|
|
@ -277,6 +299,10 @@
|
|||
}
|
||||
};
|
||||
|
||||
// Remove undefined keys if controls are absent
|
||||
if (config.autoFractionalPpmEnabled === undefined) delete config.autoFractionalPpmEnabled;
|
||||
if (config.fractionalPpmTarget === undefined) delete config.fractionalPpmTarget;
|
||||
|
||||
if (useMockData) {
|
||||
console.log('Mock save:', config);
|
||||
alert('Configuration saved (mock).');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue