Shelly - Ajout, retrait ou modification en masse du login/password du broker

/*************************************************************************
** Ajout, retrait ou modification en masse du login/password dans       **
** la configuration des Shellies pour pouvoir accéder au broker.        **
**                                                                      **
** Prérequis :                                                          **
** - Equipements gérés par le plugin jMQTT                              **
** - Pour chaque équipement, une commande info contenant son adresse IP **
**                                                                      **
** Adresse IP Gen1 - topic/du/shelly/announce - [ip]                    **
** Adresse IP Gen2 - topic/du/shelly/events/rpc - [*][wifi][sta_ip]     **
*************************************************************************/

if (!function_exists('str_contains')) { // à partir de php 8
  function str_contains($haystack, $needle) {
    return $needle !== '' && mb_strpos($haystack, $needle) !== false;
  }
}

function f_curl($_url, $_username, $_password, $_scenario, $_i) {
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL,				$_url);
  curl_setopt($curl, CURLOPT_USERNAME,			$_username);
  curl_setopt($curl, CURLOPT_PASSWORD,			$_password);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER,	true);
  curl_setopt($curl, CURLOPT_TIMEOUT,			15);
  curl_setopt($curl, CURLOPT_CONNECTTIMEOUT,	15);
  curl_setopt($curl, CURLOPT_HTTPAUTH,			CURLAUTH_ANY);

  $retour = array(curl_exec($curl), curl_getinfo($curl, CURLINFO_HTTP_CODE));
  curl_close($curl);
  $_scenario->setLog($_i . ' ==> URL : ' . $_url);
  $_scenario->setLog($_i . ' ==> HTTP Code : ' . $retour[1]);
  $_scenario->setLog($_i . ' ==> Retour : ' . $retour[0]);
  return $retour;
}

$web_user_gen1 = 'user'; // laisser '' si pas de password
$web_pass_gen1 = 'pass'; // laisser '' si pas de password
$web_user_gen2 = 'admin'; // laisser '' si pas de password
$web_pass_gen2 = $web_pass_gen1;
$mqtt_user = 'jeedom'; // laisser '' pour enlever le password
$mqtt_pass = 'toto'; // laisser '' pour enlever le password
$url1_gen1 = 'http://';
$url2_gen1 = '/settings?mqtt_user=' . $mqtt_user . '&mqtt_pass=' . $mqtt_pass;
$url1_gen2 = $url1_gen1;
$url2_gen2 = '/rpc/MQTT.SetConfig?config={"user":"' . $mqtt_user . '","pass":"' . $mqtt_pass . '"}';
$cmdIP = '[IP]'; // #[objet][équipement] . $cmdIP . #

$eqLogicJMQTTs = eqLogic::byType('jMQTT');
$i = 0;
foreach ($eqLogicJMQTTs as $eqLogicJMQTT) {
  $cmdJMQTTs = $eqLogicJMQTT->getCmd();
  foreach ($cmdJMQTTs as $cmdJMQTT) {
    if (!str_contains($cmdJMQTT->getHumanName(), $cmdIP)) {
      continue;
    }
    $ip = $cmdJMQTT->execCmd();
    $scenario->setLog(++$i . ' ==> ' . $ip . ' ==> ' . $cmdJMQTT->getHumanName() . ' <==================================');

    //password gen1
    $url = $url1_gen1 . $ip . $url2_gen1;
    $initMQTTpass = f_curl($url, $web_user_gen1, $web_pass_gen1, $scenario, $i);
    
    if ($initMQTTpass[1] === 200) {
      //reboot gen1
      $url = $url1_gen1 . $ip . '/reboot';
      f_curl($url, $web_user_gen1, $web_pass_gen1, $scenario, $i);
    } else {
      //password gen2
      $url = $url1_gen2 . $ip . $url2_gen2;
      $initMQTTpass = f_curl($url, $web_user_gen2, $web_pass_gen2, $scenario, $i);
      $reboot = json_decode($initMQTTpass[0], true)['restart_required'];
      $scenario->setLog($i . ' ==> Reboot : ' . $reboot);
      if ($reboot) {
        //reboot gen2
        $url = $url1_gen2 . $ip . '/rpc/Shelly.Reboot';
        f_curl($url, $web_user_gen2, $web_pass_gen2, $scenario, $i);
      }
    }
  }
}