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
- πΈ Screenshots
β οΈ Hardware & Safety- π Quick Start
- π Trust Model & Signatures
- π§ Configuration
- π€οΈ Track Plan
- π§© Project Reference
- π΅ 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
A visual tour of MOBAflow's main features. Click any image to view it in full resolution.
Main window β live Z21 status, active journeys and feedback monitoring.
Locomotive presets, live timetable, speed & current dials and F0βF31 function keys.
Drag & drop track editor with snap-to-connect and Win2D rendering.
Compose journeys from stations, cities and workflows with live runtime state.
Stream track numbers and live clock via UDP to an ESP32-based remote display.
The Display page also includes an interactive 5x5 LED matrix editor:
- Color palette: Pick the active LED color with the WinUI color picker.
- Left click / tap: Paint a matrix cell with the selected color.
- Right click: Clear a matrix cell back to the off state.
- MVVM interaction: Matrix input is routed through ViewModel commands, so the cell-state logic is covered by platform-neutral unit tests.
π 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 build Moba.slnxCross-platform subset (library and backend projects only):
dotnet build Backend/Backend.csproj
dotnet build Common/Common.csproj
dotnet build Domain/Domain.csproj
dotnet build SharedUI/SharedUI.csproj
dotnet test Test/Test.csprojNote: On non-Windows systems, the WinUI (
MOBAflow.csproj) and MAUI (MOBAsmart.csproj) projects are not buildable due to platform-specific dependencies. Build individual cross-platform.csprojfiles instead of the full solution. SomeSystem.Speechtests are Windows-only and will skip on Linux.
πͺ 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.Base | β Active | Base classes and geometry primitives |
| TrackPlan.Renderer | β Active | Win2D-based track plan rendering |
| 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, Desktop)
SharedUI.Web/ β ViewModels (Web-compatible subset)
β
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 | Desktop ViewModels |
| SharedUI.Web | Cross-platform | CommunityToolkit.Mvvm | Web-compatible 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 / SharedUI.Web β β MVVM Layer (Desktop + Web)
βββββββββββββββββββββββββββββββββββββββ€
β Backend (Services, Logic) β β Business Logic
βββββββββββββββββββββββββββββββββββββββ€
β Common (Configuration, Events) β β Shared Infrastructure
βββββββββββββββββββββββββββββββββββββββ€
β 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 |
| Display rendering | SkiaSharp RGB565 rendering, UDP transport to ESP32-S3 displays |
| MVVM | CommunityToolkit.Mvvm |
| Logging | Serilog (Async File Sink + In-Memory + Environment/Process/Thread Enrichers) |
| Speech | Azure Cognitive Services, Windows Speech |
| Networking | Direct UDP (Z21 Protocol) |
| Testing | NUnit |
| Communication | EventBus with UiThreadEventBusDecorator |
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(async, rolling, 7-day retention) - πΎ In-Memory Sink: Real-time log streaming to MonitorPage UI
- π Structured Logging: Searchable properties with context enrichment
- π·οΈ Enrichers: MachineName, ProcessId, ProcessName, ThreadId
- π Log Levels: Debug (Moba), Warning (Microsoft)
Example:
_logger.LogInformation(
"Feedback received: InPort={InPort}, Value={Value}",
inPort,
value);Sample Output:
[14:32:15.123 INF] [MY-PC] [12345:MOBAflow.exe] [12] [Moba.Z21] Feedback received: InPort=1, Value=255
π Details: See docs/ARCHITECTURE.md
For a developer-oriented, repository-wide reference covering structure, current models, services, pages, workflow execution, display rendering, ESP32-S3 communication, configuration, build/deploy processes, and known documentation gaps, see:
This document is the preferred onboarding companion for new contributors after reading this README.
π‘ 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 |
| PROJECT-REFERENCE.md | Repository-wide technical reference and onboarding map |
| 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 β€οΈ and ai for model railroad enthusiasts.