diff --git a/content/sv/status/index.md b/content/sv/status/index.md index 5d8d78a..d642a62 100644 --- a/content/sv/status/index.md +++ b/content/sv/status/index.md @@ -79,6 +79,20 @@ Antalet enheter av firmware version som synts i meshet de senaste 30 dagarna. In +## Unmessagable +Visar antalet noder som är markerade som "unmessagable" respektive "messagable" baserat på de senaste 30 dagarnas aktivitet. Inställningen "unmessagable" används för att identifiera oövervakade infrastrukturnoder så att meddelanden inte skickas till noder som aldrig kommer att svara. Noder som inte har denna inställning definierad räknas som "messagable" eftersom denna egenskap infördes i version 2.6.8. + +
+ +
+ +## OK to MQTT +Visar antalet noder som har "ok_to_mqtt" aktiverad eller avstängd under de senaste 30 dagarna. Flaggan är en begäran om att paket inte ska vidarebefordras till MQTT-servrar och karttjänster som sthlm-mesh. Begäran behöver dock inte respekteras. För att undvika exponering på karttjänster bör man använda krypterade kanaler istället för att dela information publikt. +Äldre firmware skickar inte denna flagga och behandlas som falskt värde. + +
+ +
## Batteri Visar genomsnittlig batterinivå av de noder som rapporterat batteri nivå och inte har fast strömförsörjning. @@ -122,4 +136,6 @@ Graferna baseras på data från [map.sthlm-mesh.se](https://map.sthlm-mesh.se), - \ No newline at end of file + + + \ No newline at end of file diff --git a/static/js/status/is-ok-to-mqtt-chart.js b/static/js/status/is-ok-to-mqtt-chart.js new file mode 100644 index 0000000..17266aa --- /dev/null +++ b/static/js/status/is-ok-to-mqtt-chart.js @@ -0,0 +1,80 @@ +async function isOkToMqttGraph() { + const canvas = document.getElementById('isOkToMqttChart'); + const ctx = canvas.getContext('2d'); + + // Show "Loading..." message + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.font = '16px Arial'; + ctx.fillStyle = 'gray'; + ctx.textAlign = 'center'; + ctx.fillText('Loading data...', canvas.width / 2, canvas.height / 2); + + try { + await fetchNodes(); + // Filter nodes to only include those updated within the last 30 days + const recentNodes = nodes.filter(node => new Date(node.updated_at) >= new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)); + + let countTrue = 0; + let countFalse = 0; + let countNull = 0; + + for (const node of recentNodes) { + const val = node.ok_to_mqtt; + if (val === true) countTrue++; + else if (val === false) countFalse++; + else countNull++; + } + + const container = canvas.parentElement; + if (container) container.style.height = `${2 * 35 + 50}px`; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + new Chart(ctx, { + type: 'bar', + data: { + labels: ['True', 'False'], + + datasets: [ + { + label: 'true', + data: [countTrue, 0,], + backgroundColor: '#7EB26D', // blue + }, + { + label: 'false', + data: [0, countFalse], + backgroundColor: '#BF1B00', // green + }, + { + label: 'unset', + data: [0, countNull], + backgroundColor: '#808080', // grey + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: false, + indexAxis: 'y', + plugins: { + legend: { display: false } + }, + scales: { + x: { beginAtZero: true, stacked: true }, + y: { stacked: true } + } + } + }); + + } catch (error) { + console.error('Error building ok_to_mqtt chart:', error); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = 'red'; + ctx.fillText('Error loading data', canvas.width / 2, canvas.height / 2); + } +} + +isOkToMqttGraph(); + + diff --git a/static/js/status/is-unmessagable-chart.js b/static/js/status/is-unmessagable-chart.js new file mode 100644 index 0000000..bca79a4 --- /dev/null +++ b/static/js/status/is-unmessagable-chart.js @@ -0,0 +1,84 @@ +async function isUnmessagableGraph() { + const canvas = document.getElementById('isUnmessagableChart'); + const ctx = canvas.getContext('2d'); + + // Show "Loading..." message + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.font = '16px Arial'; + ctx.fillStyle = 'gray'; + ctx.textAlign = 'center'; + ctx.fillText('Loading data...', canvas.width / 2, canvas.height / 2); + + try { + await fetchNodes(); + // Filter nodes to only include those updated within the last 30 days + const recentNodes = nodes.filter(node => new Date(node.updated_at) >= new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)); + + let countTrue = 0; + let countFalse = 0; + let countNull = 0; + + + for (const node of recentNodes) { + const val = node.is_unmessagable; + if (val === true) countTrue++; + else if (val === false) countFalse++; + else countNull++; + } + + const container = canvas.parentElement; + if (container) container.style.height = `${2 * 35 + 50}px`; + + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + new Chart(ctx, { + type: 'bar', + data: { + labels: ['unmessagable', 'messagable'], + datasets: [ + { + label: 'true', + data: [countTrue, 0,], + backgroundColor: '#0d6efd', // blue + }, + { + label: 'false', + data: [0, countFalse], + backgroundColor: '#7EB26D', // green + }, + { + label: 'unset', + data: [0, countNull], + backgroundColor: '#808080', // grey + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: false, + indexAxis: 'y', + plugins: { + legend: { display: false } + }, + scales: { + x: { + beginAtZero: true, + stacked: true, + }, + y: { + stacked: true, + } + } + } + }); + + } catch (error) { + console.error('Error building is_unmessagable chart:', error); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = 'red'; + ctx.fillText('Error loading data', canvas.width / 2, canvas.height / 2); + } +} + +isUnmessagableGraph(); \ No newline at end of file