提示
Victron 帮助中心
CAD 在线设计免费
Node-RED · 第一个流程

按电池荷电状态控制 Cerbo GX 继电器

四个节点:读取电池荷电状态(SoC)、带滞回的简单函数、Cerbo GX 继电器 1,以及 Debug 面板中的数据查看。继电器在 30% 时闭合,到 50% 才断开,因此不会因 SoC 波动而频繁切换。文末提供可直接导入的流程。

开始之前

  • 已启用 Node-RED。Cerbo GX 运行 Venus OS Large,并已启用 Node-RED;编辑器地址为 https://venus.local:1881。操作方法:首次启动 Node-RED。
  • GX 中可看到电池监控器。SoC 来自连接到 GX 的电池监控器或 BMS,例如 SmartShunt、BMV 或 Lynx Shunt。如果 GX 不显示荷电状态,Node-RED 也无法获取。
  • 将继电器设为手动模式。按 Victron 要求,继电器只有切换为手动控制后,才能通过 Node-RED 控制。对于 Cerbo GX 继电器:进入 Settings → Integrations → Relays,将功能设为“Manual”。同一菜单中还可设置继电器极性(常开或常闭)。
Cerbo GX:Relay 1 和 Relay 2 端子(NO、COM、NC)位于底部电源接口旁。在 Node-RED 中,Relay 1 对应“Venus relay 1 state”,路径为 /Relay/0/State。
Cerbo GX:Relay 1 和 Relay 2 端子(NO、COM、NC)位于底部,靠近电源接口。在 Node-RED 中,Relay 1 对应“Venus relay 1 state”,路径为 /Relay/0/State。

其他继电器也可通过 Node-RED 控制,但都需要先修改设置:BMV 的继电器选项设为 REM(在 VictronConnect 中);Lynx Shunt VE.Can 的功能设为“Manual control”(在 GX 菜单中);较大型号的 MPPT 控制器和 RS 系列设备设为手动模式(在 VictronConnect 中)。Lynx Smart BMS 的继电器无法通过 Node-RED 控制。MultiPlus 和 Quattro 的报警继电器及 AC-out 2 接触器也无法控制。

您想启动发电机吗?GX 内置通过继电器自动启动和停止发电机的功能,可单独设置启动条件(见 GX 手册的“Generator auto start/stop”章节),无需 Node-RED。下方的 Victron 发电机示例并不直接控制继电器,而是使用 Generator 节点。

此流程的工作原理

SoC % 0 / 1 Battery(输入) /Soc · SoC % 滞回 function · 30 / 50% Relay(输出) /Relay/0/State debug Debug 面板 滞回节点阈值(示例) 闭合(1) 保持不变 断开(0) 0% 30% 50% 100%
节点之间的消息(msg)
请您将指针悬停在示意图元素上,或轻触该元素。
  1. Battery(输入)读取电池监控器的荷电状态,每次变化时发送;未勾选“only changes”时,还会每 5 s 发送一次。
  2. 滞回(function)SoC ≤ 30% → 1,SoC ≥ 50% → 0,两者之间保持不变。仅在状态变化时发送。
  3. Relay(输出)1 使 Cerbo GX 的继电器 1 闭合,0 使其断开(/Relay/0/State)。
  4. debug在 Debug 面板中显示发送给继电器的每个数值。

逐步搭建

  1. 新建标签页。在 Node-RED 编辑器中添加新的流程标签页(工作区上方的“+”按钮),避免此示例与其他流程混在一起。
  2. Battery 节点。从节点面板的 Victron 分类中拖入 Battery 输入节点。在设置中选择您的电池监控器以及“State of charge (%)”测量值。不要勾选“only changes”——这样节点会在 SoC 每次变化时发送,并额外每 5 秒发送一次,因此重启后函数也能很快收到数值。
  3. function 节点。添加普通的 function 节点,将其命名为“滞回”,并粘贴“滞回代码”部分中的代码。将 Battery 节点的输出连接到函数的输入。
  4. Relay 节点。添加 Relay 输出节点,选择“Venus device”和“Venus relay 1 state”(路径为 /Relay/0/State——路径中的编号从 0 开始,因此索引 0 对应继电器 1)。节点根据收到的 msg.payload 设置状态:0 — Open(断开),1 — Closed(闭合)。将函数的输出连接到此节点。
  5. debug 节点。将函数的输出同时连接到 debug 节点。您可以在编辑器右侧的 Debug 面板中查看数值,在“滞回”节点下方查看当前 SoC 和继电器状态。
  6. 部署与测试。点击 Deploy。为避免等待电池放电,可临时添加 inject 节点,设置数值(类型为“number”,例如先输入 25,再输入 55),连接到函数,并检查 Relays 菜单中的继电器是否切换。随后删除 inject,再次点击 Deploy。

