Site RESTful avec Slim3 et ng-admin

SLIM 3 est un microframework php qui permet de créer des API. Associé à un module AngularJS nommé ng-admin[0], il permet de construire un tableau de bord d’administration d’une base de données dans une application de type SPA (Single Page Application). Nous verrons ici comment mettre en œuvre l’ensemble.

Les vidéos

  1. Création du projet dans NetBeans, installation du micro Framework Slim 3 avec composer
  2. Création de l’API. mise en place du routage, interrogation de ma base mySQL
  3. Installation du moteur de vue ng-admin et affichage d’une liste de données.
  4. Ajout, modification et suppression de données en faisant interagir ng-admin et l’API Slim 3

Prérequis

L’ordinateur hôte de la solution doit avoir :

Tous ces logiciels sont multiplateformes et fonctionnent quel que soit l’OS.

Création de la solution (Netbeans)

Dans Netbeans (exemple pour créer un projet portant le nom : « monProjet »)

Fichier->Nouveau Projet cela lance un assistant en 5 points

  1. Sélectionner un projet : Choisir Catégories -> PHP et Projets -> PHP Application, cliquer sur Suivant
  2. Name and Location : Project Name : monProjet, Sources Folder : pointer sur le dossier root du serveur et un sous dossier portant le nom du projet : par exemple c:\laragon\www\monProjet, PHP version (celle qui est installée sur l’ordinateur), Default Encoding : UTF-8, cliquer sur Suivant.
  3. Run Configuration : Run As : Local Web Site, project URL : le chemin du virtual host créé sur le serveur (si ce n’est fait automatiquement, il faut le faire) : http://monProjet.dev:8080
  4. PHP Frameworks : laisser vide, cliquer sur Suivant
  5. Composer : (installation des bibliothèques php nécessaires au projet, ici nous allons ajouter le paquet Slim 3 et le paquet Slim PDO).
    Dans token -> slim puis cliquer sur Search, sélectionner slim/slim, dans la liste déroulante Version choisir 3.x-dev , puis cliquer sur le bouton afin de faire apparaitre slim/slim (3.x-dev) dans la fenêtre de droite.
    refaire la même chose avec le paquet slim/PDO version dev-master

Cliquer sur Terminer, les différents dossiers du projet vont être créés, et composer va télécharger et installer les bibliothèques

A l’issue de l’opération, le dossier du projet ressemble à ceci :

Le dossier nbprojet contient les fichiers de paramétrage du projet necessaires à NetBeans (on n’y touche jamais)

Le dossier vendor, qui contient les bibliothèques téléchargées et un fichier autoload.php, qui comme son nom l’indique, permet de charger automatiquement les classes et leur espace de nom afin de les rendre disponibles facilement.

Composer.json est le fichier qui contient les références des packages installés,

{
    "name": "vendor/mon-projet",
    "description": "Description of project monProjet.",
    "authors": [
        {
            "name": "francois",
            "email": "your@email.here"
        }
    ],
    "require": {
        "slim/slim": "3.x-dev",
        "slim/pdo": "dev-master"
    }
}

Si on ajoute ou supprime une dépendance dans la partie « require » du fichier, puis qu’on effectue une commande composer update, le projet se met à jour automatiquement et chargeant ou déchargeant les bibliothèques ajoutées ou retirées. Un autoload.php est alors recréer. Composer.lock contient les informations de l’autoload actuel. (on ne touche jamais ce fichier).

Enfin un fichier index.php et un squelette de page web

L’API

Dans notre application, tous les accès au modèle de données se font au travers de requêtes web vers une API en respectant le format REST[1].

Le format REST considère l’url, non plus comme l’appel d’une page web mais comme l’appel à une fonction, les arguments étant passés soit dans l’url (pour les requêtes de type GET, DELETE) dans le corps (pour les requêtes POST) ou bien les deux (requêtes PUT).

