Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 215 additions & 20 deletions examples/python-distributed-zenoh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ nodes:
- id: sensor-temp
_unstable_deploy:
machine: edge1 # Runs on daemon with --machine-id edge1
working_dir: /Users/nupylot/Public/dora-examples/examples/python-distributed-zenoh
working_dir: /Users/username/python-distributed-zenoh
path: python3
args: sensor_node.py sensor_temp temperature
outputs:
Expand All @@ -48,7 +48,7 @@ nodes:
- id: cloud-aggregator
_unstable_deploy:
machine: cloud # Runs on daemon with --machine-id cloud
working_dir: /Users/nupylot/Public/dora-examples/examples/python-distributed-zenoh
working_dir: /Users/username/python-distributed-zenoh
inputs:
temp_data: sensor-temp/data
humidity_data: sensor-humidity/data
Expand All @@ -59,19 +59,29 @@ nodes:

## Installation

### On All Machines

```bash
pip install -r requirements.txt
# Install dora-rs (includes CLI and Python API)
pip install dora-rs

# Optional: Install Zenoh tools for cross-network deployments
# (requires Rust/Cargo)
cargo install zenoh --features unstable
```

### AWS EC2 Security Group Configuration (For Cross-Network)

If deploying to EC2, configure security group to allow:
- **TCP 7447** - Zenoh router (from 0.0.0.0/0)
- **TCP 53290** - Dora coordinator (from 0.0.0.0/0)

In AWS Console: EC2 → Security Groups → Add Inbound Rules

## Running on ONE Machine (Simulation)

Simulate distributed deployment with multiple daemons on one PC:

### Automated (Recommended)
```bash
./run_local.sh
```

### Manual Steps

**Terminal 1 - Coordinator:**
Expand Down Expand Up @@ -105,7 +115,7 @@ dora build dataflow.yml
dora start dataflow.yml
```

## Running on MULTIPLE Machines (Real Distribution)
## Running on real distribution

### Same Network (WiFi/LAN)

Expand Down Expand Up @@ -135,35 +145,198 @@ dora daemon --coordinator-addr 192.168.1.100 --machine-id edge3
dora daemon --machine-id cloud

# Start the dataflow
dora start --coordinator-addr 192.168.1.100 dataflow.yml
dora start dataflow.yml
```

### Different Networks (Cross-Network)
### Different Networks (Cross-Network) - AWS EC2 Example

When machines are in different networks (behind NAT/firewalls), use Zenoh routers. This example shows connecting a home PC to AWS EC2.

#### Prerequisites

When machines are in different networks (behind NAT/firewalls), use Zenoh routers.
1. **On Both Machines:**
```bash
pip install dora-rs
```

2. **Copy Files to EC2 (`~/dora-distributed/`):**
- `sensor_node.py`
- `cloud_node.py`
- `dataflow_distributed.yml`
- `zenoh_config.json5`

**1. Set up Zenoh Router on each network:**
3. **Update `dataflow_distributed.yml` paths:**
- Edge device: Set `working_dir` to your local path (e.g., `/Users/username/python-distributed-zenoh` for Mac, `/home/username/dora-distributed` for Linux)
- Cloud: Set `working_dir` to EC2 path (e.g., `/home/ubuntu/dora-distributed`)

Create `zenoh_config.json5`:
Example configuration:
```yaml
nodes:
- id: sensor-temp
_unstable_deploy:
machine: edge1
working_dir: /Users/username/python-distributed-zenoh # Mac path
path: python3
args: sensor_node.py sensor_temp temperature
inputs:
tick: dora/timer/millis/1000
outputs:
- data

- id: cloud-aggregator
_unstable_deploy:
machine: cloud
working_dir: /home/ubuntu/dora-distributed # EC2 path
path: python3
args: cloud_node.py
inputs:
temp_data: sensor-temp/data
```

#### Setup Zenoh Config

