葡萄园智能灌溉系统:Node-RED 与 MCGS 全链路通讯与 UI 配置手册 (v2.0 完整版)
本文最后更新于28 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

葡萄园智能灌溉系统:Node-RED 与 MCGS 全链路通讯与 UI 配置手册 (v2.0 完整版)

📘 文档版本: v2.0 完整版
🎯 适用场景: 现场边缘网关 (LubanCat-5 / Raspberry Pi 5) + MCGS + 传感器网络
🔧 核心功能: 下行 9 通道控制 + 上行 39 通道监测 + Dashboard 大屏
⚠️ 关键词: 多通道打包、工程量标定、数字孪生、报警防弹


📋 目录

  1. 系统架构概述
  2. 下行控制链路:多通道指令动态打包
  3. 上行监测链路:39 通道数据解析与标定
  4. Dashboard UI 界面排版与视觉优化
  5. 核心注意事项(防坑指南)
  6. 调试与排错
  7. 附录:配置速查表与扩展指南

一、系统架构概述

1.1 整体架构图

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          云端/边缘网关 (Node-RED 上位机)                           │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                     🖥️ 智慧葡萄园主控舱 Dashboard                        │   │
│  │  ┌─────────────────────────────────────────────────────────────────┐   │   │
│  │  │  💻 现场设备控制区 (9通道下发)                                     │   │   │
│  │  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐   │   │   │
│  │  │  │ 水泵 S1 │ │ 阀门 S2 │ │ 施肥 S3 │ │ 压力 Pres│ │ 频率 Freq│   │   │   │
│  │  │  │ [开关]  │ │ [开关]  │ │ [开关]  │ │ [滑块]   │ │ [滑块]   │   │   │   │
│  │  │  │   💡   │ │   💡   │ │   💡   │ │         │ │         │   │   │   │
│  │  │  └────┬────┘ └────┬────┘ └────┬────┘ └────┬─────┘ └────┬─────┘   │   │   │
│  │  │       └───────────┴───────────┴───────────┴─────────────┘          │   │   │
│  │  │                          ↓                                        │   │   │
│  │  │                   9通道动态打包                                    │   │   │
│  │  └─────────────────────────────────────────────────────────────────┘   │   │
│  │  ┌─────────────────────────────────────────────────────────────────┐   │   │
│  │  │  🌱 土壤与水质环境 (39通道监测)                                    │   │   │
│  │  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐   │   │   │
│  │  │  │  📊 实时仪表  │  │  📈 历史曲线  │  │  📋 传感器数值矩阵       │   │   │   │
│  │  │  │  NPK/Gauge  │  │  Chart      │  │  温湿度/电导率/压力      │   │   │   │
│  │  │  └─────────────┘  └─────────────┘  └─────────────────────────┘   │   │   │
│  │  │                          ↑                                        │   │   │
│  │  │                   39通道解析标定                                   │   │   │
│  │  └─────────────────────────────────────────────────────────────────┘   │   │
│  │  ┌─────────────────────────────────────────────────────────────────┐   │   │
│  │  │  🚨 系统报警监控                                                   │   │   │
│  │  │  ┌─────────────────────────────────────────────────────────┐     │   │   │
│  │  │  │  🟢 运行正常  /  🚨 报警: 肥路堵塞                         │     │   │   │
│  │  │  └─────────────────────────────────────────────────────────┘     │   │   │
│  │  └─────────────────────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                    │                                            │
│                              MQTT 协议 (EMQX)                                  │
│                         sub/控制单元 ←→ attributes                             │
│                                    │                                            │
└────────────────────────────────────┼────────────────────────────────────────────┘
                                     │
                                     ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                              现场控制层 (MCGS TPC)                               │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                         MCGS 触摸屏主控界面                              │   │