Dans le format REST, les verbes des requêtes permettent de définir le type d’action que le serveur devra effectuer.

Exemple :

Verbe

url

Action

GET

/products   

Récupère un jeu de
données contenant tous les éléments « products »

GET

/products/:id

Récupère un jeu de
données contenant 1 élément « products » ayant l’identifiant « :id »

POST

/products   

Créer un « product »
dans la table « products » , les paramètres passent dans le corps
de la requête

PUT

/products/:id

Mise à jour du product
 d’identifiant « :id », les
paramètres passent dans le corps de la requête

DELETE

/products/:id

Destruction du product
d’identifiant « :id »

Grâce à ces 4 verbes, on peut créer des services web qu’on nomme CRUD (Create Read Modify Delete).

Le serveur renvoie au client un jeu de données soit au format XML soit au format JSON.

Exemple :

GET /products

Renvoie un tableau JSON de type :

[
    {
      "id": 1,
      "name": "LG P880 4X HD",
      "description": "My first awesome phone!",
      "price": null,
      "category_id": 5,
      "created": "2014-06-01 01:12:26",
      "modified": "2014-05-31 17:12:26"
    },
    {
      "id": 2,
      "name": "Google Nexus 4",
      "description": "The most awesome phone of 2013!",
      "price": "56",
      "category_id": 2,
      "created": "2014-06-01 01:12:26",
      "modified": "2014-05-31 17:12:26"
    },
…
]

GET /products/2

Renvoie un objet JSON ressemblant à ceci :

{
      "id": 2,
      "name": "Google Nexus 4",
      "description": "The most awesome phone of 2013!",
      "price": "56",
      "category_id": 2,
      "created": "2014-06-01 01:12:26",
      "modified": "2014-05-31 17:12:26"
}

 

L’API sera construite à l’aide du microframework Slim Framework 3[2]. Ce dernier a été créé pour développer simplement des API, il possède un routeur pour gérer les diverses requêtes et un injecteur de dépendance qui permet d’utiliser les bibliothèques tierces.

Créer un dossier « api » sur la racine du projet. Ajouter un fichier index.php et un fichier .htaccess

Comme indiqué sur la page https://www.slimframework.com/docs/start/web-servers.html , compléter la fichier .htaccess de la manière suivante :

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

Vérifier aussi que dans la configuration de Apache l’option AllowOverride est sur All.

Sur un raspberry il s’agit du fichier /etc/apache2/apache2.conf, section :

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Comme indiqué page https://www.slimframework.com/docs/tutorial/first-app.html , le squelette de la page index est le suivant :

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response) {
    $name = $request->getAttribute('name');
    $response->getBody()->write("Hello, $name");

    return $response;
});
$app->run();

Nous allons nous inspirer de ce squelette afin que l’api puisse répondre  des données statiques dans un premier temps, puis des données issues de la BDD

exemple avec des données issues de la base de données

On suppose que la base de données est créée et qu’elle contient une table « ouvrants » (champs id et nom) avec quelques valeurs.

Dans Slim l’accès à la base de donnée est simplifié grâce à la bibliothèque slim/PDO . D’après la documentation[3]

L’usage typique se fait de la manière suivante :

require_once 'vendor/autoload.php';

$dsn = 'mysql:host=your_db_host;dbname=your_db_name;charset=utf8';
$usr = 'your_db_username';
$pwd = 'your_db_password';

$pdo = new \Slim\PDO\Database($dsn, $usr, $pwd);

// SELECT * FROM users WHERE id = ?
$selectStatement = $pdo->select()
                       ->from('users')
                       ->where('id', '=', 1234);

$stmt = $selectStatement->execute();
$data = $stmt->fetch();

// INSERT INTO users ( id , usr , pwd ) VALUES ( ? , ? , ? )
$insertStatement = $pdo->insert(array('id', 'usr', 'pwd'))
                       ->into('users')
                       ->values(array(1234, 'your_username', 'your_password'));

