Most functionality in Simple IoT is implemented in Clients.
Each client can be configured by one or more nodes in the SIOT store graph. These nodes may be created by a user, a process that detects new plug and play hardware, or other clients.
A client interacts with the system by listening for new points it is interested in and sending out points as it acquires new data.
It is important the clients cleanly implement the Run()/Stop() pattern and shut down cleanly when Stop() is called releasing all resources. If nodes are added or removed, clients are started/stopped. Additionally if a child node of a client config is added or removed, the entire client is stopped and then restarted. This relieves the burden on the client from managing the addition/removal of client functionality. Thus it is very important that clients stop cleanly and release resources in case they are restarted.
Clients need to be aware of the "echo" problem as they typically subscribe as
well as publish to the
points subject for the nodes they manage. When they
publish to these subjects, these messages will be echoed back to them. There are
- create a new NATS connection for the client with the NoEcho option set. For this to work, each client will need to establish its own connection to the server. This may not work in cases where subjects are aliased into authenticated subject namespaces.
- inspect the
Originfield -- if is blank, then it was generated by the node that owns the point and does not need to be processed by the client generating the data for that node. If is not blank, then the Point was generated by a user, rule, or something other than the client owning the node and must be processed. This may not always work -- example: user is connected to a downstream instance and modifies a point that then propagates upstream -- it may get echo'd back to an authenticated client.
- (investigation stage) A NATS messages header can be populated with the ID of the client that sent the message. If it is an authenticated client, then the message will not be echo'd on the authenticated client subject namespace of the same ID. This information is not stored, so cannot be used for auditing purposes.
The SIOT client manager filters out points for the following two scenarios:
- a point with the same ID as the client and Origin set to a blank string.
- a point received for a client where Origin matches the client root node ID.
Thus, if you want to set a point in one client and get that point to another node client, you must set the Origin field. This helps ensure that the Origin field is used consistently as otherwise stuff won't work.
This gets a little tricky for clients that manage a node and its children (for instance the rule client -- it has condition and action child nodes). If we follow the the following rule:
Clients must set the point Origin field for any point sent to anything other than than its root node.
If we following the above rule, then things should work. We may eventally provide clients with a function to send points that handles this automatically, but for now it is manual.
See also tracking who made changes.