实战案例:本地电脑监控大屏
本教程将引导你使用 OpenTwins 创建一个完整的电脑性能监控系统,实时采集并展示 CPU、内存、磁盘等性能指标。
一、案例概述
1.1 功能目标
- ✅ 实时监控本地电脑的 CPU 使用率
- ✅ 实时监控内存使用情况
- ✅ 实时监控磁盘空间
- ✅ 在 Grafana 中创建可视化大屏
- ✅ 支持历史数据查询和趋势分析
1.2 系统架构
1.3 技术栈
- 数据采集: Python + psutil
- 数据传输: MQTT 协议
- 数字孪生: Eclipse Ditto
- 时序数据库: InfluxDB 2.x
- 数据可视化: Grafana
1.4 前置条件
- ✅ 已完成 OpenTwins 部署(参见 OpenTwins Windows 部署指南)
- ✅ 所有端口转发正在运行
- ✅ 已安装 Python 3.7+
- ✅ 已安装 pip
二、快速开始(5 分钟体验)
2.1 配置 Grafana
- 访问 http://localhost:3002
- 登录(admin/admin)
- 跳过修改密码(或设置新密码)
2.2 创建数字孪生
打开 PowerShell,运行:
1# 第一步:创建 Policy2$policyBody = @{3 policyId = "local:pc-monitor"4 entries = @{5 DEFAULT = @{6 subjects = @{7 "nginx:ditto" = @{ type = "Basic auth user" }8 }9 resources = @{10 "policy:/" = @{ grant = @("READ", "WRITE"); revoke = @() }11 "thing:/" = @{ grant = @("READ", "WRITE"); revoke = @() }12 "message:/" = @{ grant = @("READ", "WRITE"); revoke = @() }13 }14 }15 }16} | ConvertTo-Json -Depth 101718# 准备认证信息19$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))20$headers = @{21 "Content-Type" = "application/json"22 "Authorization" = "Basic $auth"23}2425# 创建 Policy26Write-Host "创建 Policy..." -ForegroundColor Yellow27Invoke-RestMethod -Uri "http://localhost:8080/api/2/policies/local:pc-monitor" `28 -Method Put `29 -Headers $headers `30 -Body $policyBody3132# 第二步:创建 Thing33$thingBody = @{34 "thingId" = "local:pc-monitor"35 "policyId" = "local:pc-monitor"36 "attributes" = @{37 "hostname" = $env:COMPUTERNAME38 "os" = "Windows"39 "createdAt" = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")40 }41 "features" = @{42 "cpu" = @{43 "properties" = @{44 "usage" = 0.045 "cores" = [System.Environment]::ProcessorCount46 }47 }48 "memory" = @{49 "properties" = @{50 "usage" = 0.051 "total" = [Math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)52 }53 }54 "disk" = @{55 "properties" = @{56 "usage" = 0.057 "total" = [Math]::Round((Get-PSDrive C).Used / 1GB + (Get-PSDrive C).Free / 1GB, 2)58 }59 }60 }61} | ConvertTo-Json -Depth 106263# 创建 Thing64Write-Host "创建 Thing..." -ForegroundColor Yellow65Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor" `66 -Method Put `67 -Headers $headers `68 -Body $thingBody | ConvertTo-Json -Depth 106970Write-Host "`n✅ 数字孪生创建成功!" -ForegroundColor Green71Write-Host "主机名: $env:COMPUTERNAME" -ForegroundColor Cyan72Write-Host "CPU 核心: $([System.Environment]::ProcessorCount)" -ForegroundColor Cyan2.3 验证创建
1# 查询 Thing2$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))3Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor" `4 -Method Get `5 -Headers @{"Authorization"="Basic $auth"} | ConvertTo-Json -Depth 10三、数据采集(无需 Python)
3.1 使用 PowerShell 采集数据
无需安装 Python,直接使用 Windows PowerShell 进行数据采集!
3.2 手动发送一次数据(测试)
1# 准备认证信息2$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))3$headers = @{4 "Content-Type" = "application/json"5 "Authorization" = "Basic $auth"6}78# 采集系统数据9$cpuUsage = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue10$os = Get-CimInstance Win32_OperatingSystem11$computerSystem = Get-CimInstance Win32_ComputerSystem12$totalMemory = $computerSystem.TotalPhysicalMemory13$freeMemory = $os.FreePhysicalMemory * 1KB14$usedMemory = $totalMemory - $freeMemory15$memUsagePercent = ($usedMemory / $totalMemory) * 10016$disk = Get-PSDrive C17$diskUsagePercent = ($disk.Used / ($disk.Used + $disk.Free)) * 1001819# 显示采集的数据20Write-Host "采集到的数据:" -ForegroundColor Yellow21Write-Host " CPU: $([Math]::Round($cpuUsage, 2))%" -ForegroundColor Cyan22Write-Host " 内存: $([Math]::Round($memUsagePercent, 2))%" -ForegroundColor Cyan23Write-Host " 磁盘: $([Math]::Round($diskUsagePercent, 2))%" -ForegroundColor Cyan2425# 构建 JSON 数据26$updateBody = @{27 cpu = @{28 properties = @{29 usage = [Math]::Round($cpuUsage, 2)30 cores = [System.Environment]::ProcessorCount31 }32 }33 memory = @{34 properties = @{35 usage = [Math]::Round($memUsagePercent, 2)36 total_gb = [Math]::Round($totalMemory / 1GB, 2)37 used_gb = [Math]::Round($usedMemory / 1GB, 2)38 available_gb = [Math]::Round($freeMemory / 1GB, 2)39 }40 }41 disk = @{42 properties = @{43 usage = [Math]::Round($diskUsagePercent, 2)44 total_gb = [Math]::Round(($disk.Used + $disk.Free) / 1GB, 2)45 used_gb = [Math]::Round($disk.Used / 1GB, 2)46 free_gb = [Math]::Round($disk.Free / 1GB, 2)47 }48 }49} | ConvertTo-Json -Depth 105051# 发送到 OpenTwins52$url = "http://localhost:8080/api/2/things/local:pc-monitor/features"53Invoke-RestMethod -Uri $url -Method PUT -Headers $headers -Body $updateBody5455Write-Host "`n✅ 数据发送成功!" -ForegroundColor Green3.3 查看更新后的数据
1# 查询 Thing 验证数据2$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))3$thing = Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor" `4 -Method Get `5 -Headers @{"Authorization"="Basic $auth"}67Write-Host "`n当前监控数据:" -ForegroundColor Green8Write-Host " CPU: $($thing.features.cpu.properties.usage)%" -ForegroundColor Cyan9Write-Host " 内存: $($thing.features.memory.properties.usage)%" -ForegroundColor Cyan10Write-Host " 磁盘: $($thing.features.disk.properties.usage)%" -ForegroundColor Cyan四、持续监控(可选)
4.1 方法 1:使用 HTML 管理器手动更新
打开项目根目录的 opentwins-manager.html:
- Thing ID 填写:
local:pc-monitor - 点击"查询 Thing"查看当前数据
- CPU 使用率填写新值(如 45.5)
- 点击"更新 CPU"按钮
4.2 方法 2:PowerShell 循环脚本
创建文件 monitor-loop.ps1:
1# OpenTwins PC 监控 - 持续采集脚本2$THING_ID = "local:pc-monitor"3$INTERVAL = 10 # 采集间隔(秒)45$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))6$headers = @{7 "Content-Type" = "application/json"8 "Authorization" = "Basic $auth"9}1011Write-Host "开始监控... (按 Ctrl+C 停止)" -ForegroundColor Green12Write-Host ""1314while ($true) {15 try {16 # 采集数据17 $cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue18 $os = Get-CimInstance Win32_OperatingSystem19 $cs = Get-CimInstance Win32_ComputerSystem20 $totalMem = $cs.TotalPhysicalMemory21 $freeMem = $os.FreePhysicalMemory * 1KB22 $usedMem = $totalMem - $freeMem23 $memPct = ($usedMem / $totalMem) * 10024 $disk = Get-PSDrive C25 $diskPct = ($disk.Used / ($disk.Used + $disk.Free)) * 10026 27 # 构建数据28 $body = @{29 cpu = @{30 properties = @{31 usage = [Math]::Round($cpu, 2)32 cores = [System.Environment]::ProcessorCount33 }34 }35 memory = @{36 properties = @{37 usage = [Math]::Round($memPct, 2)38 total_gb = [Math]::Round($totalMem / 1GB, 2)39 used_gb = [Math]::Round($usedMem / 1GB, 2)40 }41 }42 disk = @{43 properties = @{44 usage = [Math]::Round($diskPct, 2)45 total_gb = [Math]::Round(($disk.Used + $disk.Free) / 1GB, 2)46 used_gb = [Math]::Round($disk.Used / 1GB, 2)47 }48 }49 } | ConvertTo-Json -Depth 1050 51 # 发送数据52 Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/$THING_ID/features" `53 -Method PUT -Headers $headers -Body $body | Out-Null54 55 # 显示状态56 $time = Get-Date -Format "HH:mm:ss"57 $cpuStr = "{0,5:N1}%" -f [Math]::Round($cpu, 2)58 $memStr = "{0,5:N1}%" -f [Math]::Round($memPct, 2)59 $diskStr = "{0,5:N1}%" -f [Math]::Round($diskPct, 2)60 61 Write-Host "[$time] CPU: $cpuStr | Memory: $memStr | Disk: $diskStr" -ForegroundColor Cyan62 63 Start-Sleep -Seconds $INTERVAL64 }65 catch {66 Write-Host "[ERROR] $_" -ForegroundColor Red67 Start-Sleep -Seconds $INTERVAL68 }69}4.3 运行监控脚本
1powershell -ExecutionPolicy Bypass -File .\monitor-loop.ps14.4 方法 3:Python 脚本(可选)
如果您已安装 Python,可以使用原版的 Python 脚本:
1"""2OpenTwins 电脑性能监控脚本3实时采集 CPU、内存、磁盘使用情况并发送到数字孪生平台4"""56import paho.mqtt.client as mqtt7import psutil8import json9import time10import platform11from datetime import datetime1213# ==================== 配置 ====================14MQTT_BROKER = "localhost"15MQTT_PORT = 188316THING_ID = "local:pc-monitor"17COLLECT_INTERVAL = 5 # 采集间隔(秒)1819# ==================== MQTT 回调函数 ====================20def on_connect(client, userdata, flags, rc):21 """MQTT 连接回调"""22 if rc == 0:23 print("✅ 已连接到 MQTT Broker")24 else:25 print(f"❌ 连接失败,返回码: {rc}")2627def on_publish(client, userdata, mid):28 """消息发布回调"""29 pass # 可以添加日志记录3031# ==================== 数据采集函数 ====================32def get_cpu_usage():33 """获取 CPU 使用情况"""34 cpu_percent = psutil.cpu_percent(interval=1)35 cpu_freq = psutil.cpu_freq()36 37 return {38 "usage": round(cpu_percent, 2),39 "cores": psutil.cpu_count(logical=False),40 "threads": psutil.cpu_count(logical=True),41 "frequency": round(cpu_freq.current, 2) if cpu_freq else 042 }4344def get_memory_usage():45 """获取内存使用情况"""46 mem = psutil.virtual_memory()47 48 return {49 "total": mem.total,50 "available": mem.available,51 "used": mem.used,52 "usage": round(mem.percent, 2),53 "total_gb": round(mem.total / (1024**3), 2),54 "used_gb": round(mem.used / (1024**3), 2),55 "available_gb": round(mem.available / (1024**3), 2)56 }5758def get_disk_usage():59 """获取 C 盘使用情况"""60 disk = psutil.disk_usage('C:\\')61 62 return {63 "total": disk.total,64 "free": disk.free,65 "used": disk.used,66 "usage": round(disk.percent, 2),67 "total_gb": round(disk.total / (1024**3), 2),68 "free_gb": round(disk.free / (1024**3), 2),69 "used_gb": round(disk.used / (1024**3), 2)70 }7172def send_metrics(client):73 """采集并发送所有指标"""74 try:75 # 采集数据76 cpu_data = get_cpu_usage()77 memory_data = get_memory_usage()78 disk_data = get_disk_usage()79 80 # 构建 Ditto 消息格式81 payload = {82 "topic": f"{THING_ID}/things/twin/commands/modify",83 "headers": {84 "response-required": False85 },86 "path": "/features",87 "value": {88 "cpu": {89 "properties": cpu_data90 },91 "memory": {92 "properties": memory_data93 },94 "disk": {95 "properties": disk_data96 }97 }98 }99 100 # 发布到 MQTT101 topic = f"{THING_ID}/things/twin/commands/modify"102 message = json.dumps(payload)103 result = client.publish(topic, message, qos=0)104 105 # 打印状态106 timestamp = datetime.now().strftime("%H:%M:%S")107 print(f"[{timestamp}] "108 f"CPU: {cpu_data['usage']:5.1f}% | "109 f"内存: {memory_data['usage']:5.1f}% ({memory_data['used_gb']:.1f}GB/{memory_data['total_gb']:.1f}GB) | "110 f"磁盘: {disk_data['usage']:5.1f}% ({disk_data['used_gb']:.0f}GB/{disk_data['total_gb']:.0f}GB)")111 112 return True113 114 except Exception as e:115 print(f"❌ 发送数据失败: {e}")116 return False117118# ==================== 主程序 ====================119def main():120 """主函数"""121 # 创建 MQTT 客户端122 client = mqtt.Client(client_id=f"pc-monitor-{platform.node()}")123 client.on_connect = on_connect124 client.on_publish = on_publish125 126 # 连接到 MQTT Broker127 try:128 client.connect(MQTT_BROKER, MQTT_PORT, 60)129 client.loop_start()130 time.sleep(2) # 等待连接建立131 except Exception as e:132 print(f"❌ 无法连接到 MQTT Broker: {e}")133 print("\n请确认:")134 print("1. OpenTwins 正在运行")135 print("2. 端口转发已启动: kubectl port-forward svc/opentwins-mosquitto 1883:1883")136 return137 138 # 显示启动信息139 print("\n" + "=" * 70)140 print("🖥️ OpenTwins 电脑性能监控系统")141 print("=" * 70)142 print(f"📌 电脑名称: {platform.node()}")143 print(f"💻 操作系统: {platform.system()} {platform.release()}")144 print(f"🔗 Thing ID: {THING_ID}")145 print(f"⏰ 采集间隔: {COLLECT_INTERVAL} 秒")146 print(f"📊 Grafana: http://localhost:3002")147 print("=" * 70)148 print("\n开始采集数据... (按 Ctrl+C 停止)\n")149 150 # 主循环151 try:152 while True:153 send_metrics(client)154 time.sleep(COLLECT_INTERVAL)155 156 except KeyboardInterrupt:157 print("\n\n⏹️ 停止监控")158 client.loop_stop()159 client.disconnect()160 print("✅ 已断开连接")161162if __name__ == "__main__":163 main()运行 Python 脚本:
1pip install paho-mqtt psutil2python pc-monitor.py预期输出:
1✅ 已连接到 MQTT Broker23======================================================================4🖥️ OpenTwins 电脑性能监控系统5======================================================================6📌 电脑名称: YOUR-PC-NAME7💻 操作系统: Windows 108🔗 Thing ID: local:pc-monitor9⏰ 采集间隔: 5 秒10📊 Grafana: http://localhost:300211======================================================================1213开始采集数据... (按 Ctrl+C 停止)1415[14:30:15] CPU: 25.3% | 内存: 45.2% (7.2GB/16.0GB) | 磁盘: 68.5% (342GB/500GB)16[14:30:20] CPU: 18.7% | 内存: 45.3% (7.2GB/16.0GB) | 磁盘: 68.5% (342GB/500GB)17[14:30:25] CPU: 32.1% | 内存: 45.1% (7.2GB/16.0GB) | 磁盘: 68.5% (342GB/500GB)验证数据更新:
在另一个 PowerShell 窗口中:
1# 查询数字孪生的实时数据2$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("ditto:ditto"))3Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor" `4 -Method Get `5 -Headers @{"Authorization"="Basic $auth"} | ConvertTo-Json -Depth 10应该能看到 features 中的数据在实时更新!
五、创建 Grafana 可视化大屏
5.1 登录 Grafana
- 访问 http://localhost:3002
- 登录(admin/admin)
5.2 验证数据源
- 点击左侧菜单 ⚙️ Configuration → Data Sources
- 应该能看到
InfluxDB数据源(绿色✅表示正常)
5.3 创建新仪表板
- 点击左侧 + → Dashboard
- 点击 Add a new panel
5.4 创建 CPU 使用率面板
如果面板显示 "No data",请确保:
- ✅ 监控脚本
monitor-loop.ps1正在运行 - ✅ 至少运行 5-10 分钟以积累数据
- ✅ 时间范围设置为 "Last 15 minutes"
- ✅ 查询语句完全正确(复制粘贴下面的查询)
步骤 1:选择数据源
在 Query 配置区域:
- Data source: 下拉选择
InfluxDB(opentwins) - Language: 确保选择
Flux(不是 InfluxQL)
步骤 2:输入查询语句
点击查询编辑器底部的 Flux language syntax 标签,在文本框中输入:
1from(bucket: "ditto")2 |> range(start: -1h)3 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")4 |> filter(fn: (r) => r["_field"] == "features.cpu.properties.usage")5 |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)6 |> yield(name: "mean")查询说明:
bucket: "ditto"- InfluxDB 数据桶名称_measurement == "local:pc-monitor"- Thing ID(必须匹配)_field == "features.cpu.properties.usage"- CPU 使用率字段路径range(start: -1h)- 查询最近 1 小时的数据aggregateWindow(every: 10s)- 每 10 秒聚合一次数据
步骤 3:测试查询
点击右上角的 Run Query 按钮(或按 Shift+Enter),应该看到:
- ✅ 数据曲线显示在预览区域
- ❌ 如果显示 "No data",检查上方的警告提示
步骤 4:配置面板样式
在右侧面板配置区域:
Panel options:
- Panel title:
CPU 使用率 - Description:
实时监控 CPU 使用百分比
Visualization:
- 点击右上角可视化类型,选择
Gauge(仪表盘)
Standard options:
- Unit: 搜索并选择
Percent (0-100) - Min:
0 - Max:
100
Thresholds:
- 点击 + Add threshold
- 设置阈值:
- 🟢 Base (0): Green
- 🟡 60: Yellow
- 🔴 80: Red
步骤 5:保存面板
点击右上角 Apply 保存面板。
5.5 创建内存使用率面板
- 点击 Add panel → Add a new panel
查询语句:
1from(bucket: "ditto")2 |> range(start: -1h)3 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")4 |> filter(fn: (r) => r["_field"] == "features.memory.properties.usage")5 |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)6 |> yield(name: "mean")配置面板
- Panel title:
内存使用率 - Visualization:
Gauge - Unit:
Percent (0-100) - Thresholds: 0-70 (绿), 70-85 (黄), 85-100 (红)
5.6 创建磁盘使用率面板
查询语句:
1from(bucket: "ditto")2 |> range(start: -1h)3 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")4 |> filter(fn: (r) => r["_field"] == "features.disk.properties.usage")5 |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)6 |> yield(name: "mean")配置面板
- Panel title:
磁盘使用率 - Visualization:
Gauge - Unit:
Percent (0-100)
5.7 创建趋势图面板
CPU 趋势图
查询语句:
1from(bucket: "ditto")2 |> range(start: -30m)3 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")4 |> filter(fn: (r) => r["_field"] == "features.cpu.properties.usage")5 |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)配置面板
- Panel title:
CPU 使用率趋势(30分钟) - Visualization:
Time series(时间序列图) - Unit:
Percent (0-100) - Graph style:
Lines - Fill opacity:
20 - Line width:
2
5.8 创建统计卡片
当前 CPU 使用率卡片
查询语句:
1from(bucket: "ditto")2 |> range(start: -1m)3 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")4 |> filter(fn: (r) => r["_field"] == "features.cpu.properties.usage")5 |> last()配置面板
- Panel title:
当前 CPU - Visualization:
Stat - Value:
Last(最新值) - Unit:
Percent (0-100) - Text size:
Title设置为大字体
5.9 推荐的大屏布局
1┌─────────────────────────────────────────────────────────┐2│ 电脑性能监控大屏 🖥️ │3│ YOUR-PC-NAME │4├───────────┬───────────┬───────────┬─────────────────────┤5│ CPU │ 内存 │ 磁盘 │ 系统信息 │6│ 32.5% │ 45.2% │ 68.5% │ 核心: 8 │7│ (Gauge) │ (Gauge) │ (Gauge) │ 内存: 16GB │8│ │ │ │ 磁盘: 500GB │9├───────────┴───────────┴───────────┴─────────────────────┤10│ CPU 使用率趋势(30分钟) │11│ [折线图显示 CPU 波动] │12├─────────────────────────────────────────────────────────┤13│ 内存使用率趋势(30分钟) │14│ [折线图显示内存使用] │15├─────────────────────────────────────────────────────────┤16│ 磁盘使用率趋势(30分钟) │17│ [折线图显示磁盘变化] │18└─────────────────────────────────────────────────────────┘5.10 保存仪表板
- 点击右上角 💾 Save dashboard
- Dashboard name:
电脑性能监控大屏 - Folder:
General或创建新文件夹 - 点击 Save
5.11 设置自动刷新
- 点击右上角的时间范围选择器旁边的刷新图标
- 选择 5s (每 5 秒自动刷新)
- 或选择 10s / 30s 根据需要
5.12 全屏显示
- 点击右上角的 Cycle view mode 图标(全屏按钮)
- 或按键盘
F键进入全屏模式 - 按
Esc退出全屏
六、高级功能
6.1 添加告警
创建 CPU 高使用率告警
- 编辑 CPU 使用率面板
- 点击 Alert 标签
- 点击 Create alert rule from this panel
- 配置条件:
1WHEN avg() OF query(A, 5m, now) IS ABOVE 80
- 配置通知渠道(邮件、Webhook 等)
6.2 监控多台电脑
修改脚本支持多台电脑
在 pc-monitor.py 中修改:
1# 使用电脑名称作为 Thing ID2import socket3THING_ID = f"local:pc-{socket.gethostname().lower()}"在 Grafana 中添加变量
-
Dashboard Settings → Variables → Add variable
-
Name:
hostname -
Type:
Query -
Query:
flux1import "influxdata/influxdb/schema"2schema.measurementTagValues(3 bucket: "ditto",4 measurement: "local:pc-*",5 tag: "_measurement"6) -
在查询中使用变量:
flux1filter(fn: (r) => r["_measurement"] == "${hostname}")
6.3 添加网络监控
在 pc-monitor.py 中添加:
1def get_network_usage():2 """获取网络使用情况"""3 net_io = psutil.net_io_counters()4 return {5 "bytes_sent": net_io.bytes_sent,6 "bytes_recv": net_io.bytes_recv,7 "packets_sent": net_io.packets_sent,8 "packets_recv": net_io.packets_recv,9 "bytes_sent_mb": round(net_io.bytes_sent / (1024**2), 2),10 "bytes_recv_mb": round(net_io.bytes_recv / (1024**2), 2)11 }1213# 在 send_metrics 中添加14network_data = get_network_usage()15payload["value"]["network"] = {16 "properties": network_data17}6.4 添加进程监控
1def get_top_processes(limit=5):2 """获取 CPU 占用最高的前 N 个进程"""3 processes = []4 for proc in psutil.process_iter(['pid', 'name', 'cpu_percent']):5 try:6 processes.append({7 'pid': proc.info['pid'],8 'name': proc.info['name'],9 'cpu': proc.info['cpu_percent']10 })11 except:12 pass13 14 # 按 CPU 使用率排序15 processes.sort(key=lambda x: x['cpu'], reverse=True)16 return processes[:limit]6.5 后台运行脚本
方法 1:使用 Windows 任务计划程序
- 打开 任务计划程序
- 创建基本任务
- 名称:
PC Monitor - 触发器: 计算机启动时
- 操作: 启动程序
- 程序:
python.exe - 参数:
D:\path\to\pc-monitor.py - 起始于:
D:\path\to\
- 程序:
方法 2:创建批处理文件
创建 start-monitor.bat:
1@echo off2cd /d "%~dp0"3python pc-monitor.py4pause双击运行即可。
方法 3:使用 pythonw(无窗口运行)
1pythonw pc-monitor.py七、故障排查
7.1 常见问题
问题 1:脚本无法连接 MQTT
症状:
1❌ 无法连接到 MQTT Broker: [Errno 10061] 由于目标计算机积极拒绝,无法连接。解决方案:
1# 1. 确认端口转发正在运行2Test-NetConnection -ComputerName localhost -Port 188334# 2. 如果失败,重新启动端口转发5kubectl port-forward svc/opentwins-mosquitto 1883:1883问题 2:Grafana 中没有数据
检查清单:
-
确认脚本正在运行
powershell1# 应该看到持续的数据输出 -
验证 Ditto 收到数据
powershell1Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor" -Method Get -
检查 InfluxDB
- 访问 http://localhost:8086
- 登录后查看
dittobucket - Data Explorer → 选择
local:pc-monitor
-
检查 Grafana 查询语句
- measurement 名称是否正确:
local:pc-monitor - field 名称格式:
features.cpu.properties.usage
- measurement 名称是否正确:
问题 3:数据不更新
可能原因:
-
Thing ID 不匹配
python1# 检查脚本中的 THING_ID2THING_ID = "local:pc-monitor" # 必须与 Grafana 查询中的一致 -
时间范围太短
- 在 Grafana 右上角调整时间范围为
Last 5 minutes
- 在 Grafana 右上角调整时间范围为
-
聚合窗口太大
flux1# 减小聚合窗口2|> aggregateWindow(every: 5s, fn: mean, createEmpty: false)
问题 4:Python 模块未安装
1# 重新安装2pip install paho-mqtt psutil --upgrade34# 或使用国内镜像5pip install paho-mqtt psutil -i https://pypi.tuna.tsinghua.edu.cn/simple7.2 调试技巧
启用详细日志
在 pc-monitor.py 中添加:
1import logging2logging.basicConfig(level=logging.DEBUG)查看 MQTT 消息
使用 MQTT Explorer 连接到 localhost:1883,订阅主题:
1local:pc-monitor/#手动测试 Ditto API
1# 手动更新 CPU 数据2$body = @{3 "usage" = 50.04} | ConvertTo-Json56Invoke-RestMethod -Uri "http://localhost:8080/api/2/things/local:pc-monitor/features/cpu/properties" `7 -Method PUT `8 -Headers @{"Content-Type"="application/json"} `9 -Body $body八、性能优化
8.1 调整采集频率
1# 在 pc-monitor.py 中2COLLECT_INTERVAL = 10 # 从 5 秒改为 10 秒,减少数据量8.2 数据保留策略
在 InfluxDB 中设置数据保留时间:
- 访问 http://localhost:8086
- Data → Buckets →
ditto - 设置保留时间(如 7 天、30 天)
8.3 优化 Grafana 查询
1# 使用更大的聚合窗口减少数据点2from(bucket: "ditto")3 |> range(start: -1h)4 |> filter(fn: (r) => r["_measurement"] == "local:pc-monitor")5 |> filter(fn: (r) => r["_field"] == "features.cpu.properties.usage")6 |> aggregateWindow(every: 30s, fn: mean, createEmpty: false) # 30秒聚合九、扩展方案
9.1 监控服务器集群
- 在每台服务器上运行监控脚本
- 使用不同的 Thing ID
- 在 Grafana 中创建多服务器概览仪表板
9.2 移动端访问
- 配置 Grafana 的移动端显示
- 使用 Grafana Cloud 实现远程访问
9.3 集成告警系统
- 邮件告警
- 企业微信/钉钉告警
- Webhook 集成其他系统
9.4 数据分析
- 导出历史数据到 Excel
- 使用 Python/Jupyter 进行数据分析
- 预测资源使用趋势
十、总结
10.1 学到的知识
- ✅ 如何使用 Ditto API 创建数字孪生
- ✅ 如何通过 MQTT 发送数据到 OpenTwins
- ✅ 如何在 Grafana 中创建可视化大屏
- ✅ 如何编写 Flux 查询语句
- ✅ 如何使用 Python 采集系统性能数据
10.2 完整代码
所有示例代码已包含在教程中,完整的项目结构:
1pc-monitor/2├── pc-monitor.py # 主监控脚本3├── requirements.txt # Python 依赖4├── start-monitor.bat # Windows 启动脚本5└── README.md # 说明文档10.3 下一步
- 尝试添加更多监控指标(网络、GPU、温度)
- 创建更复杂的 Grafana 仪表板
- 配置告警规则
- 监控多台电脑
- 探索 OpenTwins 的其他功能
十一、参考资源
教程版本: 1.0
最后更新: 2025-01-19
难度: ⭐⭐⭐ 中级
如有问题,请参考 OpenTwins 部署文档 的故障排查部分。
参与讨论