Skip to main content

Node-RED Tafy Nodes

A collection of Node-RED nodes for the Tafy Robot Distributed Operation System (RDOS).

Quick Start​

Get your robot moving in 30 minutes! See our Quick Start Guide.

Documentation​

Software Guides​

Hardware Guides​

Available Nodes​

Autonomous Behaviors​

  • obstacle-avoid - Autonomous obstacle avoidance with simple/advanced modes
  • color-tracker - HSV-based color blob tracking
  • color-follow - Follow colored objects with camera
  • sensor-fusion - Combine multiple sensor readings

Control Components​

  • pid-controller - Generic PID controller with anti-windup
  • motor-control - Differential drive motor control
  • gamepad-input - Game controller input
  • joystick-ui - Web-based joystick
  • keyboard-input - Keyboard teleop control

Hardware Interface​

  • camera-stream - MJPEG/WebRTC camera streaming
  • camera-snapshot - Capture still images
  • camera-discovery - Auto-discover cameras
  • camera-control - Camera settings control
  • nats-pub - Publish to NATS/HAL
  • nats-config - NATS connection config

Installation​

cd ~/.node-red
npm install @tafystudio/node-red-contrib-tafy

Or install directly from the Node-RED palette manager.

Camera Nodes​

tafy-camera-stream​

Connects to a Tafy camera stream and outputs frame data or stream URLs.

Features:

  • MJPEG HTTP streaming
  • WebSocket frame-by-frame delivery
  • WebRTC peer-to-peer streaming
  • Auto-reconnection support
  • Multiple output formats

Example Flow:

[{"id":"cam1","type":"tafy-camera-stream","cameraUrl":"http://camera:8080","streamType":"mjpeg"},
{"id":"template1","type":"template","template":"<img src='{{payload.url}}' />"},
{"id":"ui1","type":"ui_template"}]

tafy-camera-snapshot​

Captures single frames from a Tafy camera.

Features:

  • On-demand snapshot capture
  • Multiple output formats (Buffer, Base64, URL)
  • Metadata inclusion
  • Error handling

Use Cases:

  • Periodic image capture
  • Motion-triggered snapshots
  • Image analysis pipelines

tafy-camera-discovery​

Discovers available cameras on the network.

Features:

  • Automatic camera detection
  • Periodic discovery updates
  • Best camera selection
  • Multiple output formats

Example - Auto-select best camera:

// In a function node after discovery
const cameras = msg.payload.cameras;
const mjpegCamera = cameras.find(cam =>
cam.formats.some(f => f.name.includes('MJPEG'))
);
return { payload: mjpegCamera };

tafy-camera-control​

Controls and queries camera settings.

Current Commands:

  • status - Get camera status and statistics
  • info - Get camera information

Future Commands:

  • configure - Change camera settings
  • start/stop - Control capture state
  • Exposure, white balance, focus control

Example Flows​

1. Dashboard Camera Viewer​

[
{
"id": "inject1",
"type": "inject",
"repeat": "",
"once": true,
"topic": "",
"payload": "true",
"x": 100,
"y": 100
},
{
"id": "discovery1",
"type": "tafy-camera-discovery",
"discoveryUrl": "http://hub:8080",
"outputFormat": "simple",
"x": 250,
"y": 100
},
{
"id": "function1",
"type": "function",
"func": "// Select first camera\nconst camera = msg.payload[0];\nif (camera) {\n flow.set('cameraUrl', `http://${camera.device}:8080`);\n return { payload: true };\n}\nreturn null;",
"x": 400,
"y": 100
},
{
"id": "stream1",
"type": "tafy-camera-stream",
"cameraUrl": "{{flow.cameraUrl}}",
"streamType": "mjpeg",
"x": 550,
"y": 100
},
{
"id": "dashboard1",
"type": "ui_template",
"template": "<img src='{{msg.payload.url}}' style='width:100%' />",
"x": 700,
"y": 100
}
]

2. Motion Detection Alert​

[
{
"id": "motion1",
"type": "mqtt in",
"topic": "sensors/motion",
"x": 100,
"y": 200
},
{
"id": "filter1",
"type": "switch",
"property": "payload",
"rules": [{"t": "true"}],
"x": 250,
"y": 200
},
{
"id": "snapshot1",
"type": "tafy-camera-snapshot",
"cameraUrl": "http://camera:8080",
"outputType": "buffer",
"includeMetadata": true,
"x": 400,
"y": 200
},
{
"id": "notify1",
"type": "function",
"func": "// Send notification with image\nreturn {\n payload: {\n message: 'Motion detected!',\n image: msg.payload,\n timestamp: msg.metadata.timestamp\n }\n};",
"x": 550,
"y": 200
}
]

3. Multi-Camera Monitoring​

[
{
"id": "timer1",
"type": "inject",
"repeat": "30",
"topic": "",
"payload": "discover",
"x": 100,
"y": 300
},
{
"id": "discover1",
"type": "tafy-camera-discovery",
"outputFormat": "full",
"x": 250,
"y": 300
},
{
"id": "split1",
"type": "function",
"func": "// Create snapshot request for each camera\nconst cameras = msg.payload.cameras || [];\nreturn cameras.map(cam => ({\n payload: 'snapshot',\n camera: cam.device,\n url: `http://${cam.device}:8080`\n}));",
"x": 400,
"y": 300
},
{
"id": "snapshot2",
"type": "tafy-camera-snapshot",
"cameraUrl": "{{msg.url}}",
"outputType": "base64",
"x": 550,
"y": 300
},
{
"id": "grid1",
"type": "ui_template",
"template": "<div class='camera-grid'>\n <img src='data:image/jpeg;base64,{{msg.payload}}' />\n <div>{{msg.camera}}</div>\n</div>",
"x": 700,
"y": 300
}
]

Integration with HAL​

These nodes work with the Tafy HAL (Hardware Abstraction Layer) system:

  • Camera nodes publish telemetry to hal.v1.camera.* topics
  • Control commands follow HAL message format
  • Discovery integrates with NATS-based service discovery

Troubleshooting​

Camera not found​

  • Check camera driver is running: curl http://camera:8080/health
  • Verify network connectivity
  • Ensure discovery URL is correct

No stream displayed​

  • Check browser console for errors
  • Verify CORS settings if accessing across origins
  • Try different stream types (MJPEG vs WebSocket)

High latency​

  • Use WebRTC for lowest latency
  • Check network bandwidth
  • Reduce resolution/FPS in camera settings

Contributing​

  1. Fork the repository
  2. Create your feature branch
  3. Add tests for new functionality
  4. Submit a pull request

License​

Apache License 2.0