// recherche F1 puis F2, retourne la chaine a partir de F2 inclus
String PrefiltreJson(String F1, String F2, String Json) { // used shellyProEm
int p = Json.indexOf(F1);
Json = Json.substring(p);
p = Json.indexOf(F2);
Json = Json.substring(p);
return Json;
}
// recherche F1 puis F2, retourne la chaine a partir de F2 inclus / sans copie de chaine en mémoire
String PrefiltreJson2(const String &F1, const String &F2, const String &Json) { // used shellyProEm
int p = Json.indexOf(F1);
if (p == -1) return ""; // F1 non trouvé
p = Json.indexOf(F2, p);
if (p == -1) return ""; // F2 non trouvé après F1
return Json.substring(p);
}
//retourne la chaine contenu entre F1 inclus et F2 exclus
String SubJson(String F1, String F2, String Json) { // used shellyProEm
int p = Json.indexOf(F1);
Json = Json.substring(p);
p = Json.indexOf(F2);
Json = Json.substring(0, p + 1);
return Json;
}
//retourne la chaine contenu entre F1 inclus et F2 exclus / sans copie de chaine en mémoire
String SubJson2(const String &F1, const String &F2, const String &Json) { // used shellyProEm
int p1 = Json.indexOf(F1);
if (p1 == -1) return ""; // F1 non trouvé
int p2 = Json.indexOf(F2, p1 + F1.length());
if (p2 == -1) return ""; // F2 non trouvé
return Json.substring(p1, p2);
}
// recherche la valeur float associée a nom , la chaine doit respecter nom":123.456, xxx}
// Important, il faut le nom suivi de ": et une virgule et un accolade fermant après la data souhaité, s'il manque un élement, resultat = 0.00
// cherche nom suivi de double quote et : , le début commence a la premier lettre de nom
// cherche caractere : le début commence après le caractere :
// cherche position de la virgule suivante (q = -1 si inexistante)
// cherche position de l'accolade fermante suivante (p = -1 si inexistante)
// prend la position la plus petite entre p et q (sera -1 si pas de , ou pas de })
// reduit la chaine texte en commençant sur le 1er caractere et termine sur position , ou } (ou -1 si un des caracteres est manquant)
float ValJson(String nom, String Json) { // used EnvoiMQTT + shelly
int p = Json.indexOf(nom + "\":");
Json = Json.substring(p);
p = Json.indexOf(":");
Json = Json.substring(p + 1);
int q = Json.indexOf(",");
p = Json.indexOf("}");
p = min(p, q);
float val = 0;
if (p > 0) {
Json = Json.substring(0, p);
val = Json.toFloat();
}
return val;
}
// version revue pour traiter différemment , et }
float ValJson2(const String &nom, String Json) {
int p = Json.indexOf(nom + "\":");
Json = Json.substring(p);
p = Json.indexOf(":");
Json = Json.substring(p + 1);
int q = Json.indexOf(",");
p = Json.indexOf("}");
if (p > 0)
p = min(p, q);
else
p = q;
float val = 0;
if (p > 0) {
Json = Json.substring(0, p);
val = Json.toFloat();
}
return val;
}
// recherche nom encadré par double quote, avance jusqu'au double dot, puis optionnelement une double quote qui encadrerai la data
// retourne le float dispo a cet endroit (ou 0.0f si la chaine ne représente pas un début de nombre)
float ValJson3(String nom, String Json) {
int p = Json.indexOf("\"" + nom + "\""); // le nom encadré avant et après évite d'extraire une correspondance en fin de nom
if (p == -1) return 0.0f;
Json = Json.substring(p);
p = Json.indexOf(":");
if (p == -1) return 0.0f;
Json = Json.substring(p + 1);
Json.trim(); // supprime eventuel espace au début
if (Json.charAt(0) == '\"') Json = Json.substring(1); // supprime l'éventuel 1er double quote qui encadre la donnée
return Json.toFloat();
}
// recherche nom encadré par double quote, avance jusqu'au double dot, puis optionnelement une double quote qui encadrerai la data
// retourne le float dispo a cet endroit (ou 0.0f si la chaine ne représente pas un début de nombre)
float ValJson4(const String &nom, const String &Json, bool altSansDoubleQuote = false) {
String lookup = "\"" + nom + "\""; // le nom encadré avant et après évite d'extraire une correspondance en fin de nom
int p = Json.indexOf(lookup);
if (p == -1) { // pas trouvé le nom encadré par double cote
if (altSansDoubleQuote) {
lookup = nom;
p = Json.indexOf(nom); // on essai sans encadrement par double quote, On accepte le risque de prendre une partie de nom ?
}
if (p == -1) return 0.0f; // nom n'est pas dans le Json (ni encadré ni sans encadrement)
}
p = Json.indexOf(':', p + lookup.length()); // Sauter le nom trouvé et chercher le ':' suivant
if (p == -1) return 0.0f; // pas trouvé le ':'
p++;
while (p < Json.length() && Json[p] <= ' ') p++; // On saute tous les caractères de contrôle (ASCII <= 32)
if (p < Json.length() && Json[p] == '\"') p++; // Si on tombe sur un guillemet ouvrant, on le saute
return Json.substring(p).toFloat(); // le fonction .toFloat accepte que la chaine commence par espace, tab, \r \n ...
}
// Version historique de F1ATB : extrait une chaine assicié a un nom au format JSON (séparateur :)
// considere que clé suivi de guillement et deux point sont collés
// considere que clé existe obligatoirement
// avance dans le parsing du json en considerant que tout existe comme prévue
String StringJson(String nom, String Json) { // commence par dupliquer les 2 chaines texte
int p = Json.indexOf(nom + "\":"); // cherche nom a la fin d'une clé suivuit de double quote et double dot accolé
Json = Json.substring(p); // fait une copie du json reduit
p = Json.indexOf(":"); // avance au premier : disponible, peu importe si la clé a été trouvé ou pas
Json = Json.substring(p + 1); // fait une copie du json reduit
p = Json.indexOf("\""); // avance au guillement ouvrant de la réponse
Json = Json.substring(p + 1); // coupe tout ce qui existe avant, // fait une copie du json reduit
p = Json.indexOf("\""); // trouve la position du guillement suivant
Json = Json.substring(0, p); // retourne uniquement la réponse, // fait une copie du json reduit
return Json;
}
// cherche les index début et fin de la réponse pour retourner l'extrait sans copie de String
String StringJson2(const String &nom, const String &Json) {
String lookup = "\"" + nom + "\""; // le nom encadré avant et après évite d'extraire une correspondance en fin de nom
int p = Json.indexOf(lookup);
if (p != -1) p = Json.indexOf(":", p + lookup.length()); // pas trouvé le nom encadré par double quote
if (p != -1) p = Json.indexOf("\"", p + 1); // pas de :
int q = (p != -1) ? Json.indexOf("\"", p + 1) : -1; // pas trouvé le resultat commençant par double quote
if (p == -1 || q == -1) return ""; // pas trouvé le resultat encadré par double quote
return Json.substring(p + 1, q);
}
long myLongJson(String nom, String Json) { // Alternative a LongJson au dessus pour extraire chez RTE nb jour Tempo https://particulier.RTE.fr/services/rest/referentiel/getNbTempoDays?TypeAlerte=TEMPO
int p = Json.indexOf(nom + "\":");
Json = Json.substring(p);
p = Json.indexOf(":");
Json = Json.substring(p + 1);
int q = Json.indexOf(","); //<==== Recherche d'une virgule et non d'un point
if (q == -1) q = Json.length(); // /<==== Ajout de ces 2 lignes pour que la ligne p = min(p, q); ci dessous donne le bon résultat
p = Json.indexOf("}");
if (p > 0)
p = min(p, q);
else
p = q;
long val = 0;
if (p > 0) {
Json = Json.substring(0, p);
val = Json.toInt();
}
return val;
}
long myLongJson2(const String& nom, const String& Json) {
String lookup = "\"" + nom + "\""; // le nom encadré avant et après évite d'extraire une correspondance en fin de nom
int p = Json.indexOf(lookup); // pas trouvé le nom encadré par double quote
if (p == -1) return 0;
p = Json.indexOf(":", p + lookup.length()); // pas trouvé le : séparateur
if (p == -1) return 0;
return Json.substring(p + 1).toInt();
}
//String strfloat = "\"item\":123.456, \"topic\":0.123\" --,---}"; // Ok pour version historique et les suivantes
//String strfloat = "\"item\": 123.456, \"ABCtopic\":0.123\" --,---}"; // crash sur nom ABCtopic en cherchant topic pour historique et V1
//String strfloat = "\"item\": 123.456, \"topic\":0.123\" -----}"; // crash sur absence , pour historique et V1
//String strfloat = "\"item\": 123.456, \"topic\":0.123\" --,---"; // crash sur absence } pour historique
//String strfloat = "\"item\": 123.456, \"topic\":\"0.123\" ---,--}"; // crash sur resultat entre double quote pour historique et V1
String strfloat = "\"item\" : \"123.456\", \"topic\"\n:\n \"0.123\""; // possible extrait de JSON, crash pour historique et V1
String str = "AbCdEfGhIjKlMnOpQr";
String test = "\n12.34";
String cherche1 = "item";
String cherche2 = "topic";
void setup() {
Serial.begin(115200);
delay(1000); // laisse tourner les taches d'initialisation pour stabiliser le system
Serial.println(test.toFloat());
Serial.println("\n PrefiltreJson de F1ATB 'historique");
Serial.println(PrefiltreJson("Ef", "Mn", str));
Serial.println(SubJson("Ef", "Mn", str));
Serial.println("\n PrefiltreJson2 revisité");
Serial.println(PrefiltreJson("Ef", "Mn", str));
Serial.println("\n SubJson de F1ATB 'historique");
Serial.println(SubJson("Ef", "Mn", str));
Serial.println("\n SubJson2 revisité");
Serial.println(SubJson2("Ef", "Mn", str));
Serial.println("\n ValJson de F1ATB 'historique");
Serial.println(ValJson(cherche1, strfloat));
Serial.println(ValJson(cherche2, strfloat));
Serial.println("\n ValJson2 de F1ATB revue juin 2026");
Serial.println(ValJson2(cherche1, strfloat));
Serial.println(ValJson2(cherche2, strfloat));
Serial.println("\n ValJson3 basé sur F1ATB sans recherche caractére après la data");
Serial.println(ValJson3(cherche1, strfloat));
Serial.println(ValJson3(cherche2, strfloat));
Serial.println("\n ValJson4 optimisé sans copie de la chaine JSON");
Serial.println(ValJson4(cherche1, strfloat));
Serial.println(ValJson4(cherche2, strfloat));
Serial.println("\n StringJson F1ATB");
Serial.println(StringJson(cherche1 ,strfloat));
Serial.println(StringJson(cherche2 ,strfloat));
Serial.println("\n StringJson2 optimisé sans copie de la chaine JSON");
Serial.println(StringJson2(cherche1 ,strfloat));
Serial.println(StringJson2(cherche2 ,strfloat));
}
void loop() {
delay(10); // this speeds up the simulation
}