node-red-contrib-nhc2-z2m-light 0.4.0
Node-RED node to convert NHC2 light payloads to Zigbee2MQTT set commands with shared rate-limit config.
node-red-contrib-nhc2-z2m-light
A small Node-RED node that converts NHC2 light-style payloads into Zigbee2MQTT /set commands and sends them at a rate-limited pace using an internal FIFO queue.
Dependencies
This module is designed to be used together with:
node-red-contrib-zigbee2mqtt(provideszigbee2mqtt-out) — version >= 2.7.5node-red-contrib-nhc2(upstream NHC2 message source) — version >= 1.25.4
They are listed as dependencies/peers in package.json to make intent explicit.
Nodes
nhc2 - z2m (category: function)
Purpose
- Accepts partial NHC2 updates (only the changed fields)
- Remembers the last known values per device
- Builds a Zigbee2MQTT
/setcommand payload that is “complete enough” when needed (e.g. onOn, mode changes) - Queues commands and enforces a minimum interval (rate-limit) between sends
- Merges updates for a lamp that is still waiting in the queue: only its newest state is sent, so the queue never holds more than one item per lamp
Input
msg.device(recommended): Zigbee2MQTT friendly name for the target device (or group)- Wired straight from an nhc2-input node,
msg.deviceis the NHC2 device object instead. The node then remembers the state per NHC2 device (by itsUuid) and usesmsg.topic(the NHC2 device name) as the name. Set the Zigbee2MQTT target in thezigbee2mqtt-outnode.
- Wired straight from an nhc2-input node,
msg.payload: object that can contain any subset of:
{
"Status": "On",
"Brightness": "100",
"ColorMode": "TunableWhite",
"TunableWhite": "cwww(4422,100)",
"Color": "hsv(12,100,100)"
}
Notes:
TunableWhiteiscwww(<kelvin>,<pct>)— the<pct>part is ignored (brightness controls dimming).
Output (to zigbee2mqtt-out)
msg.topic= friendly namemsg.payload= Zigbee2MQTT/setcommand, e.g.
{
"transition": 1.0,
"state": "ON",
"brightness": 254,
"color_temp": 226
}
Shared configuration: nhc2-z2m-config
Create one or more configs and select them from the node. This makes it easy to change the rate-limit for multiple nodes at once.
Config fields:
- Rate-limit (ms): minimum interval between sends (e.g. 1000ms = max 1 msg/sec)
- Transition (seconds): always included in every outgoing command (decimal)
- Rate window (ms): window for msg/sec calculation shown in status (default 10 seconds)
Shared vs per-node rate-limit
Each nhc2-z2m-config has a checkbox:
- Shared rate-limit = enabled: one shared queue + rate-limit for all nodes using that config (good for groups).
- Shared group (optional): if set, any configs with the same group name share ONE FIFO queue + limiter, even if they are different config instances.
- Shared rate-limit = disabled: each node maintains its own queue + rate-limit even if they share the same config (good when devices should not block each other).
Status text
The node shows a status line like:
Q:3 0.8/s RL:1000ms ON B:70% CT:226m HS:12,100 M:white
Q: queue lengthx/s: average messages per second over the last 10 seconds (configurable)RL: rate-limit in msON/OFF, brightness %, CT (mired), HS (h,s), mode: last remembered state
Status icon color reflects the configured rate-limit:
- Green: <= 1000ms
- Yellow: 1001–2000ms
- Red: > 2000ms
Install (local dev)
From your Node-RED user directory (typically ~/.node-red):
cd ~/.node-red
npm install /path/to/node-red-contrib-nhc2-z2m-light
Then restart Node-RED.
Changelog
0.4.0
- New: updates for a lamp that is still waiting in the queue are merged into its waiting item (keeping its place) instead of being queued again. Only the newest state is sent; an Off replaces the waiting item, an On adds to it. The queue holds at most one item per lamp, so a busy moment no longer sends outdated in-between states, the delay stays bounded (lamps × rate-limit) and the 60 s stale-item drop can't hit legitimate commands. Measured on a real busy minute (27 NHC events for 8 lamps): 21 instead of 27 Zigbee commands, longest delay 14 s instead of 25 s.
- Fix: fed straight from an nhc2-input node (
msg.device= NHC2 device object), every lamp was remembered under the same key"[object Object]". With a shared config all lamps shared one memory, so a lamp switched on with only{"Status":"On"}got the brightness and colour temperature of whichever device came through last. The memory is now kept per NHC2 device (Uuid). - Fix: the status line shows the last device of this node, not of any node sharing the config.
License
MIT