feat: add EWMA clock delta and adjtimex nudge controls

Co-authored-by: aider (gemini/gemini-2.5-pro-preview-05-06) <aider@aider.chat>
This commit is contained in:
Chaos Rogers 2025-07-28 23:51:27 +01:00
parent 6a45660e03
commit cc782fcd7e
7 changed files with 152 additions and 59 deletions

View file

@ -64,6 +64,13 @@
<button id="manual-sync">Manual Sync</button>
<span id="sync-message"></span>
</div>
<div class="control-group">
<label>Nudge Clock (ms):</label>
<button id="nudge-down">-</button>
<input type="number" id="nudge-value" style="width: 60px;">
<button id="nudge-up">+</button>
<span id="nudge-message"></span>
</div>
</div>
<!-- Logs -->

View file

@ -25,6 +25,11 @@ document.addEventListener('DOMContentLoaded', () => {
const manualSyncButton = document.getElementById('manual-sync');
const syncMessage = document.getElementById('sync-message');
const nudgeDownButton = document.getElementById('nudge-down');
const nudgeUpButton = document.getElementById('nudge-up');
const nudgeValueInput = document.getElementById('nudge-value');
const nudgeMessage = document.getElementById('nudge-message');
function updateStatus(data) {
statusElements.ltcStatus.textContent = data.ltc_status;
statusElements.ltcTimecode.textContent = data.ltc_timecode;
@ -79,6 +84,7 @@ document.addEventListener('DOMContentLoaded', () => {
offsetInputs.m.value = data.timeturnerOffset.minutes;
offsetInputs.s.value = data.timeturnerOffset.seconds;
offsetInputs.f.value = data.timeturnerOffset.frames;
nudgeValueInput.value = data.defaultNudgeMs;
} catch (error) {
console.error('Error fetching config:', error);
}
@ -87,6 +93,7 @@ document.addEventListener('DOMContentLoaded', () => {
async function saveConfig() {
const config = {
hardwareOffsetMs: parseInt(hwOffsetInput.value, 10) || 0,
defaultNudgeMs: parseInt(nudgeValueInput.value, 10) || 0,
timeturnerOffset: {
hours: parseInt(offsetInputs.h.value, 10) || 0,
minutes: parseInt(offsetInputs.m.value, 10) || 0,
@ -140,8 +147,37 @@ document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => { syncMessage.textContent = ''; }, 5000);
}
async function nudgeClock(ms) {
nudgeMessage.textContent = 'Nudging clock...';
try {
const response = await fetch('/api/nudge_clock', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ microseconds: ms * 1000 }),
});
const data = await response.json();
if (response.ok) {
nudgeMessage.textContent = `Success: ${data.message}`;
} else {
nudgeMessage.textContent = `Error: ${data.message}`;
}
} catch (error) {
console.error('Error nudging clock:', error);
nudgeMessage.textContent = 'Failed to send nudge command.';
}
setTimeout(() => { nudgeMessage.textContent = ''; }, 3000);
}
saveConfigButton.addEventListener('click', saveConfig);
manualSyncButton.addEventListener('click', triggerManualSync);
nudgeDownButton.addEventListener('click', () => {
const ms = parseInt(nudgeValueInput.value, 10) || 0;
nudgeClock(-ms);
});
nudgeUpButton.addEventListener('click', () => {
const ms = parseInt(nudgeValueInput.value, 10) || 0;
nudgeClock(ms);
});
// Initial data load
fetchStatus();