Applicato all'IIOT

Laravel Day Verona 2018

Applicato all'IIOT

Chi Sono

class eppak extends MedioMan implements Veneto
{
    public function identity()
    {
        return [
            "Name" => "Alessandro",
            "LastName" => "Cappellozza",
            "Moniker" => "eppak",
            "Email" => "alessandro.cappellozza@gmail.com"
        ];
    }

    public function job() {
        return $this->r & $this->d;
    }

    public function company() {
        return "SENECA";
    }

    public function alcohol()
    {
        return false;
    }

    public function alpine()
    {
        return false;
    }
}

Alessandro Cappellozza

Applicato all'IIOT

Il Mondo Industriale

APPLICAZIONI

Il Contesto
Applicato all'IIOT

Il Mondo Industriale

Copyright SENECA SRL

Telemetria e Telecontrollo

Applicato all'IIOT

Il Mondo Industriale

SCHEMA GENERICO

Logica

Locale

(PLC/RTU)

Supervisione

(SCADA)

I/O

e

Sensori

Bus

di

Campo

Datalogger

N:1

Applicato all'IIOT

Il Mondo Industriale

Caratteristiche:

  • Sono RTU / PLC
  • Ram 128/256k
  • Qualche Mbit di Flash
  • Architettura ARM
  • Con e senza I/O
  • Modem (spesso 2g)
  • Ethernet
  • Bus di campo seriale
  • Datalogger
Copyright SENECA SRL
Applicato all'IIOT

Il Mondo Industriale

Protocolli

  • Modbus RTU/TCP
  • MBus
  • EtherCAT
  • Profibus
  • OPC UA/DA (COM)
  • Su chiamata, CSD (Circuit Switch Data)
  • TCP/UDP
  • Rest HTTP
  • XML/JSON per il trasporto
  • MQTT
  • AMPQ
  • CoAP
  • Binario (compressione)

INTEGRAZIONE/EVOLUZIONE

(Cambio di mentalità es. CSD)
Applicato all'IIOT

Il Mondo Industriale

LO SCADA

Supervisione

Applicato all'IIOT

Il Mondo Industriale

LO SCADA: Rappresentazione della Realtà

  • SCADA "Nativi" / "Web"
  • Origine del "Sinottico" (Mosaico)
  • Target di Utenza specifico
  • Codifica comunicazione ben definita
Applicato all'IIOT

IL PROGETTO

RealizzazionE

Scelte Tecnologiche
Applicato all'IIOT

Il Progetto: IDEA DI PRODOTTO

Time constrain

Investimento di pochi mesi, il prodotto è di traino delle vendite.

ON PREMISE

  • Volontà di avere i dati in casa
  • Non voler gestire servizi esterni (costi)
  • Tangibilità del prodotto
  • Prodotto meglio comprensibile (confinato)
  • Costo/prestazioni più certe possibili
  • Resilienza all'abbonamento
  • Supervisione contenuta

GENERALITA'

  • Semplicità (target clienti poco skillati)
  • Ricoprire uno o più ruoli dello SCADA
  • Integrabilità
Vanno individuate delle tecnologie...
Applicato all'IIOT

Il Progetto

Windows?

Applicato all'IIOT

Il Progetto

Linux & Laravel

  • Supporto ai comandi
  • Disaccoppiamento dal web
  • Supporto alle code
  • Disaccoppiamento middleware
  • "Versionamento" db con migrations
  • Molti packages e supporto
  • Ottimo per headless
  • Compatibilità
  • Riproducibilità
  • Leggero (pochi fronzoli)
  • Vasto supporto software
  • Sicuro

L'approccio web solleva problematiche di tempi di esecuzione delle richieste quindi sono necessarie elaborazioni "batch"

Debian 8

LARAVEL 5

Applicato all'IIOT

Il Progetto

SCHEMA A BLOCCHI

Metadati

(Configurazioni)

Datastore

(Serie di tempi)

Sistema Operativo/Servizi

UI JS

Laravel

Applicato all'IIOT

Il Progetto

PROTOCOLLO

