Code avec correction d'une donnée d'un JSON

Bonjour,
Je cherche a récupérer la valeur conso_base pour l’écrire dans un virtuel après.
Mon problème c’est que cette valeur n’a pas un format correcte car le nombre à un zéro devant.
Je souhaite trouvé un code PHP compatible pour le supprimer, mais pour l’instant sans succès.
Est-ce possible via un scénario code ?

Pour commencer, voici ce que j’arrive à lire dans mon scénario (log)

[2023-02-21 00:36:02][SCENARIO] -- Start : Scenario execute automatiquement sur programmation.
[2023-02-21 00:36:02][SCENARIO] - Exécution du sous-élément de type [action] : code
[2023-02-21 00:36:02][SCENARIO] Exécution d'un bloc code 
[2023-02-21 00:36:02][SCENARIO] HTTP Response : 200
[2023-02-21 00:36:02][SCENARIO] DATA : '
{
"option_tarifaire" : 0,
"tarif_courant" : 0,
"isousc" : 45,
"conso_base" : 024732216,
"conso_hc"   : 0,
"conso_hp"   : 0,
"conso_hc_b" : 0,
"conso_hp_b" : 0,
"conso_hc_w" : 0,
"conso_hp_w" : 0,
"conso_hc_r" : 0,
"conso_hp_r" : 0,
"type_imp_0" : 0,
"type_imp_1" : 1,
"type_imp_2" : 1,
"type_imp_3" : 1,
"type_imp_4" : 1,
"type_imp_5" : 1,
"label_entree1" : "PC Info             ",
"label_entree2" : "Eclairage           ",
"label_entree3" : "Chauffage",
"label_entree4" : "Chaudiere           ",
"label_entree5" : "Prises de Courant",
"label_entree_imp0" : "Gaz",
"label_entree_imp1" : "Eau",
"label_entree_imp2" : "Eau",
"label_entree_imp3" : "Eau",
"label_entree_imp4" : "Eau",
"label_entree_imp5" : "Eau",
"entree_imp0_disabled" : 1,
"entree_imp1_disabled" : 1,
"entree_imp2_disabled" : 1,
"entree_imp3_disabled" : 1,
"entree_imp4_disabled" : 1,
"entree_imp5_disabled" : 1
}'
[2023-02-21 00:36:02][SCENARIO] Parsed JSON : NULL
[2023-02-21 00:36:02][SCENARIO] conso_base Collectée :
[2023-02-21 00:36:02][SCENARIO] Fin correcte du scénario

Comme on peut le voir à la fin du log, mon problème vient à la lecture de la valeur

$conso_base = $parsed_json->{'conso_base'};
//$conso_base = (((value|regex_replace("([ :])0+(\\d+),", "\g<1>\g<2>,")|from_json).conso_base) | float * 1 / 1000) | round(1);
//$conso_base = preg_replace('`^[0]*`','',$conso_base);
$scenario->setLog("conso_base Collectée : " . $Linky);
cmd::byString('#[Maison][Compteur][Linky]#')->event(($conso_base));

Voici mon bout de code où l’erreur doit se trouver vu que c’est à partir de là que je lis ma donnée.
Les 2 lignes commençant par // sont 2 code PHP que j’ai trouvé pour supprimer ce zéro, mais sans succès.

Est-ce qu’il y a quelqu’un qui peut m’aider à trouver le bon code ?

Je vous remercie par avance.

Salut
Je ne pratique pas assez le php pour donner une reponse mais pour moi la valeur dans json est un string, il faudrait la convertir en integer et ça ignorera le zero… Sinon si la valeur commence toujours par 0 essai avec un LeftTrim

#si value = 01234 le code retournera 1234
$value = ltrim($value, '0');

a adapter dans ton code

Hello,

Tu peux nous donner la valeur du champ avant le parsing aussi ?

Si c’est le string "024732216", la réponse de @Nicoca-ine est la bonne, si c’est un nombre, alors PHP l’a vu comme de l’octal et tu peux simplement faire un changement de base (tant qu’il est inférieure à 100000000).

EDIT : Le changement de base ne marchera pas car le nombre peut contenir des chiffres >7.

Le code d’extraction du 0 que tu as trouvé semble bon mais est en Jinja :

regex_replace("([ :])0+(\\d+),", "\g<1>\g<2>,")

Voici l’équivalent pimpé en PHP :

$conso_base = preg_replace('/([:]\s*)[0]+(\d+\s*[,])/m', '\1\2', $conso_base);

Bad

2 « J'aime »

