Interface Protocol<T extends Agent<T,?,?>>
Agent
and should get its' configuration parameters from the Attribute
s
of this Agent
, how this is done is up to the Agent
/Protocol
creator to determine.
Lifecycle
When the system is started or a CRUD operation is performed on anAgent
then the following calls are made:
Destroy existing protocol instance
If a protocol instance already exists for theAgent
then the following calls are made on that instance:
unlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
- Called for each attribute linked to theAgent
stop(org.openremote.model.Container)
Create/initialise protocol instance
If theAgent
was deleted or Agent.isDisabled()
then nothing happens otherwise:
start(org.openremote.model.Container)
- If this call throws an exception then it is assumed that a permanent failure has occurred (i.e. theAgent
is incorrectly configured) and this Agent's status will be marked asConnectionStatus.ERROR
and attribute linking will not occur.linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
- Called for each attribute linked to theAgent
Configuring protocol instances
EachAgent
asset has its' own Protocol
instance and this instance is responsible for managing only
the attributes linked to that specific instance, it is up to the specific Agent
type to initialise an
instance of its' own Protocol
.
Connecting attributes to actuators and sensors
Attribute
s of Asset
s can be linked to a protocol instance by creating an MetaItemType.AGENT_LINK
MetaItem
on an attribute. Besides the MetaItemType.AGENT_LINK
, other
protocol-specific meta items may also be required when an asset attribute is linked to a protocol
instance. Attributes linked to a protocol instance will get passed to the protocol via a call to linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
.
The protocol handles read and write of linked attributes:
If the actual state of the device (or service) changes, the linked protocol writes the new state into the attribute
by sending an AttributeEvent
using the
invalid @link
{@link #
AttributeEvent
messages on the
invalid reference
#SENSOR_QUEUE
invalid reference
#SENSOR_QUEUE_SOURCE_PROTOCOL
If the user writes a new value into the linked attribute, the protocol translates this value change into a device (or
service) action. Write operations on attributes linked to an Agent
can be consumed by the agent's protocol on
the
invalid reference
#ACTUATOR_TOPIC
AttributeEvent
. Each message also contains the
target protocol name in header
invalid reference
#ACTUATOR_TOPIC_TARGET_PROTOCOL
To simplify protocol development some common protocol behaviour is recommended for generic protocols:
Inbound value conversion (Protocol -> Linked Attribute)
Standard value filtering and/or conversion should be performed in the following order:
- Configurable value filtering which allows the value produced by the protocol to be filtered through any
number of
ValueFilter
s before being written to the linked attribute (seeAgentLink.getValueFilters()
) - Configurable value conversion which allows the value produced by the protocol to be converted in a configurable
way before being written to the linked attribute (see
AgentLink.getValueConverter()
) - Automatic basic value conversion should be performed when the type of the value produced by the
protocol and any configured value conversion does not match the linked attributes underlying value type; this
basic conversion should use the
ValueUtil.convert(java.lang.Object, java.lang.Class<T>)
method
Outbound value conversion (Linked Attribute -> Protocol)
Standard value conversion should be performed in the following order:- Configurable value conversion which allows the value sent from the linked attribute to be converted in a
configurable way before being sent to the protocol for processing (see
AgentLink.getWriteValueConverter()
) - Configurable dynamic data insertion into attribute write value before processing by the protocol; it also allows
the written value to be fixed or statically converted (see
AgentLink.getWriteValue()
).
AttributeEvent
as well as the converted value should be made available.
NOTE: That start(org.openremote.model.Container)
will always be called
before linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
and unlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
will always be called before
stop(org.openremote.model.Container)
.
The following summarises the method calls protocols should expect:
Agent
asset is created/loaded:
start(org.openremote.model.Container)
linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
Agent
is modified:
unlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
stop(org.openremote.model.Container)
start(org.openremote.model.Container)
linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
Agent
is removed:
unlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
stop(org.openremote.model.Container)
Attribute linked to Agent
is created/loaded:
Attribute linked to Agent
is modified:
unlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
linkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
Attribute link to Agent
is removed:
-
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptiongetAgent()
Get theAgent
associated with this protocol instance.Map
<AttributeRef, Attribute<?>> Get a URI that describes this specific protocol instanceGet the name for this protocolvoid
linkAttribute
(String assetId, Attribute<?> attribute) Links anAttribute
to its' agent; the agent would have been connected before this call.boolean
default String
prefixLogMessage
(String msg) Prefixes the log message withgetProtocolName()
andgetProtocolInstanceUri()
.void
An Attribute event (write) has been requested for an attribute linked to this protocol; implementations should handle multithreaded requests or use some sort of synchronisation for thread safety.void
setAssetService
(ProtocolAssetService assetService) void
Called before any calls tolinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
to allow the protocol to perform required tasks withContainerService
s (e.g.void
Called once all linked attributes have been unlinked viaunlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
to allow the protocol to perform required tasks withContainerService
s e.g.void
unlinkAttribute
(String assetId, Attribute<?> attribute) Un-links anAttribute
from its' agent; the agent will still be connected during this call.void
updateLinkedAttribute
(AttributeRef attributeRef, Object value) void
updateLinkedAttribute
(AttributeRef attributeRef, Object value, long timestamp)
-
Field Details
-
LOG
-
-
Method Details
-
prefixLogMessage
Prefixes the log message withgetProtocolName()
andgetProtocolInstanceUri()
. -
getProtocolName
String getProtocolName()Get the name for this protocol -
getProtocolInstanceUri
String getProtocolInstanceUri()Get a URI that describes this specific protocol instance -
getLinkedAttributes
Map<AttributeRef,Attribute<?>> getLinkedAttributes() -
linkAttribute
Links anAttribute
to its' agent; the agent would have been connected before this call. This is called when the agent is connected or when the attribute has been modified and re-linked.If the attribute is not valid for this protocol then it is up to the protocol to log the issue and return false.
Attributes are linked to an agent via an
MetaItemType.AGENT_LINK
meta item.- Throws:
Exception
-
unlinkAttribute
Un-links anAttribute
from its' agent; the agent will still be connected during this call. This is called whenever the attribute is modified or removed or when the agent is modified or removed.- Throws:
Exception
-
start
Called before any calls tolinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
to allow the protocol to perform required tasks withContainerService
s (e.g. register Camel routes). The protocol instance should validate the settings defined in the associatedAgent
; but whether or not the protocol establishes a connection/ fully initialises at this time is up to the protocol implementation, it could be desirable to wait untillinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
is called for the first time, or it could be a connectionless protocol. If there is a configuration issue etc. then an appropriate exception should be thrown and suitable logs made.- Throws:
Exception
-
stop
Called once all linked attributes have been unlinked viaunlinkAttribute(java.lang.String, org.openremote.model.attribute.Attribute<?>)
to allow the protocol to perform required tasks withContainerService
s e.g. remove Camel routes, destroy/cleanup resources etc.- Throws:
Exception
-
getAgent
T getAgent()Get theAgent
associated with this protocol instance. -
updateLinkedAttribute
-
updateLinkedAttribute
-
setAssetService
-
processLinkedAttributeWrite
An Attribute event (write) has been requested for an attribute linked to this protocol; implementations should handle multithreaded requests or use some sort of synchronisation for thread safety. TheAttributeEvent
will be enriched with data about the relating asset and attribute. -
onAgentAttributeChanged
Called when one of the associatedAgent
'sAttribute
s are updated; the implementation can decide if it wants to request the protocol instance to be re-created thus simplifying handling of config changes.- Returns:
- true if the agent should be redeployed (this will stop current protocol instance and create a new one).
-