/* RICEVO */
class ProtocolController extends Controller
{
    use CommandBus;
    public function receive(Request $request, DataBus $bus)
    {
        $data = $request->getContent();
        $bus->dispatch(new DeivceData($data));
        
        return response()->json([ 'err' => 0 ]);
    }
}
/* RICEVO E SERVO */
class ProtocolController extends Controller
{
    use CommandBus;
    public function receive(Request $request)
    {
        $data = $request->getContent();
        $deviceData = new DeivceData($data);

        $this->dispatch($deviceData);       
        return response()->json([
              'err' => 0,
              'act' => CommandQueue::actions($data) /* LOGICA DI ESTRAZIONE */
        ]);
    }
}
  • Basato su HTTP
  • Payload JSon
  • Sincrono
  • Consente bidirezionalità solo nel caricamento del dato
Applicato all'IIOT

Il Progetto

DISTINZIONE DEL TIPO DI CHIAMATA

class DeivceData {
    private $data = null;

    public function __construct($data) 
    {
        $this->data = $data;
    }

    public function data() { return $this->data; }
}
class DeivceDataHandler {
    private $data = null;
    private $ds = null;

    public function __construct(DatastoreManager $ds, DeivceData $data) 
    {
        $this->data = $data;
        $this->ds = $ds;
    }

    public function handle() {
        $parsed = new PacketParser($this->data);
        $ds->store($parsed);
    }
}
class PacketParser {
    private $data = null;

    public function __construct($data) 
    {
        $this->data = new JSON($data);

    }

    public function isLog() { return $this->data->has('log'); }
    public function isCfg() { return $this->data->has('cfg'); }
    public function isEvent() { return $this->data->has('ev'); }
    public function isAck() { return $this->data->has('ack'); }
    public function uuid() {
         return $this->data->has('uuid') ?: $this->data->getUuid;
    }
}
Applicato all'IIOT

Il Progetto

PROCESSING CODA

class ProcessData implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $ds = null;
    private $data = null;

    public function __construct(DatastoreManager $ds, DevcieData $data)
    {
        /* .. */
    }

    public function handle()
    {
        /* .. */
    }
}
​Non sempre è stringente per l'rtu "sapere" che il dato è valido, né che è salvato correttamente nell'immediato.
Applicato all'IIOT

Il Progetto

/* ..*/

$this->app->bind(
    'App\Datastore\Contracts\Collector', 'App\Datastore\DataCollector'
);
namespace App\Datastore;

class DataCollector implements Contracts\Collector {

    public function __construct(Alarms $alarms, Datastore $ds) { /* .. */ }
    public function store($data) {
        if($this->data->isLog()) {
            $processed = $logProcessor->parse($data);
            $ds->write($processed);
            $alarms->dispatch($processed);
        }
    }
}
namespace App\Datastore\Contracts;

interface Collector {
    public function store($data);
}
namespace App\Datastore;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

class LogProcessor {
    public function parse($data) { /* LOGICA DEL DATO */ }
}

DATASTORE

PROCESSORE

  • Scatenare eventi
  • Calcolare campi virtuali, cambi scala, sommatorie (...)
namespace App\Dispatcher;

class Alarms {
    public function dispatch($data) { /* DISPATCH MESSAGGI */ }
}
Applicato all'IIOT

Il Progetto

DIFFERENZE CON WEB APP STANDARD

Procedure sensibili

 

  • Backup e Restore
  • Upgrade
  • Comunicare col sistema operativo (in maniera sicura)

Il prodotto deve essere ripristinabile in qualsiasi stato e non deve avere necessità della ui per la manutenzione base

Le procedure devono girare senza ausili esterni (rete)

Applicato all'IIOT

Il Progetto

Bootloader

Viene mutuato dal monto embed il concetto di bootloader che renda indipendente la app da possibili guasti e/o difetti di aggiornamento

# crontab

@reboot sh /var/www/bin/bootloader.sh

