Using the Device Manager - FREEDM-DGI/FREEDM GitHub Wiki

CDeviceManager is the interface between broker modules and the device architecture. CDeviceManager allows modules to access sets of devices and read device signals through a convenient interface. It's important to remember that the manager is responsible only for the devices attached to its DGI - you can't use this class to learn about the devices of another DGI in the system.

This page will cover the more commonly-used operations of CDeviceManager from the perspective of a broker module.

Singleton

CDeviceManager is a singleton, accessed through CDeviceManager::Instance(). It is therefore not possible to copy CDeviceManager.

The following example obtains a reference to the device manager within local scope:

device::CDeviceManager & manager = device::CDeviceManager::Instance();

But generally you will access the device manager "on the fly," as shown in the examples below.

Retrieving and Using a Device

A device object (of type CDevice::Pointer) can be retrieved using CDeviceManager::GetDevice. This function expects a string containing the name of the device, as specified in the adapter specification.

For example, if the adapter specification contains the following device, and you want to know its current gateway value:

<entry index = "1">
    <device>MySstDevice</device>
    <signal>gateway</signal>
    <type>Sst</type>
</entry>

The following code gets an CDevice::Pointer to the device and reads its gateway value:

device::CDevice::Pointer devPtr = CDeviceManager::Instance().GetDevice("MySstDevice");
SignalValue gateway = devPtr->GetState("gateway");

Of course, you can only call CDeviceManager::GetDevice with the string name of a device that you know is attached to the DGI. If the device does not exist, a warning will be logged and an invalid pointer will be returned. Attempting to dereference this pointer will cause a segfault. Similarly, you should only use CDevice::GetState when you are sure that the string parameter you are sending represents a valid signal for that device (as defined in the adapter specification); behavior when the device signal is invalid is adapter-defined, though it's reasonable to expect adapters to throw a std::runtime_error on an invalid get operation (crashing the system).

Working with Groups of Devices

The device manager provides several functions for working with groups of devices. They are presented here, in order of increasing abstraction.

GetDevicesOfType

You can use CDeviceManager::GetDevicesOfType to access a set containing every device of a particular type attached to the DGI. It is then possible to iterate over this set to access the individual device pointers.

using namespace device;
std::set<CDevice::Pointer> drerSet = CDeviceManager::instance().GetDevicesOfType("Drer");

If the device type ("Drer") is misspelt, or there are no devices of that type registered with the system, then this function call will return an empty set.

GetValues

CDeviceManager::GetValues might be a bit unintuitive. You give it a type of device and a signal of that type of device, and it returns a multiset containing the value for that signal on every device of that type on the DGI. This is equivalent to calling GetDevicesOfType and then calling the GetState function on each of the returned devices. For example, if the DGI has four DESDs, with storage 1.0, 1.0, 1.5, and 2.0, the following call would return a multiset containing those values:

using namespace device;
std::multiset<SignalValue> storage = CDeviceManager::Instance().GetValues("Desd", "storage")

As with the previous function calls, the returned set will be empty if the device type ("Desd") is invalid. And if the device state ("storage") is invalid, an exception will be thrown which if not caught will cause the DGI to terminate.

GetNetValue

CDeviceManager::GetNetValue is a convenient way to add up the total value of all signals for a particular type of device. It's basically the same as summing all the terms returned by GetValues, but with nicer syntax. For example, the following retrieves the total generation of all DESDs on the DGI:

using namespace device;
SignalValue totalGen = CDeviceManager::Instance().GetNetValue("Drer", "generation");

The net value will be 0 when the device type ("Drer") is invalid. This function should be used with care as it is not possible to determine whether this 0 refers to the lack of any devices or a set of devices whose total happens to be exactly 0.

⚠️ **GitHub.com Fallback** ⚠️