Bonjour,
Puisque vos données semblent être issues d’un ecoCompteur Legrand, voici un bloc code qui fait la récupération du json, sa correction et met dans le log du scénario la valeur de conso_base
En commentaire dans le code, la ligne commençant par foreach permet de mettre dans le log toutes les valeurs présentes dans le json.

  $devAddr = 'http://192.168.1.141/data.json';
  $request_http = new com_http($devAddr);
  $devResult = $request_http->exec(30);
  if ($devResult === false) {
    $scenario->setLog("Problème de connexion à l'ecoCompteur $devAddr");
  } else {
    $devResbis = utf8_encode($devResult);
    $corrected = preg_replace('/\s+/', '', $devResbis);
    $corrected = preg_replace('/\:000000000,/', ': 0,', $corrected);
    $corrected = preg_replace('/\:0,/', ': 0,', $corrected);
    $corrected = preg_replace('/\:[0]+/', ":", $corrected);
    $devList = json_decode($corrected, true);
    if (json_last_error() == JSON_ERROR_NONE) {
      $scenario->setLog('Conso_base: ' .$devList['conso_base']);
      // ou parcours et extraction de toutes les données
      // foreach($devList as $name => $value) { $scenario->setLog("Name $name Value $value"); }
    }
    else $scenario->setLog('Json_decode error: ' .json_last_error_msg());
  }

Extrait de :

2 « J'aime »

Salut,

tu as essayé avec le flag JSON_NUMERIC_CHECK ?
https://www.php.net/manual/fr/function.json-decode.php
https://www.php.net/manual/fr/json.constants.php

Ça a l’air d’être fait pour ça…

A+
Michel

Le flag JSON_NUMERIC_CHECK ne fonctionne pas.
Selon la doc, il serait pour json_encode.

Les flags de json_decode:

JSON_BIGINT_AS_STRING serait une autre option.

1 « J'aime »

Encore raté. Syntax error.

  $devResult = ' { "option_tarifaire" : 0, "tarif_courant" : 0, "isousc" : 45, "conso_base" : 020124541, "conso_hc"   : 0, "conso_hp"   : 0, "conso_hc_b" : 0, "conso_hp_b" : 0, "conso_hc_w" : 0, "conso_hp_w" : 0, "conso_hc_r" : 0, "conso_hp_r" : 0, "type_imp_0" : 1, "type_imp_1" : 1, "type_imp_2" : 1, "type_imp_3" : 1, "type_imp_4" : 1, "type_imp_5" : 1, "label_entree1" : "C1 Volets Fours     ", "label_entree2" : "C2 PC VW Up         ", "label_entree3" : "C3 LL SL            ", "label_entree4" : "C4 Info Frigo       ", "label_entree5" : "C5 Induction        ", "label_entree_imp0" : "Gaz", "label_entree_imp1" : "Eau m3 x 10", "label_entree_imp2" : "Eau", "label_entree_imp3" : "Eau", "label_entree_imp4" : "Eau", "label_entree_imp5" : "Eau", "entree_imp0_disabled" : 0, "entree_imp1_disabled" : 0, "entree_imp2_disabled" : 1, "entree_imp3_disabled" : 1, "entree_imp4_disabled" : 1, "entree_imp5_disabled" : 1 }';
    $devList = json_decode($devResult, true,512,JSON_BIGINT_AS_STRING );
    if (json_last_error() == JSON_ERROR_NONE) {
      foreach($devList as $name => $value) { echo ("Name $name Value $value<br>"); }
    }
    else {
      echo ('Json_decode error: ' .json_last_error_msg() .'<br>');
    }

Je vous laisse essayer tous les autres flags. :wink:
:warning: C’est du json Legrand :copyright:
image

Vous avez essayé lesquels ?

1 « J'aime »

Juste les 3 que vous avez donné. 1 de encode et 2 de decode.

Si vous avez du temps à perdre, il faut aussi essayer les combinaisons de flag. :rofl:

J’utilise depuis plusieurs années ce que j’ai proposé là: Code avec correction d'une donnée d'un JSON - #4 par jpty

J’ai essayé de multiples combinaisons de FLAGS ce matin, rien de probant, c’est le parser de json_decode qui refuse directement le json…

cf PHP :: Bug #50286 :: json_decode returns false when leading zeros aren't escaped with double quotes / JSON

Bonsoir,

Merci à tous pour vos différentes proposition

Ca fonctionne

@jpty j’utilise ton code, et je pensais pouvoir facilement transférer la valeur dans un virtuel, mais je n’y arrive pas malgré toutes mes tentatives et comparaison avec mes autres scénario similaire et recherche sur les poste équivalent sur le forum

Quel code PHP dois-je rajouter pour récupérer la valeur ?

      cmd:byString('#[Maison][Compteur][Linky]#')->event(('conso_base'));

Je n’y arrive pas avec celui-ci, je me doutes qu’il doit me manquer un bout quelques part, mais n’ayant pas de connaissance particulière en PHP, je ne trouve pas

Merci par avance,

Hello,

C’est $devList['conso_base'] qui contient l’information donc .....->event($devList['conso_base'])

Hello,
J’ai essayé avec

cmd:byString('#[Maison][Compteur][Linky]#')->event($devList['conso_base']);

Mais j’ai toujours le même message dans les logs et rien dans mon virtuel

[2023-02-22 13:51:02][SCENARIO] Call to undefined function byString()

cmd::byString avec 2 :

Merci @Mips

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.