Create `zenoh_config.json5` (on both machines):
```json5
{
mode: "client",
connect: {
endpoints: ["tcp/<ROUTER_IP>:7447"]
endpoints: ["tcp/YOUR_EC2_IP:7447"] // Replace with your EC2 public IP
},
listen: {
endpoints: []
}
}
```

**2. Start Zenoh Router:**
**Key Settings:**
- `mode: "client"` - Makes dora daemon a Zenoh client (not a router)
- `listen: { endpoints: [] }` - Prevents port conflicts with zenohd router
- Replace `YOUR_EC2_IP` with your actual EC2 public IP address

#### On EC2 (Cloud Server)

**Terminal 1 - Start Zenoh Router:**
```bash
zenohd --listen tcp/0.0.0.0:7447
```

**Terminal 2 - Start Dora Coordinator:**
```bash
cd ~/dora-distributed
dora coordinator
```

**Terminal 3 - Start Cloud Daemon:**
```bash
cd ~/dora-distributed
export ZENOH_CONFIG=zenoh_config.json5
dora daemon --machine-id cloud
```

You should see:
```
INFO dora_daemon::coordinator: Connected to dora-coordinator at 127.0.0.1:53290
```

#### On Your PC/Mac (Edge Device)

**Terminal 1 - Start Edge Daemon:**
```bash
zenohd -l tcp/0.0.0.0:7447
cd /path/to/dora-examples/examples/python-distributed-zenoh
export ZENOH_CONFIG=zenoh_config.json5
dora daemon --coordinator-addr YOUR_EC2_IP --machine-id edge1
```

**3. Start Dora Daemons with Zenoh Config:**
You should see:
```
INFO dora_daemon::coordinator: Connected to dora-coordinator at YOUR_EC2_IP:53290
```

#### Start the Dataflow (From EC2)

**Terminal 4 on EC2:**
```bash
# On each machine
ZENOH_CONFIG=zenoh_config.json5 dora daemon --coordinator-addr <COORDINATOR_IP> --machine-id edge1
cd ~/dora-distributed

# Verify both daemons are connected
dora list

# Build the dataflow
dora build dataflow_distributed.yml

# Start the dataflow (controls both machines)
dora start dataflow_distributed.yml
```

#### Expected Output

**On EC2 (Terminal 4) - Cloud Aggregator:**
```
dataflow start triggered: 019a5637-3863-7f52-aac5-df670c2a7132
attaching to dataflow (use `--detach` to run in background)

cloud-aggregator on daemon `cloud`: INFO daemon node is ready
cloud-aggregator on daemon `cloud`: stdout === Cloud Aggregator Node ===
cloud-aggregator on daemon `cloud`: stdout Receiving data via Dora's distributed Zenoh routing
cloud-aggregator on daemon `cloud`: stdout
cloud-aggregator on daemon `cloud`: stdout Cloud aggregator started! Press Ctrl+C to stop
cloud-aggregator on daemon `cloud`: stdout
cloud-aggregator on daemon `cloud`: stdout >> [00001] Received from sensor_temp: temperature=23.45celsius
cloud-aggregator on daemon `cloud`: stdout >> [00002] Received from sensor_temp: temperature=24.12celsius
cloud-aggregator on daemon `cloud`: stdout >> [00003] Received from sensor_temp: temperature=22.89celsius
cloud-aggregator on daemon `cloud`: stdout
cloud-aggregator on daemon `cloud`: stdout ======================================================================
cloud-aggregator on daemon `cloud`: stdout Cloud Aggregator Summary - Total Messages: 10
cloud-aggregator on daemon `cloud`: stdout Active Sensors: 1
cloud-aggregator on daemon `cloud`: stdout ======================================================================
cloud-aggregator on daemon `cloud`: stdout 🟢 ACTIVE | sensor_temp | temperature | 24.12 celsius | Count: 10
cloud-aggregator on daemon `cloud`: stdout ======================================================================
```

