Skip to main content

JSON Configuration

JSON configuration is useful for field delivery: ports, unit ids, point maps, and acquisition intervals live in a file that can be changed without recompiling.

Minimal File​

zeus.json:

{
"acquisition": {
"intervalMilliseconds": 500,
"pollImmediately": true
},
"channels": [
{
"name": "bus",
"type": "serial",
"options": {
"portName": "COM3",
"baudRate": 9600
}
}
],
"devices": [
{
"name": "oven",
"channel": "bus",
"type": "modbus-rtu",
"options": {
"unitId": 1
},
"points": [
{
"name": "temperature",
"options": {
"table": "holding",
"address": 0,
"scale": 0.1,
"lowAlarmLimit": 10,
"highAlarmLimit": 80
}
},
{
"name": "setpoint",
"options": {
"table": "holding",
"address": 1,
"scale": 0.1,
"writable": true
}
}
]
}
]
}

Load it:

await using var app = ZeusHost.Create(builder => builder.AddJsonFile("zeus.json"));
await app.StartAsync();

var temperature = app.Points.Get<double>("temperature");

Sections​

SectionMeaning
acquisitionPolling interval and whether to poll immediately after startup
reconnectAutomatic reconnect delay, backoff, jitter, max attempts, and circuit-break wait after channel failures
channelsCommunication lines such as serial, TCP, UDP, and virtual channels
devicesDevices such as Modbus RTU/TCP/ASCII, Mitsubishi MC, Siemens S7, Omron FINS, Omron Host Link, EtherNet/IP, DL/T 645, IEC104, MQTT, or SNMP
pointsBusiness points on a device, such as temperature, setpoint, or running state

Each device channel must reference an already declared channel name.

In the current configuration format, channel, device, and point roots only carry structural fields. Transport settings, protocol parameters, addresses, scaling, write-back, and alarms belong in each object's options. Legacy root-level fields such as channel host / portName or point address / writable fail during load.

Virtual Configuration Without Hardware​

Replace a serial channel with a virtual Modbus slave:

{
"name": "bus",
"type": "virtual",
"options": {
"responder": "modbus",
"unitId": 1,
"transport": "rtu"
}
}

Set options.transport to rtu, tcp, or ascii to match the master framing. When the field device is ready, switch back to serial:

{
"name": "bus",
"type": "serial",
"options": {
"portName": "COM3",
"baudRate": 9600
}
}

Channel Fields​

Root fieldMeaning
nameZeus channel name
typevirtual, serial, tcp, tcp-server, udp, or udp-server
startupStartup failure mode: required is the default and aborts host startup on open failure; optional / degraded lets the host start and recover the failed channel through reconnect
optionsChannel parameters and virtual responder parameters, included in hot-reload fingerprints

Common channels[].options:

options fieldApplies toMeaning
portName / baudRateserialCOM port and baud rate. Set parity, data bits, and stop bits in code with AddSerialPort(name, options => …)
host / porttcp / udpRemote host and port
localAddress / localPorttcp-server / udp-serverLocal bind/listen settings; udp can also use localPort for a fixed local port
respondervirtualmodbus, mc, s7, fins, host-link, mewtocol, ethernet-ip, dlt645, iec104, mqtt, or snmp
transportvirtualVirtual Modbus framing: rtu, tcp, or ascii; virtual FINS framing: udp or tcp
meterAddressvirtual + dlt645DL/T 645 virtual meter address, 12 decimal digits
commonAddressvirtual + iec104IEC104 virtual station common address, default 1
snmpCommunity / snmpWriteCommunityvirtual + snmpSNMP virtual Agent read/write communities

Device Fields​

Root fieldMeaning
nameZeus device name
channelChannel name to bind
typemodbus-rtu, modbus-tcp, modbus-ascii, mitsubishi-mc, siemens-s7, omron-fins, omron-host-link, panasonic-mewtocol, ethernet-ip, dlt645, iec104, mqtt, or snmp
optionsProtocol parameters, included in device hot-reload fingerprints
pointsPeriodically acquired points

Common devices[].options:

options fieldMeaning
transportFINS framing: udp or tcp, default udp
unitIdModbus unit id, Host Link unit number, or MEWTOCOL station number
frameType / encodingMitsubishi MC frame and encoding
MC routing fieldsnetworkNumber, pcNumber, ioNumber, stationNumber, monitoringTimer, and serialNumber
S7 fieldsrack, slot, localTsap, remoteTsap, and requestedPduLength
FINS routing fieldsDestination/source addressing, gateway, ICF, and TCP node handshake settings
wordOrderFINS / Host Link / MEWTOCOL 32-bit value word order
DL/T 645 fieldsmeterAddress, wakeUpPreambleCount, password, and operatorCode
IEC104 fieldscommonAddress, originatorAddress, and interrogationQualifier
MQTT connection fieldsClient id, credentials, keep-alive, clean session, will, packet size, keep-alive, and reconnect settings
SNMP fieldssnmpCommunity, snmpWriteCommunity, and snmpInitialRequestId

Point Fields​

Root fieldMeaning
namePoint name
optionsPoint address, type, scaling, alarm, and write-back parameters, included in point fingerprints

Common points[].options:

options fieldMeaning
topicMQTT topic; defaults to the point name and cannot contain + or #
mqttQos / mqttRetainMQTT subscription/write-back QoS and retained write-back setting
tableModbus table: holding, input, coil, or discrete
deviceCodeMitsubishi MC device code: D, M, X, Y, W, R, ZR
areaS7/FINS/Host Link/MEWTOCOL area
tagEtherNet/IP tag path
dataTypeProtocol-specific point type; IEC104 supports single-point, normalized, scaled, and short-float; MQTT supports text, boolean, int32, int64, double, and bytes
dataLengthDL/T 645 data payload length, excluding the 4-byte DI
address0-based address; DL/T 645 DI or IEC104 IOA; strings such as "0x10" are accepted where applicable
bitBit offset for bit points
scaleEngineering scale for numeric points
lowAlarmLimit / highAlarmLimitAlarm thresholds after scaling
writableEnables write-back by point name; write it as options.writable in JSON

Hot Reloaded Changes​

By default, AddJsonFile(path, watch: true) watches the file. After save, Zeus runs ReloadAsync: acquisition interval and reconnect options are written into the running option singletons, and channels/devices are added, removed, or rebuilt from the diff.

ChangeTakes effect immediatelyNotes
acquisition.intervalMillisecondsYesThe next acquisition round uses the new interval
acquisition.pollImmediatelyYesStored in options; affects the first round after a later restart
reconnect.*YesThe next reconnect backoff uses the new values
channels[].startup / channels[].optionsYesStartup policy or extended option changes rebuild the same-named channel
COM port, baud rate, TCP/UDP addressYesThe old channel is closed and a new instance is registered
Added/removed channels, devices, or pointsYesSynchronized by name
devices[].options / points[].optionsYesExtended option changes rebuild the device so protocol plugins reread parameters
Slave/unit address fields such as unitId, meterAddress, or commonAddressYesThe device is rebuilt

Changing channel parameters creates a new channel instance. DataReceived, StateChanged, and PacketTraced subscriptions attached to the old instance are migrated to the new channel with the same name. If application code keeps an old IChannel reference, call Channels.Get again after hot reload.

If JSON syntax is invalid, Zeus keeps the last valid configuration and logs the error. If you do not want file watching, call await app.ReloadAsync(path) manually. When only the acquisition interval changes and topology is unchanged, ReloadAsync keeps the device instances.

When you call ReloadAsync(path, cancellationToken) manually and the token is already canceled, Zeus returns cancellation before writing new acquisition intervals, reconnect options, or topology changes. If hot reload fails partway through, Zeus tries to restore the previous valid topology; for plain JSON syntax errors, the file watcher logs a warning and keeps the current configuration.

Reconnect Options​

"reconnect": {
"enabled": true,
"initialDelayMilliseconds": 1000,
"maxDelayMilliseconds": 30000,
"backoffMultiplier": 2,
"maxAttempts": 0,
"jitterRatio": 0.2,
"circuitBreakMilliseconds": 0
}

maxAttempts: 0 means unlimited attempts. A positive value stops reconnect after the limit, or enters the configured circuit-break wait before starting over when circuitBreakMilliseconds is greater than zero. jitterRatio spreads reconnect traffic after shared network failures; 0.1 to 0.3 is a practical field range.

{
"channels": [
{
"name": "host-link",
"type": "serial",
"options": {
"portName": "COM3",
"baudRate": 9600
}
}
],
"devices": [
{
"name": "plc",
"channel": "host-link",
"type": "omron-host-link",
"options": {
"unitId": 0
},
"points": [
{
"name": "temperature",
"options": {
"area": "dm",
"address": 100,
"dataType": "word",
"scale": 0.1,
"writable": true
}
},
{
"name": "running",
"options": {
"area": "cio",
"address": 10,
"bit": 0,
"dataType": "bit",
"writable": true
}
}
]
}
]
}

Virtual Host Link PLC:

{
"name": "host-link",
"type": "virtual",
"options": {
"responder": "host-link",
"unitId": 0
}
}

IEC104 Example​

Real station over TCP:

{
"channels": [
{
"name": "iec-link",
"type": "tcp",
"options": {
"host": "192.168.1.20",
"port": 2404
}
}
],
"devices": [
{
"name": "station",
"channel": "iec-link",
"type": "iec104",
"options": {
"commonAddress": 7
},
"points": [
{
"name": "running",
"options": {
"address": 1,
"dataType": "single-point",
"writable": true
}
},
{
"name": "temperature",
"options": {
"address": 100,
"dataType": "scaled",
"scale": 0.1,
"writable": true
}
},
{
"name": "pressure",
"options": {
"address": 200,
"dataType": "short-float"
}
}
]
}
]
}

Virtual station:

{
"channels": [
{
"name": "iec-link",
"type": "virtual",
"options": {
"responder": "iec104",
"commonAddress": 7
}
}
],
"devices": [
{
"name": "station",
"channel": "iec-link",
"type": "iec104",
"options": {
"commonAddress": 7
},
"points": [
{
"name": "running",
"options": {
"address": 1,
"dataType": "single-point",
"writable": true
}
},
{
"name": "temperature",
"options": {
"address": 100,
"dataType": "scaled",
"scale": 0.1,
"writable": true
}
},
{
"name": "pressure",
"options": {
"address": 200,
"dataType": "short-float"
}
}
]
}
]
}

IEC104 address is the three-byte IOA. single-point writes use single commands; normalized, scaled, and short-float write-back uses the matching setpoint command.

Sample JSON files live under samples/Zeus.Samples.Console.Config; copy zeus-modbus-ascii.json, zeus-dlt645.json, or zeus-iec104.json for protocol-specific examples.