[TUTORIEL] Développer une box dans le core de Gladys

tutoriel

#1

Développer une box dans le core de Gladys

Bonjour à tous !

Tout le monde peut créer une box, que ça soit pour des besoins personnels ou même pour demander à ce qu’elle soit intégrée nativement à Gladys. Mais jusqu’à maintenant il n’existait pas de véritable tutoriel sur ce sujet ce qui compliquait la tache de beaucoup d’entre vous. Ce tutoriel s’adresse plus particulièrement aux développeurs, pour ceux qui souhaitent juste personnaliser leurs dashboard il suffit d’aller dans “paramètres” puis “box” et de choisir dans la liste. :slight_smile:

Nous allons donc voir comment créer une box native et faire le tour des points “essentiels” au développement de celle-ci. Le but étant avant tout de garder un dashboard homogène !

Notez qu’il est pour le moment impossible de créer une box au sein d’un module.

Les “guidelines”

Alors commençons par quelques points important à prendre en compte lors du développement d’une box.

1. Ciblez le besoin auquel la box va répondre

Ce premier point est important. Il faut se poser les bonnes questions avant de commencer.

  • Que va faire votre box ?
  • Que va t’elle apporter à l’utilisateur (ou à vous même) ?
  • Quel type de contenu elle va afficher ?
  • Apporte elle des fonctionnalités inédites à Gladys ?

Ces quelques question vous aideront à orienter votre développement et si vous le souhaitez, vous pouvez même créer un sondage sur le forum pour avoir l’avis de la communauté. :wink:

2. La performance

Gardez à l’esprit que votre box sera chargée par le dashboard, autrement dit par la première page qu’affiche Gladys quand un utilisateur se connecte ! Elle ne doit donc pas ralentir le chargement de cette page sous peine de mauvaise expérience utilisateur. Donc évitez de faire 50 appels HTTP pour afficher votre box :wink:

Pensez au assets ( js, css ) que vous utilisez, ces fichiers sont naturellement concaténés et minimifiés dans un fichier unique (fichier de production) donc plus vos assets sont lourds plus vous ralentissez le chargement de l’interface. Si vous souhaitez utiliser une librairie qui n’est pas encore présente au sein de Gladys faite attention à son poids afin de prévenir l’impact qu’elle aura sur le fichier de production.

3. Adopter un design “flat”

Pendant le développement de votre box la partie design est surement la plus importante car c’est la première chose que l’utilisateur va voir ! C’est ce qui va l’attirer. Donc travailler cet aspect le mieux possible, d’autant plus que votre box viendra enrichir le dashboard de chaque utilisateur de Gladys et plus les boxs sont belles plus le dashboard de Gladys attirera de nouveaux utilisateur. :wink:

Simple, efficace et léger ! Ce sont les mots d’ordres :slight_smile:
Voila pourquoi un design flat est important. D’une part car l’interface de Gladys repose sur ce courant graphique (et donc il ne faut pas aller dans le sens inverse) et d’autre part car le flat design repose sur les mots d’ordres cité au dessus.

Pour ceux qui ne connaissent pas voici un article assez sympa à lire.

4. La taille de la box

Par défaut le dashboard est réglé pour avoir deux colonnes, donc inutile d’essayer de créer une box qui fait toute la largeur de la page !

Voici une image très minimaliste du dashboard de Gladys, la zone rouge représente la première colonne et la zone verte la seconde. Comprenez qu’il est inutile de paramétrer la largeur de votre box car la page s’en chargera d’elle même selon la position demandé par l’utilisateur.

Pour la hauteur il n’en n’est pas de même mais pour des raison d’homogénéité votre box ne devra pas excéder 500px !
Si votre box vient a être trop grande l’expérience utilisateur ne sera pas optimal donc essayer de réduire le contenu affiché par celle-ci ou alors faites en sorte qu’elle soit scrollable. (Ce ne sont que deux propositions parmi une multitude de solution)

Les prérequis pour développer une box

Evidemment si vous souhaitez développer une box il vous faut un minimum de connaissances avant de commencer !

Donc les prérequis sont :

  • Avoir des connaissances en JavaScript.
  • Avoir des connaissances en HTML.
  • Avoir des connaissances en CSS.
  • Avoir des connaissances en Angular.
  • Et surtout une bonne documentation :slight_smile:

Comment fonctionne l’intégration des boxs ?

Pour commencer, le schéma :

uuid: "Identifiant_unique",
title: "Titre",
path: "Chemin_du_fichier_ejs",
view: "dashboard"