$insertId = $insertStatement->execute(false);

// UPDATE users SET pwd = ? WHERE id = ?
$updateStatement = $pdo->update(array('pwd' => 'your_new_password'))
                       ->table('users')
                       ->where('id', '=', 1234);

$affectedRows = $updateStatement->execute();

// DELETE FROM users WHERE id = ?
$deleteStatement = $pdo->delete()
                       ->from('users')
                       ->where('id', '=', 1234);

$affectedRows = $deleteStatement->execute();

 

On a ici les prototypes de l’instanciation d’un objet $pdo et des diverses requêtes select, delete, insert et update. L’intégration dans Slim se fait via un « container » permettant d’instancier un objet de la bibliothèque slim/PDO qui se situe dans un autre espace de nom que l’objet $app de Slim…

Le container va permettre de préparer, gérer et injecter des dépendances à l’application. L’avantage est que l’objet lié au container est créé à la demande et non de manière permanente. D’autre part les objets de l’application pourront accéder à des ressources dans d’autres espaces de nom.

Pour créer un container « db », insérer le code suivant :

<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$config = [
    'settings' => [
        'displayErrorDetails' => true,

       
    ],
];
$app = new \Slim\App($config);
$container = $app->getContainer();
$container['db'] = function () {
    $dsn = 'mysql:host=localhost;dbname=apidb;charset=utf8';
    $usr = 'root';
    $pwd = '';
    $pdo = new \Slim\PDO\Database($dsn, $usr, $pwd);
    return $pdo;
};

Cela permet de créer un objet « db » qui sera instancié à la demande.

création d’une requête SELECT

Remplacer le code de la fonction $app->get(…) par celui-ci

/*********************************************************
 *    gestion des requêtes GET
 ******************************************************** */
$app->get('/{table}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    // SELECT * FROM {table}
    $selectStatement = $this->db->select()
            ->from($table);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetchAll();
    return $response->withJson($data);
});

$this->db fait référence au container  « db » créé précédemment.

Sur le même principe si on veut que l’api renvoie juste un produit dont on spécifie l’id, le code sera le suivant :

$app->get('/{table}/{id}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    $id = $request->getAttribute('id');
    // SELECT * FROM {table} WHERE id = {id}
    $selectStatement = $this->db->select()->from($table)->where("id","=",$id);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetch();
    return $response->withJson($data);
});

Code complet de la page /api/index.php

<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$config = [
    'settings' => [
        'displayErrorDetails' => true,
       
    ],
];
$app = new \Slim\App($config);
$container = $app->getContainer();
$container['db'] = function () {
    $dsn = 'mysql:host=localhost;dbname=apidb;charset=utf8';
    $usr = 'root';
    $pwd = '';
    $pdo = new \Slim\PDO\Database($dsn, $usr, $pwd);
    return $pdo;
};

$app->get('/{table}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    // SELECT * FROM users WHERE id = ?
    $selectStatement = $this->db->select()
            ->from($table);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetchAll();
    return $response->withJson($data);
});

$app->get('/{table}/{id}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    $id = $request->getAttribute('id');
    // SELECT * FROM {table} WHERE id = {id}
    $selectStatement = $this->db->select()->from($table)->where("id","=",$id);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetch();
    return $response->withJson($data);
});

$app->run();

Installation de NG-ADMIN

ouvrir un terminal dans le dossier qui contient la solution puis effectuer la commande

npm install -g npm@2.x (sous linux faire précéder de sudo)
npm install ng-admin –-save

Cela installera le dossier node_modules et le sous dossier ng-admin qui contient tout le matériel pour le front-end.

Le dossier du projet va ressembler à ceci :

Modifier la page web index.php à la racine du site. Le code de la page est le suivant :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Controle d'accès</title>
       <link rel="stylesheet" href="node_modules/ng-admin/build/ng-admin.min.css">
    </head>
    <body ng-app="myApp">
        <div ui-view="ng-admin"></div>
        <script src="node_modules/ng-admin/build/ng-admin.min.js" type="text/javascript"></script>
        <script src="js/app.js"></script>
    </body>
