Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of contents

  1. Goal
  2. The equipment and equipementList Create the models
  3. Create a list of 2 equipmentsSensor
  4. How to launch you organs effectivelyefficiently

Quick navigation

Child pages (Children Display)
alltrue
pageSimple Iot TutorialTutorials


Panel
titleGoal

Anchor
1
1

After the Getting Started tutorial, you should know how to create a spinal-system with one model and one organ. We will now see how to create an intelligent system with more synchronized information.In this tutorial you will learn how to :

  1. Create a model or a Digital twin of your sensors equipment.
  2. Create organs that simulate your sensors behavior.
  3. Launch your organs with efficiently
System architecture:

Image Removed

In this tutorial you will learn how to make a list of items and how to launch your organs with more efficiency.

Image Added


Panel
titleRequirements

For this tutorial, you just need the basic requirements


Panel
titleThe equipment and equipementList modelsCreate the models / Digital twins

Anchor
2
2

In this part we will create 2 new you’re going to create two sensor models:

  • equipmentSensor, a complex model with 5 4 attributes:
    • id
    , name, hydrometry, temperature and pressed (boolean)
  • equipmentList, a model that contains an array of equipments
But first you need to create a spinal-system called 'equipement-system' like in the section Creating a new Spinal System in the Getting Started tutorial, then create a folder spinal-model to store the differents models
    • : unique integer
    • name : string 
    • hygrometry : integer
    • temperature : integer
  • SensorList, a model with 1 attribute:
    • sensors : array of sensors

Create your spinal system and digital twin by following these steps:

  1. Create a new spinal-system from the browser-admin template (explained in the section "Creating a new Spinal System" in the Getting Started tutorial).
  2. Create a folder called spinal-models to store the different models you are going to create. Within this folder create a file named model.js.
spinal-model/model
  1. Complete model.js:
    1. Create the sensor model.
    2. Extend the sensor model with the Model class from spinalCore.
    3. Export the sensor model.
    4. Create the sensor list.
    5. Extend the sensor list with the Model of spinalCore.
    6. Export the sensor list.

Your model file should look like this:

spinal-models/models.js

Code Block
languagejs
themeDJango
titlemodels.js
linenumberstrue
const spinalCore = require("spinal-core-connectorjs");
// Equipment model
function equipment// SensorModel inherits from Model
class SensorModel extends Model {
  constructor() {
      equipment.super(this);
    // Creatingadd attributes
   to the model
    this.add_attr({
          id: 0,
          name: "",
         hydrometryhygrometry: 0,
         temperature: 0,
    });
  }
pressed: false
    });
}}
module.exports.SensorModel = SensorModel;

// RegisteringSensorListModel theinherits equipmentfrom modelModel
inclass theSensorListModel Spinalextends system
spinalCore.extend(equipment, Model);
module.exports = equipment;

// equipmentList model
function equipmentList() {
    equipmentList.super(this);Model {
  constructor() {
    super();
    // Array of equipments
      this.add_attr({
         equipmentssensors: []
      });
} // Registering the equipmentList model in the Spinal system
spinalCore.extend(equipmentList, Model);}
}
module.exports.SensorListModel = equipmentListSensorListModel;



After the last part you might have noticed that the way we have been launching our organs isn't very effective, you have to launch and stop organs one by one.

This is because this is not the right way to do it. In this part you will learn how to launch your organs effectively.

To do that we need to look at .apps.json. When you open it for the first time it should look like this:

Panel
titleCreate Instantiate a list of 2 equipmentsSensors

Anchor
3
3

With our new models we will now create In this part your are going to instantiate a list of 2 equipments. We will create an organ for each equipment. Each one will have an automate which changes its hydrometry virtual sensors in the database and create two "organs" of the system that will simulate the sensor behavior.

Each organ will simulate changes of hygrometry and temperature.

Equipment 1

Make
  1. Create a
folder named equipment1 and the file
  1. new folder spinal-organ-sensor1 and within it a file named index.js
