首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >电厂配电室环境监控:TCP/IP以太网温湿度变送器与本地服务器对接方案

电厂配电室环境监控:TCP/IP以太网温湿度变送器与本地服务器对接方案

原创
作者头像
BJ盛世宏博小程
发布于 2026-09-24 15:03:49
发布于 2026-09-24 15:03:49
70
举报

电厂配电室环境监控:TCP/IP以太网温湿度变送器与本地服务器对接方案

一、电厂配电室的特殊性

电厂配电室和常规机房/车间柜内监测有一个本质区别:它不是单一场景,而是一组强约束条件的叠加。

先说清楚这个背景,后面所有设计决策才有依据:

约束维度

具体条件

对监测方案的影响

电磁环境

发电机出口断路器分合闸、励磁系统、厂用电切换

传感器和通信链路必须耐受强瞬态干扰

网络架构

生产控制大区与管理信息大区物理隔离(等保+电力监控系统安全防护规定)

监测数据不能直接上云,必须落在本地

可靠性要求

连续运行,计划检修窗口外不允许中断

服务器和采集链路需冗余设计

数据完整性

环境数据可能作为事故追溯依据

不能丢数据,时间戳必须可信

设备规模

大型电厂配电室通常有20–200个监测点

需要分层架构,不能简单点对点

运维权限

生产区网络变更需工作票审批

方案要一次做对,减少后期改动

本文给出一套从传感器到本地服务器的完整对接方案,覆盖网络拓扑、通信协议、服务端架构、数据持久化和运维管理。


二、总体架构

代码语言:javascript
复制
┌─────────────────────────────────────────────────────────────────────┐
│ 电厂配电室(生产控制大区/安全区Ⅱ)                                  │
│                                                                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐    ┌───────────────┐   │
│  │ 6kV配电室 │  │ 400V配电室│  │ 励磁小室  │    │ 电缆夹层      │   │
│  │           │  │           │  │           │    │               │   │
│  │ [T1]     │  │ [T2]     │  │ [T3]     │    │ [T4]...[Tn]  │   │
│  │ 温湿度   │  │ 温湿度   │  │ 温湿度   │    │ 温湿度        │   │
│  │ 变送器   │  │ 变送器   │  │ 变送器   │    │ 变送器        │   │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘    └──────┬────────┘   │
│       │              │              │                  │            │
│       └──────────────┴──────────────┴──────────────────┘            │
│                          │                                           │
│                    ┌─────▼─────┐                                    │
│                    │ 工业交换机 │  (环网/星型, 管理VLAN隔离)         │
│                    │ 带光口    │                                    │
│                    └─────┬─────┘                                    │
│                          │                                           │
│                    ┌─────▼─────┐                                    │
│                    │ 正向隔离  │  (生产区→管理区,单向)              │
│                    │ 装置      │  如需要跨区传输                    │
│                    └─────┬─────┘                                    │
└──────────────────────────┼───────────────────────────────────────────┘
                           │
┌──────────────────────────┼───────────────────────────────────────────┐
│ 管理信息大区/安全区Ⅲ     │                                           │
│                          │                                           │
│  ┌───────────────────────▼───────────────────────────────────────┐  │
│  │ 数据采集服务(Daemon)                                        │  │
│  │  ├── TCP连接池管理(长连接/短连接可配)                       │  │
│  │  ├── 协议解析(Modbus TCP / 私有TCP / SNMP)                  │  │
│  │  ├── 数据校验与归一化                                         │  │
│  │  └── 缓存与批量写入                                           │  │
│  └───────────────────────┬───────────────────────────────────────┘  │
│                          │                                           │
│  ┌───────────────────────▼───────────────────────────────────────┐  │
│  │ 时序数据库(TDengine / InfluxDB)                             │  │
│  │  ├── 原始数据表(带时间戳、设备ID、区域标签)                  │  │
│  │  ├── 降采样表(1min/5min/1h 聚合)                            │  │
│  │  └── 保留策略(原始90天,降采样永久)                         │  │
│  └───────────────────────┬───────────────────────────────────────┘  │
│                          │                                           │
│  ┌───────────────────────▼───────────────────────────────────────┐  │
│  │ 应用层                                                       │  │
│  │  ├── 实时监控大屏(Web)                                      │  │
│  │  ├── 告警引擎(越限/变化率/通信中断)                         │  │
│  │  ├── 历史趋势分析                                             │  │
│  │  └── 数据导出(Excel/PDF,事故追溯用)                        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │ 冗余设计                                                      │  │
│  │  ├── 双机热备(主备服务器,心跳检测)                         │  │
│  │  ├── 数据库主从复制                                           │  │
│  │  └── 采集服务断线续传(本地SQLite缓存)                       │  │
│  └───────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

