AssociationConfig
AssociationConfig sets how the master works with one outstation. The outstation's address isn't part of it: you pass
the address separately when you create the association. The configuration answers these
questions:
| Decision | Why it matters |
|---|---|
| What to read at startup | The integrity poll gives you the current value of every point, at startup and after the outstation restarts |
| Whether the outstation reports unsolicited | Which event classes the master turns off and back on at startup. Choose none for an outstation that doesn't report unsolicited, and poll it instead |
| Whether and how to synchronize time | Whether the master sets the outstation's clock when it asks for the time, and with which procedure. See Time Synchronization |
| How to react to the outstation's indications | Which event classes the master scans when the outstation reports events, and whether it runs an integrity poll when the outstation's event buffer overflows |
| How long to wait, and how to retry | How long the master waits for each response, and how it retries automatic tasks that fail |
| When to check a quiet link | How long the link can be silent before the master sends a keep-alive, if at all |
| How many requests can wait | How many of your requests can queue on the association before new ones fail at once |
The examples configure an association like this:
- Rust
- C
- C++
- Java
- C#
fn get_association_config() -> AssociationConfig {
let mut config = AssociationConfig::new(
// disable unsolicited first (Class 1/2/3)
EventClasses::all(),
// after the integrity poll, enable unsolicited (Class 1/2/3)
EventClasses::all(),
// perform startup integrity poll with Class 1/2/3/0
Classes::all(),
// don't automatically scan Class 1/2/3 when the corresponding IIN bit is asserted
EventClasses::none(),
);
config.auto_time_sync = Some(TimeSyncProcedure::Lan);
config.keep_alive_timeout = Some(Duration::from_secs(60));
config
}
dnp3_association_config_t get_association_config(void)
{
dnp3_association_config_t config = dnp3_association_config_init(
// disable unsolicited first (Class 1/2/3)
dnp3_event_classes_all(),
// after the integrity poll, enable unsolicited (Class 1/2/3)
dnp3_event_classes_all(),
// perform startup integrity poll with Class 1/2/3/0
dnp3_classes_all(),
// don't automatically scan Class 1/2/3 when the corresponding IIN bit is asserted
dnp3_event_classes_none());
config.auto_time_sync = DNP3_AUTO_TIME_SYNC_LAN;
config.keep_alive_timeout = 60;
return config;
}
dnp3::AssociationConfig config(
// disable unsolicited first (Class 1/2/3)
dnp3::EventClasses::all(),
// after the integrity poll, enable unsolicited (Class 1/2/3)
dnp3::EventClasses::all(),
// perform startup integrity poll with Class 1/2/3/0
dnp3::Classes::all(),
// don't automatically scan Class 1/2/3 when the corresponding IIN bit is asserted
dnp3::EventClasses::none()
);
config.auto_time_sync = dnp3::AutoTimeSync::lan;
config.keep_alive_timeout = std::chrono::seconds(60);
private static AssociationConfig getAssociationConfig() {
return new AssociationConfig(
// disable unsolicited first (Class 1/2/3)
EventClasses.all(),
// after the integrity poll, enable unsolicited (Class 1/2/3)
EventClasses.all(),
// perform startup integrity poll with Class 1/2/3/0
Classes.all(),
// don't automatically scan Class 1/2/3 when the corresponding IIN bit is asserted
EventClasses.none())
.withAutoTimeSync(AutoTimeSync.LAN)
.withKeepAliveTimeout(Duration.ofSeconds(60));
}
private static AssociationConfig GetAssociationConfig()
{
return new AssociationConfig(
// disable unsolicited first (Class 1/2/3)
EventClasses.All(),
// after the integrity poll, enable unsolicited (Class 1/2/3)
EventClasses.All(),
// perform startup integrity poll with Class 1/2/3/0
Classes.All(),
// don't automatically scan Class 1/2/3 when the corresponding IIN bit is asserted
EventClasses.None()
)
.WithAutoTimeSync(AutoTimeSync.Lan)
.WithKeepAliveTimeout(TimeSpan.FromSeconds(60));
}
Initialization
The master turns unsolicited reporting off, reads everything with an integrity poll, then turns unsolicited reporting back on. That way it starts from the current value of every point before changes stream in. If the outstation asks for the time and automatic time synchronization is configured, the master synchronizes it before the integrity poll:
The master skips any step whose classes you leave empty. For an outstation that doesn't support unsolicited reporting, set the classes to disable and to enable at startup to none, and the master performs only the integrity poll.
Scheduling
The master runs these startup tasks, and others such as clearing the restart bit and automatic event scans, alongside your requests and polls. See Automatic Tasks and Scheduling for when each one runs and how a channel orders the work of its associations.