Host
The host is the main switch for a Zeus application. It creates channels, opens them, starts acquisition, and releases resources on shutdown.
Minimal Pattern
await using var app = ZeusHost.Create(builder =>
{
builder.AddVirtualChannel("meter");
});
await app.StartAsync();
var meter = app.Channels.Get("meter");
await meter.WriteAsync(new byte[] { 0x01 });
await app.StopAsync();
Read it as:
ZeusHost.Create: declare channels, devices, and services.StartAsync: open channels and start background services.Channels.Get: access a running channel.StopAsync: close channels and pause services.
Create Does Not Open Ports
This only registers the channel:
await using var app = ZeusHost.Create(builder =>
{
builder.AddSerialPort("meter", "COM3", 9600);
});
The port opens only after:
await app.StartAsync();
Calling WriteAsync before StartAsync fails because the channel is still Created.
Registration Order
Use this order in most apps:
await using var app = ZeusHost.Create(builder =>
{
builder.AddAcquisition(TimeSpan.FromMilliseconds(500));
builder.AddSerialPort("bus", "COM3", 9600);
builder.AddModbusRtu("oven", "bus", unitId: 1, points: map =>
{
map.HoldingRegister("temperature", 0, 0.1)
.HoldingRegister("setpoint", 1, 0.1).Writable("setpoint");
});
});
| Order | Reason |
|---|---|
| Configure acquisition | Polling interval is host-level behavior |
| Register channels | Devices bind to channel names |
| Register devices | Devices expose protocol APIs and points |
| Start host | Open everything after all declarations are complete |
Runtime Access
var channel = app.Channels.Get("bus");
var device = app.Devices.Get<ModbusDevice>("oven");
var temperature = app.Points.Get<double>("temperature");
Missing names produce exceptions that include currently registered names.
Restart After Stop
StopAsync closes channels and pauses acquisition, but the host can be started again:
await app.StopAsync();
await app.StartAsync();
After DisposeAsync, create a new host.
Runtime Topology Changes
await app.AddVirtualChannelAsync("bus");
app.AddModbusRtu("oven", "bus", points: map => map.HoldingRegister("pv", 0));
await app.RemoveDeviceAsync("oven");
await app.RemoveChannelAsync("bus");
When the host is running, new channels open immediately. Removing a channel removes bound devices by default.
Reconnects
After a channel becomes Faulted, Zeus waits 1 second, retries, then backs off up to 30 seconds by default. Explicit CloseAsync does not reconnect.
builder.AddReconnect(options =>
{
options.Enabled = true;
options.InitialDelay = TimeSpan.FromSeconds(1);
options.MaxDelay = TimeSpan.FromSeconds(30);
});
Disable reconnects if you want to drive recovery manually through StateChanged and OpenAsync.
Register Your Services
Zeus uses .NET dependency injection:
await using var app = ZeusHost.Create(builder =>
{
builder.Services.AddSingleton<MyBusinessService>();
builder.AddVirtualChannel("meter");
});
This is a good place for acquisition processing, alarm logic, or database writers that should not live inside a form class.
Next: Virtual Channel, Serial Port, or TCP / UDP.