Skip to main content

Database

You can use the Database class to manipulate the measurement types and values that the outstation exposes to the master. Note that while it's called a "database", it's really just a in-memory data structure protected by a mutex.

All database operations are executed inside a transaction protected by a mutex. Operations within a transaction are applied to the database and the event buffers atomically. If unsolicited responses are enabled, the outstation will automatically decide if an unsolicited response should be sent at the end of the transaction.

The database may be accessed in a transaction in two different ways:

  1. When measurement values need to updated due to some external changes, the user can call Outstation.transaction to acquire a locked reference to the database and make changes.

  2. Callbacks on the ControlHandler provide a DatabaseHandle which also has an identical transaction method. Similarly, the freeze operations on OutstationApplication provide this handle as well.

tip

Structure any common update code to operate on the Database type and not depend on Outstation or DatabaseHandle.

Adding Points

You must initialize the points before the outstation exposes any measurement data. While you should do this when you create the outstation, you can add points to a running outstation as well. Each measurement type has unique configuration including:

  • An optional event class assignment for the point
  • Default static and event variations for the type
  • Type-specific dead-bands that default to zero (Binary points have no deadband)

When you add a point, it is assigned the following default value with RESTART flags:

  • Binary points are set to false
  • Numeric values are set to 0
  • Double-bit Binary points set to Indeterminate
  • Octet Strings are set to the value of [0x00]

Update the value after adding the point if you don't want a connecting master to see the points with a RESTART flag set.

outstation.transaction(|db| {
for i in 0..10 {
db.add(i, Some(EventClass::Class1), BinaryInputConfig::default());
db.add(
i,
Some(EventClass::Class1),
DoubleBitBinaryInputConfig::default(),
);
db.add(
i,
Some(EventClass::Class1),
BinaryOutputStatusConfig::default(),
);
db.add(i, Some(EventClass::Class1), CounterConfig::default());
db.add(i, Some(EventClass::Class1), FrozenCounterConfig::default());
db.add(i, Some(EventClass::Class1), AnalogInputConfig::default());
db.add(
i,
Some(EventClass::Class1),
AnalogOutputStatusConfig::default(),
);
db.add(i, Some(EventClass::Class1), OctetStringConfig);
}
});

Updating Points

You can update a point value in a new transaction or in the same transaction you used to initialize it. This is useful if the outstation has local access to values at startup, such as via a local ADC. When initializing point values, it is recommended to use the UpdateOptions::no_event().

The Flags value can be built by ORing values from the constants available in Flag. Note that not all Flag values are available in every point type.

The UpdateOptions struct lets you precisely control how a point update is processed. Use the default constructor to:

  • Update the static value
  • Produce an event if the point value changes in a way that exceeds the deadband or if the flags change
tip

Use the UpdateOptions to ignore event creation during startup initialization if you don't want to create events for the initial values.

Getting Point Values

Some applications may wish to use the Database as a cache of the most recent value. Each type has a getter method to retrieve the most recently assigned value.

note

Since the point may not be defined, the getters can fail. If you try to retrieve a point that doesn't exist using Java and C#, an exception will be thrown.

Removing Points

Most applications don't need to remove points, but the option is there in case you want to remove points from a running outstation. There is a type-specific function for removing every point type given its index.

note

Removing a point stops the outstation from reporting static data for that point. However, it does NOT remove any queued events for that point from the event buffer. Those events will remain in the event buffer until they are reported and cleared by confirmation.