</html>

Le corps de la page est constitué d’une simple balise <div ui-view=”ng-admin”></div> et le <body> fait référence à l’application angularJS sous-jacente grâce à l’attribut ng-app=”myApp”[4]

Rajouter un dossier « js » et un fichier nommé app.js (dont il est fait référence dans la page index.php). Le script va créer un module angularJS nommé « myApp » et qui intégrera la bibliothèque [‘ng-admin’], la suite permet de configurer l’application. La documentation détaillée au format pdf de ng-admin est accessible ici : https://www.gitbook.com/book/marmelab/ng-admin/details

Code de /js/app.js

// declare a new module called 'myApp', and make it require the `ng-admin` module as a dependency
var myApp = angular.module('myApp', ['ng-admin']);
// declare a function to run when the module bootstraps (during the 'config' phase)
myApp.config(['NgAdminConfigurationProvider', function (nga) {
        // create an admin application
        var admin = nga.application('Mes produits')
                .baseApiUrl('/api/'); // main API endpoint;

        /************************************
         *  entité produts
         ************************************/
        var produits = nga.entity('products');
        var categories= nga.entity('categories');
        categories.listView();
        // tableau = listview
        produits.listView()
                .title('les produits')
                .fields([
                    nga.field('id'),
                    nga.field('name').label('nom'),
                    nga.field('description'),
                    nga.field('price').label('prix')
                  ]) ;
        admin.addEntity(produits);
        admin.addEntity(categories);
        nga.configure(admin);
    }]);

L’application fonctionne,

Reste à intégrer dasn l’API les fonctions d’ajout, de mise à jour et d’effacement des produits.

code complet

/api /index.php

<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$config = [
    'settings' => [
        'displayErrorDetails' => true,

       
    ],
];
$app = new \Slim\App($config);
$container = $app->getContainer();
$container['db'] = function () {
    $dsn = 'mysql:host=localhost;dbname=apidb;charset=utf8';
    $usr = 'root';
    $pwd = '';
    $pdo = new \Slim\PDO\Database($dsn, $usr, $pwd);
    return $pdo;
};

$app->get('/{table}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    // SELECT * FROM users WHERE id = ?
    $selectStatement = $this->db->select()
            ->from($table);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetchAll();
    return $response->withJson($data);
});

$app->get('/{table}/{id}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    $id = $request->getAttribute('id');
    // SELECT * FROM users WHERE id = ?
    $selectStatement = $this->db->select()->from($table)->where("id","=",$id);
    $stmt = $selectStatement->execute();
    $data = $stmt->fetch();
    return $response->withJson($data);
});

$app->post('/{table}', function (Request $request, Response $response) {
    $data=$request->getParsedBody();
    $table = $request->getAttribute('table');
    $keys= array_keys($data);
    $values=array_values($data);
    $insertStatement= $this->db->insert($keys)
            ->into($table)
            ->values($values);
    $stmt = $insertStatement->execute();
    $response->withJson($stmt);  
    
});

$app->put('/{table}/{id}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    $id = $request->getAttribute('id');
    $data=$request->getParsedBody();
    $updateStatement = $this->db->update($data)
            ->table($table)
            ->where('id',"=",$id);
        $stmt = $updateStatement->execute();
    $response->withJson($stmt);

});
$app->delete('/{table}/{id}', function (Request $request, Response $response) {
    $table = $request->getAttribute('table');
    $id = $request->getAttribute('id');
    $deleteStatement = $this->db->delete()->from($table)->where('id', '=', $id);
    $stmt = $deleteStatement->execute();
    $response->withJson($stmt);
});

$app->run();

 

/js/app.js