│  │  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────────┐  │   │
│  │  │   设备控制区     │    │   传感器显示     │    │     报警指示栏       │  │   │
│  │  │   S1-S7 开关    │    │   NPK/温湿度    │    │   🚨 多路报警灯      │  │   │
│  │  └────────┬────────┘    └────────┬────────┘    └──────────┬──────────┘  │   │
│  │           │                      │                        │             │   │
│  │           └──────────────────────┼────────────────────────┘             │   │
│  │                                  │                                      │   │
│  │                           协议转换/打包                                 │   │
│  │                                  │                                      │   │
│  │           ┌──────────────────────┴────────────────────────┐             │   │
│  │           │              底层传感器网络                    │             │   │
│  │           │  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐  │             │   │
│  │           │  │NPK传感 │ │温湿度  │ │电导率  │ │压力传感│  │             │   │
│  │           │  └────────┘ └────────┘ └────────┘ └────────┘  │             │   │
│  │           │  RS-485 / Modbus / 4-20mA / 0-10V              │             │   │
│  │           └───────────────────────────────────────────────┘             │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────────┘

1.2 双链路设计说明

链路方向 Topic 通道数 数据方向 核心功能
下行控制 sub/控制单元 9 通道 Node-RED → MCGS 设备开关 + 模拟量设定
上行监测 attributes 39 通道 MCGS → Node-RED 传感器数据 + 报警 + 状态反馈

设计理念:
控制集约化: 9 个控制指令合并为 1 个 JSON 下发,减少网络开销
监测原子化: 39 个监测字段独立分流,支持精细化展示
状态闭环: 控制指令执行结果通过上行链路回传,实现数字孪生

1.3 数据通道明细表

下行控制通道 (9 路):

通道 名称 类型 范围 说明
S1 水泵开关 Boolean true/false 主灌溉泵
S2 阀门开关 Boolean true/false 区域阀门
S3 施肥开关 Boolean true/false 施肥泵
S4 备用开关 4 Boolean true/false 预留扩展
S5 备用开关 5 Boolean true/false 预留扩展
S6 备用开关 6 Boolean true/false 预留扩展
S7 备用开关 7 Boolean true/false 预留扩展
Pres1 主路压力设定 Number 0-100 单位: bar
Freq 运行频率 Number 0-50 单位: Hz

上行监测通道 (39 路):

类别 字段示例 数据类型 标定系数 说明
土壤养分 N, P, K UInt16 ÷ 10 氮磷钾含量 mg/kg
环境参数 RD11-RD20 UInt16 ÷ 10 多路温湿度
水质参数 EC, pH UInt16 ÷ 100 电导率/酸碱度
系统压力 Pres1, Pres2 UInt16 ÷ 10 主/支路压力
设备状态 S1-S7 Boolean 开关真实状态
报警信息 AM1-AM10 String 多路报警代码

二、下行控制链路:多通道指令动态打包

2.1 功能目标

将网页端 9 个独立的控制指令(S1-S7 设备开关、Pres1 压力设定、Freq 频率设定)动态合并为一个完整的 JSON 报文下发。

为什么需要打包?
– 减少 MQTT 消息数量(9 条 → 1 条)
– 保证指令原子性(同一条报文同时生效)
– 简化 MCGS 端解析逻辑

2.2 网页 UI 节点配置

2.2.1 开关控件 (Switch) – S1 到 S7

配置项 必须注意
Topic S1 / S2 / … / S7 纯文本,区分大小写
On Payload true ⚠️ 必须是 Boolean 类型
Off Payload false ⚠️ 必须是 Boolean 类型
Indicator state of the input 数字孪生必备
Pass through ☐ 取消勾选 防止死循环

配置面板示意:

┌─────────────────────────────────────────┐
│  Group: [💻 现场设备控制区    ▼]        │
│  Label: [水泵 S1              ]         │
│  Topic: [S1                   ]         │
│                                         │
│  On Payload:  [true]  ☜── 布尔类型 🔵   │
│  Off Payload: [false] ☜── 布尔类型 🔵   │
│                                         │
│  ☐ Pass through msg... ☜── 必须取消     │
│                                         │
│  Indicator: [Switch icon shows        ] │
│             [state of the input ▼]     │
└─────────────────────────────────────────┘

