MOBAflow is an event-driven automation solution for model railroads. The system enables complex workflow sequences, train control with station announcements, and real-time feedback monitoring via direct UDP connection to the Roco Z21 Digital Command Station.
⚖️ Legal Notice: MOBAflow is an independent open-source project. See THIRD-PARTY-NOTICES.md for details on third-party software, formats, and trademarks (AnyRail, Piko, Roco).
- ✨ Features
⚠️ Hardware & Safety- 🚀 Quick Start
- 🔐 Trust Model & Signatures
- 🔧 Configuration
- 🛤️ Track Plan
- 🎵 Audio Library
- 🎨 Control Libraries
- 📦 Architecture
- 🔧 Setup Scripts (For Teams)
- 📚 Documentation
- 🚂 Z21 Direct UDP Control – Real-time communication with Roco Z21
- 🎯 Journey Management – Define train routes with multiple stations
- 🧭 Flexible Layout – Toggle City and Workflow libraries to maximize workspace
- 🔊 Text-to-Speech – Azure Cognitive Services & Windows Speech API
- ⚡ Workflow Automation – Event-driven action sequences
- 🎨 Visual Track Plan – Drag & drop track editor with snap-to-connect
- 🟢 Win2D GPU Rendering – High-performance track visualization
- 🛤️ Track Libraries – Extensible support (Piko A-Gleis, Roco Line, Tillig, Märklin)
- 📱 Multi-Host – MOBAflow (Windows), MOBAsmart (Android), MOBApi (REST)
- 🟢 Status Monitoring – Real-time startup progress with log streaming
📚 Need Help? Check out our comprehensive Wiki Documentation
- WinUI User Guide – Learn how to use MOBAflow
- Azure Speech Setup – Configure text-to-speech
- Installation Guide – Set up MOBAflow, MOBApi and MOBAsmart
MOBAflow controls model train layouts via UDP communication with the Roco Z21 Digital Command Station.
Before using MOBAflow, please read: 📖
HARDWARE-DISCLAIMER.mdThis document covers:
- ✅ Safety requirements and prerequisites
- ✅ Network configuration
- ✅ Liability & disclaimer
- ✅ Emergency procedures
Current Status: ℹ️ Azure App Configuration setup scripts are available. Hardware setup, device pairing, and layout integration are still manual.
- ✅ .NET 10 SDK matching
global.json - ✅ Visual Studio 2026 (recommended) or VS Code
- ✅ Roco Z21 Digital Command Station (for Z21 connectivity)
git clone https://github.com/ahuelsmann/MOBAflow.git
cd MOBAflow
dotnet restore MOBAflow/MOBAflow.csproj
dotnet build MOBAflow/MOBAflow.csprojCross-platform subset (library and backend projects only):
dotnet restore Backend/Backend.csproj
dotnet build Backend/Backend.csproj
dotnet test Test/Test.csprojNote: On non-Windows systems, the WinUI and MAUI projects are not buildable. Restore/build individual
.csprojfiles instead of relying on solution-level restore. SomeSystem.Speechtests are Windows-only.
🪟 MOBAflow (Windows Desktop):
dotnet run --project MOBAflow/MOBAflow.csproj🌐 MOBApi (REST API, Port 5001):
dotnet run --project MOBApi/MOBApi.csprojMOBApi listens on port 5001 (all interfaces). It provides the REST API for the MOBAflow Overview status and for MOBAsmart (client list, health).
You can start MOBApi in two ways:
- Standalone – run the command above.
- Together with MOBAflow – enable "Auto-start REST API with MOBAflow" in MOBAflow Settings so MOBAflow starts the MOBApi process automatically.
MOBAsmart discovers the server via UDP multicast; ensure PC and phone are on the same network.
📱 MOBAsmart (Android):
dotnet build MOBAsmart/MOBAsmart.csproj -f net10.0-android🧪 Run Tests:
dotnet test Test/Test.csprojOfficial MOBAflow releases are identified by signed Git tags in this repository.
- Release versions are tagged as
X.Y.Z(e.g.0.1.0). - Starting with version
0.1.0, maintainers sign these tags with their GPG keys so you can verify that a given version really comes from us and was not modified.
Typical workflow for installing a specific version:
-
Select a version: Pick a tag from the GitHub Tags / Releases list (e.g.
0.1.0). -
Fetch tags & verify:
git fetch origin --tags git tag -v 0.1.0
Only continue if GPG reports a valid signature from a maintainer key listed in
docs/legal/MAINTAINERS.md. -
Check out the tag:
git checkout 0.1.0
-
Build & run using the commands from the Quick Start section.
git fetch origin --tags
git tag -v 1.2.3- Only trust tags whose signature matches one of the maintainer keys
documented in
docs/legal/MAINTAINERS.md(e.g. key ID7DAD81238FEE2F49). - If verification fails, do not use that release and contact the maintainers.
The current list of GPG keys and fingerprints used for signing release tags is maintained in:
docs/legal/MAINTAINERS.md
MOBAflow uses Azure Cognitive Services Speech for text-to-speech announcements. Choose your preferred setup method:
| Method | Best For | Complexity |
|---|---|---|
| A) Azure App Config | Teams, shared environments | ⭐⭐⭐ |
| B) User Secrets | Individual developers | ⭐⭐ |
| C) Settings UI | End users, no coding | ⭐ |
💡 For Developer Teams: Centralized configuration shared across all team members.
Quick Setup:
# 1. Create Azure resource (once)
.\scripts\setup-azure-appconfig.ps1 -SpeechKey "YOUR-KEY" -SpeechRegion "germanywestcentral"
# 2. Install on all team systems
.\scripts\install-appconfig-connection.ps1 -ConnectionString "YOUR-CONNECTION-STRING"
# 3. Restart IDE📖 Details: See 🔧 Setup Scripts section below
1. Get Azure Speech Key:
- 🌐 Go to Azure Portal
- ➕ Create: Cognitive Services → Speech
- 📋 Copy Key and Region
2. Configure Secrets:
cd MOBAflow
dotnet user-secrets set "Speech:Key" "YOUR-AZURE-SPEECH-KEY"
dotnet user-secrets set "Speech:Region" "germanywestcentral"3. Verify: Run the app – speech should work ✅
1. Launch MOBAflow
2. Navigate: Settings → Speech Synthesis
3. Enter your Azure Speech Key
4. Select Region (e.g., germanywestcentral)
5. Click Save
⚠️ Security: The key is stored locally inappsettings.json. Never commit this file to version control.
The app loads settings in this order (first found wins):
- ☁️ Azure App Configuration (if
AZURE_APPCONFIG_CONNECTIONenv var exists) - 🔐 User Secrets (Development mode only)
- ⚙️ Settings UI (
appsettings.json) - 🚫 Fallback: Speech features disabled
Design your model railroad layout with MOBAflow's visual track planning system.
- ✅ Drag & Drop – Place tracks from toolbox
- ✅ Snap-to-Connect – Automatic track joining
- ✅ Grid Alignment – Rotation & positioning controls
- ✅ Theming – Light & Dark mode support
- ✅ Navigation – Zoom & Pan
- ✅ Feedback Points – Assign detection sensors
- ✅ Validation – Real-time constraint checking
- ✅ Signal Control – Requires active Z21 connection
- ✅ Win2D Rendering – GPU-accelerated graphics (Phase 1)
| Library | Status | Description |
|---|---|---|
| TrackLibrary.PikoA | ✅ Active | Piko A-Gleis |
| TrackLibrary.RocoLine | 🚧 Planned | Roco Line |
| TrackLibrary.Tillig | 🚧 Planned | Tillig |
| TrackLibrary.Maerklin | 🚧 Planned | Märklin |
Play sound effects in workflows (station bells, train whistles, crossing signals).
Sound/Resources/Sounds/
├── Station/ # Station bells, gongs, platform warnings
├── Train/ # Whistles, horns, brake sounds
├── Signals/ # Warning beeps, crossing bells
└── Ambient/ # Background ambience (optional)
| Property | Value |
|---|---|
| Format | .wav (PCM only) |
| Sample Rate | 44100 Hz or 48000 Hz |
| Bit Depth | 16-bit |
| Channels | Mono or Stereo |
| Not Supported | ❌ .mp3, .ogg, .flac |
| ✅ Good | ❌ Bad |
|---|---|
arrival_bell.wav |
sound1.wav |
whistle_short.wav |
ArrivalBell.wav |
crossing_warning.wav |
My Sound.wav |
- Download from Freesound.org (CC0 license recommended)
- Copy to appropriate subfolder
- Use in Workflow: Create Audio Action → Set FilePath
- ✅ CC0 (Public Domain) – No attribution required
- ✅ CC-BY 4.0 – Attribution required (add to
ATTRIBUTION.md) - ❌ CC-BY-NC – Avoid (non-commercial restriction)
📖 Attribution File: Sound/Resources/Sounds/ATTRIBUTION.md
Platform-specific UI control libraries for consistent, reusable components.
MOBAflow/Controls/ ← WinUI 3 XAML controls inside the desktop app
↓
MAUI.Controls/ ← MAUI XAML (Android Mobile)
↓
SharedUI/ ← ViewModels (Platform-agnostic)
↓
Domain/ ← Business Models
| Project | Platform | Technology | Target |
|---|---|---|---|
| MOBAflow/Controls | Windows | WinUI 3 XAML | Desktop app control set |
| MAUI.Controls | Android | .NET MAUI XAML | Mobile control library |
| SharedUI | Cross-platform | CommunityToolkit.Mvvm | ViewModels |
<Page xmlns:controls="using:Moba.WinUI.Controls">
<controls:TrainCard
TrainName="ICE 1"
Speed="120"
IsForward="True" />
</Page>Guidelines:
- Use
DependencyPropertyfor bindable properties - Prefer
x:Bind(compiled bindings) - Use
ThemeResourcefor colors/styles - Follow Fluent Design System
<ContentPage xmlns:controls="clr-namespace:Moba.MAUI.Controls;assembly=MAUI.Controls">
<controls:TrainCard
TrainName="ICE 1"
Speed="120"
IsForward="True" />
</ContentPage>Guidelines:
- Use
BindablePropertyfor bindable properties - Use
AppThemeBindingfor Light/Dark mode - Touch-optimized (minimum 44x44 dp)
- Follow MAUI design patterns
| Feature | MOBAflow/Controls | MAUI.Controls |
|---|---|---|
| Bindable Properties | DependencyProperty |
BindableProperty |
| Binding Syntax | {x:Bind} |
{Binding} |
| Base Class | UserControl |
ContentView |
| Icons | FontIcon |
FontImageSource |
| Theming | ThemeResource |
AppThemeBinding |
MOBAflow follows Clean Architecture principles with strict layer separation.
┌─────────────────────────────────────┐
│ MOBAflow / MOBAsmart / MOBApi │ ← Platform UI & API
├─────────────────────────────────────┤
│ SharedUI (ViewModels) │ ← MVVM Layer
├─────────────────────────────────────┤
│ Backend (Services, Logic) │ ← Business Logic
├─────────────────────────────────────┤
│ Domain (Models, POCOs) │ ← Core Entities
└─────────────────────────────────────┘
Shared ViewModels talk to the in-process runtime only; there is no separate UI client interface:
MainWindowViewModel / TrainControlViewModel / MauiViewModel
↓
IMobaRuntime (MobaRuntimeService)
↓
IZ21 / JourneyManager / WorkflowService
Current scope:
MainWindowViewModel,TrainControlViewModel, andMauiViewModelinjectIMobaRuntime(singletonMobaRuntimeService) instead of usingIZ21orJourneyManagerdirectly for commands and snapshots- The runtime publishes
MobaRuntimeSnapshot(and related events such as traffic and feedback) back to the shell - Project activation is performed inside
MobaRuntimeService.ActivateProjectAsync, which ownsActiveProjectContextand aJourneyManagerper active project - The active runtime still uses the live
Projectinstance from the loadedSolution; a dedicated runtime copy remains a possible future step - Shared master data (
data.json) is held inMasterDataStore(Backend DI); WinUI services expose cities and locomotives to the shell
| Layer | Technology |
|---|---|
| Framework | .NET 10 |
| UI | WinUI 3 (MOBAflow), .NET MAUI (MOBAsmart) |
| API | ASP.NET Core REST + SignalR (MOBApi) |
| Graphics | Microsoft.Graphics.Win2D |
| MVVM | CommunityToolkit.Mvvm |
| Logging | Serilog (File + In-Memory Sink) |
| Speech | Azure Cognitive Services, Windows Speech |
| Networking | Direct UDP (Z21 Protocol) |
| Testing | NUnit |
MOBAflow uses System.Text.Json with schema validation.
{
"name": "My Model Railroad",
"schemaVersion": 1,
"projects": [...]
}Current Schema Version: 1
- ✅ JSON Structure – Valid syntax
- ✅ Required Properties –
name,projects - ✅ Schema Version – Compatibility check
- ✅ Project Integrity – Valid structure
Serilog Configuration:
- 📁 File Logs:
bin/Debug/logs/mobaflow-YYYYMMDD.log(rolling, 7-day retention) - 💾 In-Memory Sink: Real-time log streaming to MonitorPage UI
- 🔍 Structured Logging: Searchable properties
- 📊 Log Levels: Debug (Moba), Warning (Microsoft)
Example:
_logger.LogInformation(
"Feedback received: InPort={InPort}, Value={Value}",
inPort,
value);📖 Details: See docs/ARCHITECTURE.md
💡 For Developer Teams: Centralized Azure App Configuration for shared environments.
👤 For End Users: Skip this section and use Settings UI instead.
| Script | Purpose | Run Where |
|---|---|---|
setup-azure-appconfig.ps1 |
Create resource | Once (any system) |
install-appconfig-connection.ps1 |
Set env var | All systems |
1. Create Azure Resource:
.\scripts\setup-azure-appconfig.ps1 `
-SpeechKey "YOUR-KEY" `
-SpeechRegion "germanywestcentral"Output: Copy the Connection String ✅
2. Install on Team Systems:
.\scripts\install-appconfig-connection.ps1 `
-ConnectionString "Endpoint=https://...;Id=...;Secret=..."3. Restart IDE:
Close and reopen Visual Studio / VS Code
4. Verify:
Speech settings automatically load from Azure – no local config needed! ✅
Purpose: Creates Azure App Configuration resource
Parameters:
-SpeechKey(required) – Azure Speech API Key-SpeechRegion(required) – Azure region (e.g.,germanywestcentral)-ResourceGroupName(optional) – Default:MOBAflow-RG-ConfigStoreName(optional) – Default:mobaflow-config-Location(optional) – Default:germanywestcentral
Requirements:
- Azure CLI installed
- Logged in (
az login) - Subscription selected (
az account set)
Purpose: Sets AZURE_APPCONFIG_CONNECTION environment variable
Parameters:
-ConnectionString(required) – From previous script output
Requirements:
- Run as normal user (not Admin)
- Restart IDE after running
- ✅ Centralized configuration for entire team
- ✅ No
appsettings.jsoncommits - ✅ Easy key rotation (update once in Azure)
- ✅ Consistent config on CI/CD pipelines
Location: docs/
| Document | Description |
|---|---|
| ARCHITECTURE.md | Architecture & design patterns |
| CHANGELOG.md | Version history & release notes |
| SECURITY.md | Security policy & reporting |
| CODE_OF_CONDUCT.md | Community conduct guidelines |
| JSON-VALIDATION.md | Solution JSON validation |
| MINVER-SETUP.md | MinVer versioning setup |
| HARDWARE-DISCLAIMER.md | Hardware safety & liability |
| THIRD-PARTY-NOTICES.md | Third-party licenses |
| CURSOR-AZURE-DEVOPS-MCP.md | Azure DevOps MCP integration |
| CLAUDE.md | AI assistant instructions |
| CLA.md | Contributor License Agreement (CLA) |
Location: docs/wiki/
| Guide | Description |
|---|---|
| INDEX.md | Wiki index & platform overview |
| INSTALLATION.md | Installation & setup guide |
| MOBAFLOW-USER-GUIDE.md | WinUI desktop app user guide |
| MOBASMART-USER-GUIDE.md | MOBAsmart Android app user guide |
| MOBASMART-WIKI.md | Detailed MOBAsmart documentation |
| AZURE-SPEECH-SETUP.md | Azure Speech setup |
| QUICK-START-TRACK-STATISTICS.md | Track statistics quick start |
| VIESSMANN-SIGNAL-MAPPING.md | Viessmann signal mapping |
| MOBATPS.md | MOBAtps track plan system architecture |
This project is licensed under the MIT License. See LICENSE for details.
Made with ❤️ for model railroad enthusiasts.