nodered
SKILL.md
Node-RED
Node-RED is a flow-based programming tool for event-driven applications, enabling visual wiring of nodes to create automation workflows.
Core Concepts
Message Object
Messages flow between nodes via msg object:
{
payload: "data", // Primary data
topic: "category", // Message type/category
_msgid: "abc123" // Auto-generated ID
}
Node Types
- Input: Inject, HTTP In, MQTT In - initiate flows
- Processing: Function, Change, Switch - transform data
- Output: Debug, HTTP Response, MQTT Out - send results
- Utility: Delay, Trigger, Split/Join - control flow
Flow JSON Structure
Flows stored in flows.json:
[
{
"id": "node-uuid",
"type": "inject",
"name": "Timer",
"repeat": "5",
"payload": "hello",
"payloadType": "str",
"x": 100,
"y": 100,
"wires": [["next-node-id"]]
},
{
"id": "next-node-id",
"type": "debug",
"name": "Output",
"active": true,
"complete": "payload",
"x": 300,
"y": 100,
"wires": []
}
]
Key properties:
id: Unique UUIDtype: Node type namex, y: Editor positionwires: Array of arrays mapping outputs to next node inputs
Function Node
Execute JavaScript with full context access:
// Access message
const data = msg.payload;
// Modify message
msg.payload = data.toUpperCase();
msg.timestamp = Date.now();
// Send to output
return msg;
// Multiple outputs
return [msg1, msg2];
// Send nothing
return null;
Context Storage
// Node context (this node only)
context.set("key", value);
const val = context.get("key");
// Flow context (all nodes in flow)
flow.set("counter", 0);
const count = flow.get("counter");
// Global context (all flows)
global.set("config", {});
const cfg = global.get("config");
Async Operations
// Using async/await
const result = await someAsyncFunction();
msg.payload = result;
return msg;
// Using node.send() for async
someAsyncFunction().then(result => {
msg.payload = result;
node.send(msg);
});
return null; // Don't return msg here
Common Nodes
Change Node
Modify message properties without code:
- Set:
msg.payloadto value - Change: Replace text in property
- Move: Rename property
- Delete: Remove property
Switch Node
Route messages based on conditions:
==,!=,<,>,<=,>=contains,matches regexis null,is not nullis of type(string, number, etc.)
Template Node
Mustache templating:
Hello {{payload.name}}!
Temperature: {{payload.temp}}°C
Integrations
MQTT
Subscribe (MQTT In):
Topic: home/sensors/#
QoS: 0/1/2
Output: parsed JSON or string
Publish (MQTT Out):
Topic: home/commands/light
Retain: true/false
QoS: 0/1/2
HTTP
Create endpoint (HTTP In → HTTP Response):
Method: GET/POST/PUT/DELETE
URL: /api/data
Make request (HTTP Request):
Method: GET
URL: https://api.example.com/data
Return: parsed JSON
WebSocket
Real-time bidirectional communication:
- WebSocket In: Listen for messages
- WebSocket Out: Send to clients
Debugging
Debug Node
- Output to sidebar panel
- Show complete msg or specific property
- Add to status bar
Console Logging
// In function node
node.warn("Warning message"); // Yellow, shows in debug
node.error("Error message"); // Red, triggers catch
console.log(msg); // Terminal only
Status Indicators
node.status({
fill: "green", // green, yellow, red, grey
shape: "dot", // dot, ring
text: "connected"
});
node.status({}); // Clear status
Error Handling
Catch Node
Catches errors from nodes in same flow:
[Any Node] → error → [Catch Node] → [Handle Error]
Try/Catch in Function
try {
const result = JSON.parse(msg.payload);
msg.payload = result;
return msg;
} catch (e) {
node.error("Parse failed: " + e.message, msg);
return null;
}
Configuration (settings.js)
Location: ~/.node-red/settings.js
module.exports = {
// Server
uiPort: 1880,
httpAdminRoot: '/admin',
httpNodeRoot: '/api',
// Flows
flowFile: 'flows.json',
credentialSecret: "your-secret-key",
// Security
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "$2b$08$hash...", // bcrypt hash
permissions: "*"
}]
},
// Logging
logging: {
console: { level: "info" }
},
// Context storage
contextStorage: {
default: { module: "memory" },
persistent: { module: "localfilesystem" }
},
// Function node globals
functionGlobalContext: {
moment: require('moment'),
_: require('lodash')
}
};
Home Assistant Integration
Use node-red-contrib-home-assistant-websocket:
Call Service Node
Domain: light
Service: turn_on
Entity: light.living_room
Data: {"brightness": 255}
Entity Node
Monitor state changes:
Entity: sensor.temperature
Output on: state change
Get Entities Node
Query current state:
Search: entity_id contains "light"
Output: array of entities
Reference
- Custom nodes - Full node development guide
- Flow patterns - Common automation patterns
- Home Assistant - HA integration details
Weekly Installs
8
Repository
szkocot/skillsFirst Seen
Jan 28, 2026
Security Audits
Installed on
opencode6
gemini-cli6
codex6
github-copilot5
cursor5
antigravity4