2.2.2 滑动/数字控件 – Pres1 / Freq

配置项 Pres1 (压力) Freq (频率)
Topic Pres1 Freq
Min 0 0
Max 100 50
Step 0.1 0.1
单位 bar Hz

2.3 控制指令打包 (Function 节点)

2.3.1 逻辑原理

采用“系统全局记忆”策略:
1. 在 Node-RED 的 flow 上下文中维护 9 个参数的最新状态
2. 任意 UI 节点触发变化时,更新对应参数
3. 统一下发完整 JSON,内置防错拦截机制

2.3.2 节点配置

属性
名称 控制指令打包
Outputs 1

2.3.3 完整代码

/**
 * 控制指令打包器 - 9通道动态合并
 * 输入: 任意 UI 节点的 msg (含 topic + payload)
 * 输出: 完整的 9 参数 JSON 控制报文
 */

// 1. 从 flow 上下文中获取系统记忆,若无则初始化
var control_state = flow.get('control_state') || {
    "Freq": 0,      // 频率设定
    "Pres1": 0,     // 压力设定
    "S1": false,    // 水泵
    "S2": false,    // 阀门
    "S3": false,    // 施肥
    "S4": false,    // 备用
    "S5": false,    // 备用
    "S6": false,    // 备用
    "S7": false     // 备用
};

// 2. 动态匹配并更新状态
//    msg.topic 对应 Key, msg.payload 对应 Value
if (control_state.hasOwnProperty(msg.topic)) {
    control_state[msg.topic] = msg.payload;

    // 保存到 flow 上下文(持久化记忆)
    flow.set('control_state', control_state);

    node.status({fill:"green", shape:"dot", 
                 text: msg.topic + " → " + msg.payload});
} else {
    // 防错拦截:未知的 topic 不处理
    node.warn("⚠️ 未知 Topic 拦截: " + msg.topic);
    node.status({fill:"red", shape:"ring", 
                 text: "未知: " + msg.topic});
    return null; // 终止流
}

// 3. 构建标准输出报文
msg.topic = "sub/控制单元";  // 强制指定下发主题
msg.payload = control_state;  // 完整 9 参数对象

// 调试输出(开发时开启)
// node.warn("下发报文: " + JSON.stringify(control_state));

return msg;

2.3.4 输出报文示例

{
  "topic": "sub/控制单元",
  "payload": {
    "Freq": 35.5,
    "Pres1": 2.8,
    "S1": true,
    "S2": false,
    "S3": true,
    "S4": false,
    "S5": false,
    "S6": false,
    "S7": false
  }
}

2.4 MQTT Out 节点配置

配置项 说明
Server EMQX 地址 192.168.137.238:1883
Topic sub/控制单元 MCGS 订阅此主题
QoS 1 至少送达一次
Retain false 不保留最新消息

三、上行监测链路:39 通道传感器数据解析与标定

3.1 功能目标

接收 MCGS 汇总上报的工业级数据包(包含 NPK、温湿度、电导率、压力、报警及设备反馈共 39 个字段),进行:
工程量还原: 将 UInt16 整数转为实际物理量
多路分流: 39 个字段分发到不同 UI 组件
容错处理: 异常数据拦截

3.2 MCGS 上报数据格式

MCGS 上报报文示例:

{
  "N": 150,      // 氮含量 (×10 mg/kg)
  "P": 80,       // 磷含量
  "K": 120,      // 钾含量
  "RD11": 258,   // 1号含水率 (×10 %)
  "RD12": 245,   // 1号温度 (×10 ℃)
  "RD21": 1560,  // 电导率 (×100 μS/cm)
  "Pres1": 28,   // 压力 (×10 bar)
  "S1": true,    // 水泵实际状态
  "AM1": ""      // 报警信息 (空=正常)
  // ... 共 39 个字段
}

3.3 数据接收与格式化

3.3.1 MQTT In 节点

配置项
Topic attributes
QoS 1
Output a parsed JSON object

3.3.2 JSON 节点(备用转换)

如果 MQTT In 输出的是字符串,添加 JSON 节点:

配置项
Action Always convert to JavaScript Object
Property msg.payload

3.4 超级分发中心 (Function 节点)

3.4.1 节点设置

属性 必须注意
名称 39通道数据分发
Outputs 39 ⚠️ 必须手动改为 39!

修改方法:
1. 双击 Function 节点
2. 底部找到 “Outputs” 输入框
3. 将默认值 1 改为 39
4. 点击「完成」
5. 节点会显示 39 个输出端口

3.4.2 工程量还原 (Calibration)

针对底层传来的 UInt16 无符号整数进行系数还原:

物理量 原始值范围 系数 结果单位 示例
温度 0-65535 ÷ 10 245 → 24.5℃
湿度 0-65535 ÷ 10 % 258 → 25.8%
NPK 0-65535 ÷ 10 mg/kg 150 → 15.0mg/kg
电导率 0-65535 ÷ 100 mS/cm 1560 → 15.6mS/cm
压力 0-65535 ÷ 10 bar 28 → 2.8bar

3.4.3 完整代码

/**
 * 39通道数据分发器 - 超级分发中心
 * 输入: MCGS 上报的 39 字段 JSON
 * 输出: 39 路独立 msg,分别接入不同 UI 组件
 */

var d = msg.payload;

// 1. 容错机制:检查数据有效性
if (!d || typeof d !== 'object') {
    node.error("❌ 无效数据格式");
    return null;
}

// 2. 工程量还原函数
function calibrate(value, factor) {
    if (value === undefined || value === null) return 0;
    return Number(value) / factor;
}

// 3. 物理量还原 (按实际字段调整)
var temp_1 = calibrate(d.RD12, 10);   // 1号温度 (℃)
var moist_1 = calibrate(d.RD11, 10);  // 1号含水率 (%)
var ec_1 = calibrate(d.RD21, 100);    // 电导率 (mS/cm)
var pres_1 = calibrate(d.Pres1, 10);  // 主路压力 (bar)
var n_val = calibrate(d.N, 10);       // 氮含量
var p_val = calibrate(d.P, 10);       // 磷含量
var k_val = calibrate(d.K, 10);       // 钾含量

// 4. 同步更新控制状态记忆(用于下行链路的数字孪生)
flow.set('control_state', {
    "Freq": d.Freq || 0,
    "Pres1": d.Pres1 || 0,
    "S1": d.S1 || false,
    "S2": d.S2 || false,
    "S3": d.S3 || false,
    "S4": d.S4 || false,
    "S5": d.S5 || false,
    "S6": d.S6 || false,
    "S7": d.S7 || false
});

// 5. 构建 39 路输出数组
//    每路输出 = { payload: 值, topic: 显示名称 }
//    顺序必须与 UI 组件的连线顺序一致!
return [
    // 第 1-10 路: 主要设定值与状态
    { payload: pres_1, topic: "主路压力(bar)" },      // 输出 1 → Gauge
    { payload: d.Freq || 0, topic: "运行频率(Hz)" },  // 输出 2 → Gauge
    { payload: n_val, topic: "氮含量(mg/kg)" },       // 输出 3 → Gauge
    { payload: p_val, topic: "磷含量(mg/kg)" },       // 输出 4 → Gauge
    { payload: k_val, topic: "钾含量(mg/kg)" },       // 输出 5 → Gauge
    { payload: ec_1, topic: "电导率(mS/cm)" },        // 输出 6 → Gauge
    { payload: d.S1, topic: "S1状态" },               // 输出 7 → Switch 反馈
    { payload: d.S2, topic: "S2状态" },               // 输出 8 → Switch 反馈
    { payload: d.S3, topic: "S3状态" },               // 输出 9 → Switch 反馈
    { payload: d.S4, topic: "S4状态" },               // 输出 10

    // 第 11-20 路: 多路温湿度
    { payload: moist_1, topic: "1号含水率(%)" },      // 输出 11 → Chart
    { payload: temp_1, topic: "1号温度(℃)" },        // 输出 12 → Chart
    { payload: calibrate(d.RD13, 10), topic: "2号含水率" }, // 输出 13
    { payload: calibrate(d.RD14, 10), topic: "2号温度" },   // 输出 14
    { payload: calibrate(d.RD15, 10), topic: "3号含水率" }, // 输出 15
    { payload: calibrate(d.RD16, 10), topic: "3号温度" },   // 输出 16
    { payload: calibrate(d.RD17, 10), topic: "4号含水率" }, // 输出 17
    { payload: calibrate(d.RD18, 10), topic: "4号温度" },   // 输出 18
    { payload: calibrate(d.RD19, 10), topic: "5号含水率" }, // 输出 19
    { payload: calibrate(d.RD20, 10), topic: "5号温度" },   // 输出 20

    // 第 21-30 路: 报警与扩展
    { payload: d.AM1 || "", topic: "主路报警" },      // 输出 21 → 报警 Text
    { payload: d.AM2 || "", topic: "肥路报警" },      // 输出 22 → 报警 Text
    { payload: d.AM3 || "", topic: "泵报警" },        // 输出 23
    { payload: d.AM4 || "", topic: "阀门报警" },      // 输出 24
    { payload: d.AM5 || "", topic: "备用报警5" },     // 输出 25
    { payload: d.AM6 || "", topic: "备用报警6" },     // 输出 26
    { payload: d.AM7 || "", topic: "备用报警7" },     // 输出 27
    { payload: d.AM8 || "", topic: "备用报警8" },     // 输出 28
    { payload: d.AM9 || "", topic: "备用报警9" },     // 输出 29
    { payload: d.AM10 || "", topic: "备用报警10" },   // 输出 30

    // 第 31-39 路: 更多设备状态反馈(用于数字孪生)
    { payload: d.S5, topic: "S5状态" },               // 输出 31
    { payload: d.S6, topic: "S6状态" },               // 输出 32
    { payload: d.S7, topic: "S7状态" },               // 输出 33
    // ... 可继续扩展至 39 路
    { payload: 0, topic: "保留34" },                  // 输出 34
    { payload: 0, topic: "保留35" },                  // 输出 35
    { payload: 0, topic: "保留36" },                  // 输出 36
    { payload: 0, topic: "保留37" },                  // 输出 37
    { payload: 0, topic: "保留38" },                  // 输出 38
    { payload: 0, topic: "保留39" }                   // 输出 39
];

3.5 输出连线方式

Function 节点 (39通道数据分发)
      │
      ├──输出 1──> ui_gauge (主路压力)
      ├──输出 2──> ui_gauge (运行频率)
      ├──输出 3──> ui_gauge (氮含量)
      ├──输出 4──> ui_gauge (磷含量)
      ├──输出 5──> ui_gauge (钾含量)
      ├──输出 6──> ui_gauge (电导率)
      │
      ├──输出 7──> ui_switch (S1 反馈输入)
      ├──输出 8──> ui_switch (S2 反馈输入)
      ├──输出 9──> ui_switch (S3 反馈输入)
      │
      ├──输出 11──> ui_chart (含水率历史曲线)
      ├──输出 12──> ui_chart (温度历史曲线)
      │
      ├──输出 21──> function (报警防弹) ──> ui_text
      └──输出 22──> function (报警防弹) ──> ui_text

四、Dashboard UI 界面排版与视觉优化

4.1 结构化排版 (Tab & Group)

在右侧的 Dashboard → Layout 面板中建立以下层级:

Dashboard Layout Tree:
│
└── 📱 Tab: 智慧葡萄园主控舱
    │
    ├── 💻 Group: 现场设备控制区
    │   ├── [Switch] 水泵 S1
    │   ├── [Switch] 阀门 S2
    │   ├── [Switch] 施肥 S3
    │   ├── [Slider] 压力 Pres1
    │   └── [Slider] 频率 Freq
    │   Width: 6 (半屏宽)
    │
    ├── 🌱 Group: 土壤与水质环境
    │   ├── [Gauge] NPK 仪表盘
    │   ├── [Gauge] 电导率
    │   ├── [Chart] 温湿度历史曲线
    │   └── [Text] 实时数值表
    │   Width: 12-18 (全屏或更宽)
    │
    └── 🚨 Group: 系统报警监控
        ├── [Text] 主路报警
        ├── [Text] 肥路报警
        └── [Text] 综合状态
        Width: 6 (半屏宽)

布局原则:
控制区: 左侧/上方,操作最频繁
监测区: 中间,信息密度最高
报警区: 右侧/下方,需要醒目提示

4.2 报警状态防弹视觉优化

4.2.1 问题描述

如果直接将报警字段接入 ui_text 节点:
– 正常运行时显示空白或 “”
– 操作人员误以为报警功能失效

4.2.2 解决方案:视觉转换过滤

在数据分发后、接入 ui_text 节点前,增加 Function 节点:

/**
 * 报警防弹过滤器
 * 将空值/undefined 转换为友好的"运行正常"提示
 */

// 兼容 undefined、null、空字符串、纯空格的鲁棒性写法
var val = msg.payload;

if (val === "" || val === undefined || val === null || 
    (typeof val === 'string' && val.trim() === "")) {
    msg.payload = "🟢 运行正常";
    msg.color = "#28a745";  // 绿色
} else {
    msg.payload = "🚨 报警: " + val;
    msg.color = "#dc3545";  // 红色
}

return msg;

4.2.3 UI 效果对比

场景 未优化 优化后
正常 [空白] ❌ 🟢 运行正常 ✅
报警 AM1:堵塞 🚨 报警: AM1:堵塞

4.3 开关状态的数字孪生双向反馈

4.3.1 闭环设计

用户操作 Web Switch S1 ──>
    │
    ├── 下行: Function 打包 ──> MQTT Out ──> MCGS 执行
    │
    └── 上行: MCGS 回传实际状态 ──> MQTT In ──> Function 分发 ──>
                                                        │
                                                        ▼
                                              Web Switch S1 (输入端)
                                                        │
                                              Switch 位置自动同步

4.3.2 Switch 节点关键配置

配置项 作用
Indicator Switch icon shows state of the input 根据回传状态改变位置
Pass through ☐ 取消勾选 阻断循环
On Payload true (Boolean) 与回传数据类型匹配
Off Payload false (Boolean) 与回传数据类型匹配

4.3.3 时序说明

时间轴 →

T0: 用户点击 S1 开关 (请求开启)
    ├── Web Switch 发出 {topic:"S1", payload:true}
    ├── Function 打包 → MQTT 下发
    └── Switch 位置暂时不变 (等待确认)

T1: MCGS 执行完毕,上报 {S1:true, ...}
    ├── MQTT In 接收
    ├── Function 分发 → 输出 7 → Switch 输入
    └── Web Switch 位置变为"开启" ✅

结果: 开关位置反映的是 MCGS 的真实状态,而非用户操作

五、核心注意事项(防坑指南)

5.1 数据类型一致性

症状

  • Switch 不随回传数据变化
  • Debug 看到数据但 UI 无反应

根因

Node-RED Switch 对数据类型敏感:

类型 示例 Switch 匹配
Boolean true ✅ 匹配 On Payload (true)
数字 1 ❌ 不匹配 true
字符串 "true" ❌ 不匹配

解决方案

统一使用 Boolean 类型:
– MCGS 上报: true / false
– Function 分发: d.S1 (原始 Boolean)
– Switch Payload: true / false (Boolean)

5.2 Function 输出数设置

