-
Notifications
You must be signed in to change notification settings - Fork 156
Unified Device Configuration
The new macchina.io device tree subsystem will also provide a unified way of configuring devices.
The current implementation of devices is such that devices are implemented in bundles.
When a device bundle is started, the BundleActivator
reads the device configuration for
the bundle's devices from the global configuration and attempts to create the respective
device. If creation of a device fails (e.g., because the device is not connected), the
device won't be available until the macchina.io application, or at least the specific
bundle, is restarted.
This article proposes an alternative device configuration mechanism that allows for more dynamic, and unified configurability of devices. Ideally, a whole device tree shall be described by a single configuration source.
The configuration source can be a JSON document or a SQLite database.
Both the device tree and individual device properties are defined via a tree structure consisting of device nodes.
Example: the following device structure:
/
Battery/
Voltage
Temperature
ChargeLevel
would be represented by the following JSON configuration, assuming that all sensor devices are Modbus-RTU based.
{
"rootDevice":
{
"device": "io.macchina.composite",
"fragments":
[
{
"device": "io.macchina.composite",
"name": "Battery",
"fragments":
[
{
"device": "io.macchina.modbus.sensor",
"name": "Temperature",
"configuration":
{
"master": "io.macchina.modbus.rtu.bus1",
"sampleInterval": 5000,
"slaveId": 1,
"properties":
{
"value":
{
"registerAddress": "0x19",
"type": "float32",
"physicalQuantity": "temperature",
"physicalUnit": "Cel"
}
}
}
},
{
"device": "io.macchina.modbus.sensor",
"name": "Voltage",
"configuration":
{
"master": "io.macchina.modbus.rtu.bus1",
"sampleInterval": 1000,
"slaveId": 2,
"properties":
{
"value":
{
"registerAddress": "0x2300",
"type": "ScaledInt16",
"slope": 0.01,
"intercept": 0.0,
"physicalQuantity": "voltage",
"physicalUnit": "V"
}
}
}
},
{
"device": "io.macchina.modbus.sensor",
"name": "ChargeLevel",
"configuration":
{
"master": "io.macchina.modbus.rtu.bus1",
"sampleInterval": 10000,
"slaveId": 2,
"properties":
{
"value":
{
"registerAddress": "0x2400",
"type": "UInt16"
}
}
}
}
]
}
]
}
}
The device tree is created with the help of factory services. For every device type, a factory service that can create and configure instances of that specific type must be registered with the service registry.
The interface of the DeviceFactory service looks as follows:
class DeviceFactoryService: public Poco::OSP::Service
{
public:
virtual Poco::OSP::ServiceRef::Ptr createDevice(const std::string& name, Poco::Util::AbstractConfiguration::Ptr pDeviceConfig) = 0;
/// Creates and registers a device service based on the given configuration.
///
/// The given device configuration is the device-specific `configuration` subtree of the entire device tree
/// configuration tree. The contents of the device configuration are specific to each device class.
};
For each device type that supports the device tree, an instance of a subclass of the DeviceFactoryService
class
must be registered with the service registry. The service name should be equal to the device type identifier,
e.g. "io.macchina.modbus.sensor" for generic Modbus sensor devices.
When creating the device tree, for each device node in the device tree configuration, the corresponding factory
service is looked up in the service registry, using the value of the "device" configuration property.
The createDevice()
method is then called, and passed the device name (value of the "name" property) and configuration
(value of the "configuration" property).
The factory is responsible for setting up the device service object, assigning a unique service name, and registering the device
with the service registry. The resulting Poco::OSP::ServiceRef
object is then returned. The properties of the returned ServiceRef
will be amended by the device tree, setting the io.macchina.composite
property to the parent composite device's service name.