diff --git a/static/index.html b/static/index.html index 02bb279..9f90575 100644 --- a/static/index.html +++ b/static/index.html @@ -3,13 +3,13 @@ - Fetch | Hachi - + Hachi-TimeTransformer +
- +

Hachi-TimeTransformer

+ +
+

PTP

+

Supported: unknown

+

Interface: --

+

Daemon: --

+

Offset (ns): --

+
+
@@ -107,6 +116,23 @@
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
@@ -137,5 +163,6 @@ + diff --git a/static/ptp.js b/static/ptp.js new file mode 100644 index 0000000..f8f2999 --- /dev/null +++ b/static/ptp.js @@ -0,0 +1,83 @@ +(function () { + function $(id) { return document.getElementById(id); } + function setText(id, val) { + var el = $(id); + if (el) el.textContent = val; + } + + async function fetchPtpStatus() { + try { + const res = await fetch('/api/status'); + if (!res.ok) return; + const data = await res.json(); + + const supported = data.ptp_supported; + const iface = data.ptp_interface; + const running = data.ptp_daemon_running; + const offset = data.ptp_offset_ns; + + if (typeof supported !== 'undefined') setText('ptp-supported', supported ? 'Yes' : 'No'); + if (typeof iface !== 'undefined' && iface !== null) setText('ptp-interface', iface); + if (typeof running !== 'undefined') setText('ptp-daemon', running ? 'Running' : 'Stopped'); + if (typeof offset !== 'undefined' && offset !== null) setText('ptp-offset', String(offset)); + } catch (_) { + // ignore fetch errors; UI will show last known values + } + } + + async function startPtp() { + const ifaceVal = $('ptp-interface-input')?.value.trim(); + const phcIdxStr = $('ptp-phc-index')?.value; + const extraArgsStr = $('ptp-extra-args')?.value.trim(); + + const body = {}; + if (ifaceVal) body.interface = ifaceVal; + if (phcIdxStr !== '' && phcIdxStr != null) { + const n = Number(phcIdxStr); + if (!Number.isNaN(n)) body.phcIndex = n; + } + if (extraArgsStr) { + body.args = extraArgsStr.split(/\s+/).filter(Boolean); + } + + try { + const res = await fetch('/api/ptp/start', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }); + const j = await res.json().catch(() => ({})); + setText('ptp-message', j.message || (res.ok ? 'PTP start requested' : 'Failed to start PTP')); + } catch (_) { + setText('ptp-message', 'Failed to start PTP'); + } + fetchPtpStatus(); + } + + async function stopPtp() { + try { + const res = await fetch('/api/ptp/stop', { method: 'POST' }); + const j = await res.json().catch(() => ({})); + setText('ptp-message', j.message || (res.ok ? 'PTP stop requested' : 'Failed to stop PTP')); + } catch (_) { + setText('ptp-message', 'Failed to stop PTP'); + } + fetchPtpStatus(); + } + + function init() { + const startBtn = $('start-ptp'); + const stopBtn = $('stop-ptp'); + if (startBtn) startBtn.addEventListener('click', startPtp); + if (stopBtn) stopBtn.addEventListener('click', stopPtp); + + fetchPtpStatus(); + setInterval(fetchPtpStatus, 2000); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})();