三、传感器侧配置

3.1 网络参数规划

电厂配电室测点多、分布广,IP规划要有层次:

代码语言:javascript
复制
网段:10.40.0.0/16(管理VLAN 40,配电室专用)

10.40.10.0/24  — 6kV配电室A列
  10.40.10.1    — 交换机管理IP
  10.40.10.11   — 变送器 T-6kVA-01(A列1柜)
  10.40.10.12   — 变送器 T-6kVA-02
  ...

10.40.11.0/24  — 6kV配电室B列
10.40.20.0/24  — 400V配电室
10.40.30.0/24  — 励磁小室
10.40.40.0/24  — 电缆夹层

10.40.254.1    — 采集服务器(主)
10.40.254.2    — 采集服务器(备)

每台变送器配置:

参数

值

说明

IP地址

静态,按规划表

DHCP在电厂环境不可靠

子网掩码

255.255.255.0

/24

网关

对应区域交换机IP

跨子网通信用

TCP端口

默认502(Modbus TCP)或自定义

与服务器采集程序一致

通信模式

Server(被动等待连接)或 Client(主动上报)

推荐Server模式,服务器主动轮询

上报周期

5–10s

平衡实时性和网络负载

数据格式

IEEE754浮点 / 整型放大10倍

与服务器解析程序匹配

3.2 命名与标签

每台设备外壳贴标签,内容与IP规划表一致:

代码语言:javascript
复制
设备ID:T-6kVA-01
区域:6kV配电室-A列
安装位置:#3开关柜母线室
IP:10.40.10.11
MAC:00:08:DC:01:0A:0B
安装日期:2025-03-15
校准有效期:2026-03-15

四、通信协议选择

4.1 三种主流方案对比

方案

优点

缺点

适用场景

Modbus TCP

标准协议,通用性强,调试工具多

无压缩,报文冗余;功能码有限

大多数场景首选

私有TCP协议

紧凑高效,可定制字段

需自行开发解析程序

自研传感器/大规模部署

SNMP

运维侧标准,轮询简单

实时性一般,不适合高频采集

已有SNMP基础设施时

推荐:电厂项目首选 Modbus TCP,理由是——电厂DCS/辅控系统普遍支持Modbus TCP,后期如需接入厂级SIS(厂级监控信息系统),协议对接零成本。

4.2 Modbus TCP寄存器映射示例

代码语言:javascript
复制
设备地址:每个变送器独立Slave ID(1–247)
功能码:0x04(读输入寄存器)

寄存器地址表:
  40001 (0x0000) — 温度值,INT16,放大10倍,单位℃
  40002 (0x0001) — 湿度值,INT16,放大10倍,单位%RH
  40003 (0x0002) — 传感器状态,UINT16,位定义见下
  40004 (0x0003) — 设备运行时间,UINT32,单位小时(占2个寄存器)
  40006 (0x0005) — 采样次数,UINT32(占2个寄存器)
  40008 (0x0007) — 通信错误计数,UINT16
  40009 (0x0008) — 软件版本号,UINT16(高字节主版本,低字节次版本)

状态寄存器位定义:
  Bit 0 — 传感器正常(1=正常,0=故障)
  Bit 1 — 温度越上限
  Bit 2 — 温度越下限
  Bit 3 — 湿度越上限
  Bit 4 — 湿度越下限
  Bit 5 — 校准标志(1=需要校准)
  Bit 6 — 通信看门狗(1=最近一次通信正常)
  Bit 7–15 — 保留

五、服务器采集程序设计

5.1 核心需求

  • 同时管理100–200个TCP连接(或短连接轮询)
  • 连接异常自动重连,不阻塞其他设备采集
  • 数据解析后写入时序数据库
  • 通信中断可检测、可告警
  • 支持断线续传(服务器宕机期间数据不丢)

5.2 Go语言实现(高并发TCP采集)

代码语言:javascript
复制
package main

import (
    "encoding/binary"
    "fmt"
    "net"
    "sync"
    "time"

    "github.com/go-modbus/modbus"
    "github.com/influxdata/influxdb-client-go/v2"
)

