Custom Widget Code - Widget global

Bonjour à tous,

Préambule :

Matériel : diy
Version Jeedom : 4.4.19
Version OS : debian 11.9

Je cherche à créer un widget qui me centralise plusieurs actions et informations.

Plugin utilisé : Virtuel
J’ai des commandes actions et informations qui fonctionnent correctement.
Je les masque toutes et je crée une autre commande de type information.
Sur cette commande, j’ajoute plusieurs paramètres optionnels où je renseigne l’ID des différentes commandes en question :


Ensuite, dans le code de mon widget, je les récupère de manière classique dans le bloc script pour les utiliser, pas de soucis (certains sont commentés volontairement) :

<script>
  // Récupération des IDs des commandes depuis les options du widget
  var temperatureCmdId = '#temperatureCmd#';
  var consigneCmdId = '#consigneCmd#';
  var sliderConsigneCmdId = '#sliderConsigneCmd#';
  var consigneEcoCmdId = '#consigneEcoCmd#';
  var sliderConsigneEcoCmdId = '#sliderConsigneEcoCmd#';
  var etatCmdId = '#etatCmd#';
  var modeCmdId = '#modeCmd#';
  //var modeOffCmdId = '#modeOffCmd#';
  //var modeChauffageCmdId = '#modeChauffageCmd#';
  //var modeChauffageEcoCmdId = '#modeChauffageEcoCmd#';
  var verrouillageCmdId = '#verrouillageCmd#';
  //var VerrouillerCmdId = '#VerrouillerCmd#';
  //var DeverrouillerCmdId = '#DeverrouillerCmd#';
  var puissanceCmdId = '#puissanceCmd#';
  var consommationCmdId = '#consommationCmd#';

Mais ensuite, je n’arrive pas à correctement les cumulés dans mon widget :