症状

  • 只显示 1 个输出端口
  • 无法连接多个 UI 组件

解决方案

双击 Function 节点 → 底部 Outputs → 改为 39

5.3 Topic 命名一致性

位置 Key/Topic 大小写敏感
MCGS JSON "S1" 大写 S
Node-RED Switch S1 大写 S
Function 检查 msg.topic === "S1" 大写 S

⚠️ s1S1,不一致会导致拦截或失效。

5.4 标定系数核对

常见错误:
– 温度显示 245℃(忘记 ÷10)
– 电导率 0.15(系数用错,应该是 ÷100 而非 ÷1000)

建议建立标定对照表贴在 MCGS 和 Node-RED 旁。


六、调试与排错

6.1 分级调试策略

层级 检查点 方法
通讯层 MQTT 连接 Dashboard → 节点状态指示
协议层 报文格式 Debug 节点查看 payload
逻辑层 Function 执行 node.warn() / node.status()
UI 层 显示效果 浏览器 F12 检查

6.2 常用 Debug 代码

在 Function 节点中添加:

// 查看完整输入
node.warn("输入: " + JSON.stringify(msg));

// 查看特定字段
node.warn("S1 = " + msg.payload.S1 + " (类型: " + typeof msg.payload.S1 + ")");

// 查看 flow 记忆
node.warn("记忆: " + JSON.stringify(flow.get('control_state')));

// 设置节点状态(显示在编辑器中)
node.status({fill:"green", shape:"dot", text:"正常"});

6.3 问题速查表

现象 可能原因 排查方法
开关不响应点击 Pass through 未取消 检查 Switch 配置
开关位置不跟随 Indicator 设置错误 改为 “state of the input”
下发数据不完整 9 参数未凑齐 检查 flow.get(‘control_state’)
传感器数据为 0 标定系数错误 核对 ÷10 / ÷100
报警显示空白 未加防弹过滤 添加空值检查 Function
只有 1 路输出 Outputs 未改 39 双击修改

七、附录:配置速查表与扩展指南

7.1 节点配置汇总

节点 名称 关键配置
ui_switch S1-S7 Topic: S1-S7, Payload: Boolean, Indicator: input, Pass through: ☐
ui_slider Pres1/Freq Topic: Pres1/Freq, Min/Max: 0-100/50
function 控制指令打包 见 2.3.3 代码
function 39通道分发 Outputs: 39, 见 3.4.3 代码
function 报警防弹 见 4.2.2 代码
mqtt out 控制下发 Topic: sub/控制单元
mqtt in 监测接收 Topic: attributes

7.2 扩展更多设备

如需增加 S8、S9:

  1. Node-RED 端:
    // control_state 添加新字段
    "S8": false,
    "S9": false
    
    // 39 路输出改为 41 路
    Outputs: 41
    
  2. MCGS 端:
    • 组态新增开关组件
    • 策略脚本添加 S8/S9 到 JSON
  3. Dashboard:
    • Layout 添加新 Switch
    • Group 宽度调整

7.3 完整流 JSON(可导入)

[
  {
    "id": "control_packer",
    "type": "function",
    "z": "grape_flow",
    "name": "控制指令打包",
    "func": "var control_state = flow.get('control_state') || {\"Freq\":0,\"Pres1\":0,\"S1\":false,\"S2\":false,\"S3\":false,\"S4\":false,\"S5\":false,\"S6\":false,\"S7\":false};\nif (control_state.hasOwnProperty(msg.topic)) {\n    control_state[msg.topic] = msg.payload;\n    flow.set('control_state', control_state);\n} else {\n    node.warn('未知Topic:' + msg.topic);\n    return null;\n}\nmsg.topic = 'sub/控制单元';\nmsg.payload = control_state;\nreturn msg;",
    "outputs": 1,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "libs": [],
    "x": 400,
    "y": 100,
    "wires": [["mqtt_out"]]
  }
]

文档结束

配置过程中如遇问题,请参考第六章调试与排错进行排查。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