滞回代码

如果继电器在同一个阈值(例如 40%)下接通和断开,那么当 SoC 在此数值附近波动时,继电器就会反复切换。滞回将这两个阈值分开:SoC 为 30% 或更低时继电器闭合,只有达到 50% 或更高时才断开。两者之间保持原有状态。函数将此状态保存在节点上下文中,仅在状态变化时发送消息,因此不会每 5 秒向继电器重复发送相同数值。

// 滞回:SoC <= 30 % 时闭合继电器,SoC >= 50 % 时断开。
// 阈值仅为示例,请自行设置。
const PROG_ZAL = 30;
const PROG_WYL = 50;

const soc = msg.payload;
if (typeof soc !== 'number' || isNaN(soc)) return null;  // 无读数:不执行任何操作

const poprzedni = context.get('stan');
let stan = (poprzedni === undefined) ? 0 : poprzedni;
if (soc <= PROG_ZAL) stan = 1;       // 1 = Closed(闭合)
else if (soc >= PROG_WYL) stan = 0;  // 0 = Open(断开)
// 两个阈值之间保持状态不变

node.status({fill: stan ? 'green' : 'grey', shape: 'dot',
             text: 'SoC ' + soc.toFixed(1) + ' %,继电器' + (stan ? '闭合' : '断开')});

if (stan === poprzedni) return null;  // 仅在状态变化时发送
context.set('stan', stan);
msg.payload = stan;
return msg;
SoC函数操作继电器
60%首次读数,50% 或更高 → 发送 0断开
40%两个阈值之间——不发送断开
30%30% 或更低 → 发送 1闭合
45%两个阈值之间——不发送闭合
50%50% 或更高 → 发送 0断开
  • 反向逻辑。您想在 SoC 较低时断开负载,而不是接通负载吗?将代码中包含阈值的两行里的 1 和 0 互换,或将电路连接到继电器的另一触点——用 NC 代替 NO。
  • 无读数。如果 msg.payload 不是数值(例如电池监控器已断开连接),函数不会发送任何消息,继电器保持原有状态。
  • 重启后。节点上下文默认保存在 GX 设备的 RAM 中,重启或断电时会丢失。重启后的首次读数始终会设置继电器状态:如果 SoC 位于两个阈值之间,则设置为 0(断开)——即使重启前处于闭合状态也是如此。如何保留上下文,请参阅“注意事项”部分。

可直接导入的流程

以下是同一流程的 JSON 格式。Victron 节点的构建方式与 node-red-contrib-victron 节点库文档中的示例一致。

  1. 复制下方整个代码块,包括括号 [ 和 ]。
  2. 导入。在编辑器中打开菜单(右上角按钮)→ Import,或按 Ctrl-I,粘贴文本并点击 Import。流程将出现在新的“按 SoC 控制继电器”标签页中。
  3. 选择您的电池监控器。打开“电池 SoC”节点,从列表中选择您的电池监控器以及“State of charge (%)”。
  4. 在“GX 继电器 1”节点中检查继电器,根据需要修改函数中的阈值,然后点击 Deploy。
导入后选择您自己的设备

Battery 节点指向 Victron 文档中的示例 SmartShunt(com.victronenergy.battery/277)。末尾编号因系统而异,取决于设备及连接方式。在节点中选择您自己的电池监控器之前,函数不会收到 SoC,继电器也不会切换。

