[Tuto Shelly jMQTT] Automatisation de la MAJ du firmware des Shellies GEN1 avec jMQTT

Pour ceux qui ne connaissent pas bien les Shellies ou le plugin-jmqtt ou les deux, il est conseillé de commencer par le tuto de @bronche :

Avec les mises à jour du firmware des Shellies qui sont assez fréquentes en ce moment, il devient vite fastidieux de faire cette mise à jour via leur interface web.

Ce tuto permet donc d’automatiser ces mises à jour et par la même occasion de monitorer la mise à disposition d’un nouveau firmware.

Ceci sera réalisé à l’aide du plugin-jmqtt de @domotruc.

Le résultat permettra d’obtenir une commande action « MAJ Firmware » pour effectuer la mise à jour du firmware de chaque Shelly.

L’automatisation pourrait être poussée à l’extrême via un scénario, elle ne sera pas proposée dans ce tutoriel. Personnellement, je préfère choisir si je dois ou pas faire la mise à jour et le moment pour le faire.

La commande action « Annonce » permet d’envoyer une demande au Shelly qui va répondre en donnant son ID, sa MAC, son IP, sa version du firmware et si une mise à jour est disponible.

La difficulté, c’est que cette réponse est envoyée sur un topic unique, quel que soit le Shelly qui répond.

Il faut donc créer un équipement jMQTT avec une commande info de ce type :

Je l’ai nommé : #[Shellies Administration][Shellies Annonces][Annonce]#

Sur le même équipement, une commande action générale « CMD Annonce » permet d’interroger tous les Shellies du réseau en même temps :

Maintenant, sur chaque équipement Shelly existant, il va falloir ajouter 2 commandes Action (Annonce et MAJ Firmware) et 5 commandes Info (ID, MAC, IP, Firmware et MAJ Dispo).

Lors de la création des commandes Info, un message d’alerte apparaît :

05%20tuto%20firmware%20shelly

C’est normal puisqu’aucun Topic n’est renseigné. La mise à jour des valeurs se fera par un scénario.

Afin de pouvoir relier, le retour des annonces au bon équipement, dans chaque équipement Shelly, dans Configuration de l’équipement, onglet Commentaire (comment), on indique l’adresse MAC du Shelly.

Enfin, le scénario qui va gérer l’affichage des widgets de nos Shellies et avertir d’un nouveau firmware dans le Centre de message. Il est à noter que les commandes Action « CMD Annonce » et « Annonce » n’ont pas besoin d’être lancées pour connaître la mise à disposition d’un nouveau firmware, chaque Shelly s’en charge automatiquement en temps réel.

C’est un scénario avec les options Multi-lancement, Synchrone et provoqué, et comme déclencheur #[Shellies Administration][Shellies Annonces][Annonce]#.

Le scénario ne contient qu’un bloc code :

