Nodel is an open source digital media control system for museums and galleries, although there are many valid uses for Nodel outside of this scope where device control, monitoring, and scheduling is required. It was originally developed by Lumicom as commissioned by Museums Victoria in response to a 2010 review and subsequent white paper in to the organisations digital media control requirements, and was first used in the First Peoples and Think Ahead exhibition located at at Melbourne Museum and Scienceworks which opened in 2013. It is released as an open source project hosted on GitHub where an installation guide and Wiki can be found.
In response to the pending renewal at the Australia Centre for the Moving Image, the technical services team decided to trial Nodel to assess it’s suitability as the control system for future exhibits and installations. I put my hand up to build a small Nodel implementation example, and write some documentation on the lessons learnt that would help future employees deploy Nodel around the organisation. This documentation will come in the form of four posts; Basic Concepts, Implementing a Simple Nodel System, Nodel System Design, and Coding Tips.
Basic Concepts, is the first of the write ups that will discuss Nodel. This post will describe Nodel in a more abstract sense. Some information will be closely regurgitated from the available GitHub Wiki page and white paper, but is never-the-less included here for completeness. It is highly recommended that you read the white paper and museum and gallery implementation before reading through these posts. Each post will be targeted towards the implementation of Nodel in museums and galleries.
The architecture of Nodel is based on individual ‘nodes’ that each perform a specific task. Each node has the ability to do something using “Local Actions”. A Local Action can be “called”, and this then performs the action. An action can literally be anything you can code. A node also has the ability to display information to the user using “Local Events”, or as they are sometimes labeled as, “Signals”. The difference between Local Events and Signals is labeling, they are the same thing, so henceforth I will only describe them as Local Events. A Local Event can be “emitted”, and this updates the displayed parameters of the Local Event. A node may have as many Local Actions or Local Events as needed.
While this is a good way to look at nodes in a broad sense, the way these Local Actions and Local Events are called and emitted are a little more complex. Figure 2 shows how some of these interactions occur. Local Actions trigger internal node functions. Emitted Local Events update data that can be seen when viewing a node. But in order for nodes to interact with each other, Remote Actions and Remote Events also exist separately to their local counterparts.
While some of these concepts may seem a little confusing to non-software engineering types now, they are important topics to grasp if you wish to design your own Nodel systems in a way you can troubleshoot yourself.
Communication Between Nodes
Nodes have ways of communicating with and influencing each others behavior. One way to do this is through “Remote Actions”. One node can call another nodes Local Action by creating a Remote Action and providing details such as the target node name and target Local Action name. Once a Remote Action is created, the Remote Action “binds” with the target nodes target Local Action and this allows the Local Action to be called “remotely” from a different node. Another way is to create “Remote Events”, which work in a similar way to Remote Actions. A Remote Event can be created using details such as the target node name and target Local Event. After it’s creation, it binds to the target nodes target Local Event. Now every time the Local Event is emitted, the data it emits is passed to the bound Remote Event in addition to being available locally on the target node.
These control and communication techniques are integral, as they allow not only control between nodes, but allow information sharing between nodes which is particularly important when performance monitoring of specific nodes is required.
Hierarchy Between Nodes
All nodes are born equal as clean slates. They have all the same properties, abilities, and potential. Despite this they can be configured in a way that enforces a hierarchy of nodes. By using the control and communication methods explained above, it is possible to group nodes. A good way of describing this is by defining the functionality of each node in to two categories, Management Nodes and Device Nodes.
A Device Node controls something directly. This might be hardware, software, or some other kind of system. It uses local actions as a form of control, and sends messages to Management nodes that might include important information about what it is doing or it’s status.
A Management Node groups multiple nodes together. Local Actions on multiple nodes can be called at once using management nodes, and Local Event messages from multiple nodes can be aggregated at one management node. This makes controlling complex systems simpler to control and monitor. Management Nodes might manage a series of Device Nodes, a series of Management Nodes, or a mix of Device and Management Nodes. There really are no rules in that regard.
All these examples and information about the guts of individual nodes is all well and good, but obviously a lot of choice exists with how you can actually implement nodes, how they communicate, and how they control each other. So now we have a bit of knowledge, let’s breakdown the core methods using some fun stick figures and a situation where we require a TV and a DVD player to be turned on and an acknowledgement from the TV and DVD player that both devices have been turned on. By observing Figure 6, It should be clear that in this case Node 1 should be a Management Node while Node 2 and Node 3 should be Device Nodes. With that being said, we can configure the three nodes in the following manner. There are two main ways to implement the Control aspect of this use case, while there is one way to implement the communication.
Control with Remote Actions
To control the Device Nodes, The Node 1 Management Node will have a Local Action called “TurnOn”, A Remote Action with a target node of “Node 2 TV” called “TurnOn”, and A Remote Action with a target node of “Node 3 DVD” called “TurnOn”. Inside the Local Action function tied to this “TurnOn” Local Action, the two Remote Actions will be called, thus triggering the Device Node Local Actions further down the hierarchy.
The Node 2 TV Device Node will have a Local Action called “TurnOn”, and the Node 3 DVD Device Node will also have a Local Action called “TurnOn”. By configuring these nodes this way, when the Node 1 Management Node Calls it’s “TurnOn” Local Action, these two Local Actions will be triggered through the bound Remote Actions. The code encapsulated within these Device Node Local Action functions should do what is required to turn on the respective devices.
It should be noted how Actions should almost always propagate downwards in a hierarchical Nodel system
Control with Remote Events
It is also possible to control the Device Nodes using Remote Events, although the setup is slightly more convoluted.
The Node 1 Management Node will have a Local Action called “TurnOn”, A Local cvent Called “Node 2 TV TurnOn”, and A Local Event called “Node 3 DVD TurnOn”. Inside the Local Action function tied to this “TurnOn” Local Action, the two Local Events will be emitted.
The Node 2 TV Device Node will have a Local Action called “TurnOn”, and the Node 3 DVD Device Node will also have a Local Action called “TurnOn”. The Node 2 TV Device Node will have a Remote Event with a target node of “Node 1 Management” and a target Local Event of “Node 2 TV TurnOn”. The handler function that this Remote Event points to will call the Node 2 TV Device Local Action “TurnOn”. The Node 3 DVD Device Node will have a Remote Event with a target node of “Node 1 Management” and a target Local Event of “Node 3 DVD TurnOn”. The handler function that this Remote Event points to will call the Node 3 TV Device Local Action “TurnOn”. Like in the previous example, The code encapsulated within these Device Node Local Action functions should do what is required to turn on the respective devices.
It should be noted how Local Events propagate downwards in a hierarchical Nodel system when used for control purposes.
To allow the two Device Nodes to report back whether the respective devices have indeed turned on The Node 1 Management Node is required to have a channel for communication in the form of a Remote Event. The Node 1 Management node will have a Remote Event with a target node of “Node 2 TV” and a target Local Event of “TV Status”, and a Remote Event with a target node of “Node 3 DVD” and a target Local Event of “DVD Status”. In order to actually see the data that is emitted to these remote events, two Local Events should also exist. These Local Events will be called “Node 2 TV Status”, and “Node 2 DVD Status”. When one of these Remote Events is emitted from one of the Device Nodes, a handler function will emit the relevant Management Local Event.
Now that the Management Node has a communication channel, The Device nodes need to bind to it. To achieve this, a Local Event should be created on the Node 2 TV Device Node called “TV Status”, and also created on the Node 3 DVD Device Node called “DVD Status”. Now every time one of these Local Events emits, The message will propagate upwards to the Management Node. In this case study, it would be wise to check if the device is on and emit these Local Events every time the Local Action “TurnOn” is called.
Finally, it can be a good idea to also aggregate messages with Management Nodes so multiple messages can essentially be condensed down to “OK”, or “NOT OK”. To do this the Node 1 Management node should have a third Local Event called “Overall Status”. Each time the Remote Events is emitted from one of the Device Nodes, the handler functions should aggregate the existing messages, and also emit this “Overall Status” Local Event with the aggregated messages as the data.
By now it should be apparent just how flexible Nodel is in regards to building complex control systems. This flexibility can be a blessing in that almost anything is possible! But this comes at the cost of implementation complexity. Developing complex Nodel Systems can take time to design and test. But fret not, Nodel Recipes make this process a whole lot easier and introduce reusable elements to this design Process. This is something I will cover in the next post, Implementing a Simple Nodel System, where it will be shown how the use case used in this post can be implemented in real life!