rust-ethernet-ip 0.7.0

High-performance EtherNet/IP communication library for Allen-Bradley CompactLogix and ControlLogix PLCs
Documentation
# PLC Web Application - Rust Backend + React/TypeScript Frontend

This example demonstrates how to build a web application with a native Rust backend and a React/TypeScript frontend for communicating with Allen-Bradley PLCs via EtherNet/IP.

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│              React + TypeScript Frontend                │
│  • Modern UI with React components                     │
│  • TypeScript for type safety                           │
│  • HTTP/REST API communication                         │
└────────────────────┬────────────────────────────────────┘
                     │ HTTP/REST
┌────────────────────┴────────────────────────────────────┐
│              Rust Backend (Axum)                        │
│  • High-performance async web server                    │
│  • RESTful API endpoints                                │
│  • Direct integration with rust-ethernet-ip library    │
└────────────────────┬────────────────────────────────────┘
                     │ EtherNet/IP Protocol
┌────────────────────┴────────────────────────────────────┐
│              Allen-Bradley PLC                          │
│  • CompactLogix / ControlLogix                         │
└─────────────────────────────────────────────────────────┘
```

## Features

- **Native Rust Backend**: Direct use of the `rust-ethernet-ip` library without C# wrappers
- **Modern Frontend**: React with TypeScript for type-safe UI development
- **RESTful API**: Clean HTTP endpoints for PLC operations
- **Real-time Status**: Connection status monitoring
- **Tag Operations**: Read and write PLC tags with full data type support
- **CORS Support**: Configured for development and production

## Project Structure

```
web_app/
├── backend/              # Rust backend server
│   ├── Cargo.toml       # Rust dependencies
│   └── src/
│       └── main.rs      # Axum web server and API handlers
├── frontend/            # React/TypeScript frontend
│   ├── package.json     # Node.js dependencies
│   ├── tsconfig.json    # TypeScript configuration
│   └── src/
│       ├── App.tsx      # Main application component
│       ├── types.ts     # TypeScript type definitions
│       └── components/  # React components
│           ├── ConnectionPanel.tsx
│           ├── TagOperations.tsx
│           └── StatusBar.tsx
└── README.md            # This file
```

## Prerequisites

- **Rust**: Install from [rustup.rs]https://rustup.rs/
- **Node.js**: Version 16 or higher (for React frontend)
- **PLC Access**: A CompactLogix or ControlLogix PLC on your network

## Setup Instructions

### 1. Backend Setup

Navigate to the backend directory and build the server:

```bash
cd examples/web_app/backend
cargo build --release
```

Or run directly in development mode:

```bash
cargo run
```

The backend server will start on `http://localhost:3000`.

### 2. Frontend Setup

Navigate to the frontend directory and install dependencies:

```bash
cd examples/web_app/frontend
npm install
```

Start the development server:

```bash
npm start
```

The frontend will start on `http://localhost:3000` (or another port if 3000 is taken).

## API Endpoints

### `GET /api/health`
Health check endpoint.

**Response:**
```json
{
  "status": "ok",
  "service": "PLC Web Backend"
}
```

### `POST /api/connect`
Connect to a PLC.

**Request:**
```json
{
  "address": "192.168.1.120:44818"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Successfully connected to 192.168.1.120:44818"
}
```

### `POST /api/disconnect`
Disconnect from the PLC.

**Response:**
```json
{
  "success": true,
  "message": "Disconnected from PLC"
}
```

### `GET /api/status`
Get current connection status.

**Response:**
```json
{
  "connected": true,
  "address": "192.168.1.120:44818"
}
```

### `POST /api/read`
Read a tag value from the PLC.

**Request:**
```json
{
  "tag_name": "TestDINT"
}
```

**Response:**
```json
{
  "success": true,
  "tag_name": "TestDINT",
  "value": {
    "type": "DINT",
    "value": 42
  },
  "data_type": "DINT",
  "error": null
}
```

### `POST /api/write`
Write a value to a PLC tag.

**Request:**
```json
{
  "tag_name": "TestDINT",
  "value": {
    "type": "DINT",
    "value": 100
  }
}
```

**Response:**
```json
{
  "success": true,
  "message": "Successfully wrote to tag 'TestDINT'",
  "error": null
}
```

## Supported Data Types

The API supports all Allen-Bradley data types:

- **BOOL**: Boolean (true/false)
- **SINT**: 8-bit signed integer
- **INT**: 16-bit signed integer
- **DINT**: 32-bit signed integer
- **LINT**: 64-bit signed integer
- **USINT**: 8-bit unsigned integer
- **UINT**: 16-bit unsigned integer
- **UDINT**: 32-bit unsigned integer
- **ULINT**: 64-bit unsigned integer
- **REAL**: 32-bit floating point
- **LREAL**: 64-bit floating point
- **STRING**: Variable-length string

## Usage Example

1. **Start the backend server:**
   ```bash
   cd examples/web_app/backend
   cargo run
   ```

2. **Start the frontend (in another terminal):**
   ```bash
   cd examples/web_app/frontend
   npm start
   ```

3. **Open your browser** to `http://localhost:3000` (or the port shown)

4. **Connect to your PLC:**
   - Enter the PLC address (e.g., `192.168.1.120:44818`)
   - Click "Connect"

5. **Read a tag:**
   - Enter a tag name (e.g., `TestDINT`)
   - Click "Read Tag"

6. **Write a tag:**
   - Enter a tag name
   - Select the data type
   - Enter the value
   - Click "Write Tag"

## Development

### Backend Development

The backend uses:
- **Axum**: Modern async web framework
- **Tokio**: Async runtime
- **Serde**: JSON serialization/deserialization
- **Tower**: Middleware and utilities

To add new endpoints, edit `backend/src/main.rs` and add new route handlers.

### Frontend Development

The frontend uses:
- **React 18**: UI library
- **TypeScript**: Type safety
- **Create React App**: Build tooling

To modify the UI, edit the components in `frontend/src/components/`.

## Production Deployment

### Backend

Build the release binary:

```bash
cd examples/web_app/backend
cargo build --release
```

The binary will be at `target/release/plc-web-backend`.

### Frontend

Build the production bundle:

```bash
cd examples/web_app/frontend
npm run build
```

The static files will be in `frontend/build/`. You can serve them with any static file server or integrate with the Rust backend.

### CORS Configuration

For production, update the CORS configuration in `backend/src/main.rs` to only allow your frontend domain:

```rust
.layer(
    CorsLayer::new()
        .allow_origin("https://yourdomain.com".parse::<HeaderValue>().unwrap())
        .allow_methods([Method::GET, Method::POST])
        .allow_headers([CONTENT_TYPE])
)
```

## Troubleshooting

### Connection Issues

- Ensure the PLC is on the same network
- Check firewall settings (port 44818)
- Verify the PLC address format: `IP:PORT` (e.g., `192.168.1.120:44818`)

### Frontend Can't Connect to Backend

- Ensure the backend is running on port 3000
- Check CORS settings if accessing from a different origin
- Verify the `API_BASE` environment variable in the frontend

### Tag Read/Write Errors

- Verify the tag exists in the PLC
- Check the data type matches the tag's actual type
- Ensure the tag is not protected or read-only

## Comparison with C# Examples

This example differs from the C# examples in that:

1. **No C# Wrapper**: Direct use of the Rust library via native Rust code
2. **Web-Based**: Browser-based UI instead of desktop applications
3. **REST API**: HTTP-based communication instead of direct library calls
4. **Cross-Platform**: Works on any platform that supports Rust and Node.js

## License

Same license as the main `rust-ethernet-ip` library.