in it.
Code Block
languagebash
themeDJango
~/equipement-system$ mkdir equipment1
~/equipement-system$ cd equipment1
~/equipement-system/equipment1$ touch index.js
​This organ will create the first equipment and will revover data from a simulated sensor.
equipment1/index.js
  1. .
  2. in the index.js file:
    1. Require spinal-core.
    2. Get the connection parameter from the config.js file in the main folder
    3. Create a function addItem. This function create, set and add an item to the list given in argument.
    4. Create a function simulate. This function simulate the value of the sensor.
    5. Create a function onSuccess. This function will be executed if the loading of ‘List’ is successful. 
    6. Create a function onFaill. This function will be executed if the loading of ‘List’ fail.
    7. Load list from spinal-core.
  3. Create a new folder spinal-organ-sensor2 
  4. Copy paste the index.js into sensor2 folder and do the appropriate modifications.
  5.  Don't forget to install spinal-core-connectorjs from GitHub in the two folders


Panel
titleNote
  • If you have and API to retrieve the real data of your sensor use it to send real data to the graph.
  • You can run every sensor independently by running the corresponding index.js (node index.js)


Your file spinal-organ-sensor1/index.js should look like this.

Code Block
languagejs
themeDJango
titlespinal-organ-sensor1/index.js
linenumberstrue
// 
Requirement
Requirements and connection
const spinalCore = require('spinal-core-connectorjs');
const models = require('../spinal-
model
models/
model
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}/`);

// Gives 
Tries
random values to
load 'List' spinalCore.load(conn, "List",
 the hygrometry and temperature of a sensor
function simulate(
list
sensor) {
//
  
If
const hydro 
the list exists but is empty a first equipment is added if (list.equipments.length < 1) addItem(list); // Else the first equipment is pressed else press(list.equipments[0]); }, function () { // If 'List'
= Math.floor(Math.random() * 100);
  const degrees = Math.floor(Math.random() * 30);
  sensor.hygrometry.set(hydro);
  sensor.temperature.set(degrees);
  // Repeats every second
  setTimeout(() => {
    console.log(sensor.name.get() + ": data has changed");
    simulate(sensor);
  }, 1000);
};

// Finds a Sensor in the SensorList, if it doesn't exist, 
an
creates it
empty
function getSensorById(list, 
is
id) 
created
{
and
 
its
 
first
let 
equipment
item;
is

pressed
  for 
const
(let 
list
i = 
new equipmentList(); spinalCore.store(conn, list, "List", function () { addItem(list); }); }); // Creates a new equipment and adds it to the list function addItem(list) { const
0; i < list.sensors.length; i++) {
    if (list.sensors[i].id.get() === id) {
      item = list.sensors[i];
      break;
    }
  }
  if (typeof item === "undefined") {
    item = new 
equipment
models.SensorModel();
    item.id.set(
0
id);
    item.name.set("
equipment0
sensor" + id);
    list.
equipments
sensors.push(item);
  
press(item)
}
  return item;
}

// 
Gives
This 
random
function 
values
will 
to
be 
the
called 
hydrometry
if 
and
the 
temperature
list 
of
is 
an
successfully 
equipment
loaded
function 
press
onSuccess(
equipment
list) {
  simulate(getSensorById(list, 0));
};

// 
const
This function 
hydro
will 
= Math.floor(Math.random() * 100); const degrees = Math.floor(Math.random() * 30); equipment.hydrometry.set(hydro); equipment.temperature.set(degrees); // Repeats every second setTimeout(function ()
be called if the list cannot be loaded
function onFailure() {
  const list = new models.SensorListModel();
  const item = getSensorById(list, 0);

  spinalCore.store(conn, list, "List", () => {
    
console.log("equipment 1: has been pressed"
simulate(item);
  });
};

press(equipment); }, 1000
spinalCore.load(conn, "List", onSuccess, onFailure);
}

You can launch your new organ with node.

Code Block
languagebash
themeDJango
~/equipement-system/equipment1$ node index.js
Go


Run spinal-organ-sensor1/index.js and go to the admin UI and put 'List' into the inspector and you should see the hydrometry hygrometry and temperature of equipment0 sensor0 change every second.

Image Removed

Equipment2

Equipment2 will be almost identical to equipment1 so I suggest you start by copying equipment1

Image Added


Your file spinal-organ-sensor2/index.js should look like this.

Code Block
Code Block
languagejs
themeDJango
linenumberstrue
languagebashjs
themeDJango
~/equipement-system/equipement1$ cd ..
~/equipement-system$ cp -r equipment1 equipment2
~/equipement-system$ cd equipment2

There are very few changes to make to index.js.

equipment2/index.js

titlespinal-organ-sensor2/index.js
linenumberstrue
// Requirements and connection
const spinalCore = require('spinal-core-connectorjs');
const models = require('../spinal-modelmodels/modelmodels.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}/`);

