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
titleGoal

Anchor
1
1

In this tutorial you learn how to :

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


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 models:

  • Sensor, a object model with 4 attributes:
    • id : unique int
    • name : string 
    •  hygrometry hydrometry : intinteger
    •  temperature temperature : intinteger
  • sensorListSensorList, an object a model with 1 listattribute:
    • sensors :  []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-equipments to store the different models. Within this folder create a file named models.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 the sensor model.
    4. Create the sensor list.
    5. Extend the sensor list with the Model of spinal-corespinalCore.
    6. Export the sensor list.

Your model file should look like this:

spinal-model-equipments/model.js

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

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

// SensorList model
spinalCore.extend(Sensor, inherits from Model);
module.exports.Sensor = Sensor;


// SensorList model
function SensorList
class SensorList extends Model {
  constructor() {
    SensorList.super(this);
    // Array of equipments
    this.add_attr({
 
      sensors: []
    });
  }
 	 // Creates a new sensor and add it to the list
	this.addItem  addItem() {
    	const item = new Sensor();
    	item.id.set(0);
    	item.name.set("sensor0");
    	this.sensors.push(item);
	  };
}
// SensorList inherit of model
spinalCore.extend(SensorList, Model);
module.exports.SensorList = SensorList;



Panel
titleInstantiate a list of 2 Sensors

Anchor
3
3

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

Each organ will simulate changes of hygrometry hydrometry and temperature.


  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 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.


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
// RequirementRequirements and connection
const spinalCore = require('spinal-core-connectorjs');
const models = require('../spinal-model/models.js');
const connection_string = require("../config");
const conn = spinalCore.connect(connection_string
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 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);
};

function findIndexById = (id, list) => {
    if (list.sensors.length <= 0)
   
    return -1;

   let i;
    

   for (i = 0;
    i < i < list.sensors.length && list.sensors[i].id !== id;
    i++);

 
  if (i < list.sensors.length)
 
      return i;
 
  else
  
     return -1;
};

//this This function will be called if the list is successfully loaded
loadfunction onSuccess = (list) => {
    const index = findIndexById(0, list);
 
  console.log("success 2 : index: ", index);

   if (index !== -1)
   
    simulate(list.sensors[index]);
 
  else
   
    list.addItem();
};

//this This function will be called if the list iscannot failedbe toloaded
load
onFail = function onFailure() => {
 
  const list = new models.SensorList();

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

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

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



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

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

// 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);
};

findIndexById = (id, list) => {
    if (list.sensors.length <= 0)
        return -1;
    let i;
    for (i = 0; i < i < list.sensors.length && list.sensors[i].id !== id; i++);

    if (i < list.sensors.length)
        return i;
    else
        return -1;
};

//this function will be called if the list is successfully load
onSuccess = (list) => {

    const index = findIndexById(1, list);
    console.log("success 2 : index:", index);
    if (index !== -1)
        simulate(list.sensors[index]);
    else
        addItem(list);
};

//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);




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)

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": "./sensor1/"
    },
    {
      "name": "sensor2",
      "script": "index.js",
      "cwd": "./sensor2/"
    }
  ]
}

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


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.

...