**On Your PC/Mac (Terminal 1) - Edge Daemon:**
```
INFO dora_daemon::coordinator: Connected to dora-coordinator at YOUR_EC2_IP:53290
WARN run_inner: dora_daemon: Daemon took 158ms for handling event
```

The sensor node runs silently in the background, sending temperature data every second through the Zenoh router to EC2.

#### Architecture Flow

```
Your PC/Mac (edge1) EC2 Cloud (YOUR_EC2_IP)
┌─────────────────┐ ┌─────────────────────────┐
│ sensor-temp │ │ zenohd :7447 (router) │
│ (publishes) │──Zenoh──▶│ │
│ │ │ dora coordinator :53290 │
│ dora daemon │◀─Control─│ │
│ (edge1) │ │ dora daemon (cloud) │
└─────────────────┘ │ │
│ cloud-aggregator │
│ (receives & aggregates) │
└─────────────────────────┘
```

#### Troubleshooting Cross-Network Setup

**"Connection refused" when starting daemon:**
- Verify EC2 public IP is correct in `--coordinator-addr`
- Check EC2 security group allows TCP port 53290 (coordinator)
- Ensure coordinator is running on EC2

**"Operation not supported (os error 45)" on Mac:**
- Update `dataflow_distributed.yml` with correct Mac path in `working_dir`
- Mac uses `/Users/...`, not `/home/...`

**"Address already in use" for port 7447:**
- Update `zenoh_config.json5` with `mode: "client"` and `listen: { endpoints: [] }`
- Only the `zenohd` router should listen on 7447

**Zenoh connection issues:**
- Verify EC2 security group allows TCP port 7447 (Zenoh router) and TCP port 53290 (coordinator)
- Test Zenoh connectivity: `z_pub --connect tcp/<EC2_IP>:7447 --key test`
- On EC2, verify services are listening: `netstat -tuln | grep -E '7447|53290'`

## Expected Output

**Sensor Node (edge1):**
Expand Down Expand Up @@ -265,6 +438,28 @@ You can monitor these topics directly with Zenoh tools:
z_sub 'dora/**'
```

## Testing Network Connectivity

Before running dora-zenoh, verify Zenoh connectivity works:

**Terminal A (on edge or EC2):**
```bash
z_sub --connect tcp/YOUR_EC2_IP:7447 --key demo/test
```

**Terminal B (on another machine):**
```bash
echo "🔥 connected!" | z_pub --connect tcp/YOUR_EC2_IP:7447 --key demo/test
```

**Expected output on Terminal A:**
```
Received (key='demo/test'): 🔥 connected!
```

If this works, your network is configured correctly. If dora still has issues, check the dora-specific troubleshooting above.


## References

- [Dora Multiple Daemons Example](https://github.com/dora-rs/dora/tree/main/examples/multiple-daemons)
Expand Down
25 changes: 25 additions & 0 deletions examples/python-distributed-zenoh/dataflow_distributed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Distributed Dataflow Configuration
# Simplified deployment: Single edge device (edge1) sending to AWS EC2 cloud node

nodes:
# Edge Device 1 - Temperature Sensor
- id: sensor-temp
_unstable_deploy:
machine: edge1
working_dir: /Users/nupylot/Public/dora-examples/examples/python-distributed-zenoh
path: python3
args: sensor_node.py sensor_temp temperature
inputs:
tick: dora/timer/millis/1000 # Generate data every 1 second
outputs:
- data

# AWS EC2 - Cloud Aggregator
- id: cloud-aggregator
_unstable_deploy:
machine: cloud
working_dir: /home/ubuntu/dora-distributed # EC2 default user is 'ubuntu'
path: python3
args: cloud_node.py
inputs:
temp_data: sensor-temp/data
3 changes: 0 additions & 3 deletions examples/python-distributed-zenoh/out/.gitignore

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading