Build and maintain distributed IoT edge computing systems using Microsoft Orleans virtual actors on Raspberry Pi with SQLite persistence and hardware control.
Expert agent for developing distributed edge computing systems using Microsoft Orleans virtual actors to control IoT hardware on resource-constrained devices like Raspberry Pi. This skill helps you build reliable edge applications with state persistence, cluster management, and hardware abstraction.
When working with OrleansEdge projects, recognize this three-tier architecture:
1. **OrleansEdge.Core (Shared Contracts)**: Defines grain interfaces and data types shared between controller and nodes
2. **OrleansEdge.Node (Orleans Silo)**: Runs on edge devices hosting grain implementations with hardware control
3. **OrleansEdge.Controller (Client)**: Terminal UI that sends commands to the Orleans cluster
The system demonstrates bringing cloud-native distributed patterns to resource-constrained edge devices with automatic state persistence and location-transparent communication.
1. Controller connects to cluster via static gateway endpoints (default port 30000)
2. Gets grain reference for target device component
3. Calls grain methods which automatically persist state changes
4. Grain communicates with physical hardware via Meadow OutputService
5. State survives grain deactivation and application restarts
Build entire solution:
```bash
dotnet build OrleansEdge.slnx
```
Build specific projects:
```bash
dotnet build OrleansEdge.Core/OrleansEdge.Core.csproj
dotnet build OrleansEdge.Node/OrleansEdge.Node.csproj
dotnet build OrleansEdge.Controller/OrleansEdge.Controller.csproj
```
Start the node (Orleans silo):
```bash
dotnet run --project OrleansEdge.Node/OrleansEdge.Node.csproj
```
Start the controller (client):
```bash
dotnet run --project OrleansEdge.Controller/OrleansEdge.Controller.csproj
```
1. Deploy Node project to Raspberry Pi with `appsettings.Production.json` configured
2. Ensure Controller uses `appsettings.Production.json` with gateway endpoint pointing to the deployed device
3. Default production topology: Primary silo at `192.168.4.22:11111`, gateway at `192.168.5.3:30000`
Key settings to configure:
Key settings:
Maintain separate Development and Production configuration files for each environment.
1. Define state class with all fields to persist (e.g., `LedState` with `CurrentColor`, `LastUpdated`, `ControllingNodeId`)
2. Inject `IPersistentState<TState>` in grain constructor
3. Call `WriteStateAsync()` after state modifications
4. Initialize SQLite schema using `InitializeSqliteDatabase()` helper on startup
Orleans uses these SQLite tables:
```csharp
public class LedState
{
public string CurrentColor { get; set; }
public DateTime LastUpdated { get; set; }
public string ControllingNodeId { get; set; }
}
```
**Critical**: This solution references Meadow projects from relative path `../../wilderness/`:
Ensure these dependencies exist at the expected path before building. Builds will fail if Meadow projects are unavailable.
When extending the system with new IoT components:
1. **Define interface in OrleansEdge.Core**:
```csharp
public interface INewDeviceGrain : IGrainWithStringKey
{
Task<DeviceState> GetState();
Task SetState(DeviceState state);
}
```
2. **Implement grain in OrleansEdge.Node**:
```csharp
public class NewDeviceGrain : Grain, INewDeviceGrain
{
private readonly IPersistentState<DeviceState> _state;
public NewDeviceGrain(
[PersistentState("device")] IPersistentState<DeviceState> state)
{
_state = state;
}
}
```
3. **Use from Controller**:
```csharp
var grain = client.GetGrain<INewDeviceGrain>("device-id");
await grain.SetState(newState);
```
**Development**: Uses `UseDevelopmentClustering()` for simplified local testing
**Production**: Should use ADO.NET clustering provider
1. **Grain Design**: Keep grains focused on single device components; use grain-to-grain communication for complex workflows
2. **State Management**: Always call `WriteStateAsync()` after state changes; don't assume in-memory state persists
3. **Hardware Abstraction**: Delegate all physical device interaction to Meadow OutputService; keep grain logic hardware-agnostic
4. **Error Handling**: Implement retry logic for hardware operations; handle device unavailability gracefully
5. **Configuration**: Use environment-specific appsettings files; never hardcode endpoints or connection strings
6. **Testing**: Test grain logic separately from hardware; use mock OutputService for unit tests
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/orleans-edge-iot-system-development/raw