// 设备配置
type DeviceConfig struct {
    ID       string
    IP       string
    Port     int
    SlaveID  byte
    Zone     string
    Location string
    Enabled  bool
}

// 采集结果
type Sample struct {
    DeviceID string
    Zone     string
    Location string
    Temp     float64
    Humi     float64
    Status   uint16
    Ts       time.Time
    Err      error
}

var (
    devices   []DeviceConfig
    influxCli influxdb2.Client
    samples   chan Sample
)

func initDevices() {
    // 从配置文件或数据库加载设备列表
    devices = []DeviceConfig{
        {"T-6kVA-01", "10.40.10.11", 502, 1, "6kV配电室", "A列#3开关柜", true},
        {"T-6kVA-02", "10.40.10.12", 502, 2, "6kV配电室", "A列#5开关柜", true},
        // ... 更多设备
    }
}

func pollDevice(dev DeviceConfig, interval time.Duration) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    var client modbus.Client
    var handler *modbus.TCPClientHandler

    for range ticker.C {
        if !dev.Enabled {
            continue
        }

        // 建立连接(短连接模式:每次轮询新建连接)
        handler = modbus.NewTCPClientHandler(fmt.Sprintf("%s:%d", dev.IP, dev.Port))
        handler.SlaveId = dev.SlaveID
        handler.Timeout = 3 * time.Second

        if err := handler.Connect(); err != nil {
            samples <- Sample{
                DeviceID: dev.ID, Zone: dev.Zone, Location: dev.Location,
                Ts: time.Now(), Err: fmt.Errorf("connect: %w", err),
            }
            handler.Close()
            continue
        }

        client = modbus.NewClient(handler)

        // 读取4个寄存器(温度、湿度、状态、保留)
        results, err := client.ReadInputRegisters(0, 4)
        if err != nil {
            samples <- Sample{
                DeviceID: dev.ID, Zone: dev.Zone, Location: dev.Location,
                Ts: time.Now(), Err: fmt.Errorf("read: %w", err),
            }
            handler.Close()
            continue
        }

        // 解析
        temp := float64(int16(binary.BigEndian.Uint16(results[0:2]))) / 10.0
        humi := float64(int16(binary.BigEndian.Uint16(results[2:4]))) / 10.0
        status := binary.BigEndian.Uint16(results[4:6])

        samples <- Sample{
            DeviceID: dev.ID, Zone: dev.Zone, Location: dev.Location,
            Temp: temp, Humi: humi, Status: status,
            Ts: time.Now(), Err: nil,
        }

        handler.Close()
    }
}

func writer() {
    writeAPI := influxCli.WriteAPI("org", "env_monitor")

    for s := range samples {
        if s.Err != nil {
            // 通信异常,写入错误日志/告警
            fmt.Printf("[%s] %v\n", s.DeviceID, s.Err)
            // 触发告警:连续3次失败 → 上报告警
            continue
        }

        p := influxdb2.NewPoint(
            "env_sample",
            map[string]string{
                "device_id": s.DeviceID,
                "zone":      s.Zone,
                "location":  s.Location,
            },
            map[string]interface{}{
                "temp_c":  s.Temp,
                "humi_pct": s.Humi,
                "status":  int(s.Status),
            },
            s.Ts,
        )
        writeAPI.WritePoint(p)
    }
}

func main() {
    initDevices()

    influxCli = influxdb2.NewClient("http://localhost:8086", "token")
    defer influxCli.Close()

    samples = make(chan Sample, 1000)

    // 启动采集协程
    for _, dev := range devices {
        go pollDevice(dev, 10*time.Second)
    }

    // 启动写入协程
    go writer()

    select {} // 阻塞运行
}

5.3 长连接模式(适合大规模)

当设备数量超过100台时,短连接(每次轮询新建TCP连接)的开销变得显著。改为长连接池模式:

代码语言:javascript
复制
type ConnectionPool struct {
    mu    sync.Mutex
    conns map[string]net.Conn  // key: deviceID
    cfg   map[string]DeviceConfig
}

func (p *ConnectionPool) Get(devID string) (net.Conn, error) {
    p.mu.Lock()
    defer p.mu.Unlock()

    if conn, ok := p.conns[devID]; ok {
        // 检查连接是否还活着
        if conn != nil {
            conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
            one := make([]byte, 1)
            _, err := conn.Read(one)
            if err == nil {
                conn.SetReadDeadline(time.Time{})
                return conn, nil
            }
            // 连接已断,关闭旧连接
            conn.Close()
        }
    }

    // 新建连接
    dev := p.cfg[devID]
    conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", dev.IP, dev.Port), 3*time.Second)
    if err != nil {
        return nil, err
    }

    p.conns[devID] = conn
    return conn, nil
}

六、数据持久化与冗余

6.1 时序数据库选型

数据库

优点

缺点

推荐度

TDengine

专为时序优化,压缩比高,集群成熟

相对较新,社区资源少

★★★★★(首选)

InfluxDB

生态成熟,查询灵活

集群版收费,单机有写入瓶颈

★★★★

TimescaleDB

基于PostgreSQL,SQL友好

时序优化不如专用TSDB

★★★★

MySQL + 分区表

运维简单

写入性能和压缩比都差

★★

推荐TDengine,理由:电厂数据量大(200点×6次/分钟×24小时=28.8万条/天),TDengine的压缩比可达1:10,单机能扛住。

6.2 本地缓存(断线续传)

采集服务在写入数据库失败时,先缓存到本地SQLite:

代码语言:javascript
复制
// 写入失败时存入本地缓存
func cacheSample(s Sample) {
    db, _ := sql.Open("sqlite3", "/var/cache/envd/offline.db")
    stmt, _ := db.Prepare(
        "INSERT INTO offline_cache(device_id, ts, temp, humi, status) VALUES(?,?,?,?,?)")
    stmt.Exec(s.DeviceID, s.Ts.Unix(), s.Temp, s.Humi, s.Status)
}

// 数据库恢复后,批量回灌
func flushCache() {
    // 读取SQLite,批量写入TDengine,成功后删除缓存记录
}

6.3 双机热备

代码语言:javascript
复制
主服务器(10.40.254.1):
  ├── 采集服务(活跃)
  ├── 数据库(主)
  └── 心跳检测(每1s ping备机)

备服务器(10.40.254.2):
  ├── 采集服务(待命,不主动采集)
  ├── 数据库(从,实时同步)
  └── 心跳检测(每1s ping主机)

切换条件:
  - 主机心跳丢失 > 5s
  - 主机数据库无新数据 > 60s
  - 手动切换(运维命令)

切换动作:
  - 备机采集服务启动
  - 备机数据库提升为主
  - 通知交换机/网关更新路由(VRRP)

七、告警引擎

7.1 告警规则

代码语言:javascript
复制
rules:
  - name: high_temp
    condition: temp_c > 40
    duration: 60s        # 持续60秒才触发,避免瞬时干扰
    severity: warning
    message: "{{device_id}} 温度超限: {{temp_c}}℃"

  - name: high_humi
    condition: humi_pct > 80
    duration: 120s
    severity: warning
    message: "{{device_id}} 湿度超限: {{humi_pct}}%RH"

  - name: rapid_temp_change
    condition: abs(rate(temp_c[1m])) > 2
    duration: 30s
    severity: critical
    message: "{{device_id}} 温度骤变: {{rate}}℃/min"

  - name: comm_lost
    condition: time_since_last_sample > 120s
    severity: critical
    message: "{{device_id}} 通信中断超过120秒"

  - name: sensor_fault
    condition: status & 0x0001 == 0
    severity: warning
    message: "{{device_id}} 传感器故障"

7.2 告警通知渠道

渠道

触发条件

实现方式

声光报警器

任何Critical级别

继电器输出到现场声光

短信网关

Critical

HTTP API调用电厂短信平台

运维平台工单

Warning持续>30min

调用运维系统API

大屏弹窗

任何告警

WebSocket推送到前端


八、安全隔离

8.1 网络隔离

电厂网络按等保2.0和《电力监控系统安全防护规定》要求分区:

代码语言:javascript
复制
安全区Ⅰ(控制区):DCS、保护系统 — 绝对不能接环境监测
安全区Ⅱ(非控制区):辅控系统、SIS接口 — 监测数据可接入
安全区Ⅲ(管理区):MIS、办公网 — 监控展示、告警通知

环境监测系统部署在安全区Ⅱ,采集服务器通过正向隔离装置(如南瑞SysKeeper)单向同步数据到安全区Ⅲ的展示服务器。

关键点:

  • 正向隔离装置只允许数据从Ⅱ区到Ⅲ区,不允许反向
  • 监测数据不包含任何控制指令,纯采集
  • 采集服务器不开放任何入站端口(除了SSH运维,且限定源IP)

8.2 加固措施

层面

措施

网络

VLAN隔离,ACL限定只允许采集服务器访问变送器TCP端口

主机

采集服务器关闭不必要的服务,只开502(采集)和SSH(运维)

应用

采集程序以非root用户运行,最小权限

数据

数据库启用认证,通信加密(TLS,如变送器支持)

审计

所有配置变更、告警确认操作记录日志


九、部署验收清单

9.1 安装阶段

代码语言:javascript
复制
□ IP规划表确认,无冲突
□ 交换机端口VLAN配置正确
□ 传感器安装位置合理(避开热源、气流短路)
□ 网线敷设符合规范(与强电线缆间距>30cm,交叉时垂直)
□ RJ45接头打线牢固,线序T568B
□ 屏蔽网线屏蔽层单端接地(交换机侧)
□ 设备上电,Web界面可访问
□ 配置静态IP、网关、TCP参数
□ 标签张贴,与规划表一致

9.2 联调阶段

代码语言:javascript
复制
□ 采集服务器能ping通所有变送器
□ Modbus TCP读取成功,数据准确
□ 与手持仪比对,温度误差≤±0.5℃,湿度≤±3%RH
□ 模拟通信中断(拔网线),告警正确触发
□ 模拟越限,告警正确触发
□ 数据库写入正常,Grafana可查询
□ 连续运行72小时,数据完整率≥99.9%

9.3 文档交付

代码语言:javascript
复制
□ 网络拓扑图
□ IP-区域-测点映射表
□ 寄存器地址表
□ 采集服务配置说明
□ 数据库备份恢复流程
□ 告警规则说明
□ 运维手册(常见问题处理)
□ 备品备件清单

十、经验总结

电厂配电室环境监控的对接方案,核心在于在强约束条件下找到可靠、可维护的平衡点:

  1. 协议选标准,别选"酷"。Modbus TCP虽然老,但电厂所有系统都认它。私有协议省了几个字节的报文长度,换来的是后期对接SIS时的无穷麻烦。
  2. 网络隔离不是障碍,是保护。别想着"打通所有VLAN方便调试",等保检查过不了事小,生产系统被误碰事大。正向隔离装置配好,数据单向流通,干净利落。
  3. 冗余不是奢侈,是刚需。电厂不会因为你"服务器重启一下"就给你停机窗口。双机热备、本地缓存、断线续传,这些在普通机房可能过度设计,在电厂是基本要求。
  4. 数据完整性比实时性重要。温度从23℃变到24℃晚10秒看到没关系,但事故追溯时发现那段数据丢了,就是大问题。宁可多缓存,不可少记录。
  5. 告警要"迟钝"一点。电厂电磁环境复杂,瞬时干扰不可避免。告警规则加持续时间条件,避免误报淹没真正的问题。

关键词:电厂配电室,环境监控,TCP/IP,温湿度变送器,本地服务器,Modbus TCP,数据采集,时序数据库,冗余设计,安全隔离

标签:#电厂 #配电室 #环境监控 #ModbusTCP #温湿度变送器 #TCP #数据采集 #时序数据库 #冗余 #电力安全

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 电厂配电室环境监控:TCP/IP以太网温湿度变送器与本地服务器对接方案
    • 一、电厂配电室的特殊性
    • 二、总体架构
    • 三、传感器侧配置
      • 3.1 网络参数规划
      • 3.2 命名与标签
    • 四、通信协议选择
      • 4.1 三种主流方案对比
      • 4.2 Modbus TCP寄存器映射示例
    • 五、服务器采集程序设计
      • 5.1 核心需求
      • 5.2 Go语言实现(高并发TCP采集)
      • 5.3 长连接模式(适合大规模)
    • 六、数据持久化与冗余
      • 6.1 时序数据库选型
      • 6.2 本地缓存(断线续传)
      • 6.3 双机热备
    • 七、告警引擎
      • 7.1 告警规则
      • 7.2 告警通知渠道
    • 八、安全隔离
      • 8.1 网络隔离
      • 8.2 加固措施
    • 九、部署验收清单
      • 9.1 安装阶段
      • 9.2 联调阶段
      • 9.3 文档交付
    • 十、经验总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档