spinalCore.load(conn, "List", function (list)
{
// Gives Anrandom values itemto isthe createdhygrometry ifand theretemperature areof lessa thansensor
2 equipments in the list
  if (list.equipments.length < 2)
    addItem(list);
//  The second item is pressed (instead of the first)
  press(list.equipments[1]);
}, function () {
  spinalCore.store(conn, list, "List", function () {
    addItem(listfunction simulate(sensor) {
  const hydro = Math.floor(Math.random() * 100);
  const degrees = Math.floor(Math.random() * 30);
  sensor.hygrometry.set(hydro);
  sensor.temperature.set(degrees);
  // Repeats every second
  setTimeout(() => {
    console.log(sensor.name.get() + ": data has changed");
    simulate(sensor);
  }, 1000);
});

function addItem(list;

// Finds a Sensor in the SensorList, if it doesn't exist, creates it
function getSensorById(list, id) {
  let item;

 = newfor equipment()(let i = 0; i <  itemlist.id.set(1);
// The new item is named equipment1 (instead of equipment0)
  item.name.set("equipment1");
  list.equipments.push(item);
  press(item);
}

function press(equipment) {
  const hydro = Math.floor(Math.random() * 100);
  const degrees = Math.floor(Math.random() * 30);

  equipment.hydrometry.set(hydro);
  equipment.temperature.set(degrees);
  setTimeout(function () {
//  This message changes
    console.log("equipment 2: has been pressed");
    press(equipment);
  }, 1000);
}

Now launch equipment2 with node.

Code Block
languagebash
themeDJango
~/equipement-system/equipment2$ node index.js

If you go back to the inspector you will notice that a new equipment has appeared in the List.

Image Removed

Panel
titleHow to launch you organs effectively
Anchor
44
Code Block
languagejs
themeDJango
linenumberstrue
{
  "apps": [
    {
      "name": "spinal-core-hub",
      "script": "spinalhub.js",
      "cwd": "./nerve-center/"
    }
  ]
}
.apps.json contains the organs that should be launched. They are identified by:
sensors.length; i++) {
    if (list.sensors[i].id.get() === id) {
      item = list.sensors[i];
      break;
    }
  }
  if (typeof item === "undefined") {
    item = new models.SensorModel();
    item.id.set(id);
    item.name.set("sensor" + id);
    list.sensors.push(item);
  }
  return item;
}

// This function will be called if the list is successfully loaded
function onSuccess(list) {
  simulate(getSensorById(list, 1));
};

// This function will be called if the list cannot be loaded
function onFailure() {
  const list = new models.SensorListModel();
  const item = getSensorById(list, 1);

  spinalCore.store(conn, list, "List", () => {
    simulate(item);
  });
};

spinalCore.load(conn, "List", onSuccess, onFailure); 


Image Added


Panel
titleLaunch efficiently your organs

Anchor
4
4

You might have noticed that you are running every organ independently.

In a system where all the organs run on the same server, you can simplify this process and monitor your organs using pm2.

  1. Take a look at .app.json.
  2. add dependency to your organs.
    1. name: The name they will be identified by pm2
    2. script: The name of the script to be executed to launch the organ
    3. cwd: The location of the script (relative to the root of the project)
With all that in mind let's add equipment 1 and 2 to the list.
  1. run the commande pm2 restart launch.config.json.

Your .app.json should look like this:

Code Block
languagejs
themeDJango
linenumberstrue
{
  "apps": [
    {
      "name": "spinal-core-hub",
      "script": "spinalhub.js",
      "cwd": "./nerve-center/"
    },
    {
      "name": "equipment1sensor1",
      "script": "index.js",
      "cwd": "./equipment1spinal-organ-sensor1/"
    },
    {
      "name": "equipment2sensor2",
      "script": "index.js",
      "cwd": "./equipment2spinal-organ-sensor2/"
    }
  ]
}

Now all we have to do is let pm2 do the work.

Code Block
languagebash
themeDJango
~/equipement-system$ pm2 restart launch.config.json

pm2 will now show you equipment sensor 1 and 2 along with spinal-core-hub.

Image RemovedImage Added


Conclusion


In this tutorial you learned:

  • how to create complex models
  • how to organize your data coming from multiple organs
  • how to launch you your organs effectivelyefficiently


This tutorial will be continued in Basic Automate Tutorial.

...