[
{"id":"c24a5c0f10000001","type":"tab","label":"按 SoC 控制继电器","disabled":false,"info":"30/50 % 滞回控制 - cpv24.pl 示例"},
{"id":"c24a5c0f10000002","type":"victron-input-battery","z":"c24a5c0f10000001","service":"com.victronenergy.battery/277","path":"/Soc","serviceObj":{"service":"com.victronenergy.battery/277","name":"SmartShunt(示例 - 请选择您的设备)"},"pathObj":{"path":"/Soc","type":"float","name":"State of charge (%)"},"initial":"","name":"电池 SoC","onlyChanges":false,"x":150,"y":120,"wires":[["c24a5c0f10000003"]]},
{"id":"c24a5c0f10000003","type":"function","z":"c24a5c0f10000001","name":"滞回控制","func":"// 滞回控制:SoC <= 30 % 时闭合继电器,SoC >= 50 % 时断开。\n// 阈值仅为示例 - 请设置您自己的阈值。\nconst PROG_ZAL = 30;\nconst PROG_WYL = 50;\n\nconst soc = msg.payload;\nif (typeof soc !== 'number' || isNaN(soc)) return null;  // 无读数:不执行操作\n\nconst poprzedni = context.get('stan');\nlet stan = (poprzedni === undefined) ? 0 : poprzedni;\nif (soc <= PROG_ZAL) stan = 1;       // 1 = Closed(闭合)\nelse if (soc >= PROG_WYL) stan = 0;  // 0 = Open(断开)\n// 两个阈值之间保持状态不变\n\nnode.status({fill: stan ? 'green' : 'grey', shape: 'dot',\n             text: 'SoC ' + soc.toFixed(1) + ' %,继电器' + (stan ? '闭合' : '断开')});\n\nif (stan === poprzedni) return null;  // 仅在状态变化时发送\ncontext.set('stan', stan);\nmsg.payload = stan;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":120,"wires":[["c24a5c0f10000004","c24a5c0f10000005"]]},
{"id":"c24a5c0f10000004","type":"victron-output-relay","z":"c24a5c0f10000001","service":"com.victronenergy.system/0","path":"/Relay/0/State","serviceObj":{"service":"com.victronenergy.system/0","name":"Venus device"},"pathObj":{"path":"/Relay/0/State","type":"enum","name":"Venus relay 1 state","enum":{"0":"Open","1":"Closed"},"writable":true},"initial":"","name":"GX 继电器 1","onlyChanges":true,"x":600,"y":120,"wires":[]},
{"id":"c24a5c0f10000005","type":"debug","z":"c24a5c0f10000001","name":"继电器状态","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":180,"wires":[]}
]

Victron 内置示例

Victron 节点面板内置示例库:菜单(右上角)→ Import → Examples → node-red-contrib-victron。同样的流程也可在节点面板的 wiki 页面查看,无需打开编辑器。其中三个示例与本页示例最接近:

示例功能与本页流程的区别
Threshold Control输入值超过 ON 阈值时开启输出,低于 OFF 阈值时关闭输出。每次切换前都会等待设定的延迟时间(ON/OFF delay)。阈值和手动控制位于仪表板上。控制同一个继电器 1(/Relay/0/State),但输入是 System 节点的电池电压(/Dc/Battery/Voltage),而非 SoC,并增加了延迟。需要额外模块:node-red-dashboard、node-red-contrib-ui-led 和 node-red-contrib-countdown。
Run generator at certain time when SOC is below 50%每天 18.00 检查已保存的 SoC。如果电量较低,则启动发电机运行 45 分钟:trigger 节点先发送 1,45 分钟后发送 0。SoC 通过 change 节点保存到上下文 flow.SOC。控制 Generator 节点(Manual Start),而非继电器。注意:说明写的是“低于 50%”,但该流程中的 switch 节点检查的是“小于或等于 50”(名称为“Start if SOC is <= 50%”)。
Only messages at regular intervalschange 节点将最新值保存到上下文,inject 节点按固定间隔读取该值。当您需要按固定周期获取最新值,而不受输入节点发送时间影响时,此流程很有用。

所有 Victron 输入和输出节点的说明:Node-RED 中的 Victron 节点。

注意事项

  • 重启后的上下文。要在重启后保留上下文,可参考 Victron FAQ 中的说明,在 /data/home/nodered/.node-red/settings-user.js 文件中设置 contextStorage(使用 localfilesystem 模块,每 300 s,即每 5 分钟保存一次)。如果将其设为默认上下文存储,函数代码无需修改即可运行。Victron 提醒不要过于频繁地写入,以免造成闪存磨损。
  • 安全模式。如果修改后的流程导致 GX 负荷过高或运行异常,请在 GX 菜单中以安全模式(safe mode)启用 Node-RED。Node-RED 将启动,但不运行流程,您可以修改流程,点击 Deploy 后才会运行。
  • 重启 Node-RED。在 GX 菜单的 Venus OS Large Features → Node-RED 中,关闭后重新开启 Node-RED。
  • 流程中的时间。在按时间控制的示例中,例如 18.00 启动发电机,Node-RED 使用 Remote Console 中设置的时区。更改时区后,需要重启 Node-RED。
自动化控制,不是安全保护

Node-RED 流程不能替代 BMS、保险丝或断路器——GX 重启或流程出错时,继电器可能停留在非预期状态。连接到继电器的电路必须在两种状态下都安全。Victron 不为使用 Node-RED 实现高级功能的系统提供技术支持。

适用设备

资料来源

继续阅读:Cerbo GX 上的 Node-RED — 所有文章 · 首次启动 · Victron 节点 · Cerbo GX

内容已与 Victron Energy 文档(数据表和说明书)核对,截至 2026年9月22日。报告内容错误 · 修订记录