$trigger = cmd::cmdToHumanReadable($scenario->getRealTrigger());
$scenario->setLog('Trigger : ' . $trigger);
$cmd = cmd::byString($trigger);
$value = $cmd->execCmd();
$scenario->setLog('Valeur : ' . $value);
$jsonShelly = json_decode($value,true);
$id = $jsonShelly[id];
$scenario->setLog('ID : ' . $id);
$mac = $jsonShelly[mac];
$scenario->setLog('MAC : ' . $mac);
$ip = $jsonShelly[ip];
$scenario->setLog('IP : ' . $ip);
$fw_ver = $jsonShelly[fw_ver];
$fw_ver = substr($fw_ver,0,strpos($fw_ver,'-')) . substr($fw_ver,strpos($fw_ver,'/'),strpos($fw_ver,'@')-strpos($fw_ver,'/'));
$scenario->setLog('FW_VER : ' . $fw_ver);
$new_fw = $jsonShelly[new_fw];
$source = 'Scénario ' . $scenario->getHumanName() . ' ' . $id;
if ($new_fw) {
  $new_fw_txt = 'Oui';
  // Ajout d'un message dans le Centre de Message
  message::add($source,$fw_ver,'Nouveau firmware disponible - Mettre à jour le firmware');
} else {
  $new_fw_txt = 'Non';
  // Retrait d'un message dans le Centre de Message
  message::removeAll($source);
}
$scenario->setLog('NEW_FW : ' . $new_fw_txt);
$shellies = eqLogic::byType('jMQTT');
foreach ($shellies as $shelly) {
  $eqLogicMac = $shelly->getComment();
  if ($mac === $eqLogicMac) {
    $scenario->setLog('Adresse MAC : ' . $eqLogicMac);
    $eqLogicName = $shelly->getHumanName();
    $scenario->setLog('Nom : ' . $eqLogicName);
    cmd::byString('#' . $eqLogicName . '[ID]#')->event($id);
    cmd::byString('#' . $eqLogicName . '[MAC]#')->event($mac);
    cmd::byString('#' . $eqLogicName . '[IP]#')->event($ip);
    cmd::byString('#' . $eqLogicName . '[Firmware]#')->event($fw_ver);
    $cmdMajDispo = cmd::byString('#' . $eqLogicName . '[MAJ Dispo]#');
    $cmdMajDispo->event($new_fw_txt);
    $cmdMajFirmware = cmd::byString('#' . $eqLogicName . '[MAJ Firmware]#');
    if ($new_fw) {
      $scenario->setLog('Visible OUI');
      $cmdMajDispo->setIsVisible(0)->save();
      $cmdMajFirmware->setIsVisible(1)->save();
    } else {
      $scenario->setLog('Visible NON');
      $cmdMajDispo->setIsVisible(1)->save();
      $cmdMajFirmware->setIsVisible(0)->save();
    }
  }
}
5 « J'aime »

Pourquoi faire une mise à jour, si le shelly fonctionne comme il devrait et qu’il n’apporte pas de nouveauté ?

Eric

1 « J'aime »

C’est pour ça que :

1 « J'aime »

Avec un Shelly1PM :

Le script m’a bien remonté une nouvelle mise à jour du firmware en 1.6 pour mes 12 Shellies, le 09/03 entre 12h00 et 13h00.

Depuis le firmware 1.6.0, la commande « announce » remonte sur les topics de chaque Shelly.
Cela simplifie cette procédure de MàJ du firmware.
Il n’est plus nécessaire de relier, le retour des annonces au bon équipement et donc d’indiquer l’adresse MAC du Shelly dans l’onglet « Commentaire ».
Le code est lui aussi simplifié.

$trigger = cmd::cmdToHumanReadable($scenario->getRealTrigger());
$scenario->setLog('Trigger : ' . $trigger);
$cmd = cmd::byString($trigger);
$value = $cmd->execCmd();
$scenario->setLog('Valeur : ' . $value);
$jsonShelly = json_decode($value,true);
$fw_ver = $jsonShelly[fw_ver];
//20200206-083604/v1.5.10@e6a4205e
$fw_ver = substr($fw_ver,0,strpos($fw_ver,'-')) . substr($fw_ver,strpos($fw_ver,'/'),strpos($fw_ver,'@')-strpos($fw_ver,'/'));
$scenario->setLog('FW_VER : ' . $fw_ver);
$new_fw = $jsonShelly[new_fw];
$eqLogicName = $cmd->getEqLogic()->getHumanName();
$scenario->setLog('Equipement logique : ' . $eqLogicName);
$source = 'Scénario ' . $scenario->getHumanName() . ' ' . $eqLogicName;
if ($new_fw) {
  $new_fw_txt = 'Oui';
  // Ajout d'un message dans le Centre de Message
  message::add($source,$fw_ver,'Nouveau firmware disponible - Mettre à jour le firmware');
} else {
  $new_fw_txt = 'Non';
  // Retrait d'un message dans le Centre de Message
  message::removeAll($source);
}
$scenario->setLog('NEW_FW : ' . $new_fw_txt);
cmd::byString('#' . $eqLogicName . '[Firmware]#')->event($fw_ver);
$cmdMajDispo = cmd::byString('#' . $eqLogicName . '[MAJ Dispo]#');
$cmdMajDispo->event($new_fw_txt);
$cmdMajFirmware = cmd::byString('#' . $eqLogicName . '[MAJ Firmware]#');
if ($new_fw) {
  $scenario->setLog('Visible OUI');
  $cmdMajDispo->setIsVisible(0)->save();
  $cmdMajFirmware->setIsVisible(1)->save();
} else {
  $scenario->setLog('Visible NON');
  $cmdMajDispo->setIsVisible(1)->save();
  $cmdMajFirmware->setIsVisible(0)->save();
}