#!/bin/bash
sleep 15
/usr/bin/php /var/www/bootloader/upgrade.php
/usr/bin/php /var/www/bootloader/restore.php
// UPGRADE
<?php
$this->loadEnv();
if (file_exists('...') {
    $this->stopServices();
    $this->upgrade();
    $this->migrate();
    $this->startServices();
}

// RESTORE
<?php
$this->loadEnv();
if (file_exists('...') { 
    $this->stopServices();
    $this->upgrade();
    $this->migrate();
    $this->startServices();
}
  • Output rediretto in console
  • Output salvato su log
  • Procedura unattended
  • Gira con privilegi elevati
  • Pochissime dipendenze
  • Procedura valida per restore/upgrade (simili)
Applicato all'IIOT

Il Progetto

Comunicazione col sistema

FAI giraRE

HTTPD come

root...

Applicato all'IIOT

Il Progetto

Comunicazione col sistema

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <syslog.h>

int
main (int argc, char *argv[])
{
    int res = 1;
    char buff[1024];
    setuid (0);

    if (/* SECURITY CHECK */)
    {
        syslog(LOG_INFO, "RUN SOMETHING");
        sprintf(buff, "/SOME/PATH/BIN");
        system(buff);
        syslog(LOG_INFO, buff);
        res = 0;
    }

    return res;
}

COME BIN

Applicato all'IIOT

Il Progetto

Comunicazione col sistema

class System
{
    private $exec = false;
    private $jobid = 0;

    public function _construct()
    {
        declare(ticks=1);
        pcntl_async_signals(true);
        pcntl_signal(SIGUSR1, [$this, 'receivedSignal']);
    }

    public function apply()
    {
        $pid = posix_getpid();
        $this->exec = false;
        $this->jobid = Queue::push(new \App\Jobs\UpdateSystemSettings($pid));

        $ts = time();
        while(time() - $ts < SYSTEM_SETTINGS_TIMEOUT) {
            usleep(250);
            if($this->exec) { return true; }
        }

        return false;
    }

    private function receivedSignal($signo) {
        // CHECK $this->jobid
        $this->exec = true;
    }
}

COME JOB

Applicato all'IIOT

Il Progetto

Backup

class Backup implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $clt = null;
    private $meta = null;
    private $settings = null;

    public function __construct(Settings $settings, System $system, Collector $clt, MetaData $meta)
    {
        $this->settings = $settings;
        $this->system = $system;
        $this->clt = $clt;
        $this->meta = $meta;
    }

    public function handle()
    {
        $path= $this->settings->backupDestination();
        $this->meta->backup($path); 
        $this->clt->backup($path);
        $zipped = $this->system->zip($path);
        $this->system->move($zipped);
    }
}

Necessita <<solo>> di privilegi elevati

Datastore

BIG DATA

Applicato all'IIOT
Scelta del Datastore
Applicato all'IIOT

Datastore

"Big data is like teenage sex: everyone talks about it, nobody really knows how to do it, everyone thinks everyone else is doing it, so everyone claims they are doing it..."

Dan Ariely

http://fb.me/1r54f62oU

Applicato all'IIOT

Datastore

"Big data" con MySQL?

NUMERO DI CAMPIONI:

50 (device) x

100 (tag) x

1440 (minuti/g) x

720(giorni) x

=~ 5.2 x 10^9

Dai test

  • Le query cominciavano a rallentare vistosamente dopo i 500k record
  • Difficoltà di trovare uno schema che coniugasse prestazioni e generalità
  • Modalità di estrazione del dato (ampi frame temporali)
Applicato all'IIOT

Datastore

Di che Tipo di dato ho bisogno (e come)?

  • Per lo più float 64: anche i booleani spesso sono compattati in bitmask
  • Confine temporale: alcuni tipi di dati non hanno quasi mai necessità di span larghi
  • Downsampling (1): rappresentare ampi intervalli con pochi dati
  • Downsampling (2): risparmio di banda tra client/server (e nella rappresentazione)
  • Rielaborazione del dato: necessità di estrazione di un unico dato rappresentativo da un bucket
Applicato all'IIOT

Datastore: InfluxDB

namespace App\Datastore\Contracts;

interface Datastore {
    public function read($vars, $tags, $from, $to);
    public function last($vars, $tags);
    public function history($vars, $tags, $from, $to, $span = null, $agg = null);
    public function write($values, $tags);
    public function setRetention($days);
    public function getSize();
    public function getVersion();
}
namespace App\Datastore;

class InfluxDatastore implements Contracts\Datastore {
    public function read($vars, $tags, $from, $to) { /* ... */ }
    public function last($vars, $tags) { /* ... */ }
    public function history($vars, $tags, $from, $to, $span = null, $agg = null) { /* ... */ }
    public function write($values, $tags) { /* ... */ }
    public function setRetention($days){ /* ... */ }
    public function getSize() { /* ... */ }
    public function getVersion() { /* ... */ }
}
  • Semplicità e completezza
  • Scritto in go
  • Integrazione con PHP
  • Manutenzione
  • Installazione semplice
  • Prestante
  • Query Continue

 

  • SSD obbligatorio
  • Alias sul downsample
  • Cluster non open

Test con i3 (2GB)/SSD: 5.2 Mld campioni, estrazione 8 tracce (media) su periodo random fino a due anni

=~ 14sec di media

+

-

Applicato all'IIOT

Datastore: InfluxDB

PROBLEMATICA DELL'Aliasing

  • Insito nella procedura di downsampling
  • Non tutti i dati lo subiscono: es. monotone crescenti.
  • I booleani hanno bisogno di una rappresentazione a parte (es duty cycle).
Applicato all'IIOT

Datastore: InfluxDB

Largest Triangle Three Buckets

public class InfluxDatastoreLTTB extends InfluxDatastore {

    public function history($vars, $tags, $from, $to, $span = null, $agg = null); {
        
        if ($agg == "LTTB") {
            $data = $this->read($vars, $tags, $from, $to);
            return DataProcess::LTTB($data, MAX_SAMPLES);
        } else {
            return parent::history($vars, $tags, $from, $to, $span, $agg);
        }
    }
}
/* ... */
public function LTTB($data, $thr = MAX_SAMPLES)
{
	$downampled = [];
	$prev = $data[0];
	
	for($b=1; $b<count($blocks)-1; $b++) {
		$rank = 0;
		$block = $blocks[$b];
		$avg = $this->avg($blocks[$b + 1]);
		
		for($i=0; $i<count($block); $i++) {
			$rank = $this->getRank($block[$i], $avg, $prev);
			if($downampled[$b] < $rank) {
				$downampled[$b] = $rank;
				$prev = $rank;
			}
		}
	}
	
	
	return $downampled;
}

private function makeBlocks($data) { /* DIVISION + LAST BLOCK */ }
private function avg($block) { /* .. */ }
private function getRank($sample, $avg, $prev) { /* .. */ };
  • Consuma RAM: i campioni vengono caricati blocco.
  • Consuma CPU: l'elaborazione è esaustiva.
  • Consuma IOPS: l'estrazione è onerosa.

 

 

Il tutto è proporzionato al timespan in questione.
(Mockup)
Però il risultato è visivamente notevole...
Applicato all'IIOT

Datastore: InfluxDB

Largest Triangle Three Buckets

5000 samples
100 samples
250 samples
50 samples

DOWNSAMPLE

Sveinn Steinarsson (https://skemman.is/handle/1946/15343)
Applicato all'IIOT

DERIVAZIONI

RISULTATI

Progetti Derivati
Applicato all'IIOT

DERIVAZIONI

Copyright SENECA SRL

Dashboard

Applicato all'IIOT

DERIVAZIONI

Copyright SENECA SRL

SINOTTICO

Applicato all'IIOT

Derivazioni

Copyright SENECA SRL

MyBoat

  • Realtime (MQTT)
  • Riuso struttura di base
  • Integrazione Node
  • UI Solo tramite app
  • Portale Laravel
Applicato all'IIOT

Derivazioni

VPN

Copyright SENECA SRL
Applicato all'IIOT

Derivazioni

https://joind.in/talk/c72fa

Laravel applicato all'IIOT

alessandro.cappellozza@gmail.com 

Laravel Day 2018 Verona - Alessandro Cappellozza

By Alessandro Cappellozza

Laravel Day 2018 Verona - Alessandro Cappellozza

Laravel Applicato all'IIOT - Laravel Day 2018 Verona - Alessandro Cappellozza

  • 1,207