Step 7: Connect Your First Device

Bridge your local network to ControlBird and bring live device data into the cloud.

Full reference

For complete details, field tables, and limitations, see the Device Manager reference.

The Network Challenge

Your ControlBird node runs in the cloud, but your devices (thermostats, PLCs, sensors) are on your local network. The cloud can't directly reach 192.168.1.100: that address only exists inside your home or facility.

Your Local Network
Thermostat
192.168.1.100
PLC
192.168.1.101
Sensor
192.168.1.102
NAT / Firewall
Cloud
ControlBird Node
node.example.com

To bridge this gap, you'll create a reverse SSH tunnel from your local network to your cloud node. This tunnel makes your local devices appear as if they're directly connected to the node.

Understanding Device Connections

Connecting a device in ControlBird involves three parts:

1
SSH Tunnel: the secure bridge between your local network and the cloud. Forwards protocol ports (Modbus 502, MQTT 1883, etc.) to your node.
2
Controller: the protocol connection configuration. Points to localhost since the tunnel makes devices appear local to the node.
3
Mapper: which data points to read. Maps device registers/topics to entities in ControlBird's database.

Step 1: Enable SSH Tunnel on Your Node

First, enable the SSH tunnel feature on your node. Go to the Control Plane Dashboard and select your node.

Enable the Tunnel

In the node settings, locate the SSH Tunnel section and click Enable. This provisions:

  • A TLS certificate for secure connections
  • An SSH endpoint at ssh-{your-node}.controlbird.io
  • An authentication token for tunnel connections

Works on Restrictive Networks

The tunnel connects over port 443 using TLS, so it works even on networks that block SSH port 22: to the network it looks like normal HTTPS traffic.

Copy Your Connection Details

After enabling, you'll see your tunnel credentials:

SSH Hostssh-mynode-network-user.controlbird.io
Port443
Usernamecontrolbird
Token••••••••••••••••

Step 2: Establish the Tunnel

From a computer or gateway device on your local network, establish the SSH tunnel. This creates reverse port forwards that expose your local devices to the cloud node.

Docker Tunnel (Recommended)

The easiest way to set up a persistent, auto-reconnecting tunnel is with the controlbird/tunnel Docker image. One command is all you need:

docker run -d --restart always \
  --name controlbird-tunnel \
  -e SSH_HOST=ssh-mynode-network-user.controlbird.io \
  -e SSH_PASSWORD=your-token-here \
  -e TUNNELS=R:502:192.168.1.100:502 \
  controlbird/tunnel

Understanding the TUNNELS Variable

Each entry in TUNNELS follows the format direction:nodePort:deviceHost:devicePort.
R: prefix = reverse tunnel (expose a local device to the cloud)
L: prefix = forward tunnel (access a cloud service from local)
Separate multiple forwards with commas.

Forwarding Multiple Devices

List additional forwards in the TUNNELS variable, separated by commas:

docker run -d --restart always \
  --name controlbird-tunnel \
  -e SSH_HOST=ssh-mynode-network-user.controlbird.io \
  -e SSH_PASSWORD=your-token-here \
  -e TUNNELS=R:502:192.168.1.100:502,R:503:192.168.1.101:502,R:1883:192.168.1.50:1883 \
  controlbird/tunnel
Node PortLocal DeviceProtocol
502192.168.1.100:502Modbus (Thermostat)
503192.168.1.101:502Modbus (PLC)
1883192.168.1.50:1883MQTT Broker

Docker Compose

If you prefer Docker Compose, add this to your docker-compose.yml:

services:
  tunnel:
    image: controlbird/tunnel
    restart: always
    environment:
      SSH_HOST: ssh-mynode-network-user.controlbird.io
      SSH_PASSWORD: your-token-here
      TUNNELS: R:502:192.168.1.100:502,R:1883:192.168.1.50:1883

Gateway Devices

The Docker tunnel is ideal for Raspberry Pi, NAS, or any gateway device on your network. A single docker run command gives you a persistent, auto-reconnecting tunnel with no extra configuration: no sshpass, openssl, or systemd setup required.

Advanced: Manual SSH Commands

If Docker is not available, you can establish the tunnel with raw SSH commands.

Basic Tunnel Command

Open a terminal and run:

ssh -o "ProxyCommand=openssl s_client -connect ssh-mynode-network-user.controlbird.io:443 -servername ssh-mynode-network-user.controlbird.io -quiet" \
    -R 502:192.168.1.100:502 \
    controlbird@localhost

When prompted, paste your authentication token as the password.

Understanding the Command