Pour une information :
il me faut 2 éléments dans le script :
jeedom.cmd.addUpdateFunction('#id#', function(_options) {
La doc dit :

La fonction est appelée lors d’une mise à jour du widget. Elle met alors à jour le code html du widget_template.

Je comprends que cette fonction est appelé par le core lorsqu’il y a changement, sur la page ou par un autre moyen (scénario, appuis manuel) qui déclenche un changement de l’information associé et cela permet la mise à jour du widget, est-ce bien cela ?

jeedom.cmd.refreshValue([{
La doc dit :

L’appel à cette fonction pour l’initialisation du widget.

Je comprends que c’est cette fonction qui est appelé lors du chargement de la page et donc récupère la première valeur de l’information, est-ce bien cela ?

Source : https://doc.jeedom.com/fr_FR/core/4.4/widgets

Pour une action :
D’après le code des widgets core, il me suffit d’avoir la fonction suivante pour réaliser l’action :
jeedom.cmd.execute({ id: '#id#' })
Est-ce exact ?

A tout réécrire dans mon message, cela me parait simple de compiler plusieurs commandes, je ne comprends pas pourquoi je ne m’en sors pas. Je m’en vais repousser mes tests pour voir ce qui cloche et vous collerai une version de mon widget pour avis

Bonne journée,

Hello
Je reviens avec le complément d’information et mes tests :

  • J’ai créé un virtuel qui ressemble à cela :
    image
    Et configuré ainsi :

    Tous les widgets associés sont les widgets core standard

Ensuite, je créé un second virtuel dans un autre objet :


Et je lui affecte mon custom widget code

<div class="cmd cmd-widget #history# widget-temperature" data-cmd_id="#id#" data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#">
	<div class="info-block temperature">
		<span class="label">Température</span>
		<span class="value"></span>
	</div>

	<div class="info-block consigne-slider" style="display: block;">
    	<div class="label">Consigne</div>
    	<div class="input-group buttons">
			<span class="input-group-btn">
        		<a class="btn btn-default btn-sm bt_minus roundedLeft"><i class="fas fa-minus"></i></a>
			</span>
			<input type="text" class="input-sm in_value">
			<span class="input-group-btn">
				<a class="btn btn-default btn-sm bt_plus roundedRight"><i class="fas fa-plus"></i></a>
			</span>
		</div>
		<input type="range" class="slider" min="10" max="30" step="0.5" style="display: none;">
	</div>

	<div class="info-block consigne-eco-slider" style="display: block;">
		<div class="label">Consigne Éco</div>
		<div class="slider-container">
			<button class="btn-minus">-</button>
			<div class="value"></div>
			<button class="btn-plus">+</button>
		</div>
		<input type="range" class="slider" min="10" max="30" step="0.5" style="display: none;">
	</div>

	<div class="info-block etat">
		<div class="label">État</div>
		<div class="value"></div>
	</div>

	<div class="info-block mode">
		<div class="label">Mode</div>
		<div class="value"></div>
	</div>

	<div class="info-block verrouillage">
		<div class="label">Verrouillage</div>
		<div class="value"></div>
	</div>

	<div class="info-block puissance">
		<div class="label">Puissance</div>
		<div class="value"></div>
	</div>

	<div class="info-block consommation">
		<div class="label">Consommation</div>
		<div class="value"></div>
	</div>

	<div class="parametres">
		<div class="parametres-icon">
			<i class="fa fa-cog"></i>
		</div>
		<div class="parametres-menu">
			<button class="mode-button" data-mode="off"><i class="fa fa-power-off"></i></button>
			<button class="mode-button" data-mode="chauffage"><i class="fa fa-fire"></i></button>
			<button class="mode-button" data-mode="chauffage-eco"><i class="fa fa-leaf"></i></button>
		</div>
	</div>
</div>

<style>
.widget-temperature {
  font-family: Arial, sans-serif;
  padding: 20px;
}

.info-block {
  margin-bottom: 10px;
}

.label {
  font-weight: bold;
}

.parametres {
  position: absolute;
  top: 10px;
  right: 10px;
  cursor: pointer;
}

.parametres-menu {
  display: none;
  position: absolute;
  top: 30px;
  right: 0;
  background-color: #fff;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.parametres-menu button {
  background: none;
  border: none;
  display: block;
  width: 100%;
  text-align: left;
  padding: 5px 10px;
  cursor: pointer;
}

.mode-button.active {
  color: #fff;
}

.mode-button[data-mode="off"].active {
  background-color: #0000ff; /* Bleu pour le mode off */
}

.mode-button[data-mode="chauffage"].active {
  background-color: #ff0000; /* Rouge pour le mode chauffage */
}

.mode-button[data-mode="chauffage-eco"].active {
  background-color: #00ff00; /* Vert pour le mode chauffage éco */
}
</style>

<script>
	// Récupération des IDs des commandes depuis les options du widget
	var Temperature = '#TemperatureCmdId#';
	var Consigne = '#ConsigneCmdId#';
		var SliderConsigne = '#SliderConsigneCmdId#';
	var ConsigneEco = '#ConsigneEcoCmdId#';
		var SliderConsigneEco = '#SliderConsigneEcoCmdId#';
	//var Etat = '#EtatCmdId#';
	var Puissance = '#PuissanceCmdId#';
	var Consommation = '#ConsommationCmdId#';
	var Mode = '#ModeCmdId#';
		var ModeOff = '#ModeOffCmdId#';
		var ModeChauffage = '#ModeChauffageCmdId#';
		var ModeChauffageEco = '#ModeChauffageEcoCmdId#';
	var Verrouillage = '#VerrouillageCmdId#';
		var Verrouiller = '#VerrouillerCmdId#';
		var Deverrouiller = '#DeverrouillerCmdId#';


	// Sélection des éléments pour chaque info/action
	if (is_object(cmd = document.querySelector('.cmd[data-cmd_uid="#uid#"]'))) {
		var TemperatureElement = cmd.querySelector('.temperature .value');
		var ConsigneElement = cmd.querySelector('.consigne-slider .value');
			var ConsigneSlider = cmd.querySelector('.consigne-slider .slider');
		var ConsigneEcoElement = cmd.querySelector('.consigne-eco-slider .value');
			var ConsigneEcoSlider = cmd.querySelector('.consigne-eco-slider .slider');
		//var EtatElement = cmd.querySelector('.etat .value');
		var PuissanceElement = cmd.querySelector('.puissance .value');
		var ConsommationElement = cmd.querySelector('.consommation .value');
		var ModeElement = cmd.querySelector('.mode .value');
		var VerrouillageElement = cmd.querySelector('.verrouillage .value');
	}

	jeedom.cmd.addUpdateFunction(Temperature,function(_options) {
		TemperatureElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	jeedom.cmd.addUpdateFunction(Consigne,function(_options) {
		ConsigneElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	jeedom.cmd.addUpdateFunction(ConsigneEco,function(_options) {
		ConsigneEcoElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	/*jeedom.cmd.addUpdateFunction(Etat,function(_options) {
		EtatElement.empty().append(_options.display_value + ' ' + _options.unit);
	});*/
	jeedom.cmd.addUpdateFunction(Puissance,function(_options) {
		PuissanceElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	jeedom.cmd.addUpdateFunction(Consommation,function(_options) {
		ConsommationElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	jeedom.cmd.addUpdateFunction(Mode,function(_options) {
		ModeElement.empty().append(_options.display_value + ' ' + _options.unit);
	});
	jeedom.cmd.addUpdateFunction(Verrouillage,function(_options) {
		VerrouillageElement.empty().append(_options.display_value + ' ' + _options.unit);
	});

// Rafraîchir les valeurs initiales
	jeedom.cmd.refreshValue([{cmd_id: Temperature, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: Consigne, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: ConsigneEco, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	//jeedom.cmd.refreshValue([{cmd_id: Etat, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: Puissance, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: Consommation, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: Mode, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);
	jeedom.cmd.refreshValue([{cmd_id: Verrouillage, value: '#value#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#', unit: '#unite#'}]);

</script>

J’obtiens le visuel suivant :
image
Avec le message suivant dans la console du navigateur :

J’ai donc la Consigne qui ne se charge pas et je pense bloque les éléments suivants. Et la température qui est le premier élément n’est pas correcte : affiche ici 0 au lieu de 17.8

Je n’arrive pas à trouver mes erreurs et fais donc appel à votre aide,
Merci

Bonsoir,

C’est pas possible de faire comme ceci, tous les tag (#value#, #state# …), le core les remplaces par les infos de la commande en cours, donc la commande Thermostat.

Il faut faire une requête sur l’id (jeedom.cmd.execute) pour pouvoir récupérer la valeur de chaque commande que tu veux afficher.
Même avec cette méthode, tu sera obliger d’initier en dur dans le code, l’unité, et tu ne pourra pas avoir le valueDate, collectDate… ni même la conversion des unités.

Merci pour ton retour Phpvarious,

Je comprends ton point 1, c’est logique.
Pour le point 2 : je croyais que la commande jeedom.cmd.execute était pour des actions ? Comment la rédiger pour récupérer les informations aux chargements et au refresh alors ?

Je n’ai peut être pas bien compris l’utilisation des 3 fonctions (refresh / execute / addupdatefuncton).

Si celle-ci est faite sur un id de type info, elle renverra la valeur de la commande.

exemple pour Temperature et Consigne :

    if (is_object(cmd = document.querySelector('.cmd[data-cmd_uid="#uid#"]'))) {
      
      // Température
      if (is_numeric('#TemperatureCmdId#')) { // verifie si bien un id numérique
        jeedom.cmd.execute({ // recupère la valeur de la commande
          id: '#TemperatureCmdId#', // id de la commande
          success:  function(value) { // valeur de la commande
            // fonction appelé par le core lors d'un event de la commande.
            jeedom.cmd.addUpdateFunction('#TemperatureCmdId#',function(_options) {
              if (is_object(TemperatureElement = document.querySelector('.cmd[data-cmd_uid="#uid#"] .temperature .value'))) { // vérifie si le DOM existe pour eviter les erreurs de TypeError
		        TemperatureElement.innerHTML = _options.value + ' ' + _options.unit; // inject de la valeur + unit dans le DOM
              }
	        });
            
            // force l'appel de la fonction addUpdateFunction ci-dessus a l'initialisation.
            jeedom.cmd.refreshValue([{cmd_id: '#TemperatureCmdId#', value: value, unit: '°C'}]);
          }
        })
      }
      
      // Consigne
      if (is_numeric('#ConsigneCmdId#')) { // verifie si bien un id numérique
        jeedom.cmd.execute({ // recupère la valeur de la commande
          id: '#ConsigneCmdId#', // id de la commande
          success:  function(value) { // valeur de la commande
            // fonction appelé par le core lors d'un event de la commande.
            jeedom.cmd.addUpdateFunction('#ConsigneCmdId#',function(_options) {
              if (is_object(ConsigneElement = document.querySelector('.cmd[data-cmd_uid="#uid#"] .consigne-slider .value'))) { // vérifie si le DOM existe pour eviter les erreurs de TypeError
		        ConsigneElement.innerHTML = _options.value + ' ' + _options.unit; // inject de la valeur + unit dans le DOM
              }
	        });
            
            // force l'appel de la fonction addUpdateFunction ci-dessus a l'initialisation.
            jeedom.cmd.refreshValue([{cmd_id: '#ConsigneCmdId#', value: value, unit: '°C'}]);
          }
        })
      }
      
      // ....
    }
1 « J'aime »

Oh merci pour ton retour rapide, je m’en vais de ce pas tester tout cela :slight_smile: