Xamarin Forms permet de créer des applications cross-platform, c’est à dire qui pourront être compilées pour Android, IoS et Universal Windows. Ce tuto d’initiation permet de découvrir l’interface de développement pour créer une petite application qui affiche la météo en renseignant le code postal.
La playlist contient 7 vidéos
Première application : découverte de l’environnement . Il s’agit ici de créer une petite application permettant de changer le texte d’un label en réponse à un “clic” sur un bouton. C’est un peu la version “Hello world ! ” d’une application Xamarin Forms.
Application météo partie 1 : utilisation de l’API openWeatherMap afin de récupérer un jeu de données pour un code postal donné.
Application météo partie2 : Création d’un client web dans l’application puis interrogation de openWeatherMap à l’aide de ce client.
Application météo partie3 : Création d’une classe permettant d’exploiter je fichier json fournit par openWeatherMap.
Application météo partie 4 : Mise en forme de l’interface graphique.
Application météo partie 5 : Finalisation de l’application –
Intégration d’une image représentative de l’état du temps.
Gestion des exceptions.
Application météo partie 5 : Dans cette vidéo on aborde la question du débogage. L’application fonctionne pour un ciblaque d’android 8 mais ne fonctionne plus quand on cible une version d’android 9 et supérieure. On voit donc comment repérer le dysfonctionnement et comment y remédier.
Série de 4 Vidéos pour débuter avec Node Red. Rien à installer !
Cette initiation utilise une version de Node-Red en ligne. L’objectif est de créer une horloge graphique.
Vidéo 1 : création d’un compte sur le site fred.sensetecnic.com
Vidéo 2 : construction du premier flux « bonjour tout le monde »
Vidéo 3 : utilisation d’un nœud de traitement : écrire la date et l’heure courante à partir du temps Unix.
Vidéo 4 : utilisation du Dashboard afin de visualiser l’heure de manière graphique.
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
Création du projet dans NetBeans, installation du micro Framework Slim 3 avec composer
Création de l’API. mise en place du routage, interrogation de ma base mySQL
Installation du moteur de vue ng-admin et affichage d’une liste de données.
Ajout, modification et suppression de données en faisant interagir ng-admin et l’API Slim 3
un serveur web avec PHP (ici nous utiliserons laragon)
la base de données exemple apidb (le fichier sql de la base est téléchargeable ici)
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
Sélectionner un projet : Choisir Catégories -> PHP et Projets -> PHP Application, cliquer sur Suivant
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.
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
PHP Frameworks : laisser vide, cliquer sur Suivant
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,
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.
{
"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
<?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 :
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.
// 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);
}]);
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 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
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
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.
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:
Si la base myDB a été créée (voir l’installation de mongodb et les commandes shell), il faut modifier le fichier config.js :
// Accessing 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 requestSize
Limit: 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 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.
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:
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)
É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 )