platform_driver.interfaces package
Driver Development
New drivers are implemented by subclassing BaseInterface
.
While it is possible to create an Agent which handles communication with a new device it will miss out on the benefits of creating a proper interface for the Platform Driver Agent.
Creating an Interface for a device allows users of the device to automatically benefit from the following platform features:
Existing Agents can interact with the device via the Actuator Agent without any code changes.
- Configuration follows the standard form of other devices. Existing and future tools
for configuring devices on the platform will work with the new device driver.
Historians will automatically capture data published by the new device driver.
Device data can be graphed in VOLTTRON Central in real time.
- If the device can receive a heartbeat signal the driver framework can be configured to
automatically send a heartbeat signal.
- When the configuration store feature is rolled out the device can by dynamically configured
through the platform.
Creating a New Interface
To create a new device driver create a new module in the
PlatformDriverAgent.platform_driver.interfaces
package. The name of
this module will be the name to use in the “driver_type” setting in
a driver configuration file in order to
load the new driver.
In the new module create a subclass of BaseInterface
called Interface.
The Interface class must implement the following methods:
These methods are required but can be implemented using the BasicRevert
mixin.
Each point on the device must be represented by an instance of the
BaseRegister
. Create one or more subclasses of BaseRegister
as needed to represent the points on a device.
Interface Configuration and Startup
When processing a driver configuration file
the Platform Driver Agent will use the “driver_type” setting to automatically find and load the
appropriate Interface
class for the desired driver.
After loading the class the Platform Driver Agent will call BaseInterface.configure()
with the contents of the “driver_config” section of the
driver configuration file
parsed into a python dictionary and the contents of the file referenced in
“registry_config” entry.
BaseInterface.configure()
must setup register representations of all points
on a device by creating instances of BaseRegister
(or a subclass) and adding them
to the Interface with BaseInterface.insert_register()
.
After calling BaseInterface.configure()
the Platform Driver Agent
will use the created registers to create meta data for each point on the device.
Device Scraping
The work scheduling and publish periodic device scrapes is handled by
the Platform Driver Agent. When a scrape starts the Platform Driver Agent calls the
BaseInterface.scrape_all()
. It will take the results of the
call and attach meta data and and publish as needed.
Device Interaction
Requests to interact with the device via any method supported by the platform are routed to the correct Interface instance by the Platform Driver Agent.
Most commands originate from RPC calls to the
Actuator Agent
and are forwarded
to the Platform Driver Agent.
- A command to set the value of a point on a device results in a call to
- A request for the current value of a point on a device results in a call to
- A request to revert a point on a device to its default state results in a call to
- A request to revert an entire device to its default state results in a call to
Registers
The Platform Driver Agent uses the BaseInterface.get_register_names()
and
BaseInterface.get_register_by_name()
methods to get registers to setup meta data.
This means that its a requirement to use the BaseRegister class to store information about points on a devices.
Using the BasicRevert Mixin
If the device protocol has no support for reverting to a default state an Interface
this functionality can be implemented with the BasicRevert
mixin.
When using the BasicRevert
mixin you must specify it first in the list
of parent classes, otherwise it won’t Python won’t detect that the
BaseInterface.revert_point()
and BaseInterface.revert_all()
have
been implemented.
If desired the BasicRevert.set_default()
can be used by the Interface class
to set values for each point to revert to.
- class platform_driver.interfaces.BaseInterface(vip=None, core=None, **kwargs)[source]
Bases:
object
Main class for implementing support for new devices.
All interfaces must subclass this.
- Parameters
vip – A reference to the PlatformDriverAgent vip subsystem.
core – A reference to the parent driver agent’s core subsystem.
- abstract configure(config_dict, registry_config_str)[source]
Configures the
Interface
for the specific instance of a device.- Parameters
This method must setup register representations of all points on a device by creating instances of
BaseRegister
(or a subclass) and adding them to the Interface withBaseInterface.insert_register()
.
- abstract get_point(point_name, **kwargs)[source]
Get the current value for the point name given.
- Parameters
point_name (str) – Name of the point to retrieve.
kwargs – Any interface specific parameters.
- Returns
Point value
- get_register_by_name(name)[source]
Get a register by it’s point name.
- Parameters
name (str) – Point name of register.
- Returns
An instance of BaseRegister
- Return type
- get_register_names_view()[source]
Get a dictview of register names. :return: Dictview of names :rtype: dictview
- get_registers_by_type(reg_type, read_only) List[BaseRegister] [source]
Get a list of registers by type. Useful for an
Interface
that needs to categorize registers by type when doing a scrape.
- insert_register(register)[source]
Inserts a register into the
Interface
.- Parameters
register (
BaseRegister
) – Register to add to the interface.
- abstract revert_all(**kwargs)[source]
Revert entire device to it’s default state
- Parameters
kwargs – Any interface specific parameters.
- abstract revert_point(point_name, **kwargs)[source]
Revert point to it’s default state.
- Parameters
kwargs – Any interface specific parameters.
- abstract scrape_all()[source]
Method the Platform Driver Agent calls to get the current state of a device for publication.
- Returns
Point names to values for device.
- Return type
- set_multiple_points(path, point_names_values, **kwargs)[source]
Set multiple points on the interface.
- abstract set_point(point_name, value, **kwargs)[source]
Set the current value for the point name given.
Implementations of this method should make a reasonable effort to return the actual value the point was set to. Some protocols/devices make this difficult. (I’m looking at you BACnet) In these cases it is acceptable to return the value that was requested if no error occurs.
- Parameters
point_name (str) – Name of the point to retrieve.
value – Value to set the point to.
kwargs – Any interface specific parameters.
- Returns
Actual point value set.
- class platform_driver.interfaces.BaseRegister(register_type, read_only, pointName, units, description='')[source]
Bases:
object
Class for containing information about a point on a device. Should be extended to support the device protocol to be supported.
The member variable
python_type
should be overridden with the equivalent python type object. Defaults toint
. This is used to generate meta data.- Parameters
The Platform Driver Agent will use
BaseRegister.get_units()
to populate metadata for publishing. When instantiating register instances be sure to provide a useful string for the units argument.
- class platform_driver.interfaces.BasicRevert(**kwargs)[source]
Bases:
object
A mixin that implements the
BaseInterface.revert_all()
andBaseInterface.revert_point()
methods on anInterface
.It works by tracking change to all writable points until a set_point call is made. When this happens the point is marked dirty and the previous value is remembered. When a point is reverted via either a revert_all or revert_point call the dirty values are set back to the clean value using the
BasicRevert._set_point()
method.As it must hook into the setting and scraping of points it implements the
BaseInterface.scrape_all()
andBaseInterface.set_point()
methods. It then addsBasicRevert._set_point()
andBasicRevert._scrape_all()
to the abstract interface. An existing interface that wants to use this class can simply mix it in and rename it’s set_point and scrape_all methods to _set_point and _scrape_all respectively.An
BaseInterface
may also override the detected clean value with its own value to revert to by callingBasicRevert.set_default()
. While default values can be set anytime they should be set in theBaseInterface.configure()
call.- revert_all(**kwargs)[source]
Implementation of
BaseInterface.revert_all()
Calls
BasicRevert._set_point()
with point_name and the value to revert the point to for every writable point on a device.Currently **kwargs is ignored.
- revert_point(point_name, **kwargs)[source]
Implementation of
BaseInterface.revert_point()
Revert point to its default state.
Calls
BasicRevert._set_point()
with point_name and the value to revert the point to.- Parameters
point_name (str) – Name of the point to revert.
Currently **kwargs is ignored.
- scrape_all()[source]
Implementation of
BaseInterface.scrape_all()
- set_default(point, value)[source]
Set the value to revert a point to.
- Parameters
point (str) – name of point to set.
value – value to set the point to.
- set_point(point_name, value)[source]
Implementation of
BaseInterface.set_point()
Passes arguments through to
BasicRevert._set_point()
- class platform_driver.interfaces.RevertTracker[source]
Bases:
object
A helper class for tracking the state of writable points on a device.
- clear_dirty_point(point)[source]
Clears the dirty flag on a point.
- Parameters
point (str) – Name of dirty point flag to clear.
- get_all_revert_values()[source]
Returns a dict of points to revert values.
If no default is set use the clean value, otherwise returns the default value.
If no default value is set and a no clean values have been submitted a point value will be an instance of
DriverInterfaceError
.
- get_revert_value(point)[source]
Returns the clean value for a point if no default is set, otherwise returns the default value.
If no default value is set and a no clean values have been submitted raises
DriverInterfaceError
.- Parameters
point (str) – Name of point to get.
- Returns
Value to revert to.
- mark_dirty_point(point)[source]
Sets the dirty flag on a point.
Ignores points with a default value.
- Parameters
point (str) – Name of point flag to dirty.
Subpackages
- platform_driver.interfaces.chargepoint package
- platform_driver.interfaces.dnp3 package
- platform_driver.interfaces.modbus_tk package
- Subpackages
- platform_driver.interfaces.modbus_tk.maps package
- platform_driver.interfaces.modbus_tk.tests package
- platform_driver.interfaces.modbus_tk.client module
- platform_driver.interfaces.modbus_tk.config_cmd module
- platform_driver.interfaces.modbus_tk.helpers module
- platform_driver.interfaces.modbus_tk.server module
- Subpackages
- platform_driver.interfaces.ted_meter package
- platform_driver.interfaces.bacnet module
- platform_driver.interfaces.ecobee module
- platform_driver.interfaces.fakedriver module
- platform_driver.interfaces.home_assistant module
- platform_driver.interfaces.modbus module
- platform_driver.interfaces.obix module
- platform_driver.interfaces.radiothermostat module
- platform_driver.interfaces.rainforesteagle module
- platform_driver.interfaces.rainforestemu2 module
- platform_driver.interfaces.restful module
- platform_driver.interfaces.thermostat_api module
- platform_driver.interfaces.universal module