Speedport JSON Parser

Parse and display VDSL information fom Speedport Plus COSMOTE modems.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Speedport JSON Parser
// @namespace    http://tampermonkey.net/
// @version      1.2.2
// @author       sfortis
// @description  Parse and display VDSL information fom Speedport Plus COSMOTE modems.
// @match        http://192.168.1.1/data/Status.json
// @grant        GM_addStyle
// @license MIT
// @require      https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js
// ==/UserScript==

(function() {
    'use strict';

    // Add custom CSS styles to hide the JSON input and output
    GM_addStyle(`
        pre:first-child {
            display: none !important;
        }

        body > pre {
            visibility: hidden !important;
        }

        #dsl-info-container {
            display: block !important;
        }

        #dsl-info-container h3 {
            font-weight: bold;
        }

        #dsl-info-container p {
            margin: 5px 0;
        }

        .dsl-info-title {
            font-weight: bold;
        }

        .chart-container {
            display: flex;
            justify-content: space-between;
            width: 100%;
            max-width: 600px;
            margin: 20px auto;
        }

        .chart {
            width: 30%;
            height: 200px;
        }

        .chart-legend {
            display: flex;
            justify-content: space-between;
            margin-top: 10px;
        }

        .chart-legend span {
            display: flex;
            align-items: center;
        }

        .chart-legend span::before {
            content: '';
            display: inline-block;
            width: 10px;
            height: 10px;
            margin-right: 5px;
        }

        .chart-labels {
            font-size: 12px;
            line-height: 1;
        }
    `);

    // Clear the screen
    document.body.innerHTML = '';

    // Fetch the JSON data
    fetch("http://192.168.1.1/data/Status.json")
        .then(response => response.json())
        .then(data => {
            // Find the DSL variables
            const dslMaxDownstream = data.find(item => item.varid === "dsl_max_downstream");
            const dslMaxUpstream = data.find(item => item.varid === "dsl_max_upstream");
            const firmwareVersion = data.find(item => item.varid === "firmware_version");
            const uptime = data.find(item => item.varid === "uptime");
            const dslSyncTime = data.find(item => item.varid === "dsl_sync_time");
            const dslDownstream = data.find(item => item.varid === "dsl_downstream");
            const dslUpstream = data.find(item => item.varid === "dsl_upstream");
            const dslCRCerrors = data.find(item => item.varid === "dsl_crc_errors");
            const dslFECerrors = data.find(item => item.varid === "dsl_fec_errors");
            const snr = data.find(item => item.varid === "dsl_snr");
            const attn = data.find(item => item.varid === "dsl_atnu");

            // Create HTML elements to display the DSL information
            const container = document.createElement("div");
            container.id = "dsl-info-container";
            container.style.margin = "10px";
            container.style.padding = "10px";

            const title = document.createElement("h3");
            title.textContent = "Speedport VDSL Information";

            const infoTable = document.createElement("table");
            infoTable.classList.add("info-table");

            const tableBody = document.createElement("tbody");

            const addRow = (label, value) => {
                const row = document.createElement("tr");

                const labelCell = document.createElement("td");
                labelCell.textContent = label;
                labelCell.style.fontWeight = "bold";

                const valueCell = document.createElement("td");
                valueCell.textContent = value;

                row.appendChild(labelCell);
                row.appendChild(valueCell);
                tableBody.appendChild(row);
            };

            addRow("Firmware Version:", firmwareVersion ? firmwareVersion.varvalue : "N/A");
            addRow("Uptime:", uptime ? uptime.varvalue : "N/A");
            addRow("DSL Sync Time:", dslSyncTime ? dslSyncTime.varvalue : "N/A");
            addRow("DSL Downstream:", dslDownstream ? dslDownstream.varvalue + " Mbps" : "N/A");
            addRow("DSL Upstream:", dslUpstream ? dslUpstream.varvalue + " Mbps" : "N/A");
            addRow("DSL Max Downstream:", dslMaxDownstream ? dslMaxDownstream.varvalue + " Mbps" : "N/A");
            addRow("DSL Max Upstream:", dslMaxUpstream ? dslMaxUpstream.varvalue + " Mbps" : "N/A");
            addRow("DSL CRC Errors:", dslCRCerrors ? dslCRCerrors.varvalue : "N/A");
            addRow("DSL FEC Errors:", dslFECerrors ? dslFECerrors.varvalue : "N/A");
            addRow("Signal-to-Noise Ratio:", snr ? snr.varvalue : "N/A");
            addRow("Attenuation:", attn ? attn.varvalue : "N/A");

            infoTable.appendChild(tableBody);

            const chartContainer = document.createElement("div");
            chartContainer.classList.add("chart-container");

            const createPieChart = (title, values, containerId) => {
                const chartWrapper = document.createElement("div");
                chartWrapper.classList.add("chart");

                const chartCanvas = document.createElement("canvas");
                chartCanvas.id = containerId;
                chartWrapper.appendChild(chartCanvas);

                const legend = document.createElement("div");
                legend.classList.add("chart-legend");

                values.forEach((value, index) => {
                    const legendItem = document.createElement("span");
                    legendItem.innerHTML = `<span style="background-color: ${value.color}"></span> ${value.label}: ${value.value} Mbps`;
                    legend.appendChild(legendItem);
                });

                chartWrapper.appendChild(legend);
                chartContainer.appendChild(chartWrapper);

                const ctx = chartCanvas.getContext("2d");
                new Chart(ctx, {
                    type: "pie",
                    data: {
                        datasets: [{
                            data: values.map(item => item.value),
                            backgroundColor: values.map(item => item.color),
                            borderWidth: 1
                        }],
                        labels: values.map(item => item.label)
                    },
                    options: {
                        responsive: true,
                        legend: {
                            display: true
                        },
                        tooltips: {
                            callbacks: {
                                label: (tooltipItem, data) => {
                                    const dataset = data.datasets[tooltipItem.datasetIndex];
                                    const value = dataset.data[tooltipItem.index];
                                    return `${data.labels[tooltipItem.index]}: ${value} Mbps`;
                                }
                            }
                        },
                    }
                });
            };

            const downstreamValues = [
                {
                    value: dslDownstream ? parseInt(dslDownstream.varvalue) : 0,
                    color: "rgba(54, 162, 235, 0.6)",
                    label: "VDSL Downstream"
                },
                {
                    value: dslMaxDownstream ? parseInt(dslMaxDownstream.varvalue) : 0,
                    color: "rgba(255, 99, 132, 0.6)",
                    label: "VDSL Max Downstream"
                }
            ];
            createPieChart("VDSL Downstream", downstreamValues, "downstream-chart");

            const upstreamValues = [
                {
                    value: dslUpstream ? parseInt(dslUpstream.varvalue) : 0,
                    color: "rgba(75, 192, 192, 0.6)",
                    label: "VDSL Upstream"
                },
                {
                    value: dslMaxUpstream ? parseInt(dslMaxUpstream.varvalue) : 0,
                    color: "rgba(153, 102, 255, 0.6)",
                    label: "VDSL Max Upstream"
                }
            ];
            createPieChart("VDSL Upstream", upstreamValues, "upstream-chart");

            // Append the HTML elements to the page
            container.appendChild(title);
            container.appendChild(infoTable);
            container.appendChild(chartContainer);
            document.body.appendChild(container);
        })
        .catch(error => {
            console.error("An error occurred while fetching or parsing the JSON data:", error);
        });
})();