首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >边缘网关 + 以太网温湿度传感器:本地化环境数据采集架构案例

边缘网关 + 以太网温湿度传感器:本地化环境数据采集架构案例

原创
作者头像
盛世宏博小可
发布于 2026-10-10 16:03:24
发布于 2026-10-10 16:03:24
970
举报

边缘网关 + 以太网温湿度传感器:本地化环境数据采集架构案例

物联网 · 盛世宏博 · 边缘网关、以太网温湿度传感器、本地化数据采集、分布式监控架构


一、为什么要在"边缘"做采集

档案库房、配电室、实验室这类场景有一个共同特征:网络不可靠,但数据不能丢。集中式采集架构把所有传感器数据直送云端或中心服务器,一旦网络抖动、交换机重启、光纤中断,整条链路数据清零。而环境监控恰恰最怕"盲区"——温湿度越是在网络故障时越容易出事(空调跳闸、门窗未关、设备过热),等网络恢复再去看数据,事故已经发生了。

边缘网关的核心价值:把采集、缓存、预处理、联动决策下沉到离传感器最近的地方。网络通的时候上送,网络断的时候本地照常跑,恢复后补传。某省级档案馆 12 个库房、86 个分区、312 个以太网温湿度传感器,采用"边缘网关 + 本地时序库 + 按需上云"架构后,数据到达率从 97.2% 提升到 99.97%,网络中断期间(月均 1~2 次,每次 5~30 分钟)零数据丢失。


二、架构总览

代码语言:javascript
复制
┌─────────────────────────────────────────────────────────────────────────┐
│  设备层(以太网温湿度传感器)                                           │
│  • RJ45 接口,IEEE 802.3af PoE 供电                                   │
│  • 支持 Modbus TCP / HTTP API / MQTT 三种协议                          │
│  • 采样周期 5~60s 可配                                                │
│  • 内置温湿度校准系数,支持远程校准                                    │
│  • 每台独立 IP,双网卡冗余(部分高端型号)                             │
└───────────────────────────┬─────────────────────────────────────────────┘
                            │ TCP/IP(VLAN 隔离)
┌───────────────────────────▼─────────────────────────────────────────────┐
│  边缘网关层(每库房 1~2 台)                                            │
│  • 硬件:ARM Cortex-A55 四核 / 2GB RAM / 32GB eMMC                    │
│  • 系统:Debian 12 + Docker                                           │
│  • 功能:                                                               │
│    ├── 多协议并发采集(Modbus TCP / SNMP / HTTP)                      │
│    ├── 数据预处理(去抖、插值、加权聚合)                              │
│    ├── 本地时序库(InfluxDB,保留 90 天热数据)                        │
│    ├── 联动规则引擎(断网也能执行启停逻辑)                            │
│    ├── 断网缓存(SQLite WAL 模式,支持 30 天补传)                     │
│    └── 安全:TLS 双向认证 + 防火墙白名单                               │
└───────────────────────────┬─────────────────────────────────────────────┘
                            │ 加密上送(MQTT over TLS / HTTPS)
┌───────────────────────────▼─────────────────────────────────────────────┐
│  中心层(监控中心 / 云平台)                                           │
│  • 接收网关聚合数据(非原始逐点数据,降低带宽 80%)                    │
│  • 组态画面展示 + 告警推送 + 历史报表                                  │
│  • 配置下发(阈值、采样周期、联动规则)                                │
│  • 审计日志存储(永久)                                                │
└─────────────────────────────────────────────────────────────────────────┘

三、边缘网关硬件选型与部署

1. 选型规格

参数

推荐规格

说明

CPU

ARM Cortex-A55 四核 1.8GHz 或 x86 Celeron J4125

需支持 Docker 容器

内存

≥2GB DDR4

采集进程 + 时序库 + 规则引擎并发

存储

≥32GB eMMC + 外接 mSATA SSD 可选

本地缓存用

网口

≥2×千兆 RJ45

一路接传感器网,一路接上行

串口

≥2×RS485(备用,兼容老设备)

老库房可能有旧传感器

供电

12V DC / PoE++(802.3bt)

配电室取电方便

工作温度

-20~70℃

配电室夏季高温

防护等级

IP40(导轨安装)

柜内安装

2. 部署拓扑(单库房)

代码语言:javascript
复制
┌──────────────┐
                        │  核心交换机   │
                        └──────┬───────┘
                               │ 光纤/网线
                        ┌──────▼───────┐
                        │ 边缘网关      │ ← Docker 容器组
                        │ (库房A)      │   ├── collector (采集)
                        │              │   ├── influxdb  (存储)
                        │ 172.20.10.1  │   ├── rules     (联动)
                        └──┬───┬───┬──┘   └── uploader  (上送)
                           │   │   │
              ┌────────────┘   │   └────────────┐
              ▼                ▼                ▼
        ┌──────────┐    ┌──────────┐     ┌──────────┐
        │ 传感器01  │    │ 传感器02  │     │ 传感器08  │
        │ 172.20.10│    │ 172.20.10│     │ 172.20.10│
        │   .11    │    │   .12    │ ... │   .18    │
        └──────────┘    └──────────┘     └──────────┘

四、采集引擎实现

1. 并发采集核心代码

代码语言:javascript
复制
import asyncio
from pymodbus.client import AsyncModbusTcpClient
import time

class EdgeCollector:
    def __init__(self, sensors: list, concurrency=16):
        self.sensors = sensors
        self.semaphore = asyncio.Semaphore(concurrency)
        self.results = {}

    async def fetch_one(self, sensor: dict):
        async with self.semaphore:
            client = AsyncModbusTcpClient(
                sensor['ip'], port=502,
                timeout=3, retries=2
            )
            try:
                await client.connect()
                rr = await client.read_holding_registers(
                    sensor['reg_base'], 2, slave=sensor.get('slave', 1)
                )
                if not rr.isError():
                    self.results[sensor['id']] = {
                        'temp': rr.registers[0] / 10,
                        'hum': rr.registers[1] / 10,
                        'ts': time.time(),
                        'status': 'OK'
                    }
                else:
                    self.results[sensor['id']]['status'] = 'READ_ERR'
            except Exception as e:
                self.results[sensor['id']] = {
                    'status': 'CONN_ERR', 'err': str(e)
                }
            finally:
                await client.close()

    async def collect_all(self):
        tasks = [self.fetch_one(s) for s in self.sensors]
        await asyncio.gather(*tasks)
        return self.results

2. 本地预处理与聚合

代码语言:javascript
复制
class LocalProcessor:
    def __init__(self, zone_weights: dict):
        self.weights = zone_weights

    def aggregate(self, raw: dict) -> dict:
        valid = {k: v for k, v in raw.items()
                 if v.get('status') == 'OK'}
        if not valid:
            return {'error': 'no valid data'}

        total_w = sum(self.weights.get(k, 1.0) for k in valid)
        avg_temp = sum(v['temp'] * self.weights.get(k, 1.0)
                       for k, v in valid.items()) / total_w
        avg_hum = sum(v['hum'] * self.weights.get(k, 1.0)
                      for k, v in valid.items()) / total_w
        max_hum = max(v['hum'] for v in valid.values())
        min_hum = min(v['hum'] for v in valid.values())

        return {
            'zone_avg_temp': round(avg_temp, 2),
            'zone_avg_hum': round(avg_hum, 2),
            'zone_hum_gradient': round(max_hum - min_hum, 2),
            'point_count': len(valid),
            'ts': time.time()
        }

3. 断网缓存与补传

代码语言:javascript
复制
import sqlite3, json

class OfflineBuffer:
    def __init__(self, db_path='/data/offline.db'):
        self.conn = sqlite3.connect(db_path, check_same_thread=False)
        self.conn.execute('''CREATE TABLE IF NOT EXISTS cache (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            payload TEXT, ts REAL, uploaded INTEGER DEFAULT 0
        )''')
        self.conn.commit()

    def store(self, data: dict):
        self.conn.execute(
            'INSERT INTO cache (payload, ts) VALUES (?, ?)',
            (json.dumps(data), time.time())
        )
        self.conn.commit()

    def pending(self, limit=500):
        cur = self.conn.execute(
            'SELECT id, payload FROM cache WHERE uploaded=0 ORDER BY ts LIMIT ?',
            (limit,)
        )
        return [(row[0], json.loads(row[1])) for row in cur.fetchall()]

    def mark_uploaded(self, ids: list):
        self.conn.executemany(
            'UPDATE cache SET uploaded=1 WHERE id=?',
            [(i,) for i in ids]
        )
        self.conn.commit()

五、Docker 化部署

代码语言:javascript
复制
# docker-compose.yml
version: '3.8'
services:
  collector:
    build: ./collector
    network_mode: host
    restart: always
    volumes:
      - /data/config:/app/config

  influxdb:
    image: influxdb:2.7
    ports:
      - "8086:8086"
    volumes:
      - /data/influxdb:/var/lib/influxdb2
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUX_PWD}
      - DOCKER_INFLUXDB_INIT_ORG=archive
      - DOCKER_INFLUXDB_INIT_BUCKET=env_data

  rules_engine:
    build: ./rules
    network_mode: host
    restart: always
    depends_on:
      - influxdb

  uploader:
    build: ./uploader
    network_mode: host
    restart: always
    environment:
      - UPLOAD_URL=${CENTER_URL}
      - UPLOAD_TOKEN=${UPLOAD_TOKEN}

六、性能与验收

1. 性能指标(单台边缘网关)

指标

实测值

说明

并发采集传感器数

64 台

每 15s 一轮,CPU 占用 <35%

单轮采集耗时

2.1~3.8s

16 并发,含超时重试

本地聚合延迟

<100ms

内存计算

断网缓存容量

30 天(15s 粒度)

32GB eMMC

补传速率

200 条/s

恢复后匀速补传

联动规则执行延迟

<500ms

本地闭环

2. 验收标准

项目

标准

数据到达率

≥99.9%(含断网补传后)

采集周期

15s(可配 5~60s)

断网缓存

≥7 天(验收要求),实测 30 天

补传完整性

断网期间数据 100% 恢复

联动响应

本地规则 <1s 执行

网关重启恢复

<60s 自动恢复全部服务

协议兼容性

Modbus TCP / HTTP / MQTT 三协议


七、一句话总结

边缘网关 + 以太网温湿度传感器的组合,本质是把"数据采集、预处理、存储、联动"四件事从中心服务器下沉到现场。网络是"尽力而为"的,但环境数据是"一个不能丢"的——边缘架构用本地缓存兜底、用聚合降带宽、用规则引擎保联动,让监控系统从"依赖网络活着"变成"网络只是锦上添花"。


关键词:边缘网关、以太网温湿度传感器、本地化采集、并发采集、数据预处理、断网缓存、补传机制、Docker部署、Modbus TCP、联动规则引擎、分布式架构、环境监控

标签:#边缘网关 #以太网温湿度传感器 #本地化采集 #并发采集 #断网缓存 #补传机制 #Docker部署 #ModbusTCP #联动规则 #分布式架构 #环境监控 #边缘计算

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

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

目录
  • 边缘网关 + 以太网温湿度传感器:本地化环境数据采集架构案例
    • 一、为什么要在"边缘"做采集
    • 二、架构总览
    • 三、边缘网关硬件选型与部署
      • 1. 选型规格
      • 2. 部署拓扑(单库房)
    • 四、采集引擎实现
      • 1. 并发采集核心代码
      • 2. 本地预处理与聚合
      • 3. 断网缓存与补传
    • 五、Docker 化部署
    • 六、性能与验收
      • 1. 性能指标(单台边缘网关)
      • 2. 验收标准
    • 七、一句话总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档