Le schéma vous permet de répertorier votre box dans la base de données de Gladys. Si vous ne créez pas ce schéma dans le fichier boxTypes.js votre box ne sera tout simplement pas enregistrée et l’utilisateur n’y aura pas accès.

Une fois votre box créée dans ce fichier, allez dans paramètres et cliquez sur le bouton “mettre à jour les données Gladys” pour que votre box soit enregistrée et disponible dans la liste.

Ce fameux fichier se trouve dans le dossier config de Gladys.

Voila à quoi ressemble le schéma de la box Calendrier par exemple :

uuid: "81afa4ed-c084-45b3-ba8a-e9e22c9753ae",		
title: "calendar",		
path: "views/boxs/calendar.ejs",		
view: "dashboard"

Notez que l’attribut “uuid” doit être unique.

L’attribut “title” prend comme valeur le titre en anglais de votre box tandis que l’attribut “path” prend le chemin d’accès du fichier EJS de celle-ci.

Point important, le fichier EJS de votre box doit impérativement se trouver dans le dossier views/boxs de Gladys. De même si vous avez besoin d’écrire un bout de CSS le fichier devra être situé dans le dossier assets/styles, et il sera automatiquement minimifiés et importé dans le layout principal par le framwork.

Le fichier EJS contient l’HTML de votre box, c’est donc dans celui-ci que la partie design entre compte. :wink:

Les différents types de box et leurs structures

Entrons dans le vif du sujet !

Nous allons voir qu’il existe plusieurs type de box intégrable à Gladys, et souvenez vous des question à vous poser avant de commencer votre développement, elles visent à vous orienter vers le type de box adapter au besoin auquel elle va répondre :wink:

Un lien vous permettant de modifier l’HTML de la box et d’avoir un rendu en temps réelle est fournis pour chaque exemple.

La box basique

Rien ne vaut mieux qu’un exemple :wink:
Donc voici l’HTML pour construire une box vide. Et une jolie capture de son aperçu.

<!-- box  -->
<div class="box">
  <div class="box-header with-border">
    <h3 class="box-title">Default Box Example</h3>
  </div>
  <!-- /.box-header -->
  <div class="box-body">
    The body of the box
  </div>
  <!-- /.box-body -->
  <div class="box-footer">
    The footer of the box
  </div>
  <!-- box-footer -->
</div>
<!-- /.box -->

image

Edit on JSfiddle

Comme vous pouvez le voir il n’y a rien de bien compliqué, la div avec la classe “box” représente notre box et celle-ci possède donc un “header”, un “body” et un “footer”.

Bon notre box est un peu triste non ?
Donc sachez que vous pouvez changer son style en ajoutant une classe à la div principale.

<!-- box  -->
<div class="box box-primary">
  <div class="box-header with-border">
    <h3 class="box-title">Default Box Example</h3>
  </div>
  <!-- /.box-header -->
  <div class="box-body">
    The body of the box
  </div>
  <!-- /.box-body -->
  <div class="box-footer">
    The footer of the box
  </div>
  <!-- box-footer -->
</div>
<!-- /.box -->

image

Edit on JSfiddle

Les classes en question sont :

box-primary
box-info
box-warning
box-success
box-danger

La box “solid”

Il existe un second type de box basique, ce sont les box “solid”.
L’HTML de la box ne change pas mais la différence se situe dans le fait que la couleur choisi est bien plus présente.
Voici quelques exemples :

Edit on JSfiddle

On peut voir sur cet exemple que l’header prend la couleur sur sa surface totale et que des bordures entourant la box sont présente ce qui accentue encore un peu plus la présence de la couleur.

Ce changement réside la encore dans une simple classe ajouté à la div principale :

box-solid

L’info box

L’info box est totalement différente sur tous les points. Ce type de box est conçue pour afficher une petite quantité d’informations (comme la température d’une pièce par exemple)
Voici un exemple :

<!-- info-box -->
<div class="info-box">
  <!-- Apply any bg-* class to to the icon to color it -->
  <span class="info-box-icon bg-red"><i class="fa fa-thermometer"></i></span>
  <div class="info-box-content">
    <span class="">House 1 : bedroom</span>
    <span class="info-box-number">68 °F</span>
  </div>
  <!-- /.info-box-content -->
</div>
<!-- /.info-box -->

image

Edit on JSfiddle