-o "ProxyCommand=...": routes SSH through TLS on port 443
-R 502:192.168.1.100:502: forwards port 502 on the node to your local Modbus device
controlbird@localhost: the tunnel user (localhost because we're proxying)

Forwarding Multiple Devices

Add multiple -R flags to forward several devices through one tunnel:

ssh -o "ProxyCommand=openssl s_client -connect ssh-mynode-network-user.controlbird.io:443 -servername ssh-mynode-network-user.controlbird.io -quiet" \
    -R 502:192.168.1.100:502 \
    -R 503:192.168.1.101:502 \
    -R 1883:192.168.1.50:1883 \
    controlbird@localhost

Running as a Persistent Service (systemd)

For production use without Docker, run the tunnel as a systemd service that reconnects automatically:

# /etc/systemd/system/controlbird-tunnel.service
[Unit]
Description=ControlBird SSH Tunnel
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/usr/bin/ssh -N -o "ExitOnForwardFailure=yes" \
    -o "ProxyCommand=openssl s_client -connect ssh-mynode-network-user.controlbird.io:443 -servername ssh-mynode-network-user.controlbird.io -quiet" \
    -R 502:192.168.1.100:502 \
    controlbird@localhost

[Install]
WantedBy=multi-user.target

Step 3: Open the Device Manager

With the tunnel established, open ControlBird and click the logo in the taskbar, then select Device Manager. This app manages all your device connections and data mappings.

Device Manager empty state
Click to enlarge
The Device Manager showing the Controllers and Mappers panels

Supported Protocols

ControlBird supports multiple industrial and IoT protocols:

Modbus TCP
Energy monitors, thermostats, PLCs, industrial sensors
Port 502
MQTT
Smart sensors, DIY devices, home automation bridges
Port 1883
OPC UA
Industrial equipment, factory automation, process control
Port 4840
BACnet
Building automation, HVAC systems
Port 47808
DNP3
Utility SCADA, power grids, water treatment
Port 20000

Step 4: Create a Controller

Click "Add Controller" and select your protocol type. We'll use Modbus TCP as an example.

Add controller wizard
Click to enlarge
Select your device's protocol from the list

Controller Configuration

Since your tunnel forwards device ports to localhost on the node, configure the controller to connect locally:

FieldDescriptionExample
NameA friendly name for this connectionLiving Room Thermostat
HostAlways localhost when using SSH tunnellocalhost
PortThe port you forwarded in your SSH command502
Unit IDModbus slave address (usually 1)1
Poll IntervalHow often to read data (milliseconds)1000 (= 1 second)
Controller configuration form
Click to enlarge
Configure the controller to connect via your tunnel

Host Must Be localhost

When using SSH tunnels, always set the host to localhost, not the device's actual IP address. The tunnel makes remote devices appear as local ports on the node.

Connection Status

After saving, the controller will attempt to connect through your tunnel. Watch the status indicator:

Connected: successfully communicating through the tunnel
Connecting: attempting to establish connection
Error: connection failed (check tunnel and port forwarding)

Step 5: Create a Mapper

With the controller connected, add a Mapper to read specific data points. Click "Add Mapper" under your controller.

Mapper Configuration

Each mapper reads one piece of data from your device and stores it in ControlBird:

FieldDescriptionExample
NameWhat this data point representsCurrent Temperature
Register TypeModbus register type to readHolding Register (HR)
AddressRegister address from device documentation100
Data TypeHow to interpret the raw dataFloat32
Target EntityWhere to store this value in the database/Home/LivingRoom/Temperature
Mapper configuration form
Click to enlarge
Configure which register to read and where to store the value

Where Do I Find Register Addresses?

Register addresses come from your device's documentation (usually called a "Modbus register map" or "point list"). Search for "[your device name] modbus registers" or check the manufacturer's website. Common examples: temperature at register 100, humidity at 102, setpoint at 200.

Common Modbus Data Types

Int16
16-bit integer (-32768 to 32767)
UInt16
16-bit unsigned (0 to 65535)
Float32
32-bit floating point (decimals)
Bool
Single bit (on/off, true/false)

Step 6: Verify the Data

Once your mapper is active, you'll see live values in the Device Manager:

Device Manager showing live data
Click to enlarge
The Value column updates in real-time as your device reports data

Confirm in Database Browser

Open the Database Browser and navigate to your target entity. You should see the field value updating at your configured poll interval:

Verify data in Database Browser
Click to enlarge
Your device data now appears in the entity tree with real-time updates

Testing Your Setup

Change something on your physical device (adjust a thermostat, trigger a sensor) and watch the value update in ControlBird. This confirms the entire data pipeline, from device through tunnel to cloud, is working correctly.

What's Next?

Now that you have live data flowing from your local network to the cloud, let's create an automation that reacts to changes automatically.

Troubleshooting

SSH tunnel won't connect

If your tunnel fails to establish:

  • Check the SSH host: make sure you're using the exact hostname from your node settings
  • Verify your token: regenerate the token if needed and try again
  • Check network restrictions: some corporate networks block outbound connections; try from a different network
  • Check Docker logs: run docker logs controlbird-tunnel to see connection details. If using manual SSH, add -v for verbose output
Controller shows "Error" after tunnel connects

If the tunnel is up but the controller can't connect:

  • Verify port forwarding: make sure the TUNNELS port matches your controller's port setting
  • Check local device: confirm the device is reachable from your tunnel machine (try nc -zv 192.168.1.100 502)
  • Look for port conflicts: the forwarded port might already be in use on the node
Tunnel disconnects frequently

For more reliable tunnels:

  • Use the Docker image with --restart always for automatic reconnection (recommended)
  • If using manual SSH, add -o ServerAliveInterval=30 to send keepalives
  • If using manual SSH, consider autossh or a systemd service with Restart=always
I'm not seeing any data updates

If your device is connected but values aren't updating:

  • Check that your mapper configuration points to valid registers/addresses
  • Verify the data type matches what your device sends
  • Try increasing the poll interval if your device is slow to respond
  • Check tunnel latency: high latency may cause timeouts
Can I run the tunnel from a Raspberry Pi?

Yes! A Raspberry Pi makes an excellent tunnel gateway. Install Docker on your Pi, then run a single docker run command to set up a persistent, auto-reconnecting tunnel to all your devices. Any Pi model with Docker and network access will work.

How do I connect MQTT devices?

For MQTT, forward port 1883 (or your broker's port) through the tunnel, then configure an MQTT controller pointing to localhost:1883. The mapper uses topic subscriptions instead of register addresses.

Architecture Summary

Here's how data flows from your local device to ControlBird:

Local Device
192.168.1.100:502
Tunnel Gateway
Raspberry Pi / PC
TLS + SSH
ControlBird Node
localhost:502
Store
/Home/LivingRoom