// declare a new module called 'myApp', and make it require the `ng-admin` module as a dependency
var myApp = angular.module('myApp', ['ng-admin']);
// declare a function to run when the module bootstraps (during the 'config' phase)
myApp.config(['NgAdminConfigurationProvider', function (nga) {
        // create an admin application
        var admin = nga.application('Mes produits')
                .baseApiUrl('/api/'); // main API endpoint;

        /************************************
         *  entité produts
         ************************************/
        var produits = nga.entity('products');
        var categories= nga.entity('categories');
        categories.listView();
        // tableau = listview
        produits.listView()
                .title('les produits')
                .fields([
                    nga.field('id'),
                    nga.field('name').label('nom'),
                    nga.field('description'),
                    nga.field('price').label('prix'),
                    nga.field('category_id','reference')
                            .targetEntity(categories)
                            .targetField(nga.field('name'))
                            .label('catégorie')
                ])
                .listActions(['edit']);
        produits.creationView()
                .title('Ajout d\'un produit')
                .fields(produits.listView().fields());
        
        produits.editionView()
                .fields(produits.creationView().fields());
        admin.addEntity(produits);
        admin.addEntity(categories);
        nga.configure(admin);
    }]);

 

  1. https://marmelab.com/fr/blog
  2. https://openclassrooms.com/courses/utilisez-des-api-rest-dans-vos-projets-web/pourquoi-rest
  3. https://www.grafikart.fr/tutoriels/php/slim-framework-831
  4. https://github.com/FaaPz/Slim-PDO
  5. Voir formation angularJS : https://www.grafikart.fr/formations/angularjs
    ou le livre « AngularJS » editions ENI ISBN 978-2-7460-9334-8

Freeboard et Node-Red

Freeboard est un projet de tableau de bord gratuit et open source avec des abonnements hébergés optionnels, facile à intégrer à diverses sources de données. Ce projet a été développé par Bug Labs, les créateurs d’un puissant service appelé dweet , un service de messagerie conçu pour l’Internet des Objets. Il existe un nœud Node-Red qui permet de mettre en relation un flux et le tableau de bord freeboard. Nous allons voir ici comment l’installer et l’utiliser.

IPX800-V4

IPX800 est un automate programmable orienté domotique. Il possède 4 entrées analogiques, 8 entrées logiques et 8 sorties sur relais. Le paramétrage et la programmation se font via une interface WEB. Un système de bus permet de connecter divers périphériques et on peut accéder aux données via une API. La plateforme est donc polyvalente et ouverte, ce qui permet de l’inclure à de nombreux projets.

Présentation de l’IPX800-V4

Programmation d’un scénario : thermostat d’ambiance

Interface de gestion de base de données

jsGrid est une bibliothèque jQuery qui permet de gérer un tableau de données et offre les options de CRUD (Create Read Update Delete) au travers de requêtes AJAX. L’objet de l’article consiste à mettre en œuvre ce composant en liaison avec une collection mongoDB, à travers l’interface de développement Node-Red.

Exemple de grille obtenue avec jsGrid

vidéos

La playlist suivante contient 5 vidéos :

  • Installation en local des fichiers scripts et CSS
  • Mise en œuvre de jsGrid à partir de l’exemple fournit sur le site de jsGrid dans une page structurée avec le framework BootStrap
  • Utilisation de la base de données afin de remplir la grille jsGrid avec les documents d’une collection.
  • Insertion et effacement d’un nouveau document dans la collection
  • Mise à jour d’un  document.

 

Mongodb et Node-red

Mongodb est un moteur de base de données noSQL (not only SQL) orienté documents. Ce genre de base de données est structurée autour de classeurs qu’on nomme “collections”, chaque collection contenant des documents. Les documents sont indexés afin de pouvoir y accéder rapidement. Les bases de données noSQL favorisent la vitesse d’accès aux données, au détriment parfois de la compacité. Nous verrons ici comment installer mongoDB sur Raspberry Pi, puis comment l’utiliser au sein de Node-Red.