Comme vous le voyez la box ne possède plus d’“header” n’y de “body” ou de “footer”, elle est divisée en deux partie soit l’icone et le “content”. La particularité de cette box réside dans le fait qu’elle possède ses propres classes de mise en forme de texte et qu’elle est très simple niveau HTML.

Bien entendu elle peux prendre elle aussi plusieurs couleurs.

Edit on JSfiddle

Les classes de couleur possible sont les suivantes :

bg-aqua
bg-green
bg-yellow
bg-red

Le controller Angular

Comme chaque box, la votre aura un controller Angular vous permettant de faire des appels HTTP afin de récupérer des données. Grace à lui vous aller pouvoir enregistrer ou mettre à jour des paramètres utilisateurs dans la base de données de Gladys. Mais aussi récupérer d’autres type de données comme les deviceState ou même les événements du calendrier.

Celui-ci devra être situé dans le dossier assets/js/app/Nom_de_votre_box et devra se nommer Nom_de_votre_box.box.controller.js afin de pouvoir le différencier d’un autre controller quelconque et pour vous faire économiser du temps voici la structure de base :wink:

(function () {
	'use strict';
	
	angular
		.module('gladys')
		.controller('Nom_de_votre_boxBoxCtrl', Nom_de_votre_boxBoxCtrl); 
		//Gardez bien le "BoxCtrl" !

	Nom_de_votre_boxBoxCtrl.$inject  = [];

	function  Nom_de_votre_boxBoxCtrl() {
		var  vm  =  this;
		
		activate();
		
		function activate(){
			//do something
		}
	}
})();

Avant tout n’oubliez pas de faire la liaison entre votre box et votre controller Angular :wink:
Pour ça, ajoutez data-ng-controller="Nom_de_votre_boxBoxCtrl as vm" à l’HTML de votre box. ( vm représente la variable qui vous permet de faire appel à votre controller n’importe où dans l’HTML de votre box)
Cette ligne est a placer à la div englobant la totalité de votre box, comme dans l’exemple ci-dessous.

<!-- box-->
<div class="box box-primary" data-ng-controller="Nom_de_votre_boxBoxCtrl as vm">
  <div class="box-header with-border">
    <h3 class="box-title">Default Box Example</h3>
  </div>
  <div class="box-body">
    The body of the box
  </div>
  <div class="box-footer">
    The footer of the box
  </div>
</div>

Comme je le disais plus haut il vous est possible de faire des appels HTTP vers Gladys afin de récupérer des données ou même de lui en envoyer. Pour ça il vous faut injecter les services qui contiennent les routes existantes. Pour ça, rien de bien compliqué, rajoutez simplement le nom du service à la ligne inject de votre controller ainsi qu’en paramètre de sa fonction.

Pour l’exemple nous allons voir comment récupérer les paramètres d’une box grace au service boxService ! Avant ça rajoutez cette ligne à l’HTML de votre box ng-init="vm.init(<%= boxId %>);"

Celle-ci va appeler la fonction init() de votre controller au démarrage de votre box en lui passant son id en paramètre. Et grâce à lui il nous sera possible de demander les paramètres de votre box à Gladys. Ce qui donnera :

(function () {
	'use strict';
	
	angular
		.module('gladys')
		.controller('Nom_de_votre_boxBoxCtrl', Nom_de_votre_boxBoxCtrl); 
		//Gardez bien le "BoxCtrl" !

	Nom_de_votre_boxBoxCtrl.$inject  = ['boxService'];

	function  Nom_de_votre_boxBoxCtrl(boxService) {
		var  vm  =  this;
		vm.init = init;
        vm.updateBoxParams = updateBoxParams;
		vm.box = null;
		
		function init(id){
			boxService.getById(id) //On appel la route "getById" du service
				.then(function(data){
					vm.box = data.data; //On sauvegarde tout 
					activate(); //On active notre box
				});
		}
		
		function activate(){
			console.log(vm.box.param)
		}

		function updateBoxParams(hello_world){
			boxService.update(vm.box.id, {params: {text: hello_world}})
				.then(function(data){
					console.log("Paramètres sauvegardés !")
				});
		}
	}
})();

Remarquez que j’ai aussi introduit une fonction updateBoxParams pour, comme son nom l’indique, mettre à jour les paramètres de votre box. Bien entendu ce n’est pas le seul service disponible (ils se trouvent tous dans le dossier assets/js/app) et vous pouvez aussi créer le votre avec de nouvelles routes si nécessaire. :slight_smile:

Internationalisation

Votre box doit, dès le début, être international. N’y pensez pas après !
Il faut gérer au minimum le français et l’anglais ! ( les deux langues par défaut dans Gladys ).