Par contre il faudra un déclencheur pour chaque commande « Annonce ».

Déploiement du firmware 20200320-123430/v1.6.2@514044b4 en cours.

20 messages ont été scindés en un nouveau sujet : Custom prefix mqtt

Déploiement en cours du firmware 20200601-122823/v1.7.0@d7961837 sur les shelly1 et shelly1pm.

Salut Jeandhom

J’essaie de mettre en place ce scénario mais il m’est retourné :

[2020-06-02 23:21:23][SCENARIO] Lancement du scénario en mode synchrone
[2020-06-02 23:21:23][SCENARIO] Start : Scénario lancé manuellement.
[2020-06-02 23:21:23][SCENARIO] Exécution du sous-élément de type [action] : code
[2020-06-02 23:21:23][SCENARIO] Exécution d’un bloc code
[2020-06-02 23:21:23][SCENARIO] Trigger : user
[2020-06-02 23:21:23][SCENARIO] La commande n’a pas pu être trouvée : user => user
[2020-06-02 23:21:23][SCENARIO] Fin correcte du scénario

Je ne vois a quoi c’est du, peux tu m’éclairer ?

Le scénario ne s’exécute pas manuellement mais via un déclencheur qui est la commande info « announce » de chaque shelly.

Tu dois donc avoir autant de déclencheur que de shelly.

C’est bien ce que j’avais compris et paramétré, mais je pensais que le lancement de la commande action annonce manuelle aurait eu le même effet.

Je ne peux donc pas tester manuellement le résultat ?

Cela semble vouloir dire que le scénario a été lancé manuellement.

Oui, cela doit fonctionner comme ça.

Tu as raison je l’ai effectivement lancé manuellement, la commande action announce n’ayant pas d’effet, j’avais fait l’essai. J’ai du louper quelque chose quelquepart…
Une piste de recherche ?

La commande info announce ne doit pas changer lorsque tu lances l’action, donc le scénario ne doit pas se lancer.
Change le paramètre « Gestion de la répétition des valeurs » en toujours répéter pour la commande info.

OK

Cette fois le scénario se lance, bien vu. Mais, erreur SQL, cela me rappelle un échange que tu m’avais fait parvenir sur le sujet de la longueurs des noms de shellies.

2020-06-02 23:47:43][SCENARIO] [MySQL] Error code : 22001 (1406). Data too long for column ‹ logicalId › at row 1 : INSERT INTO message SET id = :id, date = :date, logicalId = :logicalId, plugin = :plugin, message = :message, action = :action, occurrences = :occurrences

Le JSON ne doit pas dépasser 127 caractères du à la régression du passage de stretch à buster.
On a d’ailleurs aucune information sur l’issue de cette régression.

EDIT : En fait, il n’y a pas de régression du au passage à Buster.

Déploiement en cours du firmware 20200812-092009/v1.8.0@8acf41b0.

Hello Jeandhom,

Comment fais tu pour faire apparaitre l’alerte dans le centre de messagerie (en 2 mots) stp ?
Je ne le maitrise pas, ce sera l’occasion de m’y mettre :wink:

Merci.

Avec message::add();

https://doc.jeedom.com/dev/phpdoc/4.0/classes/message.html#method_add