Installation de mongoDB sur raspberry pi

(voir le document complet)

MongoDB et node-red

Installation du nœud mongodb2 et insertion d’un document dans une collection par injection :

Création d’un formulaire d’insertion de données à l’aide des nœuds Dashboard.

 

Installation de mongoDB et mongo-express

Pour mongoDB c’est plutôt simple :

sudo apt-get install mongodb

On peut vérifier que cela fonctionne :
Démarrage du service mongodb

$ sudo /etc/init.d/mongodb start

Le serveur mongo db démarre normalement à l’adresse 127.0.0.1 :27017

$ mongo

Ça lance une console

> use myDB
> db.LicencePlate.insert({})

Confirmation de l’existence de la base et de la collection :

> show dbs
> show collections

Mongo-express est une interface utilisateur permettant de manipuler mongoDB de manière visuelle. Il faut que node-red et npm soit installés (voir le document d’installation de node-red avec Johnny5)

sudo npm install -g mongo-express

Par défaut le login et le mot de passe sont admin et pass cela peut être changé en modifiant le fichier de configuration. Sur raspberry le fichier de configuration se trouve dans /usr/lib/node_modules/mongo-express

Il faut recopier en le renommant config.js  puis l’éditer:

sudo cp /usr/lib/node_modules/mongo-express/config.default.js /usr/lib/node_modules/mongo-express/config.js
sudo nano /usr/lib/node_modules/mongo-express/config.default.js

Si la base myDB a été créée (voir l’installation de mongodb et les commandes shell), il faut modifier le fichier config.js :

// Accesing Bluemix variable to get MongoDB info
if (process.env.VCAP_SERVICES) {
var dbLabel = 'mongodb-2.4';
var env = JSON.parse(process.env.VCAP_SERVICES);
if (env[dbLabel]) {
mongo = env[dbLabel][0].credentials;
}
} else {
mongo = {
db: 'myDB',
host: 'localhost',
// password: 'pass',
port: 27017,
ssl: false,
url: 'mongodb://localhost:27017/db',
// username: 'admin',
};
}

Si on veut accéder à l’interface utilisateur depuis un autre ordinateur que le raspberry, dans la section « site »,  il faut renseigner l’adresse IP du raspberry à la place de localhost et modifier le login et le mot de passe:

site: {
// baseUrl: the URL that mongo express will be located at - Remember to add the forward slash at the start and end!
baseUrl: process.env.ME_CONFIG_SITE_BASEURL || '/',
cookieKeyName: 'mongo-express',
cookieSecret: process.env.ME_CONFIG_SITE_COOKIESECRET || 'cookiesecret',
host: process.env.VCAP_APP_HOST || '0.0.0.0', //connexion quelle que soit l’adresse de la carte Raspberry
port: process.env.VCAP_APP_PORT || 8081, //port du serveur web
requestSizeLimit: process.env.ME_CONFIG_REQUEST_SIZE || '50mb',
sessionSecret: process.env.ME_CONFIG_SITE_SESSIONSECRET || 'sessionsecret',
sslCert: process.env.ME_CONFIG_SITE_SSL_CRT_PATH || '',
sslEnabled: process.env.ME_CONFIG_SITE_SSL_ENABLED || false,
sslKey: process.env.ME_CONFIG_SITE_SSL_KEY_PATH || '',
},
//set useBasicAuth to true if you want to authenticate mongo-express loggins
//if admin is false, the basicAuthInfo list below will be ignored
//this will be true unless ME_CONFIG_BASICAUTH_USERNAME is set and is the empty string
useBasicAuth: process.env.ME_CONFIG_BASICAUTH_USERNAME !== '',
//useBasicAuth: false,
basicAuth: {
username: process.env.ME_CONFIG_BASICAUTH_USERNAME || 'admin',
password: process.env.ME_CONFIG_BASICAUTH_PASSWORD || 'pass',
},

Ensuite on peut lancer mongo-express :

cd /usr/lib/node_modules/mongo-express/ && node app.js

ou plus simplement

$ mongo-express

Lancer un navigateur http://<adresse_IP_Raspberry>:8081 puis s’authentifier avec le l’identifiant et le mot de passe choisit précédemment :

Page d’accueil de mongo express Collections de la base myDB(cliquer sur « View » sur la page d’accueil pour voir les collections)
Documents de la collection « LicencePlate », on voit qu’une plaque d’immatriculation est inscrite (AV865XG) Cliquer sur « New Document » pour créer une nouvelle plaque d’immatriculation : ajouter “immatriculation”:”XX123YY”, avant “_id”: ObjectID() puis cliquer sur Save.

En cliquant sur le numéro de plaque on peut modifier le document, en cliquant sur le bouton rouge représentant une poubelle, on peut effacer ce document.

openALPR sur raspberry

OpenALPR est un logiciel de reconnaissance de plaque d’immatriculation. Ce logiciel s’appuie sur la bibliothèque openCV et le logiciel de reconnaissance de caractères tesseract.

Raspbian Jessie

On trouve sur les forums tout ce qu’il faut pour télécharger, compiler et installer ce package depuis les sources. L’inconvénient est que la compilation sur raspberry est très longue. Nous proposons ici une version packagée de openALPR, ce qui réduit considérablement le temps d’installation.

sudo apt-get update
sudo apt-get install liblog4cplus-1.0-4 beanstalkd libgtk2.0-0 libtiff5 libdc1394-22 libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev
wget http://www.rgot.org/wp-content/uploads/2016/12/openalpr.tgz
tar -zxvf openalpr.tgz
sudo dpkg -i openalpr_20161219-1-complet_armhf.deb
rm openalpr_20161219-1-complet_armhf.deb
rm openalpr.tgz

Pour déinstaller :

sudo dpkg -r openalpr

Pour Raspbian Stretch c’est plus simple :

il suffit de suivre les instructions disponibles sur le github de openalpr

sudo apt-get update && sudo apt-get install -y openalpr openalpr-daemon openalpr-utils libopenalpr-dev

Réinstallation de NODE-RED, RASPI-IO et JOHNNY-FIVE sur Raspberry Pi

La version intégrée de node-red permet de s’initier mais ne permet pas d’utiliser la bibliothèque raspi-io utilisée par le raspberry pour communiquer avec l’extérieur (problème de droits d’accès aux broches du raspi).
Pour pouvoir communiquer avec l’extérieur (capteurs, afficheurs, leds…) il faut donc réinstaller node.js et node-red.

Télécharger le fichier install_johnny5 , le rendre exécutable puis le lancer:

wget http://www.rgot.org/wp-content/uploads/2016/12/install_johnny5.txt
sudo chmod 755 install_johnny5.txt
./install_johnny5.txt

