From 6ae623ab2220520a8b055a75d8148e5de7151410 Mon Sep 17 00:00:00 2001
From: Olivier <16240457+TiTidom-RC@users.noreply.github.com>
Date: Mon, 5 Jan 2026 22:20:15 +0100
Subject: [PATCH 01/24] bugfix on templates
---
.vscode/cspell.json | 2 +
core/template/dashboard/AsusWRT.html | 364 ++++++++++-------
core/template/dashboard/Monitoring.html | 509 ++++++++++++++----------
3 files changed, 524 insertions(+), 351 deletions(-)
diff --git a/.vscode/cspell.json b/.vscode/cspell.json
index 00eadc69..4e41ac8a 100644
--- a/.vscode/cspell.json
+++ b/.vscode/cspell.json
@@ -36,6 +36,8 @@
"Equipement",
"esata",
"Etat",
+ "Eteindre",
+ "Etes",
"firmver",
"Formated",
"freebsd",
diff --git a/core/template/dashboard/AsusWRT.html b/core/template/dashboard/AsusWRT.html
index 42cd756a..7e6931f4 100644
--- a/core/template/dashboard/AsusWRT.html
+++ b/core/template/dashboard/AsusWRT.html
@@ -197,6 +197,26 @@
(() => {
'use strict'
+ // Get reference to this specific widget container
+ const widgetRoot = document.querySelector('.eqLogic-widget[data-eqLogic_uid="#uid#"]')
+ if (!widgetRoot) return
+
+ /**
+ * Safely parse JSON from data attribute
+ * @param {string} jsonString - JSON string to parse
+ * @param {object} fallback - Fallback value if parsing fails
+ * @returns {object} Parsed object or fallback
+ */
+ const safeJSONParse = (jsonString, fallback = {min: '-', avg: '-', max: '-'}) => {
+ if (!jsonString || jsonString === 'undefined' || jsonString === '') return fallback
+ try {
+ return JSON.parse(jsonString)
+ } catch (e) {
+ console.warn('[Monitoring AsusWRT] JSON parse error:', e, 'Input:', jsonString)
+ return fallback
+ }
+ }
+
// ========================================
// === UTILITY FUNCTIONS ===
// ========================================
@@ -285,7 +305,8 @@
* Initialize SSH connection status icon
*/
const initIconSSH = () => {
- const iconSSH = document.getElementById('iconSSH#id#')
+ try {
+ const iconSSH = widgetRoot.querySelector('#iconSSH#id#')
if (!iconSSH) return
if ('#cnx_ssh#' === 'OK') {
@@ -293,13 +314,17 @@
} else if ('#cnx_ssh#' === 'KO') {
iconSSH.innerHTML = ''
}
- }
-
- /**
- * Initialize Cron status icon
- */
- const initIconCron = () => {
- const iconCron = document.getElementById('iconCron#id#')
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initIconSSH:', e)
+ }
+ }
+
+ /**
+ * Initialize Cron status icon
+ */
+ const initIconCron = () => {
+ try {
+ const iconCron = widgetRoot.querySelector('#iconCron#id#')
if (!iconCron) return
const isOn = '#cron_status#' === '1'
@@ -312,13 +337,17 @@
const color = isCustom ? '--al-warning-color' : (isOn ? '--al-success-color' : '--al-danger-color')
iconCron.innerHTML = ``
- }
-
- /**
- * Initialize Check Firmware icon
- */
- const initIconCheckFirmware = () => {
- const el = document.getElementById('iconCheckFirmware#id#')
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initIconCron:', e)
+ }
+ }
+
+ /**
+ * Initialize firmware check icon
+ */
+ const initIconCheckFirmware = () => {
+ try {
+ const el = widgetRoot.querySelector('#iconCheckFirmware#id#')
if (!el) return
if ('#asus_fw_check#' === '1') {
@@ -326,17 +355,21 @@
} else if ('#asus_fw_check#' === '0') {
el.innerHTML = ''
}
- }
-
- // ========================================
- // === BUTTON HANDLERS ===
- // ========================================
-
- /**
- * Initialize Reboot button with confirmation dialog
- */
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initIconCheckFirmware:', e)
+ }
+ }
+
+ // ========================================
+ // === BUTTON HANDLERS ===
+ // ========================================
+
+ /**
+ * Initialize Reboot button with confirmation dialog
+ */
const initRebootButton = () => {
- const rebootBtn = document.querySelector('.reboot[data-cmd_id="#cmd_reboot_id#"]')
+ try {
+ const rebootBtn = widgetRoot.querySelector('.reboot[data-cmd_id="#cmd_reboot_id#"]')
rebootBtn?.addEventListener('click', () => {
jeeDialog.confirm({
title: ' Redémarrer l\'équipement',
@@ -348,13 +381,17 @@
callback: result => result && jeedom.cmd.execute({ id: '#cmd_reboot_id#' })
})
})
- }
-
- /**
- * Initialize Refresh button
- */
- const initRefreshButton = () => {
- const refreshBtn = document.querySelector('.eqLogic[data-eqLogic_uid="#uid#"] .refresh')
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initRebootButton:', e)
+ }
+ }
+
+ /**
+ * Initialize Refresh button
+ */
+ const initRefreshButton = () => {
+ try {
+ const refreshBtn = widgetRoot.querySelector('.refresh')
if (!refreshBtn) return
if ('#refresh_id#' !== '') {
@@ -362,84 +399,112 @@
} else {
refreshBtn.remove()
}
- }
-
- // ========================================
- // === VALUE DISPLAYS - Simple ===
- // ========================================
-
- /**
- * Initialize Uptime display
- */
- const initUptime = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initRefreshButton:', e)
+ }
+ }
+
+ // ========================================
+ // === VALUE DISPLAYS - Simple ===
+ // ========================================
+
+ /**
+ * Initialize Uptime display
+ */
+ const initUptime = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const uptimeEl = document.getElementById('uptime#id#')
+ const uptimeEl = widgetRoot.querySelector('#uptime#id#')
if (uptimeEl) uptimeEl.innerHTML = '#uptime#'
- }
-
- /**
- * Initialize Network Infos display
- */
- const initNetworkInfos = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initUptime:', e)
+ }
+ }
+
+ /**
+ * Initialize Network Infos display
+ */
+ const initNetworkInfos = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const networkInfosEl = document.getElementById('network_infos#id#')
+ const networkInfosEl = widgetRoot.querySelector('#network_infos#id#')
if (networkInfosEl) networkInfosEl.innerHTML = '#network_infos#'
- }
-
- /**
- * Initialize Network Traffic display
- */
- const initNetwork = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initNetworkInfos:', e)
+ }
+ }
+
+ /**
+ * Initialize Network display
+ */
+ const initNetwork = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const networkEl = document.getElementById('network#id#')
+ const networkEl = widgetRoot.querySelector('#network#id#')
if (networkEl) networkEl.innerHTML = '#network#'
- }
-
- /**
- * Initialize Asus Clients display
- */
- const initAsusClients = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initNetwork:', e)
+ }
+ }
+
+ /**
+ * Initialize Asus Clients display
+ */
+ const initAsusClients = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const el = document.getElementById('asus_clients#id#')
+ const el = widgetRoot.querySelector('#asus_clients#id#')
if (el) el.innerHTML = '#asus_clients#'
- }
-
- /**
- * Initialize Asus WAN IP display
- */
- const initAsusWan0IP = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initAsusClients:', e)
+ }
+ }
+
+ /**
+ * Initialize Asus WAN0 IP display
+ */
+ const initAsusWan0IP = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const el = document.getElementById('asus_wan0_ip#id#')
+ const el = widgetRoot.querySelector('#asus_wan0_ip#id#')
if (el) el.innerHTML = 'IP (WAN) : #asus_wan0_ip#'
- }
-
- /**
- * Initialize Asus WiFi Temperature display
- */
- const initAsusWifiTemp = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initAsusWan0IP:', e)
+ }
+ }
+
+ /**
+ * Initialize Asus WiFi Temperature display
+ */
+ const initAsusWifiTemp = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const el = document.getElementById('asus_wifi_temp#id#')
+ const el = widgetRoot.querySelector('#asus_wifi_temp#id#')
if (el) el.innerHTML = '#asus_wifi_temp#'
- }
-
- // ========================================
- // === VALUE DISPLAYS - With Thresholds ===
- // ========================================
-
- /**
- * Initialize Load Average displays (1mn, 5mn, 15mn)
- */
- const initLoadAverage = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initAsusWifiTemp:', e)
+ }
+ }
+
+ // ========================================
+ // === VALUE DISPLAYS - With Thresholds ===
+ // ========================================
+
+ /**
+ * Initialize Load Average displays (1mn, 5mn, 15mn)
+ */
+ const initLoadAverage = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
// Load avg 1mn
- const loadAvg1mn = document.getElementById('load_avg_1mn#id#')
+ const loadAvg1mn = widgetRoot.querySelector('#load_avg_1mn#id#')
if (loadAvg1mn) {
const html = buildThresholdHTML(
'#load_avg_1mn#', '#load_avg_1mn_colorlow#', '#load_avg_1mn_colorhigh#',
@@ -451,7 +516,7 @@
}
// Load avg 5mn
- const loadAvg5mn = document.getElementById('load_avg_5mn#id#')
+ const loadAvg5mn = widgetRoot.querySelector('#load_avg_5mn#id#')
if (loadAvg5mn) {
const html = buildThresholdHTML(
'#load_avg_5mn#', '#load_avg_5mn_colorlow#', '#load_avg_5mn_colorhigh#',
@@ -463,7 +528,7 @@
}
// Load avg 15mn
- const loadAvg15mn = document.getElementById('load_avg_15mn#id#')
+ const loadAvg15mn = widgetRoot.querySelector('#load_avg_15mn#id#')
if (loadAvg15mn) {
const html = buildThresholdHTML(
'#load_avg_15mn#', '#load_avg_15mn_colorlow#', '#load_avg_15mn_colorhigh#',
@@ -473,15 +538,19 @@
)
loadAvg15mn.innerHTML = html === '' ? html : ` - 15 min : ${html}`
}
- }
-
- /**
- * Initialize Memory display with percentage
- */
- const initMemory = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initLoadAverage:', e)
+ }
+ }
+
+ /**
+ * Initialize Memory display with percentage
+ */
+ const initMemory = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const memoryEl = document.getElementById('memory_available_percent#id#')
+ const memoryEl = widgetRoot.querySelector('#memory_available_percent#id#')
if (!memoryEl) return
const value = '#memory_available_percent#'
@@ -496,15 +565,19 @@
{ min: '#memory_available_percent_minHistory#', avg: '#memory_available_percent_averageHistory#', max: '#memory_available_percent_maxHistory#' },
'#memory_available_percent_tendance#', '#memory# (', '%', true
)
- }
-
- /**
- * Initialize Swap display with percentage
- */
- const initSwap = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initMemory:', e)
+ }
+ }
+
+ /**
+ * Initialize Swap display with percentage
+ */
+ const initSwap = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const swapEl = document.getElementById('swap_free_percent#id#')
+ const swapEl = widgetRoot.querySelector('#swap_free_percent#id#')
if (!swapEl) return
const value = '#swap_free_percent#'
@@ -519,15 +592,19 @@
{ min: '#swap_free_percent_minHistory#', avg: '#swap_free_percent_averageHistory#', max: '#swap_free_percent_maxHistory#' },
'#swap_free_percent_tendance#', '#swap# (', '%', true
)
- }
-
- /**
- * Initialize HDD display with percentage
- */
- const initHDD = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initSwap:', e)
+ }
+ }
+
+ /**
+ * Initialize HDD display with percentage
+ */
+ const initHDD = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const hddEl = document.getElementById('hdd#id#')
+ const hddEl = widgetRoot.querySelector('#hdd#id#')
if (!hddEl) return
const value = '#hdd_free_percent#'
@@ -542,21 +619,25 @@
{ min: '#hdd_free_percent_minHistory#', avg: '#hdd_free_percent_averageHistory#', max: '#hdd_free_percent_maxHistory#' },
'#hdd_free_percent_tendance#', '#hdd# (', '%', true
)
- }
-
- /**
- * Initialize CPU display with optional temperature
- */
- const initCPU = () => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initHDD:', e)
+ }
+ }
+
+ /**
+ * Initialize CPU display with optional temperature
+ */
+ const initCPU = () => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const cpuEl = document.getElementById('cpu#id#')
+ const cpuEl = widgetRoot.querySelector('#cpu#id#')
if (!cpuEl) return
if ('#cpu_temp#' !== '' && '#cpu_temp_display#' === 'block') {
cpuEl.innerHTML = '#cpu# '
- const tempEl = document.getElementById('cpu_temp#id#')
+ const tempEl = widgetRoot.querySelector('#cpu_temp#id#')
if (!tempEl) return
const temp = parseFloat('#cpu_temp#')
@@ -569,18 +650,22 @@
} else {
cpuEl.innerHTML = '#cpu#'
}
- }
-
- /**
- * Initialize custom command display (perso1-4) using data attributes
- * @param {HTMLElement} container - The container div with data-perso-* attributes
- */
- const initPerso = (container) => {
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initCPU:', e)
+ }
+ }
+
+ /**
+ * Initialize custom command display (perso1-4) using data attributes
+ * @param {HTMLElement} container - The container div with data-perso-* attributes
+ */
+ const initPerso = (container) => {
+ try {
if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
const dataset = container.dataset
const persoId = dataset.persoId
- const el = document.getElementById(`${persoId}_unite#id#`)
+ const el = widgetRoot.querySelector(`#${persoId}_unite#id#`)
if (!el) return
const value = dataset.persoValue
@@ -588,15 +673,18 @@
el.innerHTML = ''
return
}
-
- const val = parseFloat(value)
- const low = parseFloat(dataset.persoLow)
- const high = parseFloat(dataset.persoHigh)
- const history = JSON.parse(dataset.persoHistory)
- const title = `Stats : ${dataset.persoName}
Min: ${history.min} | Moy : ${history.avg} | Max : ${history.max}`
- const color = getColorStyle(val, low, high, false)
-
- el.innerHTML = `${value}${dataset.persoUnite}${dataset.persoTendance}`
+
+ const val = parseFloat(value)
+ const low = parseFloat(dataset.persoLow)
+ const high = parseFloat(dataset.persoHigh)
+ const history = safeJSONParse(dataset.persoHistory)
+ const title = `Stats : ${dataset.persoName}
Min: ${history.min} | Moy : ${history.avg} | Max : ${history.max}`
+ const color = getColorStyle(val, low, high, false)
+
+ el.innerHTML = `${value}${dataset.persoUnite}${dataset.persoTendance}`
+ } catch (e) {
+ console.error('[Monitoring AsusWRT] Error in initPerso for', container.dataset?.persoId || 'unknown', ':', e)
+ }
}
// ========================================
@@ -632,7 +720,7 @@
initCPU()
// Custom commands - generic initialization using data attributes
- document.querySelectorAll('[data-perso-id]').forEach(initPerso)
+ widgetRoot.querySelectorAll('[data-perso-id]').forEach(initPerso)
}
})()
diff --git a/core/template/dashboard/Monitoring.html b/core/template/dashboard/Monitoring.html
index 2e715e2a..6519d202 100644
--- a/core/template/dashboard/Monitoring.html
+++ b/core/template/dashboard/Monitoring.html
@@ -259,10 +259,30 @@
(() => {
'use strict'
+ // Get reference to this specific widget container
+ const widgetRoot = document.querySelector('.eqLogic-widget[data-eqLogic_uid="#uid#"]')
+ if (!widgetRoot) return
+
// ========================================
// === UTILITY FUNCTIONS ===
// ========================================
+ /**
+ * Safely parse JSON from data attribute
+ * @param {string} jsonString - JSON string to parse
+ * @param {object} fallback - Fallback value if parsing fails
+ * @returns {object} Parsed object or fallback
+ */
+ const safeJSONParse = (jsonString, fallback = {min: '-', avg: '-', max: '-'}) => {
+ if (!jsonString || jsonString === 'undefined' || jsonString === '') return fallback
+ try {
+ return JSON.parse(jsonString)
+ } catch (e) {
+ console.warn('[Monitoring] JSON parse error:', e, 'Input:', jsonString)
+ return fallback
+ }
+ }
+
/**
* Calculate color style based on thresholds
* @param {number} val - Current value
@@ -347,13 +367,17 @@
* Initialize SSH connection status icon
*/
const initIconSSH = () => {
- const iconSSH = document.getElementById('iconSSH#id#')
- if (!iconSSH) return
-
- if ('#cnx_ssh#' === 'OK') {
- iconSSH.innerHTML = ''
- } else if ('#cnx_ssh#' === 'KO') {
- iconSSH.innerHTML = ''
+ try {
+ const iconSSH = widgetRoot.querySelector('#iconSSH#id#')
+ if (!iconSSH) return
+
+ if ('#cnx_ssh#' === 'OK') {
+ iconSSH.innerHTML = ''
+ } else if ('#cnx_ssh#' === 'KO') {
+ iconSSH.innerHTML = ''
+ }
+ } catch (e) {
+ console.error('[Monitoring] Error in initIconSSH:', e)
}
}
@@ -361,19 +385,23 @@
* Initialize Cron status icon
*/
const initIconCron = () => {
- const iconCron = document.getElementById('iconCron#id#')
- if (!iconCron) return
-
- const isOn = '#cron_status#' === '1'
- const isCustom = '#cron_status_custom#' === '1'
- const display = '#cron_status_display#'
-
- const icon = isOn ? 'play-circle' : 'pause-circle'
- const label = isOn ? 'ON' : 'OFF'
- const customLabel = isCustom ? 'Custom' : 'Default'
- const color = isCustom ? '--al-warning-color' : (isOn ? '--al-success-color' : '--al-danger-color')
-
- iconCron.innerHTML = ``
+ try {
+ const iconCron = widgetRoot.querySelector('#iconCron#id#')
+ if (!iconCron) return
+
+ const isOn = '#cron_status#' === '1'
+ const isCustom = '#cron_status_custom#' === '1'
+ const display = '#cron_status_display#'
+
+ const icon = isOn ? 'play-circle' : 'pause-circle'
+ const label = isOn ? 'ON' : 'OFF'
+ const customLabel = isCustom ? 'Custom' : 'Default'
+ const color = isCustom ? '--al-warning-color' : (isOn ? '--al-success-color' : '--al-danger-color')
+
+ iconCron.innerHTML = ``
+ } catch (e) {
+ console.error('[Monitoring] Error in initIconCron:', e)
+ }
}
// ========================================
@@ -384,53 +412,65 @@
* Initialize Reboot button with confirmation dialog
*/
const initRebootButton = () => {
- const rebootBtn = document.querySelector('.reboot[data-cmd_id="#cmd_reboot_id#"]')
- rebootBtn?.addEventListener('click', () => {
- jeeDialog.confirm({
+ try {
+ const rebootBtn = widgetRoot.querySelector('.reboot[data-cmd_id="#cmd_reboot_id#"]')
+ rebootBtn?.addEventListener('click', () => {
+ jeeDialog.confirm({
title: ' Redémarrer l\'équipement',
message: 'Etes-vous sûr de vouloir redémarrer l\'équipement #name# ?',
- buttons: {
- confirm: { label: 'Redémarrer', className: 'warning' },
- cancel: { label: 'Annuler', className: 'info' }
- },
- callback: (result) => {
- if (result) jeedom.cmd.execute({ id: '#cmd_reboot_id#' })
- }
+ buttons: {
+ confirm: { label: 'Redémarrer', className: 'warning' },
+ cancel: { label: 'Annuler', className: 'info' }
+ },
+ callback: (result) => {
+ if (result) jeedom.cmd.execute({ id: '#cmd_reboot_id#' })
+ }
+ })
})
- })
+ } catch (e) {
+ console.error('[Monitoring] Error in initRebootButton:', e)
+ }
}
/**
* Initialize Poweroff button with confirmation dialog
*/
const initPoweroffButton = () => {
- const poweroffBtn = document.querySelector('.poweroff[data-cmd_id="#cmd_poweroff_id#"]')
- poweroffBtn?.addEventListener('click', () => {
- jeeDialog.confirm({
+ try {
+ const poweroffBtn = widgetRoot.querySelector('.poweroff[data-cmd_id="#cmd_poweroff_id#"]')
+ poweroffBtn?.addEventListener('click', () => {
+ jeeDialog.confirm({
title: ' Eteindre l\'équipement',
message: 'Etes-vous sûr de vouloir éteindre l\'équipement #name# ?',
- buttons: {
- confirm: { label: 'Eteindre', className: 'danger' },
- cancel: { label: 'Annuler', className: 'info' }
- },
- callback: (result) => {
- if (result) jeedom.cmd.execute({ id: '#cmd_poweroff_id#' })
- }
+ buttons: {
+ confirm: { label: 'Eteindre', className: 'danger' },
+ cancel: { label: 'Annuler', className: 'info' }
+ },
+ callback: (result) => {
+ if (result) jeedom.cmd.execute({ id: '#cmd_poweroff_id#' })
+ }
+ })
})
- })
+ } catch (e) {
+ console.error('[Monitoring] Error in initPoweroffButton:', e)
+ }
}
/**
* Initialize Refresh button
*/
const initRefreshButton = () => {
- const refreshBtn = document.querySelector('.eqLogic[data-eqLogic_uid="#uid#"] .refresh')
- if (!refreshBtn) return
-
- if ('#refresh_id#' !== '') {
- refreshBtn.addEventListener('click', () => jeedom.cmd.execute({ id: '#refresh_id#' }))
- } else {
- refreshBtn.remove()
+ try {
+ const refreshBtn = widgetRoot.querySelector('.refresh')
+ if (!refreshBtn) return
+
+ if ('#refresh_id#' !== '') {
+ refreshBtn.addEventListener('click', () => jeedom.cmd.execute({ id: '#refresh_id#' }))
+ } else {
+ refreshBtn.remove()
+ }
+ } catch (e) {
+ console.error('[Monitoring] Error in initRefreshButton:', e)
}
}
@@ -442,30 +482,45 @@
* Initialize Uptime display
*/
const initUptime = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const uptimeEl = document.getElementById('uptime#id#')
- if (uptimeEl) uptimeEl.innerHTML = '#uptime#'
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const uptimeEl = widgetRoot.querySelector('#uptime#id#')
+ if (uptimeEl) uptimeEl.innerHTML = '#uptime#'
+ } catch (e) {
+ console.error('[Monitoring] Error in initUptime:', e)
+ }
}
/**
* Initialize Network Infos display
*/
const initNetworkInfos = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const networkInfosEl = document.getElementById('network_infos#id#')
- if (networkInfosEl) networkInfosEl.innerHTML = '#network_infos#'
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const networkInfosEl = widgetRoot.querySelector('#network_infos#id#')
+ if (networkInfosEl) networkInfosEl.innerHTML = '#network_infos#'
+ } catch (e) {
+ console.error('[Monitoring] Error in initNetworkInfos:', e)
+ }
}
/**
* Initialize Network Traffic display
*/
const initNetwork = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const networkEl = document.getElementById('network#id#')
- if (networkEl) networkEl.innerHTML = '#network#'
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const networkEl = widgetRoot.querySelector('#network#id#')
+ if (networkEl) {
+ const history = {min: '#network_minHistory#', avg: '#network_averageHistory#', max: '#network_maxHistory#'}
+ networkEl.innerHTML = buildThresholdHTML('#network#', '#network_colorlow#', '#network_colorhigh#', 'Vitesse du réseau', '#network_id#', history, '#network_tendance#', false)
+ }
+ } catch (e) {
+ console.error('[Monitoring] Error in initNetwork:', e)
+ }
}
// ========================================
@@ -476,42 +531,46 @@
* Initialize Load Average displays (1mn, 5mn, 15mn)
*/
const initLoadAverage = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- // Load avg 1mn
- const loadAvg1mn = document.getElementById('load_avg_1mn#id#')
- if (loadAvg1mn) {
- const html = buildThresholdHTML(
- '#load_avg_1mn#', '#load_avg_1mn_colorlow#', '#load_avg_1mn_colorhigh#',
- 'Charge Système (1min)', '#load_avg_1mn_id#',
- { min: '#load_avg_1mn_minHistory#', avg: '#load_avg_1mn_averageHistory#', max: '#load_avg_1mn_maxHistory#' },
- '#load_avg_1mn_tendance#'
- )
- loadAvg1mn.innerHTML = html === '' ? html : `1 min : ${html}`
- }
-
- // Load avg 5mn
- const loadAvg5mn = document.getElementById('load_avg_5mn#id#')
- if (loadAvg5mn) {
- const html = buildThresholdHTML(
- '#load_avg_5mn#', '#load_avg_5mn_colorlow#', '#load_avg_5mn_colorhigh#',
- 'Charge Système (5min)', '#load_avg_5mn_id#',
- { min: '#load_avg_5mn_minHistory#', avg: '#load_avg_5mn_averageHistory#', max: '#load_avg_5mn_maxHistory#' },
- '#load_avg_5mn_tendance#'
- )
- loadAvg5mn.innerHTML = html === '' ? html : ` - 5 min : ${html}`
- }
-
- // Load avg 15mn
- const loadAvg15mn = document.getElementById('load_avg_15mn#id#')
- if (loadAvg15mn) {
- const html = buildThresholdHTML(
- '#load_avg_15mn#', '#load_avg_15mn_colorlow#', '#load_avg_15mn_colorhigh#',
- 'Charge Système (15min)', '#load_avg_15mn_id#',
- { min: '#load_avg_15mn_minHistory#', avg: '#load_avg_15mn_averageHistory#', max: '#load_avg_15mn_maxHistory#' },
- '#load_avg_15mn_tendance#'
- )
- loadAvg15mn.innerHTML = html === '' ? html : ` - 15 min : ${html}`
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ // Load avg 1mn
+ const loadAvg1mn = widgetRoot.querySelector('#load_avg_1mn#id#')
+ if (loadAvg1mn) {
+ const html = buildThresholdHTML(
+ '#load_avg_1mn#', '#load_avg_1mn_colorlow#', '#load_avg_1mn_colorhigh#',
+ 'Charge Système (1min)', '#load_avg_1mn_id#',
+ { min: '#load_avg_1mn_minHistory#', avg: '#load_avg_1mn_averageHistory#', max: '#load_avg_1mn_maxHistory#' },
+ '#load_avg_1mn_tendance#'
+ )
+ loadAvg1mn.innerHTML = html === '' ? html : `1 min : ${html}`
+ }
+
+ // Load avg 5mn
+ const loadAvg5mn = widgetRoot.querySelector('#load_avg_5mn#id#')
+ if (loadAvg5mn) {
+ const html = buildThresholdHTML(
+ '#load_avg_5mn#', '#load_avg_5mn_colorlow#', '#load_avg_5mn_colorhigh#',
+ 'Charge Système (5min)', '#load_avg_5mn_id#',
+ { min: '#load_avg_5mn_minHistory#', avg: '#load_avg_5mn_averageHistory#', max: '#load_avg_5mn_maxHistory#' },
+ '#load_avg_5mn_tendance#'
+ )
+ loadAvg5mn.innerHTML = html === '' ? html : ` - 5 min : ${html}`
+ }
+
+ // Load avg 15mn
+ const loadAvg15mn = widgetRoot.querySelector('#load_avg_15mn#id#')
+ if (loadAvg15mn) {
+ const html = buildThresholdHTML(
+ '#load_avg_15mn#', '#load_avg_15mn_colorlow#', '#load_avg_15mn_colorhigh#',
+ 'Charge Système (15min)', '#load_avg_15mn_id#',
+ { min: '#load_avg_15mn_minHistory#', avg: '#load_avg_15mn_averageHistory#', max: '#load_avg_15mn_maxHistory#' },
+ '#load_avg_15mn_tendance#'
+ )
+ loadAvg15mn.innerHTML = html === '' ? html : ` - 15 min : ${html}`
+ }
+ } catch (e) {
+ console.error('[Monitoring] Error in initLoadAverage:', e)
}
}
@@ -519,69 +578,81 @@
* Initialize Memory display with percentage
*/
const initMemory = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const memoryEl = document.getElementById('memory_available_percent#id#')
- if (!memoryEl) return
-
- const value = '#memory_available_percent#'
- if (value === '') {
- memoryEl.innerHTML = '#memory#'
- return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const memoryEl = widgetRoot.querySelector('#memory_available_percent#id#')
+ if (!memoryEl) return
+
+ const value = '#memory_available_percent#'
+ if (value === '') {
+ memoryEl.innerHTML = '#memory#'
+ return
+ }
+
+ memoryEl.innerHTML = buildPercentageHTML(
+ value, '#memory_available_percent_colorlow#', '#memory_available_percent_colorhigh#',
+ 'Mémoire Vive (% Disponible)', '#memory_available_percent_id#',
+ { min: '#memory_available_percent_minHistory#', avg: '#memory_available_percent_averageHistory#', max: '#memory_available_percent_maxHistory#' },
+ '#memory_available_percent_tendance#', '#memory# (', '%', true
+ )
+ } catch (e) {
+ console.error('[Monitoring] Error in initMemory:', e)
}
-
- memoryEl.innerHTML = buildPercentageHTML(
- value, '#memory_available_percent_colorlow#', '#memory_available_percent_colorhigh#',
- 'Mémoire Vive (% Disponible)', '#memory_available_percent_id#',
- { min: '#memory_available_percent_minHistory#', avg: '#memory_available_percent_averageHistory#', max: '#memory_available_percent_maxHistory#' },
- '#memory_available_percent_tendance#', '#memory# (', '%', true
- )
}
/**
* Initialize Swap display with percentage
*/
const initSwap = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const swapEl = document.getElementById('swap_free_percent#id#')
- if (!swapEl) return
-
- const value = '#swap_free_percent#'
- if (value === '') {
- swapEl.innerHTML = ''
- return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const swapEl = widgetRoot.querySelector('#swap_free_percent#id#')
+ if (!swapEl) return
+
+ const value = '#swap_free_percent#'
+ if (value === '') {
+ swapEl.innerHTML = ''
+ return
+ }
+
+ swapEl.innerHTML = buildPercentageHTML(
+ value, '#swap_free_percent_colorlow#', '#swap_free_percent_colorhigh#',
+ 'Mémoire Swap (% Libre)', '#swap_free_percent_id#',
+ { min: '#swap_free_percent_minHistory#', avg: '#swap_free_percent_averageHistory#', max: '#swap_free_percent_maxHistory#' },
+ '#swap_free_percent_tendance#', '#swap# (', '%', true
+ )
+ } catch (e) {
+ console.error('[Monitoring] Error in initSwap:', e)
}
-
- swapEl.innerHTML = buildPercentageHTML(
- value, '#swap_free_percent_colorlow#', '#swap_free_percent_colorhigh#',
- 'Mémoire Swap (% Libre)', '#swap_free_percent_id#',
- { min: '#swap_free_percent_minHistory#', avg: '#swap_free_percent_averageHistory#', max: '#swap_free_percent_maxHistory#' },
- '#swap_free_percent_tendance#', '#swap# (', '%', true
- )
}
/**
* Initialize HDD display with percentage
*/
const initHDD = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const hddEl = document.getElementById('hdd#id#')
- if (!hddEl) return
-
- const value = '#hdd_free_percent#'
- if (value === '') {
- hddEl.innerHTML = ''
- return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const hddEl = widgetRoot.querySelector('#hdd#id#')
+ if (!hddEl) return
+
+ const value = '#hdd_free_percent#'
+ if (value === '') {
+ hddEl.innerHTML = ''
+ return
+ }
+
+ hddEl.innerHTML = buildPercentageHTML(
+ value, '#hdd_free_percent_colorlow#', '#hdd_free_percent_colorhigh#',
+ 'Espace Disque (% Libre)', '#hdd_free_percent_id#',
+ { min: '#hdd_free_percent_minHistory#', avg: '#hdd_free_percent_averageHistory#', max: '#hdd_free_percent_maxHistory#' },
+ '#hdd_free_percent_tendance#', '#hdd# (', '%', true
+ )
+ } catch (e) {
+ console.error('[Monitoring] Error in initHDD:', e)
}
-
- hddEl.innerHTML = buildPercentageHTML(
- value, '#hdd_free_percent_colorlow#', '#hdd_free_percent_colorhigh#',
- 'Espace Disque (% Libre)', '#hdd_free_percent_id#',
- { min: '#hdd_free_percent_minHistory#', avg: '#hdd_free_percent_averageHistory#', max: '#hdd_free_percent_maxHistory#' },
- '#hdd_free_percent_tendance#', '#hdd# (', '%', true
- )
}
/**
@@ -589,61 +660,69 @@
* @param {HTMLElement} synoContainer - The container div with data-syno-* attributes
*/
const initSynoVolume = (synoContainer) => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const dataset = synoContainer.dataset
- if (dataset.synoDisplay !== 'block') return
-
- const synoId = dataset.synoId
- const container = document.getElementById(`${synoId}#id#`)
- if (!container) return
-
- container.className = 'tooltips'
- container.style.display = dataset.synoDisplay
- container.innerHTML = `${dataset.synoIcon} `
-
- const percentEl = document.getElementById(`${synoId}_free_percent#id#`)
- if (!percentEl) return
-
- const value = dataset.synoPercent
- if (value === '') {
- percentEl.innerHTML = ''
- return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const dataset = synoContainer.dataset
+ if (dataset.synoDisplay !== 'block') return
+
+ const synoId = dataset.synoId
+ const container = widgetRoot.querySelector(`#${synoId}#id#`)
+ if (!container) return
+
+ container.className = 'tooltips'
+ container.style.display = dataset.synoDisplay
+ container.innerHTML = `${dataset.synoIcon} `
+
+ const percentEl = widgetRoot.querySelector(`#${synoId}_free_percent#id#`)
+ if (!percentEl) return
+
+ const value = dataset.synoPercent
+ if (value === '') {
+ percentEl.innerHTML = ''
+ return
+ }
+
+ const history = safeJSONParse(dataset.synoHistory)
+ percentEl.innerHTML = buildPercentageHTML(
+ value, dataset.synoLow, dataset.synoHigh,
+ `${dataset.synoName} (% Libre)`, dataset.synoCmdId,
+ history,
+ dataset.synoTendance, `${dataset.synoValue} (`, '%', true
+ )
+ } catch (e) {
+ console.error('[Monitoring] Error in initSynoVolume for', synoContainer.dataset?.synoId || 'unknown', ':', e)
}
-
- const history = JSON.parse(dataset.synoHistory)
- percentEl.innerHTML = buildPercentageHTML(
- value, dataset.synoLow, dataset.synoHigh,
- `${dataset.synoName} (% Libre)`, dataset.synoCmdId,
- history,
- dataset.synoTendance, `${dataset.synoValue} (`, '%', true
- )
}
/**
* Initialize CPU display with optional temperature
*/
const initCPU = () => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const cpuEl = document.getElementById('cpu#id#')
- if (!cpuEl) return
-
- if ('#cpu_temp#' !== '' && '#cpu_temp_display#' === 'block') {
- cpuEl.innerHTML = '#cpu# '
-
- const tempEl = document.getElementById('cpu_temp#id#')
- if (!tempEl) return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
- const temp = parseFloat('#cpu_temp#')
- const low = parseFloat('#cpu_temp_colorlow#')
- const high = parseFloat('#cpu_temp_colorhigh#')
- const title = 'Stats : Température CPU
Min: #cpu_temp_minHistory# | Moy : #cpu_temp_averageHistory# | Max : #cpu_temp_maxHistory#'
- const color = getColorStyle(temp, low, high, false)
+ const cpuEl = widgetRoot.querySelector('#cpu#id#')
+ if (!cpuEl) return
- tempEl.innerHTML = `(#cpu_temp#°C#cpu_temp_tendance#)`
- } else {
- cpuEl.innerHTML = '#cpu#'
+ if ('#cpu_temp#' !== '' && '#cpu_temp_display#' === 'block') {
+ cpuEl.innerHTML = '#cpu# '
+
+ const tempEl = widgetRoot.querySelector('#cpu_temp#id#')
+ if (!tempEl) return
+
+ const temp = parseFloat('#cpu_temp#')
+ const low = parseFloat('#cpu_temp_colorlow#')
+ const high = parseFloat('#cpu_temp_colorhigh#')
+ const title = 'Stats : Température CPU
Min: #cpu_temp_minHistory# | Moy : #cpu_temp_averageHistory# | Max : #cpu_temp_maxHistory#'
+ const color = getColorStyle(temp, low, high, false)
+
+ tempEl.innerHTML = `(#cpu_temp#°C#cpu_temp_tendance#)`
+ } else {
+ cpuEl.innerHTML = '#cpu#'
+ }
+ } catch (e) {
+ console.error('[Monitoring] Error in initCPU:', e)
}
}
@@ -652,27 +731,31 @@
* @param {HTMLElement} container - The container div with data-perso-* attributes
*/
const initPerso = (container) => {
- if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
-
- const dataset = container.dataset
- const persoId = dataset.persoId
- const el = document.getElementById(`${persoId}_unite#id#`)
- if (!el) return
-
- const value = dataset.persoValue
- if (value === '') {
- el.innerHTML = ''
- return
+ try {
+ if ('#cnx_ssh#' !== 'OK' && '#cnx_ssh#' !== 'No') return
+
+ const dataset = container.dataset
+ const persoId = dataset.persoId
+ const el = widgetRoot.querySelector(`#${persoId}_unite#id#`)
+ if (!el) return
+
+ const value = dataset.persoValue
+ if (value === '') {
+ el.innerHTML = ''
+ return
+ }
+
+ const val = parseFloat(value)
+ const low = parseFloat(dataset.persoLow)
+ const high = parseFloat(dataset.persoHigh)
+ const history = safeJSONParse(dataset.persoHistory)
+ const title = `Stats : ${dataset.persoName}
Min: ${history.min} | Moy : ${history.avg} | Max : ${history.max}`
+ const color = getColorStyle(val, low, high, false)
+
+ el.innerHTML = `${value}${dataset.persoUnite}${dataset.persoTendance}`
+ } catch (e) {
+ console.error('[Monitoring] Error in initPerso for', container.dataset?.persoId || 'unknown', ':', e)
}
-
- const val = parseFloat(value)
- const low = parseFloat(dataset.persoLow)
- const high = parseFloat(dataset.persoHigh)
- const history = JSON.parse(dataset.persoHistory)
- const title = `Stats : ${dataset.persoName}
Min: ${history.min} | Moy : ${history.avg} | Max : ${history.max}`
- const color = getColorStyle(val, low, high, false)
-
- el.innerHTML = `${value}${dataset.persoUnite}${dataset.persoTendance}`
}
// ========================================
@@ -702,13 +785,13 @@
initHDD()
// Synology volumes - generic initialization using data attributes
- document.querySelectorAll('[data-syno-id]').forEach(initSynoVolume)
+ widgetRoot.querySelectorAll('[data-syno-id]').forEach(initSynoVolume)
// CPU with temperature
initCPU()
// Custom commands - generic initialization using data attributes
- document.querySelectorAll('[data-perso-id]').forEach(initPerso)
+ widgetRoot.querySelectorAll('[data-perso-id]').forEach(initPerso)
}
})()
From cca06594b8a351e1cd0d7df886f3cb40daff7e56 Mon Sep 17 00:00:00 2001
From: Olivier <16240457+TiTidom-RC@users.noreply.github.com>
Date: Mon, 5 Jan 2026 22:31:16 +0100
Subject: [PATCH 02/24] update templates
---
core/template/dashboard/AsusWRT.html | 1142 ++++++++++-----------
core/template/dashboard/Monitoring.html | 1244 +++++++++++------------
2 files changed, 1179 insertions(+), 1207 deletions(-)
diff --git a/core/template/dashboard/AsusWRT.html b/core/template/dashboard/AsusWRT.html
index 7e6931f4..331847a0 100644
--- a/core/template/dashboard/AsusWRT.html
+++ b/core/template/dashboard/AsusWRT.html
@@ -3,6 +3,7 @@
div.eqLogic-widget[data-eqLogic_uid="#uid#"] .cmd.monitor-btn {
font-size: 12px !important;
}
+
div.eqLogic-widget[data-eqLogic_uid="#uid#"].editingMode .cmd.monitor-btn {
display: none !important;
}
@@ -21,6 +22,7 @@
align-items: center;
box-sizing: border-box;
}
+
div.eqLogic-widget[data-eqLogic_uid="#uid#"] div.monitor-name-left span:not(:empty) {
padding-right: 3px;
}
@@ -38,7 +40,7 @@
padding-right: 5px;
box-sizing: border-box;
}
-
+
div.eqLogic-widget[data-eqLogic_uid="#uid#"] div.widget-name.monitor-name-center a {
overflow: hidden !important;
text-overflow: ellipsis;
@@ -59,7 +61,7 @@
padding-right: 5px;
color: inherit !important;
}
-
+
div.eqLogic-widget[data-eqLogic_uid="#uid#"] div.monitor-cmds {
display: block;
text-align: left;
@@ -92,636 +94,636 @@