String test = "{2025-09-03: \"BLUE\", 2025-09-02: \"BLUE\", 2025-09-02-fallback: \"false\", 2025-09-03-fallback: \"false\"}";
String deb = "2025-09-02";
String fin = "2025-09-02-fallback";
String PrefiltreJson(String F1, String F2, String Json) { //??? retourne une bribe de la chaine Json, en commençant a la chaine F1 finisant au premier caractere de la chaine F2
int p = Json.indexOf(F1);
Json = Json.substring(p);
p = Json.indexOf(F2);
Json = Json.substring(p);
return Json; // resultat étrange
}
String SubJson(String F1, String F2, String Json) { //??? retourne une bribe de la chaine Json, en commençant a la 1ere chaine F1 finisant au premier caractere de la chaine F2
int p = Json.indexOf(F1);
Json = Json.substring(p);
p = Json.indexOf(F2);
Json = Json.substring(0,p+1);
return Json;// pas utile de reduire une chaine json bien encodée
}
// sur base json.org / sauf whitespace qui pourrait être autre chose que espace ... // + libre interpretation de string pour le clé
// a partir d'un couple "clé":valeur contenu dans une chaine typique au format JSON (la clé est entre guillement ou pas)
// fait le menage et retourne une chaine de la réponse valeur
// en supprimant les potentiels guillements qui encadrent valeur, il ne restera qu'a faire une conversion numérique au format souhaité
String primaryExtract(String nom, String Json) {
int16_t p = Json.indexOf("\"" + nom + "\""); // le mot clé d'un chaine JSON est obligatoirement une string encadré par des guillements
if (p < 0) {
log_e("\"%s\" not found in %s",nom.c_str(),Json.c_str());
p = Json.indexOf(nom); // on tente quand même une recherche mot clé sans les guillements : le piege c'est q'une partie du Json corresponde
if (p < 0) {
log_e("%s not found in %s",nom.c_str(),Json.c_str());
return "00"; // retourne quelques chose de non cohérent, qui vaudra 0 si converti en numérique !!!
}
}
if ((p = Json.indexOf(":", p + 1)) < 0) return "00"; else p++;// au cas ou il y aurait un/des espace(s) entre le " de la clé et le :
while (Json.charAt(p) == ' ') {p++;} // supprime espace(s) apres le :
bool valueEntreGuil = false;
if (Json.charAt(p) == '\"') { // au cas ou ça serait un codage avec le nombre entre guillement
valueEntreGuil = true;
p++;
}
if (!valueEntreGuil) while (Json.charAt(p) == ' ') {p++;} // supprime encore les espaces de début
if (valueEntreGuil) {
int q = Json.indexOf("\"", p); //cherche la fin apres la valeur entre guillement
if (q > 0) Json.remove(q); else return "00"; // on supprime la fin ou c'est une chaine mal formée
} else { // la fin de la valeur pourrait être suivi de , ou }
if (Json.indexOf(",", p)) Json.remove(Json.indexOf(",", p)); // abrege la fin après la premiere virgule suivante
if (Json.indexOf("}", p)) Json.remove(Json.indexOf("}", p)); // abrege la fin après la premiere accolade suivante
}
Serial.printf(" (%s) ", Json.substring(p).c_str());
return Json.substring(p);
}
// le séparateur décimal étant le point
// retourne un nombre a virgule flottante (sur 64 bit, il y ~15 chiffres representatif : x.1234567 le reste c'est garbadge)
double DoubleJson(String nom, String Json, bool commaDecimal = false) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0.0L;
if (commaDecimal) part.replace(",",".");
double forReturn = 0.0L; // or double/int32_t float to catch maximum of representative digit
char c;
if (sscanf(part.c_str(),"%lf%c", &forReturn, &c) >= 1) return double(forReturn); else return 0.0L;// on retourne même si on a pas tous les digits après la virgule
}
// a partir d'un couple "clé":valeur ou "clé":"valeur" séparateur décimal étant le point
// retourne un nombre a virgule flottante (sur 32 bit, il y ~7 chiffres representatif : x.1234567 le reste c'est garbadge)
float ValJson(String nom, String Json, bool commaDecimal = false) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0.0F;
if (commaDecimal) part.replace(",",".");
float forReturn = 0.0F; // or double/int32_t float to catch maximum of representative digit
char c;
if (sscanf(part.c_str(),"%f%c", &forReturn, &c) >= 1) return float(forReturn); else return 0.0F;// on retourne même si on a pas tous les digits après la virgule
}
// retourne un signé sur 64 bit (retour exotique si le nombre représenté est hors des bornes ...)
int64_t LongLongJson(String nom, String Json) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
int64_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%lld%c", &forReturn, &c) == 2) return int64_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite - (et +) et s'arrete au premier caractere qui n'est pas un chiffre
}
// retourne un signé sur 32 bit (retour exotique si le nombre représenté est hors des bornes ~-2milliard ~+2millard)
int32_t LongJson(String nom, String Json) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
int32_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%ld%c", &forReturn, &c) == 2) return int32_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite - (et +) et s'arrete au premier caractere qui n'est pas un chiffre
}
long myLongJson(String nom, String Json) { // en utilisant un peu de conformité avec le codage JSON, c'est la même chose que LongJson
return LongJson(nom, Json);
}
int IntJson(String nom, String Json) { // en utilisant un peu de conformité avec le codage JSON, c'est la même chose que LongJson
return LongJson(nom, Json);
}
// retourne un non signé sur 32 bit (retour exotique si le nombre représenté est hors des bornes 0 ~+4millard)
uint32_t ULongJson(String nom, String Json) { // Alternative a ULongJson au dessus pour extraire chez RTE nb jour Tempo https://particulier.RTE.fr/services/rest/referentiel/getNbTempoDays?TypeAlerte=TEMPO
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
uint32_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%lu%c", &forReturn, &c) == 2) return uint32_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite un eventuel + et s'arrete au premier caractere qui n'est pas un chiffre
}
// retourne un entier signé sur 16 bit (retour exotique si le nombre représenté est hors des bornes -32768 +32767)
int16_t ShortJson(String nom, String Json) { // Pour éviter des problèmes d'overflow
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
int16_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%hd%c", &forReturn, &c) == 2) return int16_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite - (et +) et s'arrete au premier caractere qui n'est pas un chiffre
}
// retourne un entier non signé sur 16 bit (retour exotique si le nombre représenté est hors des bornes 0 +65535)
uint16_t UShortJson(String nom, String Json) { // Pour éviter des problèmes d'overflow
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
uint16_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%hu%c", &forReturn, &c) == 2) return uint16_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite un eventuel + et s'arrete au premier caractere qui n'est pas un chiffre
}
// retourne un non signé sur 8 bit (retour exotique si le nombre représenté est hors des bornes 0 +255)
byte ByteJson(String nom, String Json) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
uint8_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%hhu%c", &forReturn, &c) == 2) return uint8_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite un eventuel + et s'arrete au premier caractere qui n'est pas un chiffre
}
// retourne un signé sur 8 bit (retour exotique si le nombre représenté est hors des bornes -128 +127)
int8_t ScharJson(String nom, String Json) {
String part = primaryExtract(nom, Json);
if (part == "00") return 0;
int8_t forReturn = 0;
char c;
if (sscanf(part.c_str(),"%hhd%c", &forReturn, &c) == 2) return int8_t(forReturn); else return 0; // sscanf ignore les espaces au debut, traite signe - + et s'arrete au premier caractere qui n'est pas un chiffre
}
// a partir d'un couple "clé":valeur contenu dans une chaine typique au format JSON (la clé est entre guillement ou pas)
// nom étant la clé souhaité
// retourne la chaine de caractere encadré par guillement ou "" si pas trouvé ou mal formé
String StringJson(String nom, String Json) {
bool entreG = true; // une chaine de caracteres est attendu entre guillement
int16_t p = Json.indexOf(nom + "\"");
if (p < 0) {
log_e("%s\" not found in %s",nom.c_str(),Json.c_str());
entreG = false;
p = Json.indexOf(nom);
if (p < 0) {
log_e("%s not found in %s",nom.c_str(),Json.c_str());
return String(); // retourne une chaine vide car clé non trouvé
}
}
entreG = true;
if ((p = Json.indexOf(":", p + 1)) < 0) return String(); // au cas ou il y aurait un/des espace(s) avant le : de la valeur, sans : on retourne chaine vide
if ((Json.indexOf("\"", p + 1)) < 0) {// au cas ou il aurait un espace entre le separant clé/valeur et le " du début de la chaine texte attendu
entreG = false; // la chaine n'est pas encadré par guillemets = étrange situation non conforme
}
if (entreG) p = Json.indexOf("\"", p + 1); // else p pointe toujours juste après le :
// si on a pas de guillement, la fin de la chaine est signalé par une virgule ou une accolante fermante
if (entreG && Json.indexOf("\"", p + 1) < 0) return String(); // il n'y a pas de " final
String final = "\"";
if (!entreG) {
final = ",";
if (Json.indexOf(final, p + 1) < 0) final = "}";
if (Json.indexOf(final, p + 1) < 0) return String(); // on a pas trouvé , ou } pour une valeur type chaine sans guillement
}
return Json.substring(p + 1, Json.indexOf(final, p + 1));
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
Serial.println(test);
Serial.println("***** Prefiltre");
Serial.println(PrefiltreJson(deb, fin, test));
Serial.println("***** SubJson");
Serial.println(SubJson(deb, fin, test));
Serial.println("***** primaryExtract");
Serial.println(primaryExtract(deb, test));
Serial.println("***** StringJson");
Serial.println(StringJson(deb, test));
Serial.println("***** End");
Serial.println();
Serial.println();
String JS[11];
JS[0]="{\"key\":\"12147483640.123\"};";
JS[1]="{key:\"12147483640.123\"};";
JS[2]="{\"key\":12147483640.123};";
JS[3]="{key:12147483640.123};";
JS[4]="{\"key\":\"121.123\"};";
JS[5]="{key:\"121.123\"};";
JS[6]="{\"key\":121.123};";
JS[7]="{key:121.123};";
JS[8]="{key: 121.123,";
JS[9]="{key: \"121.123,";
JS[10]="{key: 121.123\"};";
for (int i=0; i < sizeof(JS)/sizeof(JS[0]); i++) {
Serial.printf("Brute %d : %s\n", i, JS[i].c_str());
Serial.printf("Double : %.15lf\n", DoubleJson("key",JS[i])); //+
Serial.printf("Val (float) : %1.10f\n", ValJson("key",JS[i])); // ! trop grand pour un float
Serial.printf("LongLong : %lld\n", LongLongJson("key",JS[i])); //+
Serial.printf("Long : %ld\n", LongJson("key",JS[i]));
Serial.printf("ULong : %lu\n", ULongJson("key",JS[i]));
Serial.printf("Short : %hd\n", ShortJson("key",JS[i])); // -1?
Serial.printf("UShort : %hu\n", UShortJson("key",JS[i]));
Serial.printf("Byte : %hhu\n", ByteJson("key",JS[i]));
Serial.printf("UChar : %hhd\n", ScharJson("key",JS[i])); // -1 ?
Serial.printf("String : %s\n", StringJson("key",JS[i]).c_str());//+
Serial.println("********");
}
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}