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`Goal

Anchor
1
1

In this tutorial you will learn how to :

  1. Create a model of the informations from your sensorsor a Digital twin of your sensors equipment.
  2. Create organs representing yours that simulate your sensors behavior.
  3. Launch your organs with efficiency. efficiently
System architecture:

Image RemovedImage Added


Panel
titleRequirements

For this tutorial, you just need the basic requirements


Panel
titleCreate the models / Digital twins

Anchor
2
2

In this part you’re going to create two sensor modelmodels:

  • Sensor, a complex model with 4 attributes:
    • -id : unique intinteger
    • -name : string 
    • - hydrometry hygrometry : intinteger
    • - temperature : intinteger
  • sensorListSensorList, a model with 1 attribute:
    • sensors :  []
Sensor and sensorList model
    • array of sensors

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

  1. Create a new spinal-system with from 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 called spinal-model models to store the differents different models you are going to create. Within this folder create a file modelsnamed model.js.
  3. Complete the file model.js:
    1. Create the sensor model.
    2. Extend the sensor model with the Model of spinal-coreclass from spinalCore.
    3. export Export the sensor model.
    4. Create the sensor list.
    5. Extend the sensor list with the Model of spinal-corespinalCore.
    6. export Export the sensor list.

Your model file should look like this:

spinal-modelmodels/modelmodels.js

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

// Sensor model
function Sensor// SensorModel inherits from Model
class SensorModel extends Model {
  constructor() {
    Sensor.super(this);
    // add attributes to the model
    this.add_attr({
        id: 0,
 
      name: "",
        hydrometryhygrometry: 0,
        temperature: 0,
    });
} // Sensor inherit of model
spinalCore.extend(Sensor, Model);}
}
module.exports.SensorSensorModel = SensorSensorModel;


// SensorList model
function SensorList SensorListModel inherits from Model
class SensorListModel extends Model {
  constructor() {
    SensorList.super(this);
    // Array of equipments
    this.add_attr({

       sensors: []
    });
}
// SensorList inherit}
of model
spinalCore.extend(SensorList, Model);
}
module.exports.SensorListSensorListModel = SensorListSensorListModel;



Panel
titleCreate Instantiate a list of 2 SensorSensors

Anchor
3
3

In this part your are going to create instantiate a list of 2 virtual sensors in the database and create two "organs" of the system that will simulate the sensor behavior.

Every sensor will have its own organ.

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

create a list of two sensor:


  1. Create a new folder spinal-organ-sensor1 and within it a file named index.js.
  2. in the index.js file:
    1. Require spinal-core.
    2. Get the connection
    string
    1. parameter from the config.js
    .
    1. file in the main folder
    2. Create a function addItem. This function create, set and add an item to the list given in argument.
    3. Create a function simulate. This function simulate the value of the sensor.
    4. Create a function onSuccess.
    this
    1. 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.
    1.  
    2. Create a function onFaill.
    this
    1. 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
    1. Load list from spinal-core.
  3. Load list from Create a new folder spinal-core.organ-sensor2 
  4. Copy paste this folder the index.js into sensor2 folder and do the appropriate modification in index.js .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
// RequirementRequirements and connection
const spinalCore = require('spinal-core-connectorjs');
const models = require('../spinal-modelmodels/models.js');
const connection_string


process.env.SPINALHUB_PORT = 7777;
process.env.SPINALHUB_IP = require("127.0./config0.1");
const conn = spinalCore.connect(connection_string);

// Creates a new sensor and add it to the list
addItem = (list) => {
    const item = new Sensor();
    item.id.set(0);
    item.name.set("sensor0");
    list.sensors.push(item);
    simulate(item);
};

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 random values to the hydrometryhygrometry and temperature of a sensor
function simulate = (sensor) => {
 
  const hydro = Math.floor(Math.random() * 100);
 
  const degrees = Math.floor(Math.random() * 30);
     sensor.hydrometryhygrometry.set(hydro);
 
  sensor.temperature.set(degrees);
     // Repeats every second
    setTimeout(() => {
 
      console.log("sensor 1.name.get() + ": data has changed");

       simulate(sensor);
    }, 1000);
};


//this function will be called if the list is successfully load
onSuccess = (list) => Finds a Sensor in the SensorList, if it doesn't exist, creates it
function getSensorById(list, id) {
  let item;

  for (let i = 0; i < list.sensors.length; i++) {
    if (list.sensors[i].id.get() === id) {
    if  item = (list.sensors.length < 1)
[i];
      break;
    }
  }
  if (typeof item === "undefined") {
    item = new addItemmodels.SensorModel(list);
    item.id.set(id);
    simulate(item.name.set("sensor" + id);
    list.sensors[0].push(item);
  }
  return item;
}

//this This function will be called if the list is failed to load
onFail = () => {
    successfully loaded
function onSuccess(list) {
  simulate(getSensorById(list, 0));
};

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

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

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


Run sensor1 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 sensor0 change every second.

Image RemovedImage Added


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

Code Block
languagejs
themeDJango
titleSensor2spinal-organ-sensor2/index.js
linenumberstrue
// RequirementRequirements and connection
const spinalCore = require('spinal-core-connectorjs');
const models = require('../spinal-modelmodels/models.js');

console.log("Configuration Environment const connection_string = require("../not found, using default config");
const conn = 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);
};

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 random values to the hydrometryhygrometry and temperature of a sensor
function simulate = (sensor) => {

   const hydro = Math.floor(Math.random() * 100);
    const degrees = Math.floor(Math.random() * 30);
     sensor.hydrometryhygrometry.set(hydro);
    sensor.temperature.set(degrees);
     // Repeats every second
 
  setTimeout(() => {
   
    console.log("sensor 2sensor.name.get() + ": 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 Finds a Sensor in the SensorList, if it doesn't exist, creates it
function getSensorById(list, id) {
  let item;

  for (let i = 0; i < list.sensors.length; i++) {
    if (list.sensors[i].id.get() === id) {
      item = list.sensors[i];
      break;
    }
  }
  if (typeof item === "undefined") {
    item = new models.SensorModel();
     simulate(list.sensors[1]);
};

//thisitem.id.set(id);
    item.name.set("sensor" + id);
    list.sensors.push(item);
  }
  return item;
}

// This function will be called if the list is successfully failed to load
onFail = () => {
 loaded
function onSuccess(list) {
  simulate(getSensorById(list, 1));
};

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

  spinalCore.store(conn, list, "List", () => {
        addItem(listsimulate(item);
 
  });
};
//  Tries to load
'List'
spinalCore.load(conn, "List", onSuccess, onFailonFailure); 


Image RemovedImage Added


Panel
titleLaunch efficiently your organs

Anchor
4
4

You might have noticed that you are 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 efficientlya 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)
  3. run the commande pm2 start restart 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)

Your .app.json should look like this:

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

pm2 will now show you 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.

...