Il existe des fichier de langues au sein de Gladys situé dans config/locales. Il vous suffit donc de rajouter vos variables de langues dans le fichier fr.json et en.json. Dans l’HTML de la box vos variables de langues ressemblerons à ceci <%= __('box-nom_de_votre_variable') %> et seront automatiquement remplacées. :wink:
Attention les variables de langues ne sont pas liées à votre controller angular c’est pourquoi le vm ne doit pas être présent dans leurs nom.


Script BOX temperature
Module gladys-Netatmo
[RESOLU] Création module - Créer box à l'install
[RÉFÉRENTIEL] - Les tutoriels
#2

Woua super tutoriel !
Merci beaucoup :slight_smile:.

J’ai quelque questions :
Les boxes ne sont pas installable par les modules a cause des fichiers se devant d’être dans les bon dossier ?
Car si oui il est possible avec le code de copier les fichiers et les installer non?

En tout cas encore merci pour ce taf !


#3

Non le problème ne vient pas de la car comme tu le dit les fichiers pourraient être copiés automatiquement à l’installation du module !

La contrainte principal vient des assets qui sont concaténés et minimifiés pour obtenir deux fichiers de production super léger, hors ce processus prend énormément de temps et de ressources. Mais sans ces assets les boxs ne peuvent pas fonctionner car il leurs faut bien un controller voir même un bout de css.

Sauf qu’on ne peux pas se permettre de lancer ce processus à chaque fois qu’un module à besoin de charger des assets XD
Pour l’exemple, sur mon RPI 3 le processus prend 30 min ! Imagine sur un RPI première génération ! Surtout que ça bloque le fonctionnement de Gladys car toute l’interface repose sur ces deux fichiers de production !

Donc bon tout bloquer pendant 30 min juste parce qu’un module a besoin d’afficher une petite box c’est un peu abusé…

Mais on y réfléchis ^^
Et merci à toi de ton retour ça fait plaisir :slight_smile:


[RESOLU] Création module - Créer box à l'install
#4

Dac donc le soucis est in problême de perf je comprend mieux :slight_smile:
Dans mon cas je faisait une box avec un select pour changer le mode du thermostat si on voulait l’actionner manuellement.
Car si je ne me trompe pas pour l’instant un devicetype ne peut pas être sous la forme d’un select avec plusieurs option.
Donc en attendant une solution il faut que je demande à linstall que l’utilisateur créé une box manuellement c’est bien ça ?


#5

Pourquoi ne pas justement essayer de développer ça dans le core de Gladys ? :slight_smile: C’est autant open-source que les modules !

Quel est ton use case précis ?

J’aimerais éviter qu’on demande à l’utilisateur de faire des manips qui casse toute son installation à chaque mise à jour… ^^


#6

j’ai une petit question quand tu parle de Nom_de_votre_box dans Le controller Angular, on le récupère ou ce nom ?


#7

C’est toi qui défini le nom de ta box quand tu la crée ^^
Si tu veux qu’elle s’appelle “blabla” ça donnera “blablaBoxCtrl” (pour le nom de ton controller) :slight_smile:


#8

Salut @pierre-gilles!
Je sais bien que gladys est open source :slight_smile:.
Je vais regarder ça des que je trouverais un peut de temps :slight_smile:.

Mise à part que les box sois plus propre je trouve ça dommage que l’on empute certain module de cette creation de box comparé à avant.
Celon moi l’utilisateur finale ne devrais pas à avoir besoin de créer des box mais simplement sélectionné celle dont il a besoin.
Une espèce de store de box :slight_smile:.
Un peut comme fait Samsung pour les volets latéraux téléchargeable :


#9

Hello,
Je me tente à l’aventure, pour creuser un peu le code Gladys. Je pars donc sur l’idée d’une box Monitoring pour superviser mon RPI (température CPU et GPU, %File System occupé…) qui devrait être un bon exercice.
Je rencontre un problème de base, après avoir forké le git et suivi le tuto. Mon .eps ne trouve pas mon contrôleur: “Argument ‘MonitoringBoxCtrl’ is not a function, got undefined”
J’imagine qu’il s’agit d’un problème stupide, mais je ne vois pas ce qui cloche…
Could you help me? ;D
Merci par avance.

