Skip to main content

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:

  1. ZeusHost.Create: declare channels, devices, and services.
  2. StartAsync: open channels and start background services.
  3. Channels.Get: access a running channel.
  4. 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");
});
});
OrderReason
Configure acquisitionPolling interval is host-level behavior
Register channelsDevices bind to channel names
Register devicesDevices expose protocol APIs and points
Start hostOpen 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.