Use DHCP leases for LAN client wake support

This commit is contained in:
seo
2026-07-21 10:13:47 +09:00
parent 2d79ee3de4
commit de96ddcda7
3 changed files with 165 additions and 9 deletions
+47 -4
View File
@@ -184,6 +184,10 @@
wifiAliasTitle: 'WiFi Hostname',
wifiAliasPrompt: 'Enter a name to keep for this MAC address.',
wifiAliasSaved: 'WiFi hostname saved.',
wolConfirmTitle: 'Wake LAN Device',
wolConfirm: ({ hostname, mac }) => `Send one Wake-on-LAN request to ${hostname || mac}?`,
wolSent: 'Wake-on-LAN request sent.',
wolFailed: 'Wake-on-LAN request failed',
show: 'Show',
hide: 'Hide',
translateButton: 'Translate',
@@ -332,6 +336,10 @@
wifiAliasTitle: 'WiFi 호스트명',
wifiAliasPrompt: '이 MAC 주소에 계속 표시할 이름을 입력하세요.',
wifiAliasSaved: 'WiFi 호스트명을 저장했습니다.',
wolConfirmTitle: 'LAN 기기 켜기',
wolConfirm: ({ hostname, mac }) => `${hostname || mac} 기기에 WOL 요청을 1회 보낼까요?`,
wolSent: 'WOL 요청을 보냈습니다.',
wolFailed: 'WOL 요청 실패',
show: '보기',
hide: '숨기기',
translateButton: '번역',
@@ -1215,6 +1223,14 @@
return `<td><button type="button" class="wifi-host-edit" data-mac="${attr(row.mac || '')}" data-hostname="${attr(row.hostname || '')}" title="${attr(title)}">${escapeHtml(row.hostname || '-')}</button></td>`;
}
function wifiBandCell(row) {
if (row?.band !== 'LAN' || !row?.wol_available) {
return td(row?.band || '-');
}
return `<td><button type="button" class="lan-wake-btn" data-mac="${attr(row.mac || '')}" data-hostname="${attr(row.hostname || '')}" title="${attr(t('wolConfirmTitle'))}">LAN</button></td>`;
}
function wifiMetricCell(row, key) {
if (key !== 'signal') {
return `<td>${escapeHtml(row[key] || '-')}</td>`;
@@ -1287,6 +1303,26 @@
}
}
async function wakeLanDevice(mac, hostname = '') {
if (!mac) return;
const confirmed = await window.customConfirm(t('wolConfirm', { hostname, mac }), {
title: t('wolConfirmTitle'),
okText: t('dialogOk'),
cancelText: t('dialogCancel'),
});
if (!confirmed) return;
try {
const data = await api('wake_lan', { mac });
notice(t('wolSent'), 'success');
render(data.status || await api('status'));
} catch (e) {
console.error(e);
notice(e.message || t('wolFailed'), 'error');
}
}
function parseWifiDurationSeconds(value) {
const text = String(value ?? '').trim();
if (text === '' || text.toUpperCase() === 'N/A') {
@@ -1451,7 +1487,7 @@
els.wifiTable.innerHTML = rows.length
? rows.map(row => `
<tr>
${td(row.band)}
${wifiBandCell(row)}
${wifiHostCell(row)}
${td(row.ip)}
${td(row.mac)}
@@ -2273,9 +2309,16 @@
els.customServiceList?.addEventListener(eventName, holdCustomServiceScroll, { passive: true });
});
els.wifiTable?.addEventListener('click', event => {
const button = event.target?.closest?.('.wifi-host-edit');
if (!button) return;
editWifiHostname(button.dataset.mac || '', button.dataset.hostname || '');
const hostButton = event.target?.closest?.('.wifi-host-edit');
if (hostButton) {
editWifiHostname(hostButton.dataset.mac || '', hostButton.dataset.hostname || '');
return;
}
const lanButton = event.target?.closest?.('.lan-wake-btn');
if (lanButton) {
wakeLanDevice(lanButton.dataset.mac || '', lanButton.dataset.hostname || '');
}
});
els.statusBatteryRemaining?.addEventListener('mouseenter', showBatteryTooltip);
els.statusBatteryRemaining?.addEventListener('mouseleave', hideBatteryTooltip);