Add blocks to node-red
The addition of new blocks in Ronoco is done in two parts : on the one hand the creation of the block in Node-RED allowing to define its colour, its parameters, etc. On the other hand the creation of the block in the vm allowing to define the behaviour of the block during its execution.
Ronoco - Node-RED
Go to the $HOME/catkin_ws/ronoco/ronoco-nodered
folder. We will create a simple
block which will be part of the common blocks. This block will have a Name (optional) and a number (not optional) as parameters.
First, it will be necessary to create the common/simple.html
file as follows:
<script type="text/javascript">
RED.nodes.registerType('simple', {
category: 'ronoco/common',
color: '#59c059',
defaults: {
name: {value: ""},
data: {value: "", required: true}
},
credential:{
name: {},
mode: {},
data:{}
},
inputs: 1,
outputs: 1,
icon: "icons/simple.svg",
label: function () {
return this.name || "simple";
},
});
</script>
<script type="text/html" data-template-name="simple">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-data"><i class="fa fa-tag"></i> Data</label>
<input type="number" id="node-input-data" placeholder="Data">
</div>
</script>
<script type="text/html" data-help-name="simple">
Here we have a simple documentation
</script>
Then you need to create the common/simple.js
file as follows
"use strict";
module.exports = function (RED) {
function Simple(config) {
RED.nodes.createNode(this, config);
const node = this;
node.on('input', function (msg) {
node.send(msg);
});
}
RED.nodes.registerType("simple", Simple);
}
Finally, you just have to fill in the new block in the package.json
of the project
"node-red": {
"nodes": {
...
"simple": "common/simple.js"
...
}
}
Simply reinstall the palette in Node-RED to see the new block
cd $HOME/.node-red
npm install $HOME/catkin_ws/src/ronoco/ronoco-nodered/
For more information on the construction of the blocks, please refer to the Node-RED documentation
Ronoco - VM
Once the block is defined in Node-RED it is still necessary to give it behaviour in the vm. The definition of behaviour in the VM happens in the $HOME/catkin_ws/src/ronoco/ronoco-vm/ronoco_vm/behaviour
folder. First we will define the node behaviour. As Ronoco-vm uses the py_trees
library to execute behaviour trees we must respect the interface, refer to the py_trees documentation for more information. Then just create a simple.py
file in the behaviour
folder.
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import logger
import py_trees
class Simple(py_trees.behaviour.Behaviour):
def __init__(self, name, data):
super(Simple, self).__init__(name)
self.time = float(data)
def setup(self, timeout):
self.logger.debug(" %s [Simple::setup()]" % self.name)
return True
def initialise(self):
self.logger.debug(" %s [Simple::initialise()]" % self.name)
def update(self):
self.logger.debug(" %s [Simple::update()]" % self.name)
# Do something
return py_trees.Status.SUCCESS #or return py_trees.Status.FAILURE
def terminate(self, new_status):
self.logger.debug(" %s [Simple::terminate().terminate()][%s->%s]" % (self.name, self.status, new_status))
⚠ This implementation allows you to define execution blocks. Control blocks and decorators are natively supported by py_trees. To define others, please refer to the py_trees documentation
Once the behaviour of the block is defined it is still necessary to register the block in the vm so that it can be recognised and interpreted. To do this open the behaviour.py
file in the behaviour
folder. Start by defining the method for building the block. This method must require the parameters name, data, child. The method should return a tuple Boolean, Object, String
where Boolean
is True
if the block is buildable, Object
contains the built block if it is buildable and String
contains an error message if the object is not buildable. In sum for the simple
block we have :
def simple(name, data, child):
# Set default name if it is empty
if name is None or name == "":
name = "Record"
# If data is None we can't build the bloc
if data is None:
return False, None, "No data"
# Else return a Simple object
return True, behaviour.simple.Simple(name, data), None
You still need to associate the name of the block with this function. At the end of the behaviour.py
file add 'simple':simple
to the types
dictionary. Since the simple
block is an execution block and requires data to function it is necessary to add its name to the leaf
and data_node
dictionaries.
⚠ In case the new block has multiple parameters it is necessary to signal this to the vm by modifying the multiple_data_nodes(node_json)
method of the control.py
file in the ronoco_vm
folder