[how to] création d'un plugin

Déjà, faudra modifier ta structure dans le gît. Jeedom et le market vont pas aimer, défaut être a la racine (on doit trouver le répertoire core direct)

Ta fonction de création est assez dépouiller en protection, j’ai pas vu ou tu l’appelle et donc si c’est fait en amont mais a mettre de base :

  • faire un eqlogic::bylogicalid et tester si il existe déjà, faire la création que dans la négative (sinon erreur)
  • tester ton logicalid non vide par précaution pareil

Car sinon t’as ce qu’il faut

1 « J'aime »

J’en suis pas encore à publier sur le market mais merci pour l’info :wink: je pensais mettre un rep de test (unitaire) et je ne voulais pas le mettre direct dans le rép du plugin c’est pour ça que j’ai fait un sous-répertoire. Sinon, tout le monde qui installe le plugin aura aussi les tests, ça n’est pas très intéressant…

j’ai pas encore toutes les protections mais j’y travaille. En attendant, j’ai trouvé l’erreur c’est quand je tente d’ajouter un log avec comme message « insert $this » l’objet $this ne doit pas être évalué correctement…
La méthode log::add plante silencieusement ( à cause du @ devant l’instruction) donc je ne voyais rien :’(

Pour les fichiers à la root tu n’as pas le choix.
J’avais déjà fait un pr il y a plusieurs jours pour cela.

Le $this représente l’instance actuelle, dans une méthode static il n’y en a pas puisque c’est une méthode de class.

oui pour le $this je le savais bien, mais comme j’appelais le log depuis ma méthode d’instance $eqLogic j’espérais afficher mon objet en cours de création…

Autre question, je remarque dans les plugins existants ( je m’inspire du plugin zwave ) que après le save() on fait toujours un getById pour « retrouver » l’objet enregistré:

$eqLogic->save();
$eqLogic = lgthinq::byId($eqLogic->getId());

il y a une raison pour ça ? en théorie l’objet est juste enregistré en DB mais on ne devrais pas avoir besoin de le recharger…

Autre question, il n’y a aucune notion de namespace dans jeedom :frowning: c’est possible / acceptable / souhaitable que je mette mon plugin dans un namespace spécifique ?

Je n’ai pas compris encore si les classes sont incluses par la convention de nommage imposée, ou par le système d’auto-load… ( ou les 2 ? )

Tu peux avoir des namespaces pour tes classes mais c’est à toi de gérer le load.
Sur certain plug-in j’ai découpé la partie api du reste et je load via composer et autoload des librairies (à moi ou d’autres genre guzzlehttp).

Mais les class jeedom eqlogic et cmd jeedom ne doivent pas se trouver dans un namespace sinon elles ne seront pas trouvées par le core; il faut suivre la convention pour celles-là.

C’est intéressant ce que tu me dis, est-ce que composer gère les lib autre que PHP ? j’ai une lib python dans 3rparty, pour l’instant je l’ai mise copié / collé dans mon repo.

Pas que je sache.
Et les lib Php chargée avec composer doivent être fournie avec le plug-in, le core ne gère pas les dépendances via composer (ou alors le plug-in doit l’installer).
Loic travaille sur un nouveau système de dépendances pour la 4.1; on verra avec ça.
Sinon tu peux aussi faire un gît clone et déplacer les fichiers au bon endroit dans l’install des dépendances.

git clone ==> présuppose que toutes les box jeedom sont installées avec les commandes git par défaut, est-ce vraiment le cas ?

Pour le namespace je laisse tomber, c’est pas très cohérent d’avoir certaines classes avec un namespace et d’autres sans dans un même répertoire.

Comment le plugin peut-il installer ses dépendances automatiquement ? J’en ai besoin car le plugin doit installer python et flask ( pip install flask en ligne de commande ) … et du coup je mettrais ma lib 3rparty aussi en dépendance git clone :slight_smile:

Salut,

Prend exemple sur le plugin networks qui installe des dépendances comme arping par example:

Bonjour,
Dans le cadre du développement d’un plugin, j’ai la même interrogation.
J’ai créé un fichier install_apt.sh dans le répertoire « resources » sur le modèle ci-dessus, avec les bons droits.
Dans l’interface de configuration du plugin, le clic sur le bouton « relancer » ne produit aucune action alors que le script se lance bien à la main.
Qu’est ce que j’ai raté ?

Il faut écrire les méthodes suivantes dans ta class eqLogic:

celle-ci devrait être ok telle quel:

	public static function dependancy_install() {
		log::remove(__CLASS__.'_update');
		return array('script' => dirname(__FILE__) . '/../../resources/install_#stype#.sh ' . jeedom::getTmpFolder(__CLASS__) . '/dependency', 'log' => log::getPathToLog(__CLASS__.'_update'));
	}

dans la suivante, tu dois adapter le if sur les modules pour tester tout ce que tu installes:

	public static function dependancy_info() {
		$return = array();
		$return['log'] = log::getPathToLog(__CLASS__.'_update');
		$return['progress_file'] = jeedom::getTmpFolder(__CLASS__) . '/dependency';
		if (file_exists(jeedom::getTmpFolder(__CLASS__) . '/dependency')) {
			$return['state'] = 'in_progress';
		} else {
			if (exec(system::getCmdSudo() . system::get('cmd_check') . '-Ec "python3\-requests"') < 1) {
				$return['state'] = 'nok';
			} else {
				$return['state'] = 'ok';
			}
		}
		return $return;
	}

exemple (attention, bien penser à adapter le nombre de ligne devant être retournée (< xxx):

            if (exec(system::getCmdSudo() . system::get('cmd_check') . '-Ec "python3\-requests|python3\-setuptools"') < 2) {
                $return['state'] = 'nok';
            } elseif (exec(system::getCmdSudo() . 'pip3 list | grep -Ec "monotonic|sseclient|requests"') < 3) {
                $return['state'] = 'nok';
            } else {
                $return['state'] = 'ok';
            }
1 « J'aime »

OK merci de ton retour

toujours pas de news pour moi ? le confinement est terminé :slight_smile:

Sinon autre question, comment se passe la mise à jour d’un plugin? J’ai eu la surprise que jeedom proposait un maj sur mon plugin - qui n’est pas encore sur le market, je ne l’installe que via github pour le moment -

Et comment ça marche les n° de version des plugins? il n’y a aucune notion de la version du plugin dans le fichier json.info, ni nulle part en fait. Pour mon plugin, jeedom compare les « sha » long des commit, pour les plugins du market c’est seulement les dates (date de quoi d’ailleurs?)

Pour les mises à jours, chaque jeedom à un cron, à des heures différents et il va vérifier sur la source.

Pour les versions, chaque commit dans les branches configurées pour la version stable et bêta fera que le market créera un nouveau zip, ce n’est pas immédiat, il faut le temps qu’il passe.

Bonjour,
Me revoila, encore avec des questions sur le développement d’un plugin :slight_smile:
Aujourd’hui j’essaye de faire un simple appel ajax à mon plugin, mais je ne suis pas dans la page de configuration - ou ça marchait pourtait si bien - et j’ai toujours la même erreur en réponse à mon appel ajax: error : Token d'accès invalide
Je fais le même genre d’appel ajax dans la page de configuration et ça marche bien, je ne vois pas la différence!?

$.ajax({
	type: 'POST',
	url: 'plugins/lgthinq/core/ajax/lgthinq.ajax.php?action=synchro',
	data: $('#LgSynchronize').serialize(),
	dataType: 'json',
	global: false,
	error: function (request, status, error) { ... },
	success: function (data, textStatus) { ... }
});

vu l’erreur, je pensais à la clé API de jeedom, mais je ne l’utilise pas dans la page configuration non plus, doit-on l’ajouter dans un appel ajax ?

Salut,

Déjà, ne fait pas un POST en passant des paramètres en querystring, passe l’action dans le data.

$.ajax({
	type: 'POST',
	url: 'plugins/lgthinq/core/ajax/lgthinq.ajax.php',
	data: {
            action: "synchro",
        },
	dataType: 'json',
	global: false,
	error: function (request, status, error) { ... },
	success: function (data, textStatus) { ... }
});

Et sinon faudra savoir ce qu’il y a dans $('#LgSynchronize').serialize(), il doit y avoir quelque chose qui casse l’appel non?

Et pour le token invalide, es-tu certain d’être bien connecté et que ta session est toujours valide?

serialize, c’est une fonction jquery pour envoyer tous les paramètres du formulaire dans l’appel ajax ( .serialize() | jQuery API Documentation) je suis pas trop inquiet la dessus :slight_smile:
mettre les paramètres en GET dans la query String ou bien en POST dans le data, c’est un peu pareil puisque côté jeedom la fonction init() ramasse tous les éléments (dans l’ordre GET puis POST puis REQUEST ) https://github.com/jeedom/core/blob/b198e1a8dfe5cd4b0ab728c5398e9d368de65c56/core/php/utils.inc.php#L109

Au final, j’ai trouvé, j’ai oublié de dire que je développe sur jeedom V3 et c’est la fonction ajax::init de la v3 qui lance cette erreur (cf ici sur github master) donc pour v3 il faut relancer le token avec une syntaxe dans ce style dans l’appel JS ajax:
url: 'plugins/lgthinq/core/ajax/lgthinq.ajax.php?action=synchro&jeedom_token=<?php ajax::getToken(); ?>',
sinon, virer le ajax:init dans mon fichier du plugin ajax semble être la meilleure solution…

J’ai pas regardé en détails mais pour moi y a autre chose à creuser: je n’ai jamais codé différemment les appels (ni réception) Ajax en v3 ou en v4 et jamais eu de soucis…

1 « J'aime »