Versions Compared

Key

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

Quick navigation

Child pages (Children Display)
alltrue
pageSimple Iot Tutorial


Panel
titleGoalGoal`

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 informationIn this tutorial you learn how to :

  1. Create model of the informations from your sensors.
  2. Create organs representing yours sensors.
  3. Launch your organs with efficiency.
System architecture:

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


Panel
titleRequirements

For this tutorial, you just need the basic requirements


Panel
titleThe equipment and equipementList Create the models

Anchor
2
2

In this part we will create 2 new modelsyou’re going to create two sensor model:

  • 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
    • -id : unique int
    • -name : string 
    • - hydrometry : int
    • - temperature : int
  • sensorList, a model with 1 attribute:
    • sensors : []

Sensor and sensorList model

  1. Create a new spinal-system with the browser-admin template like it’s explained in the in the section Creating a new Spinal System in the Getting Started tutorial.
  2. Create a folder spinal-model to store the differents models. Within this folder create a file models.js.
  3. Complete the file model.js
    1. Create the sensor model.
    2. Extend the sensor model with the Model of spinal-core.
    3. export the sensor model
    4. Create the sensor list.
    5. Extend the sensor list with the Model of spinal-core.
    6. export the sensor list.

Your model file should look like this:

spinal-model/model.js

Code Block
languagejs
themeDJango
titlemodels.js
linenumberstrue
const spinalCore = require("spinal-core-connectorjs");

// EquipmentSensor model
function equipmentSensor() {
      equipmentSensor.super(this);
    // Creatingadd attributes
   to the model
    this.add_attr({
            id: 0,
            name: "",
        hydrometry: 0,         temperaturehydrometry: 0,
        pressedtemperature: false0,
     });
}
// RegisteringSensor theinherit equipmentof model in the Spinal
system
spinalCore.extend(equipmentSensor, Model);
module.exports.Sensor = equipmentSensor;


// equipmentListSensorList model
function equipmentListSensorList() {
      equipmentListSensorList.super(this);
// Array of equipments
      this.add_attr({
           equipmentssensors: []
      });
}
// RegisteringSensorList theinherit equipmentListof model in the Spinal system
spinalCore.extend(equipmentListSensorList, Model);
module.exports.SensorList = equipmentListSensorList;



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 a list of 2 equipmentsSensor


Anchor
3
3

With our new models we will now In this part your are going to create a list of 2 equipmentssensor. We will create an organ for each equipment. Each one

Every sensor will have its own organ.

Each one of those will have an automate which will changes its hydrometry and temperature.

Equipment 1

Make a folder named equipment1 and the file

create a list of two sensor:

  1. Create a new folder sensor1 within a file named index.js
in it
​This organ will create the first equipment and will revover data from a simulated sensor.
equipment1/index.js
  1. .
Code Block
languagebash
themeDJango
~/equipement-system$ mkdir equipment1
~/equipement-system$ cd equipment1
~/equipement-system/equipment1$ touch index.js
  1. Require spinal-core.
  2. Get the connection string from config.js.
  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. For this part you to add an element to the list if the list is empty and simulate the data of this element this element.
  6. Create a function onFaill. this function will be executed if the loading of ‘List’ fail. For this part if the loading fail you want to create a new list and store it into spinal-core.
  7. Load list from spinal-core.
  8. Copy paste this folder into sensor2 and do the appropriate modification in index.js .


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 sensor1/index.js should look like this.

Code Block
languagejs
themeDJango
titlesensor1/index.js
linenumberstrue
// Requirement and connection
const spinalCore = require('spinal-core-connectorjs');
require('../spinal-model/
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 connection_string = require("../config");
const conn = spinalCore.connect(
`http://${process.env.SPINAL_USER_ID}:${process.env.SPINAL_PASSWORD}@${process.env.SPINALHUB_IP}:${process.env.SPINALHUB_PORT}/`
connection_string);

// Creates a new sensor 
Tries
and add it to 
load
the 
'List' spinalCore.load(conn, "List", function
list
addItem = (list) => {
//
   
If
 
the
const 
list
item 
exists
= 
but is empty a first equipment is added
new Sensor();
    item.id.set(0);
   
if
 item.name.set("sensor0");
    list.
equipments.length < 1)
sensors.push(item);
    
addItem
simulate(
list
item);
};

// 
Else the first equipment is pressed else press(list.equipments[0]); }, function () { // If 'List' doesn't exist an empty list is created and its first equipment is pressed const list = new equipmentList(); spinalCore.store(conn, list, "List", function () { addItem(list); }); }); // Creates a new equipment and adds it to the list function addItem(list) { const item = new equipment(); item.id.set(0); item.name.set("equipment0"); list.equipments.push(item); press(item); } // Gives random values to the hydrometry and temperature of an equipment 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); // Repeats every second setTimeout(function () { console.log("equipment 1: has been pressed"); press(equipment); }, 1000); }

You can launch your new organ with node.

Code Block
languagebash
themeDJango
~/equipement-system/equipment1$ node index.js
Go
Gives random values to the hydrometry and temperature of a sensor
simulate = (sensor) => {
    const hydro = Math.floor(Math.random() * 100);
    const degrees = Math.floor(Math.random() * 30);

    sensor.hydrometry.set(hydro);
    sensor.temperature.set(degrees);

    // Repeats every second
    setTimeout(() => {
        console.log("sensor 1: data has changed");
        simulate(sensor);
    }, 1000);
};


//this function will be called if the list is successfully load
onSuccess = (list) => {
    if (list.sensors.length < 1)
        addItem(list);

    simulate(list.sensors[0]);
};

//this function will be called if the list is failed to load
onFail = () => {
    const list = new SensorList();
    spinalCore.store(conn, list, "List", () => {
        addItem(list);
    });
};

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

Run sensor1 and go to the admin UI and put 'List' into the inspector and you should see the hydrometry and temperature of equipment0 sensor0 change every second.

Equipment2

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



Your file sensor2/index.js should look like this.

equipment2
Code Block
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.

titleSensor2/index.js
Code Block
languagejs
themeDJango
linenumberstrue
// Requirement and connection
const spinalCore = require('spinal-core-connectorjs');
require('../spinal-model/modelmodels.js');

console.log("Configuration Environment not found, using default const connection_string = require("../config");
process.env.SPINALHUB_PORT
const conn = 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) {
//  An item is created if there are less than 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(list);
  });
});

function addItem(list) {
  let item = new equipment();

  item.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/"
    }
  ]
}spinalCore.connect(connection_string);
// Creates a new sensor and add it to the list
addItem = (list) => {
    const item = new Sensor();
    item.id.set(1);
    item.name.set("sensor1");
    list.sensors.push(item);
    simulate(item);
};

// Gives random values to the hydrometry and temperature of a sensor
simulate = (sensor) => {
    const hydro = Math.floor(Math.random() * 100);
    const degrees = Math.floor(Math.random() * 30);

    sensor.hydrometry.set(hydro);
    sensor.temperature.set(degrees);

    // Repeats every second
    setTimeout(() => {
        console.log("sensor 2: data has changed");
        simulate(sensor);
    }, 1000);
};


//this function will be called if the list is successfully load
onSuccess = (list) => {
    if (list.sensors.length < 2)
        addItem(list);

    simulate(list.sensors[1]);
};

//this function will be called if the list is failed to load
onFail = () => {
    const list = new SensorList();
    spinalCore.store(conn, list, "List", () => {
        addItem(list);
    });
};
//  Tries to load 'List'
spinalCore.load(conn, "List", onSuccess, onFail);


Image Added


~/equipement-system$

pm2

restart launch.config.json

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

Panel
titleLaunch efficiently your organs

Anchor
4
4

You might have noticed that running every organ independently is painful.

If you wonder why it’s so painful it’s because you are not supposed to do that :p.

In this part you will learn a to run you organs efficiently.

  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)
  3. run the commande pm2 start launch.config.json.


.apps.json contains the organs that should be launched. They are identified by:

  • name: The name they will be identified by pm2
  • script: The name of the script to be executed to launch the organ
  • 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.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": "./equipment1sensor1/"
    },
    {
      "name": "equipment2sensor2",
      "script": "index.js",
      "cwd": "./equipment2sensor2/"
    }
  ]
}

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

Code Block
languagebash
themeDJango


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 effectively


This tutorial will be continued in Basic Automate Tutorial.

...