controller:
(function () {
‘use strict’;
angular
.module(‘gladys’)
.controller(‘MonitoringBoxCtrl’, MonitoringBoxCtrl);
//Gardez bien le “BoxCtrl” !
MonitoringBoxCtrl.$inject = [];
function MonitoringBoxCtrl() {
var vm = this;
vm.informations = “”;
activate();
function activate(){
vm.informations = “test affichage”;
}
}
})();

et mon ejs:

div class=“info-box” data-ng-controller=“MonitoringBoxCtrl as vm”>

div class=“info-box-content”>
{{ vm.informations }}
/div>


#10

Bonjour

Comment as-tu lancé Gladys ? Tu utilise un IDE ?


#11

J’utilise visual studio code et lancé par npm start sur Terminal Mac (testé sur http://localhost:1337/dashboard)


#12

Pourquoi tu n’utilise pas le terminal intégré à VSCode ? ^^
Tu as bien mis ton controller dans le dossier assets/js/app ? Si oui, lance Gladys en mode développement avec la commande sails lift et ça devrais fonctionner :slight_smile:


#13

L’habitude du terminal :smiley:
controller dans assets/js/app/monitoring
j’essaie avec sails lift

J’ai un problème de connection refused avec un acess denied pour root sur la base mysql… je cherche…


#14

j’ai réussi a créer une box :slight_smile: merci pour le tuto, la j’aimerait insérer une valeur d’un device, me je ne vois pas comment faire …


#15

Après avoir tout repris à zéro, et créé les variables d’environnement qui me manquaient, tout est ok. Par contre, j’ai du créer mon nouveau boxtype directement dans la base mysql (??) Je pensais que la mise à jour du fichier config/boxtypes.js suffisait à la mise à jour de la base de données, mais à priori non (peut-être juste en dev?)
Merci en tout cas


#16

C’est work in progress, c’est juste que ce n’est pas encore possible, mais ça va l’être. En attendant je pense que 99% des cas peuvent être géré via des boxs natives :slight_smile:

C’est déjà le cas non ? ^^ Tu sélectionne les boxs dont tu as besoin dans la vue paramètre, et c’est tout. Ce tutoriel s’adresse aux développeurs Gladys !

Avec “sails lift” le .env n’est pas pris en compte. Lance npm start et ça lance en mode développement + avec le .env pris en compte.

Alors tu peux faire un controller qui appelle un service angular qui fait appel à la route :

GET /devicetype/:id

Pour récupérer le deviceType en question avec sa dernière valeur :slight_smile:

Ensuite tu injecte la valeur dans la vue.

Je ne sais pas si tu as de l’expérience avec angular ou pas donc n’hésite pas si tu veux plus de détails…

Il faut aller dans les paramètres de Gladys et faire “mise à jour les données Gladys” pour que ce fichier soit reloadé ! :slight_smile:


#17

@LepetitGeek => Tiens d’ailleurs elle est géniale ta box device =>

https://jsfiddle.net/LePetitGeek/803e2ud3/

Il y aurait moyen que tu l’as propose en PR ? J’adore !

Je vois bien une petite selectbox pour sélectionner le deviceType (comme la box music/mode)

Pour l’icone fontawesome d’affichée, faudrait juste faire un petit switch en fonction du “type” du deviceType, genre par exemple pour le “binary” une icone genre “power on” ( https://fontawesome.com/icons/toggle-on?style=solid ) et si c’est binary off => https://fontawesome.com/icons/toggle-off?style=solid

Pour le type “temperature”, l’icone que t’as mise, etc…

De mon côté je bosse sur cette petite box bien sympa =>


#18

C’est rajouté dans le tuto pour éviter les faux problèmes ^^

Bien entendu ! Tout est possible !
Pas mal l’idée de l’icone qui s’adapte :thinking:
Je suis sur l’app en ce moment et je suis un peu en mode hors ligne depuis quelques jours mais je vais remettre au boulot ! Attention à l’avalanche de PR que j’ai en tête XD

J’adore !!! Comment tu gère la sélection des devicetypes affichés ? Et le toogle dans l’header gère aussi les slider ?


#19

Nice !! J’ai hâte de voir ça :slight_smile:

Ah bien :slight_smile: Hésite pas à poster ce que tu fais/tes idées pour qu’on en parle avant ! C’est toujours sympa d’échanger sur les différents projets en cours :slight_smile:

Pas encore bossé sur cette partie, à mon avis :

  • L’utilisateur choisit le titre de la box
  • L’utilisateur choisit les deviceTypes dans la box. Full personnalisable !

#20

Effectivement, je ne lavais pas vu comme ça :smiley:.
Merci des réponses !