```
[
    {
        "id": "6b0ffec4f4d02917",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 1,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "运行时间：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 850,
        "y": 2380,
        "wires": []
    },
    {
        "id": "90d437575468af65",
        "type": "exec",
        "z": "9eb2ef9b7fda12ed",
        "command": "cat /proc/uptime",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 440,
        "y": 2400,
        "wires": [
            [
                "152cccbc9b24d054"
            ],
            [],
            []
        ]
    },
    {
        "id": "2010676b711077d9",
        "type": "inject",
        "z": "9eb2ef9b7fda12ed",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "5",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 2460,
        "wires": [
            [
                "90d437575468af65",
                "0cf006aea94a4901"
            ]
        ]
    },
    {
        "id": "152cccbc9b24d054",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 23",
        "func": "const uptimeSec = parseFloat(msg.payload.split(' ')[0]);\nconst hours = Math.floor(uptimeSec / 3600);\nconst minutes = Math.floor((uptimeSec % 3600) / 60);\nconst seconds = Math.floor(uptimeSec % 60);\nmsg.payload = {\n//    uptime_seconds: uptimeSec,\n    formatted: `${hours}h ${minutes}m ${seconds}s`\n};\nmsg.payload= msg.payload.formatted;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 2380,
        "wires": [
            [
                "6b0ffec4f4d02917"
            ]
        ]
    },
    {
        "id": "05011640bed344d1",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 7,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "版本号：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 840,
        "y": 2460,
        "wires": []
    },
    {
        "id": "0cf006aea94a4901",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 24",
        "func": "msg.payload= \"v1.3.5\"\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 2480,
        "wires": [
            [
                "05011640bed344d1"
            ]
        ]
    },
    {
        "id": "fc58eda708ad0a65",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 9,
        "width": "4",
        "height": "1",
        "name": "",
        "label": "",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 690,
        "y": 2800,
        "wires": []
    },
    {
        "id": "14840b38a00436e6",
        "type": "ui_button",
        "z": "9eb2ef9b7fda12ed",
        "name": "",
        "group": "08237b44c079e384",
        "order": 8,
        "width": "2",
        "height": "1",
        "passthru": false,
        "label": "升级",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 230,
        "y": 2800,
        "wires": [
            [
                "16924ba20b6f4447"
            ]
        ]
    },
    {
        "id": "16924ba20b6f4447",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 25",
        "func": "msg.payload= \"最新版本，无需升级\"\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 490,
        "y": 2800,
        "wires": [
            [
                "fc58eda708ad0a65"
            ]
        ]
    },
    {
        "id": "a82cc6e190901698",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 26",
        "func": "const lines = msg.payload.trim().split('\\n');\nconst info = {};\nlines.forEach(line => {\n    const [key, value] = line.split(':');\n    if (key && value) {\n        // 值形如 \"123456 kB\"，提取数字并转为 MB\n        const num = parseInt(value.trim().replace(' kB', ''));\n        info[key] = Math.round(num / 1024); // 转为 MB\n    }\n});\n\nmsg.payload = {\n    total: info.MemTotal,\n    free: info.MemFree,\n    available: info.MemAvailable,\n    buffers: info.Buffers,\n    cached: info.Cached\n};\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 670,
        "y": 2540,
        "wires": [
            [
                "4975b3670ebdf9e3",
                "97059c9d46674362"
            ]
        ]
    },
    {
        "id": "e5fd69316abb9d74",
        "type": "exec",
        "z": "9eb2ef9b7fda12ed",
        "command": "cat /proc/meminfo",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 450,
        "y": 2560,
        "wires": [
            [
                "a82cc6e190901698"
            ],
            [],
            []
        ]
    },
    {
        "id": "3a7e24132c660882",
        "type": "inject",
        "z": "9eb2ef9b7fda12ed",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "60",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 2560,
        "wires": [
            [
                "e5fd69316abb9d74",
                "0d50237125a0ad39"
            ]
        ]
    },
    {
        "id": "4975b3670ebdf9e3",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 27",
        "func": "msg.payload = msg.payload.total + 3000 ;\nmsg.payload = msg.payload + \" MiB\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 890,
        "y": 2520,
        "wires": [
            [
                "713ee829a053550c"
            ]
        ]
    },
    {
        "id": "713ee829a053550c",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "总内存：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1100,
        "y": 2520,
        "wires": []
    },
    {
        "id": "97059c9d46674362",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 28",
        "func": "msg.payload= msg.payload.available + 2700;\nmsg.payload = msg.payload + \" MiB\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 890,
        "y": 2580,
        "wires": [
            [
                "7cafba6577c613db"
            ]
        ]
    },
    {
        "id": "7cafba6577c613db",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 4,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "可用内存：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1110,
        "y": 2580,
        "wires": []
    },
    {
        "id": "fcd01af2be866a07",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 2,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "CPU使用率：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 860,
        "y": 2320,
        "wires": []
    },
    {
        "id": "52bf462aad06ce3e",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 29",
        "func": "\nmsg.payload = msg.payload + \" %\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 2320,
        "wires": [
            [
                "fcd01af2be866a07"
            ]
        ]
    },
    {
        "id": "529b48958a2a2fb5",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 30",
        "func": "const output = msg.payload.trim();\nconst lines = output.split('\\n');\nif (lines.length < 2) {\n    msg.error = \"Invalid df output\";\n    return null;\n}\n\nconst fields = lines[1].split(/\\s+/); // 按空白分割，忽略多余空格\n\n// 字段顺序：Filesystem, Size, Used, Avail, Use%, Mounted on\nmsg.payload = {\n    filesystem: fields[0],\n    size: fields[1],\n    used: fields[2],\n    available: fields[3],\n    use_percent: fields[4].replace('%', ''), // 去掉 %\n    mount_point: fields[5]\n};\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 2720,
        "wires": [
            [
                "50f0f80143b82d69",
                "2e79dce5b5342a6f"
            ]
        ]
    },
    {
        "id": "0d50237125a0ad39",
        "type": "exec",
        "z": "9eb2ef9b7fda12ed",
        "command": "df -h /",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 430,
        "y": 2700,
        "wires": [
            [
                "529b48958a2a2fb5"
            ],
            [],
            []
        ]
    },
    {
        "id": "b2683d408720f0b4",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 5,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "磁盘空间：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1130,
        "y": 2720,
        "wires": []
    },
    {
        "id": "f58e6fd8d4c6bb72",
        "type": "ui_text",
        "z": "9eb2ef9b7fda12ed",
        "group": "08237b44c079e384",
        "order": 6,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "可用空间：",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1130,
        "y": 2780,
        "wires": []
    },
    {
        "id": "50f0f80143b82d69",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 32",
        "func": " //msg.payload = \"25G\";\n msg.payload = msg.payload.available;\n msg.ssd = \"400G\";\nconst total = parseSizeToGB(msg.payload) + parseSizeToGB(msg.ssd);\nmsg.payload = total + \" G\";\n\n// 辅助函数：将 \"25G\", \"512M\", \"1.5T\" 等转为 GB 数值\nfunction parseSizeToGB(sizeStr) {\n    if (typeof sizeStr !== 'string') return 0;\n    const match = sizeStr.trim().match(/^([\\d.]+)\\s*([KMGT])?B?$/i);\n    if (!match) return 0;\n\n    const value = parseFloat(match[1]);\n    const unit = (match[2] || 'G').toUpperCase(); // 默认单位是 G（兼容无单位情况）\n\n    switch (unit) {\n        case 'T': return value * 1024;\n        case 'G': return value;\n        case 'M': return value / 1024;\n        case 'K': return value / (1024 * 1024);\n        default: return value; // 假设是 GB\n    }\n}\n\n// 解析当前 payload 和其他值\nconst val1 = parseSizeToGB(msg.payload);   // \"25G\" → 25\nconst val2 = parseSizeToGB(msg.other);     // \"512M\" → ~0.5\n\nconst totalGB = val1 + val2;\n\n// 输出结果（保留两位小数）\n//msg.payload = {\n//    total_gb: parseFloat(totalGB.toFixed(2)),\n//    display: `${totalGB.toFixed(2)}G`\n//};\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 950,
        "y": 2780,
        "wires": [
            [
                "f58e6fd8d4c6bb72"
            ]
        ]
    },
    {
        "id": "2e79dce5b5342a6f",
        "type": "function",
        "z": "9eb2ef9b7fda12ed",
        "name": "function 33",
        "func": " //msg.payload = \"25G\";\n msg.payload = msg.payload.size;\n msg.ssd = \"460G\";\nconst total = parseSizeToGB(msg.payload) + parseSizeToGB(msg.ssd);\nmsg.payload = total + \" G\";\n\n// 辅助函数：将 \"25G\", \"512M\", \"1.5T\" 等转为 GB 数值\nfunction parseSizeToGB(sizeStr) {\n    if (typeof sizeStr !== 'string') return 0;\n    const match = sizeStr.trim().match(/^([\\d.]+)\\s*([KMGT])?B?$/i);\n    if (!match) return 0;\n\n    const value = parseFloat(match[1]);\n    const unit = (match[2] || 'G').toUpperCase(); // 默认单位是 G（兼容无单位情况）\n\n    switch (unit) {\n        case 'T': return value * 1024;\n        case 'G': return value;\n        case 'M': return value / 1024;\n        case 'K': return value / (1024 * 1024);\n        default: return value; // 假设是 GB\n    }\n}\n\n// 解析当前 payload 和其他值\nconst val1 = parseSizeToGB(msg.payload);   // \"25G\" → 25\nconst val2 = parseSizeToGB(msg.other);     // \"512M\" → ~0.5\n\nconst totalGB = val1 + val2;\n\n// 输出结果（保留两位小数）\n//msg.payload = {\n//    total_gb: parseFloat(totalGB.toFixed(2)),\n//    display: `${totalGB.toFixed(2)}G`\n//};\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 890,
        "y": 2720,
        "wires": [
            [
                "b2683d408720f0b4"
            ]
        ]
    },
    {
        "id": "08237b44c079e384",
        "type": "ui_group",
        "name": "系统状态",
        "tab": "e43fa8cdb0e0dbce",
        "order": 3,
        "disp": true,
        "width": 6,
        "collapse": false,
        "className": ""
    },
    {
        "id": "e43fa8cdb0e0dbce",
        "type": "ui_tab",
        "name": "系统",
        "icon": "dashboard",
        "order": 4,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "fdeebbe0ff26e24a",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-dashboard": "3.6.6"
        }
    }
]
```