autre méthode : exécuter les lignes suivantes dans une console. (démarche issue de la note d’installation de node-red : http://nodered.org/docs/hardware/raspberrypi )

sudo apt-get update
sudo apt-get remove nodered
sudo apt-get remove nodejs nodejs-legacy
curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
sudo apt-get install -y build-essential python-rpi.gpio nodejs
sudo npm cache clean
sudo npm install -g --unsafe-perm node-red
sudo apt-get update && sudo apt-get install python-rpi.gpio
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.service -O /lib/systemd/system/nodered.service
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start -O /usr/bin/node-red-start
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop -O /usr/bin/node-red-stop
sudo chmod +x /usr/bin/node-red-st*
sudo systemctl daemon-reload
sudo npm i -g npm@2.x

Pour les raspi 2 et 3 il faut aussi exécuter les lignes suivantes pour installer raspi-io (gestion des entrées/sorties) et johnny5 (bibliothèque permettant la programmation d’automates)

sudo npm install -g johnny-five --unsafe-perm --force
sudo npm install -g raspi-io --unsafe-perm --force
sudo npm install -g node-red-contrib-gpio --unsafe-perm --force
sudo npm install serialport --unsafe-perm --build-from-source
sudo npm i -g oled-js oled-font-5x7

Éditer le fichier /lib/systemd/system/nodered.serviceet remplacer USER=pi par USER=root
ainsi la commande node-red-start lancera node-red en mode root (dans le dossier /root/.node-red )

Activer SSH au premier boot d’une carte Raspberry Pi

Depuis la dernière version de Raspbian Jessie (nov 2016) ssh est déactivé par défaut. Il faut donc se connecter via l’interface graphique et activer ssh dans la configuration de raspberry ( bouton framboise -> Préférences -> configuration du Raspberry Pi puis dans l’onglet “Interfaces” cocher SSH)
Si on possède une carte Raspberry qui n’est pas connectée à un ensemble clavier/souris/écran, il semble impossible de se connecter…
La solution consiste à ajouter un fichier (vide) nommé ssh dans la partition boot (c’est la partition visible lorsque la carte SD est introduite dans un PC Windows).
Au premier boot Raspberry détecte le fichier ssh, active le protocole ssh et efface le fichier ssh sur la partition boot.

connexion wifi d’une carte Raspberry Pi 3

La Carte Raspberry 3 possède nativement d’une interface réseau sans fils (WIFI) . Nous allons voir diverses méthodes pour se connecter au wifi

Utilisation de l’interface graphique :

C’est certainement la méthode la plus simple : connecter la carte raspberry à un clavier, une souris et un écran (via la prise HDMI) . Dans la  barre supérieur on voit l’icône réseau , il suffit alors de sélectionner le réseau wifi, de saisir le mot de passe… et voilà.

Pour les raspberry sans interface graphique.

Une autre méthode consiste à écrire un petit fichier de configuration qui est pris en compte au boot de la carte.
Il faut connaitre le nom du point d’accès et le mot de passe. Pour l’exemple imaginons que le point d’accès se nomme mammouth et que le mot de passe soit motDePasse
Sur un PC, il faut créer un fichier texte nommé wpa_supplicant.conf
Puis le compléter de la manière suivante :

country=FR
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
                ssid="mammouth"
                psk="motDePasse"
               }

Une fois ce fichier créé, il faut le sauvegarder sur la carte SD du raspberry :

  • Couper l’alimentation du raspberry
  • Extraire la carte SD
  • A l’aide d’un adaptateur SD/ USB, introduire la carte SD dans le PC
  • Sauvegarder le fichier wpa_supplicant.conf précédemment créé sur la carte SD
  • Réintroduire la carte SD dans le raspberry pi et le redémarrer.

Le fichier wpa_supplicant.conf est automatiquement placé au bon endroit dans l’arborescence et la connexion wifi se fait.

Retrouver l’adresse IP d’une carte Raspberry.

Une fois connecté au wifi, pour pouvoir se connecter à la carte raspberry, il faut connaitre son adresse IP. Nous allons utiliser un logiciel qui scanne le réseau afin de retrouver son adresse IP : Advanced port Scanner (http://www.advanced-port-scanner.com/fr/ ).
Ce Logiciel « ping » les diverses adresses IP du réseau et indique les informations qu’il trouve lorsqu’il rencontre une machine.
Il faut juste connaitre la plage réseau qu’on veut balayer :
Exemple : Réseau Classe C 192.168.5 les adresses possibles vont de 1 à 254. Ce qui veut dire que nous allons balayer de 192.168.5.1 à 192.168.5.254

Une fois le scan effectué on repère la (les) carte(s) Raspberry par leur adresse MAC qui commence toujours par B8:27:EB . On peut alors connaitre l’adresse IP de la carte et s’y connecter via WinSCP et PuTTY.