Panel | ||||||
---|---|---|---|---|---|---|
| ||||||
In the previous tutorial we created a list of 2 equipmentssensors. In this tutorial we're going to create an organ which will make equipments sensors for us and 2 two automates to handle this new list. System architecture: |
Panel | ||
---|---|---|
| ||
To follow this tutorial you must have done the Basic Equipment Tutorial. |
Panel | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||
In this part we will create another model a new model, named an "automate", that will be in charge of a group of equipmentsensors. This model needs 2 attributes:
We're going to add an empty array named automates as property of the SensorListModel and create a model Automate with the two previously described attributes. Take care of SensorListModel, an automate as been added to the model. spinal-models/models.js
| |||||||||||||||
Panel | |||||||||||||||
| |||||||||||||||
Anchor | | 3 | 3 |
temperature: 0,
pressed: false
});
}
}
module.exports.SensorModel = SensorModel;
class SensorListModel extends Model {
constructor() {
super();
this.add_attr({
sensors: [],
automates: []
});
}
}
module.exports.SensorListModel = SensorListModel;
// Automate model
class AutomateModel extends Model {
constructor() {
super();
this.add_attr({
name: "",
sensors: []
});
}
}
module.exports.AutomateModel = AutomateModel; |
Panel | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||
Before we can use our new model we're going to need sensors for them to handle. The createSensor organ will create 10 virtual sensors in a new list stored in the file "Automate". Create a folder called createSensor and add a file called index.js inside. createSensor/index.js
Install spinal-core-connectorjs from GitHub. You can test it to see if it is working fine. A new file named "Automate" should have appeared in the admin UI. Drag & Drop it in the inspector. You can see that the sensor array contains 10 sensors whereas the automate array is still empty. At this point in this tutorial our spinal system looks like this: |
Panel | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||
We are now going to create 2 automates. Each one will be in charge of 5 sensors from the list. Both will periodically choose one of their sensors and change its hygrometry and temperature. Create two folders, called automate1 and automate2 and inside, create a file index.js. Don't forget to install spinal-core-connectorjs from GitHub, inside the two folders. Automate 1automate1/index.js
Automate 2Automate2 will be almost identical to automate1 so I suggest you start by copying automate1 and modify the file as follow.
You can test it to see if it is working fine.
A new list named "Automate" should have appeared in the admin UI, put it in the inspector. You can see that that the equipment array contains 10 items whereas the automate array is empty. At this point in this tutorial our spinal system looks like this: | |||||||||||||||||||||||||||||||
Panel | |||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||
Anchor | | 4 | 4 |
Code Block | ||||
---|---|---|---|---|
| ||||
~/button-system$ mkdir automate1
~/button-system$ cd automate1
~/button-system/automate1$ touch index.js |
automate1/index.js
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
// 1: Requirements and connection
var spinalCore = require('spinal-core-connectorjs');
require('../spinal-model-button/model.js');
console.log("Configuration Environment not found, using default config");
process.env.SPINALHUB_PORT = 7777;
process.env.SPINALHUB_IP = "127.0.0.1";
process.env.SPINAL_USER_ID = 168;
process.env.SPINAL_PASSWORD = "JHGgcz45JKilmzknzelf65ddDadggftIO98P";
var conn = spinalCore.connect(`http://${process.env.SPINAL_USER_ID}:${process.env.SPINAL_PASSWORD}@${process.env.SPINALHUB_IP}:${process.env.SPINALHUB_PORT}/`);
// 2: Loading the list
spinalCore.load(conn, "Automate", function (list) {
// callback success: if the array of automates is empty we create a first automate, else we press the first automate
if (list.automates.length < 1)
addAutomate(list);
press(list.automates[0]);
}, function () {
// callback error
});
// 3: Adds an automate to the list and attributes him the first 5 equipments
function addAutomate(list) {
var automate1 = new automate();
automate1.name.set("automate0");
for (let i = 0; i < 5; i++) {
automate1.equipments.push(list.equipments[i]);
}
list.automates.push(automate1);
}
// 4: Randomly selects an equipment in the list and changes its hydrometry and temperature
function press(automate) {
let selectEquipement = Math.floor(Math.random() * 5);
const equipment = automate.equipments[selectEquipement];
let hydro = Math.floor(Math.random() * 100);
let degrees = Math.floor(Math.random() * 30);
equipment.hydrometry.set(hydro);
equipment.temperature.set(degrees);
// 5: Repeats every second
setTimeout(function () {
console.log("automate1: has been pressed");
press(automate);
}, 1000);
} |
Automate 2
Automate2 will be almost identical to automate1 so I suggest you start by copying automate1.
Code Block | ||||
---|---|---|---|---|
| ||||
~/button-system/automate1$ cd ..
~/button-system$ cp -r automate1 automate2
~/button-system$ cd automate2 |
the array of automates is empty we create a first automate, else we press the first automate
if (list.automates.length < 2)
addAutomate(list);
press(list.automates[1]);
}, function () {
// callback error
});
// Adds an automate to the list and attributes him the first 5 sensors
function addAutomate(list) {
var automate = new models.AutomateModel();
automate.name.set("automate1");
for (let i = 5; i < 10; i++) {
automate.sensors.push(list.sensors[i]);
}
list.automates.push(automate);
}
// Randomly selects a sensor in the list and changes its hygrometry and temperature
function press(automate) {
let selectedSensor = Math.floor(Math.random() * 5);
const sensor = automate.sensors[selectedSensor];
let hydro = Math.floor(Math.random() * 100);
let degrees = Math.floor(Math.random() * 30);
sensor.hydrometry.set(hydro);
sensor.temperature.set(degrees);
// Repeats every second
setTimeout(function () {
console.log("automate2: has been pressed");
press(automate);
}, 1000);
}
|
Panel | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||
Don't forget to add all this new organs to your .apps.json if you wan't to use pm2 to launch them. .apps.json
2 new automates with 5 sensors each should have appeared in your list. You can compare the sensors in the array and those in the automates to verify that they correspond. |
Panel | |||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||
We now have 2 automates that change the data of their sensors. Let's add analytic to the press function to catch those modifications. We will change the press function in both so that when the hygrometry exceeds 70% or the temperature exceeds 20°, it will create a alert log. automate1/index.js
| |||||||||||||||||||||||||||||||||||||||||
Panel | |||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
Anchor | 5 | 5 |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"apps": [
{
"name": "spinal-core-hub",
"script": "spinalhub.js",
"cwd": "./nerve-center/"
},
{
"name": "createEquipement",
"script": "index.js",
"cwd": "./createEquipement/"
},
{
"name": "automate1",
"script": "index.js",
"cwd": "./automate1/"
},
{
"name": "automate2",
"script": "index.js",
"cwd": "./automate2/"
}
]
} |
2 new automates with 5 equipment each should have appeared in your list. You can compare the equipments in the equipments array and those in the automates to verify that they correspond.
title | Create warnings |
---|
We now have 2 automates that change the data of equipments. Let's add analytic to the press function to catch those modifications.
We will change the press function in both so that when the hydrometry exceeds 70% or the temperature
automate1/index.js
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
function press(automate) {
let selectEquipement = Math.floor(Math.random() * 5);
const equipment = automate.equipments[selectEquipement];
let hydro = Math.floor(Math.random() * 100);
let degrees = Math.floor(Math.random() * 30);
equipment.hydrometry.set(hydro);
equipment.temperature.set(degrees);
// 1: If the equipment's hydrometry or temperature are above certain value we send a message and press the equipment
if (hydro > 70 || degrees > 20) {
equipment.pressed.set(true);
console.log("Alert: " + equipment.name.get() + " warning");
} else
// 2: Else we release the equipment
pressed.set(false);
setTimeout(function () {
console.log("automate1: has been pressed");
press(automate);
}, 1000);
} |
automate2/index.js
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
function press(automate) { let selectEquipement= Math.floor(Math.random() * 30); sensor.hydrometry.set(hydro); sensor.temperature.set(degrees); // If the sensor's hygrometry or temperature are above certain value we send a message and press the sensor if (hydro > 70 || degrees > 20) { sensor.pressed.set(true); console.log("Alert: " + sensor.name.get() + " warning"); } else // Else we release the sensor sensor.pressed.set(false); setTimeout(function () { console.log("automate1: has been pressed"); press(automate); }, 1000); } |
automate2/index.js
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
// Requirements and connection const spinalCore = require('spinal-core-connectorjs'); const models = require('../spinal-models/models.js'); console.log("Configuration Environment not found, using default config"); process.env.SPINALHUB_PORT = 7777; process.env.SPINALHUB_IP = "127.0.0.1"; process.env.SPINAL_USER_ID = 168; process.env.SPINAL_PASSWORD = "JHGgcz45JKilmzknzelf65ddDadggftIO98P"; const conn = spinalCore.connect(`http://${process.env.SPINAL_USER_ID}:${process.env.SPINAL_PASSWORD}@${process.env.SPINALHUB_IP}:${process.env.SPINALHUB_PORT}/`); // Loading the list spinalCore.load(conn, "Automate", function (list) { // callback success: if the array of automates is empty we create a first automate, else we press the first automate if (list.automates.length < 2) addAutomate(list); press(list.automates[1]); }, function () { // callback error }); // Adds an automate to the list and attributes him the first 5 sensors function addAutomate(list) { var automate = new models.AutomateModel(); automate.name.set("automate1"); for (let i = 5; i < 10; i++) { automate.sensors.push(list.sensors[i]); } list.automates.push(automate); } // Warning fonction alert log for hygrometry and temperature function press(automate) { const selectedEquipment = Math.floor(Math.random() * 5); const equipmentsensor = automate.equipmentssensors[selectEquipementselectedEquipment]; let const hydro = Math.floor(Math.random() * 100); letconst degrees = Math.floor(Math.random() * 30); equipment sensor.hydrometry.set(hydro); equipmentsensor.temperature.set(degrees); if (hydro > 70 || degrees > 20) {) { equipmentsensor.pressed.set(true); console.log("Alert: " + equipmentsensor.name.get() + " warning"); } else equipmentsensor.pressed.set(false); setTimeout(function () { console.log("automate2: has been pressed"); press(automate); }, 1000); } |
Now use pm2 restart and pm2 log to see when an equipment is in dangerunder alarm.
Code Block | ||||
---|---|---|---|---|
| ||||
~/button-system$ pm2 restart launch.config.js ~/button-system$ pm2 log |
You should see something like this.
Conclusion
In this tutorial you learned how to:
- Automatically created equipments create sensors using an organ
- Created 2 automates to handle the equipmentssensors
- Made those automates display warnings if a problem occurs
This tutorial will be continued in Getting Started Extended to Viewer 1in Get your Automate in the viewer.