node-red-contrib-cip 1.2.0
Connects node-red with Crestron processors though CIP protocol
node-red-contrib-cip
Professional Node-RED nodes for seamless integration with Crestron control systems through the CIP (Crestron Internet Protocol). This package provides both client and server nodes, enabling bidirectional communication with Crestron processors.
š¬ Reverse-Engineered Protocol: This implementation is based on comprehensive reverse-engineering of the proprietary Crestron Internet Protocol (CIP), achieved through extensive network traffic analysis, packet inspection, and protocol behavior study. The library provides a complete, independent implementation of the CIP protocol stack.
⨠Features
š Dual Node Architecture
- CIP Client Node: Connect Node-RED to Crestron processors as a client
- CIP Server Node: Allow Crestron processors to connect to Node-RED as clients
š” Complete Protocol Support
- Digital Joins: Boolean control (lights, relays, switches)
- Analog Joins: Numeric control (volume, dimming, position: 0-65535)
- Serial Joins: String communication (text, commands, feedback)
- Smart Objects: Advanced UI controls with intelligent state management
- Pulse Commands: Momentary button presses with configurable timing
- Real-time Feedback: Instant status updates from Crestron systems
š Enterprise Features
- Automatic Reconnection: Robust connection management with configurable timeouts
- Smart Object Support: Advanced UI controls with dynamic lists, keypads, and button arrays
- Heartbeat Monitoring: Built-in ping/pong mechanism for connection health
- Packet-level Debugging: Comprehensive logging for troubleshooting
- State Synchronization: Full system state retrieval on connection
- TypeScript Support: Complete type definitions included
š§ Development Tools
- Docker Environment: Pre-configured development setup
- Debug Logging: Detailed CIP protocol inspection
š¦ Installation
Via Node-RED Palette Manager
- Open Node-RED in your browser
- Go to Menu ā Manage Palette
- Click the "Install" tab
- Search for
node-red-contrib-cip
- Click "Install"
Via npm
cd ~/.node-red
npm install node-red-contrib-cip
Via Docker (Development)
git clone https://github.com/moty66/node-red-contrib-cip.git
cd node-red-contrib-cip
docker-compose up --build
Access Node-RED at http://localhost:1880 with the plugin pre-installed.
šÆ Quick Start
1. CIP Client Setup (Node-RED ā Crestron)
Crestron Configuration:
// In your Crestron program, add an Ethernet device
ETHERNET_SERVER MyServer {
DEVICE = "192.168.1.100:41794"; // Node-RED IP
IPID = 04;
}
Node-RED Configuration:
// Node configuration
{
name: "Crestron Processor",
host: "192.168.1.50", // Crestron processor IP
port: 41794, // CIP port (default)
ipid: "04", // Must match Crestron IPID (hex)
reconnect: true,
timeout: 10000
}
2. CIP Server Setup (Crestron ā Node-RED)
Node-RED Configuration:
// Server node configuration
{
name: "Crestron Server",
port: 41794, // Listening port
ipid: "04", // Server IPID (hex)
debug: false,
timeout: 10000
}
Crestron Configuration:
// Configure Crestron to connect to Node-RED server
ETHERNET_CLIENT MyClient {
DEVICE = "192.168.1.100:41794"; // Node-RED server IP:port
IPID = 04;
}
š” Usage Examples
Digital Control (Lights, Relays)
// Turn on light (Digital Join 1)
msg.payload = {
type: "event",
payload: {
type: "digital",
join: 1,
data: true, // true = on, false = off
},
};
Analog Control (Volume, Dimming)
// Set volume to 75% (Analog Join 5)
msg.payload = {
type: "event",
payload: {
type: "analog",
join: 5,
data: 49152, // 75% of 65535
},
};
Serial Communication (Text, Commands)
// Send text to display (Serial Join 10)
msg.payload = {
type: "event",
payload: {
type: "serial",
join: 10,
data: "Conference Room Available",
},
};
Button Press Simulation
// Simulate 500ms button press (Digital Join 3)
msg.payload = {
type: "event",
payload: {
type: "pulse",
join: 3,
time: 500, // milliseconds
},
};
System Synchronization
// Request current state of all joins
msg.payload = {
type: "sync",
};
šļø Smart Objects
Smart Objects provide advanced UI control capabilities beyond basic joins, allowing for complex interface elements like dynamic lists, button arrays, and interactive controls. Smart Objects are available with the CIP Server node.
Supported Smart Object Types
š Dynamic List
Interactive lists with programmable content and selection handling.
// Register a dynamic list
msg.payload = {
type: "registerSmartObject",
payload: {
smartObjectId: 101,
profile: "dynamicList",
config: {
maxItems: 20,
allowMultipleSelection: false,
},
},
};
// Set list item count
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 101,
action: "setItemCount",
itemCount: 5,
},
};
// Set list item text
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 101,
action: "setItemText",
itemIndex: 1,
text: "Living Room",
},
};
// Enable/disable list item
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 101,
action: "setItemEnabled",
itemIndex: 1,
enabled: true,
},
};
š Page Reference
Multi-page navigation controls with page switching and button management.
// Register a page reference
msg.payload = {
type: "registerSmartObject",
payload: {
smartObjectId: 102,
profile: "pageReference",
config: {
totalPages: 5,
showNavButtons: true,
},
},
};
// Select a page
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 102,
action: "selectPage",
pageNumber: 3,
},
};
// Enable/disable navigation button
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 102,
action: "setButtonEnabled",
buttonNumber: 1,
enabled: false,
},
};
š Button List
Arrays of programmable buttons with individual text and state control.
// Register a button list
msg.payload = {
type: "registerSmartObject",
payload: {
smartObjectId: 103,
profile: "buttonList",
config: {
buttonCount: 8,
allowToggle: true,
},
},
};
// Set button text
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 103,
action: "setText",
buttonIndex: 1,
text: "Power",
},
};
// Enable/disable button
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 103,
action: "setEnabled",
buttonIndex: 1,
enabled: true,
},
};
š¢ Keypad
Numeric input controls with display feedback and key simulation.
// Register a keypad
msg.payload = {
type: "registerSmartObject",
payload: {
smartObjectId: 104,
profile: "keypad",
config: {
allowDecimal: true,
maxValue: 999,
minValue: 0,
},
},
};
// Send key press
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 104,
action: "sendKey",
keyValue: "5",
},
};
// Set display text
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 104,
action: "setDisplay",
displayText: "125",
},
};
// Enable/disable keypad
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 104,
action: "setEnabled",
enabled: true,
},
};
Smart Object Events
Smart Objects generate specialized events that provide context about user interactions:
// Smart Object event output
{
"topic": "smartObject",
"payload": {
"type": "smartObject",
"smartObjectId": 101,
"join": 1,
"data": {
"action": "itemSelected",
"itemIndex": 3,
"itemText": "Kitchen",
"currentPage": 1
},
"timestamp": "2025-08-16T10:30:00.000Z"
}
}
Advanced Smart Object Features
State Tracking
// Get current page of a page reference
msg.payload = {
type: "getSmartObjectState",
payload: {
smartObjectId: 102,
property: "currentPage",
},
};
// Get all registered Smart Objects
msg.payload = {
type: "getRegisteredSmartObjects",
};
Batch Operations
// Configure multiple items at once
msg.payload = {
type: "smartObject",
payload: {
smartObjectId: 101,
action: "batchSetItems",
items: [
{ index: 1, text: "Zone 1", enabled: true },
{ index: 2, text: "Zone 2", enabled: true },
{ index: 3, text: "Zone 3", enabled: false },
],
},
};
š Node Outputs
Output 1: Join Events
Real-time events from Crestron processor:
// Digital join feedback
{
payload: {
join: 1,
data: true,
type: "digital"
}
}
// Analog join feedback
{
payload: {
join: 5,
data: 32768,
type: "analog"
}
}
// Serial join feedback
{
payload: {
join: 10,
data: "Status: Online",
type: "serial"
}
}
// Smart Object interaction
{
payload: {
join: 1,
data: {
smartObjectId: 101,
action: "itemSelected",
itemIndex: 3,
itemText: "Kitchen",
currentPage: 1
},
type: "smartObject"
}
}
Output 2: Connection Status
System events and connection status:
// Connection established
{ connected: true }
// Connection lost
{ connected: false, error: "Connection timeout" }
// Update events
{ connected: true, update: { status: "ready" } }
// Server-specific: client connected
{ connected: true, clientConnected: true }
šļø Smart Object Configuration
Smart Objects require specific configuration in both Node-RED and Crestron Studio for proper operation.
Crestron Studio Setup
Add Smart Object to Your Project:
- In Crestron Studio, add desired Smart Objects to your project - Configure Smart Object IDs (typically 101-199) - Program SIMPL logic to handle Smart Object events
Smart Object ID Mapping:
Smart Object Type Suggested ID Range Purpose Dynamic Lists 101-110 Room/Zone selection Page References 111-120 Multi-page navigation Button Lists 121-130 Function button arrays Keypads 131-140 Numeric input controls SIMPL Programming Example:
// For Dynamic List Smart Object ID 101 Smart_Object_101.Item_Clicked -> [Your logic here] Smart_Object_101.Current_Item_Text$ -> [Process selected item]
Node-RED Configuration
Smart Objects must be registered before use:
// Register Smart Objects on connection
msg.payload = [
{
type: "registerSmartObject",
payload: {
smartObjectId: 101,
profile: "dynamicList",
config: { maxItems: 20 },
},
},
{
type: "registerSmartObject",
payload: {
smartObjectId: 102,
profile: "pageReference",
config: { totalPages: 5 },
},
},
];
Configuration Profiles
Dynamic List Profile
{
maxItems: 50, // Maximum number of items
allowMultipleSelection: false, // Allow multi-select
enableScrolling: true, // Enable scrolling
itemHeight: 30 // Item height in pixels
}
Page Reference Profile
{
totalPages: 10, // Total number of pages
showNavButtons: true, // Show navigation buttons
enableSwipeGestures: true, // Enable swipe navigation
loopPages: false // Loop from last to first page
}
Button List Profile
{
buttonCount: 12, // Number of buttons
allowToggle: true, // Allow toggle state
buttonStyle: "raised", // "raised" or "flat"
columns: 3 // Number of columns
}
Keypad Profile
{
allowDecimal: true, // Allow decimal input
maxValue: 9999, // Maximum value
minValue: 0, // Minimum value
maxDigits: 4, // Maximum digits
showDisplay: true // Show numeric display
}
š§ Configuration Options
Parameter | Description | Default | Required |
---|---|---|---|
name | Display name for the node | "Crestron" | No |
host | Crestron processor IP address | - | Yes (Client) |
port | CIP protocol port | 41794 | Yes |
ipid | Hexadecimal IPID value | "04" | Yes |
reconnect | Enable automatic reconnection | true | No |
timeout | Connection timeout (ms) | 10000 | No |
debug | Enable packet-level debugging | false | No |
š ļø Development
Local Development Setup
Clone the repository:
git clone https://github.com/moty66/node-red-contrib-cip.git cd node-red-contrib-cip
Start development environment:
docker-compose up --build
Access Node-RED: Open http://localhost:1880 in your browser
Enable debug logging:
DEBUG=CIP* node-red
Project Structure
node-red-contrib-cip/
āāā lib/node-cip/ # Core CIP protocol library
ā āāā cip.js # CIP client implementation
ā āāā cip-server.js # CIP server implementation
ā āāā helpers/ # Protocol helpers
ā ā āāā cip-input.helper.js # Message parsing
ā ā āāā cip-output.helper.js # Message building
ā āāā constants/ # Protocol constants
ā āāā interfaces/ # TypeScript interfaces
āāā node-red-contrib-cip.js # Client node implementation
āāā node-red-contrib-cip.html # Client node UI
āāā node-red-contrib-cip-server.js # Server node implementation
āāā node-red-contrib-cip-server.html# Server node UI
āāā docker-compose.yml # Development environment
āāā package.json # Package configuration
Making Changes
# For code changes
docker-compose restart
# For package.json changes
docker-compose down && docker-compose up --build
š Protocol Implementation Details
Reverse Engineering Achievement
This library represents a complete reverse-engineering of Crestron's proprietary CIP protocol, accomplished through:
- Network Traffic Analysis: Deep packet inspection of Crestron-to-Crestron communications
- Protocol State Mapping: Understanding connection handshakes, authentication, and state management
- Message Format Decoding: Binary protocol structure analysis and documentation
- Timing Behavior Study: Heartbeat intervals, timeout handling, and reconnection logic
- Join Type Implementation: Digital, analog, serial, and unicode message formats
Technical Specifications
Feature | Implementation |
---|---|
Protocol Version | CIP (Crestron Internet Protocol) |
Transport | TCP/IP |
Default Port | 41794 |
Message Format | Binary protocol with custom headers |
Heartbeat | 5-10 second ping intervals |
Authentication | IPID-based device identification |
Join Types | Digital, Analog, Serial, Unicode |
Reconnection | Configurable automatic retry logic |
Message Types Supported
0x00
: ACK0x01
: Server Sign-on0x02
: Connection Accepted0x04
: Connection Refused0x05
: Join Event0x0a
: Client Sign-on0x0d
: Ping0x0e
: Pong0x0f
: Who Is0x12
: Unicode
šØ Troubleshooting
Common Issues
1. Connection Refused
Error: Connection refused by Crestron processor
Solutions:
- Verify IPID matches between Node-RED and Crestron program
- Check that the IPID exists in Crestron's IP table
- Ensure network connectivity (ping test)
- Verify port 41794 is not blocked by firewall
2. No Response from Joins
Joins not responding to commands
Solutions:
- Verify join numbers are correct (1-based indexing)
- Check Crestron program logic for join assignments
- Enable debug logging:
DEBUG=CIP* node-red
- Confirm join types match (digital/analog/serial)
3. Frequent Disconnections
Connection drops repeatedly
Solutions:
- Increase timeout value in node configuration
- Check network stability and latency
- Verify Crestron processor is not overloaded
- Review debug logs for specific error patterns
Debug Mode
Enable comprehensive debugging:
# Start Node-RED with debug logging
DEBUG=CIP* node-red
# Docker environment
docker-compose up # DEBUG=* already configured
Debug Output Example:
CIP ## connecting. { host: '192.168.1.50', port: 41794, ipid: 4 }...
CIP ## connection opened
CIP <= ipid 4
CIP => accepted
CIP <= ping request n° 1
CIP => pong
CIP => digital 1: High
Network Requirements
- Connectivity: Node-RED and Crestron processor must be on same network or routable
- Firewall: Port 41794 must be open for TCP connections
- Latency: Low-latency network recommended for real-time control
- Bandwidth: Minimal bandwidth required (~1-10 Kbps typical)
š¤ Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Workflow
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Reporting Issues
- Use GitHub Issues for bug reports
- Include debug logs when possible
- Specify Node-RED and Crestron firmware versions
- Provide network configuration details
š License
This project is licensed under the ISC License - see the LICENSE file for details.
š Acknowledgments
- Crestron Electronics: For creating innovative control systems that inspired this project
- Node-RED Community: For the excellent platform and development tools
- Open Source Community: For protocols, libraries, and inspiration
š Support
- GitHub Issues: Report bugs and request features
- NPM Package: node-red-contrib-cip
Built with ā¤ļø by Motaz Abutihab
Bringing Crestron control systems into the Node-RED ecosystem through innovative protocol reverse-engineering.