Comment transformer une chaîne après séparation en JSON?

Bonjour a tous,
J'utilise un nodemcu esp8266, avec une led IR récepteur et émetteur pour décoder une télécommande d'air conditionner.
Grace a l’exemple IRrecvDumpV2 de la librairie IRremoteESP8266 je reçois ce String:

Mesg Desc.: Power: Off, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), Turbo: Off, Quiet: Off, XFan: Off, Ion: Off, Light: On, Swing(H): Off, Swing(V): On

Avec strtok je sépare la chaîne

char str_array[description.length()+1];
     for( int i = 0; i < sizeof(str_array);  ++i )
     str_array[i] = (char)0; //reset str_array
     
     description.toCharArray(str_array, description.length()+1);
     char * token = strtok(str_array, ",");
     
     while (token != NULL) {
      printf ("%s\n",token);
      //token = strtok (NULL, " ");
      token = strtok (NULL, ",");
      }

Le résultat de la séparation:

Power: Off
Mode: 1 (Cool)
Temp: 26C
Fan: 1 (Low)
Turbo: Off
Quiet: Off
XFan: Off
Ion: Off
Light: On
Swing(H): Off
Swing(V): On

Je cherche a transformer ce résultat en format JSON je n'ai pas trouvé d'exemple comment le faire.
la librairie que j'utilise est celle de bblanchon
Le resultat voulue :

{
"Power": Off,
"Mode": 1,
"Temp": 25,
"Fan": 1,
"Turbo": Off,
"Quiet": Off,
"XFan": Off,
"Ion": Off,
"Light": On,
"Swing(H)": Off,
"Swing(V)": On
}

As-tu essayé l'assistant ?

Merci, si je comprend bien l'assistant est conçu pour un format JSON au départ, que je n'ai pas encore.

Je dois d'abord convertir le résultat en format JSON, mais comment ?

L'assistant te crée le code pour serialiser les données que tu mets dans sa fenêtre. Je suppose qu'en copiant ton résultat voulu dans cette fenêtre il te créera un code dont tu peux t'inspirer pour ton objectif.

Cela ne marche pas il me donne un message d'erreur, le résultat que j'ai n'est pas un JSON, l'assistant ne convient pas.

Je ne sais pas trop comment faire....

Est-ce que ma question est claire, compréhensible ?

Ce que je cherche a faire c'est de créer le JSON apartir de ma chaîne, c'est la que je suis coincé.

L'assistant utilise un JSON existant, dans mon cas je ne l'ai pas encore.

le strtok s'epare bien la chaine.

J'ai besoin de votre aide pour créer le format JSON depuis le strtok.

Bonjour

La librairie ArduinoJson de benoit Blanchon ne fait pas que le parsing, voir son exemple JsonGeneratorExample qui crée et envoie sur le port série ce texte au format JSON :

    "sensor": "gps",
    "time": 1351824120,
    "data": [
      48.756080,
      2.302038
    ]

ça pourrait faciliter le travail...

Bonjour, peut être que

Le résultat voulu que tu présente n est pas un json compatible.

Regarde les spécifications json

J ai eu ce problème et en rajoutant ce qu il faut ça marche.

Sinon, tu fais ça "à la main", tu dois juste transformer
Power: Offen

"Power": "Off",

et créer un tableau de char dans lequel tu mets une { et tout le reste à la suite.

Pour la transformation, il suffit de trouver la position des : et de mettre des " autour...
Il faut parfois aussi traiter la présence de parenthèses, mais c'est faisable.

Merci pour vos conseil .

al1fch:
La librairie ArduinoJson de benoit Blanchon ne fait pas que le parsing, voir son exemple JsonGeneratorExample qui crée et envoie sur le port série ce texte au format JSON :

    "sensor": "gps",

"time": 1351824120,
    "data": [
      48.756080,
      2.302038
    ]



ça pourrait faciliter le travail...

Je vais voir ça si cela me convient

jfs59:
Le résultat voulu que tu présente n est pas un json compatible.
Regarde les spécifications json
J ai eu ce problème et en rajoutant ce qu il faut ça marche.

J'ai besoin que ces rajouts ce fasse automatiquement.

lesept:
Sinon, tu fais ça "à la main", tu dois juste transformer

Power: Off

en

"Power": "Off",

et créer un tableau de char dans lequel tu mets une { et tout le reste à la suite.

Pour la transformation, il suffit de trouver la position des : et de mettre des " autour...
Il faut parfois aussi traiter la présence de parenthèses, mais c'est faisable.

La chaîne change en fonction des/du choix par la télécommande, le Power Off, peut passer en Power On,et autres,
de rajouter les : et les guillemet " bien cela que je cherche, de faire ça avec des codes de façon automatique.

Voila un début de code pour créer le Json : pas encore parfait mais c'est une base de travail...

void setup() {
  Serial.begin (115200);
  char str_array[100] = "Power: Off, Mode: 1 (Cool), Temp: 26C";
  char Json[100] = "{\"";
  Serial.println(str_array);

  char * token = strtok(str_array, ",: ");

  int count = 0;
  while (token != NULL) {
    Serial.printf ("%s --> ", token);

    if (strcmp(token, "(Cool)")) {
      if (count % 2 && count) strcat(Json, "\": \"");
      else if (count) strcat(Json, "\" , \"");
      strcat(Json, token);
      Serial.println(Json);
      ++count;
    }
    token = strtok (NULL, ",: ");
  }
  strcat (Json, "\"}");
  Serial.println();
  Serial.println(Json);
}

void loop() {}

Quand on le lance on obtient :

Power: Off, Mode: 1 (Cool), Temp: 26C
Power --> {"Power
Off --> {"Power": "Off
Mode --> {"Power": "Off" , "Mode
1 --> {"Power": "Off" , "Mode": "1
(Cool) --> Temp --> {"Power": "Off" , "Mode": "1" , "Temp
26C --> {"Power": "Off" , "Mode": "1" , "Temp": "26C

{"Power": "Off" , "Mode": "1" , "Temp": "26C"}

Le Json se crée et grandit au fur et à mesure de l'analyse des tokens.

Il reste à :

  • Ne pas mettre de guillemets lorsque la valeur est un chiffre
  • Ne pas mettre le C après la température

Bon courage...

Un grand merci :slight_smile:

lesept:
Voila un début de code pour créer le Json : pas encore parfait mais c'est une base de travail...

Il reste à :

  • Ne pas mettre de guillemets lorsque la valeur est un chiffre
  • Ne pas mettre le C après la température

Bon courage...

Merci pour ce bon début; j'ai fais la modif pour adapter a mon code, je n'ai pas encore regarder pour ce qui restent a faire.

a la fin du code je recois bien un format JSON, puis des messages d'erreur dans le serial monitor et un reset de la carte.

Je post mon code complet puis les erreur

#include <Arduino.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>


// ==================== start of TUNEABLE PARAMETERS ====================
// An IR detector/demodulator is connected to GPIO pin 14
// e.g. D5 on a NodeMCU board.
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
const uint16_t kRecvPin = 14;
const uint32_t kBaudRate = 115200;

// than normal buffer so we can handle Air Conditioner remote codes.
const uint16_t kCaptureBufferSize = 1024;

#if DECODE_AC
// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator
// A value this large may swallow repeats of some protocols
const uint8_t kTimeout = 40;
#else   // DECODE_AC
// Suits most messages, while not swallowing many repeats.
const uint8_t kTimeout = 15;
#endif  // DECODE_AC
// Alternatives:
// const uint8_t kTimeout = 90;
// Suits messages with big gaps like XMP-1 & some aircon units, but can
// accidentally swallow repeated messages in the rawData[] output.
//
// const uint8_t kTimeout = kMaxTimeoutMs;
// This will set it to our currently allowed maximum.
// Values this high are problematic because it is roughly the typical boundary
// where most messages repeat.
// e.g. It will stop decoding a message and start sending it to serial at
//      precisely the time when the next message is likely to be transmitted,
//      and may miss it.

const uint16_t kMinUnknownSize = 80;

// Legacy (No longer supported!)
// Change to `true` if you miss/need the old "Raw Timing[]" display.
#define LEGACY_TIMING_INFO false
// ==================== end of TUNEABLE PARAMETERS ====================

// Use turn on the save buffer feature for more complete capture coverage.
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;  // Somewhere to store the results
// This section of code runs only once at start-up.
char Json[100] = "{\"";
void setup() {
 
#if defined(ESP8266)
 Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY);
#else  // ESP8266
 Serial.begin(kBaudRate, SERIAL_8N1);
#endif  // ESP8266
 while (!Serial)  // Wait for the serial connection to be establised.
   delay(50);
 Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin);
#if DECODE_HASH
 // Ignore messages with less than minimum on or off pulses.
 irrecv.setUnknownThreshold(kMinUnknownSize);
#endif  // DECODE_HASH
 irrecv.enableIRIn();  // Start the receiver
}

// The repeating section of the code
void loop() {
 // Check if the IR code has been received.
 if (irrecv.decode(&results)) {
   // Display a crude timestamp.
   // uint32_t now = millis();
   if (results.overflow)
   // Display the basic output of what we found.
   Serial.print(resultToHumanReadableBasic(&results));
   // Display any extra A/C info if we have it.
    String description = IRAcUtils::resultAcToString(&results);
    if (description.length()) Serial.println(D_STR_MESGDESC ": " + description);
    yield();
    Serial.println();

    char str_array[description.length()+1];
    for( int i = 0; i < sizeof(str_array);  ++i )
    str_array[i] = (char)0; //reset str_array
    
    description.toCharArray(str_array, description.length()+1);
    char *token = strtok(str_array, ",: ");

    int count = 0;
    while (token != NULL) {
     Serial.printf ("%s --> ", token);
     if (strcmp(token, "(Cool)")) {
      if (count % 2 && count) strcat(Json, "\": \"");
      else if (count) strcat(Json, "\" , \"");
      strcat(Json, token);
      Serial.println(Json);
      ++count;
     }

     token = strtok (NULL, ",: ");
    }
     strcat (Json, "\"}");
     Serial.println();
     Serial.println(Json);

   Serial.println();    // Blank line between entries
   yield();             // Feed the WDT (again)
 }
}

le serial moniteur avec les erreurs

Mesg Desc.: Power: Off, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), Turbo: Off, Quiet: Off, XFan: Off, Ion: Off, Light: On, Swing(H): Off, Swing(V): On

Power --> {"Power
Off --> {"Power": "Off
Mode --> {"Power": "Off" , "Mode
1 --> {"Power": "Off" , "Mode": "1
(Cool) --> Temp --> {"Power": "Off" , "Mode": "1" , "Temp
26C --> {"Power": "Off" , "Mode": "1" , "Temp": "26C
Fan --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan
1 --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1
(Low) --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)
Turbo --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo
Off --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off
Quiet --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet
Off --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off
XFan --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan
Off --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off
Ion --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion
Off --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off
Light --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light
On --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On
Swing(H) --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On": "Swing(H)
Off --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On": "Swing(H)" , "Off
Swing(V) --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On": "Swing(H)" , "Off": "Swing(V)
On --> {"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On": "Swing(H)" , "Off": "Swing(V)" , "On

{"Power": "Off" , "Mode": "1" , "Temp": "26C" , "Fan": "1" , "(Low)": "Turbo" , "Off": "Quiet" , "Off": "XFan" , "Off": "Ion" , "Off": "Light" , "On": "Swing(H)" , "Off": "Swing(V)" , "On"}

Exception (9):
epc1=0x40106bd9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2022 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (4):
epc1=0x400005cb epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

Exception (9):
epc1=0x40215f8a epc2=0x00000000 epc3=0x00000000 excvaddr=0x202c2032 depc=0x00000000

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld

Bonjour

Exception(9) et autres...

Un moteur de recherche renvoie vers de nombreuses pages et divers échanges , exemple
https://links2004.github.io/Arduino/dc/deb/md_esp8266_doc_exception_causes.html

L'une des librairies utilisées ne tient peut être pas compte du fait que les mots sont codés içi sur 32 bits et non 16 comme sur les AVR d'ou l'exception de défaut d'alignement.

Le reset par watchdog final est peut être un effet de bord des exceptions antérieures

Peut-être que le 100 dans la ligne suivante est sous estimé.
char Json[100] = "{\"";vérifie la longueur de ton json attendu, 300 donnera un peu de marge

Pour qu'il ne prenne pas (Low) il faut changer cette ligne

if (strcmp(token, "(Cool)"))

En

if (strcmp(token, "(Cool)") ||  strcmp(token, "(Low)"))

Merci
J'ai changé char Json[100] = "{\""; en char Json[400] = "{\""; plus de message d'erreur.

pour la condition du filtre cela marche si je met un seul mot ça enlève bien le (Cool),if (strcmp(token, "(Cool)"))
dès que je rajoute d'autre cela ne marche plusif (strcmp(token, "(Cool)") ||  strcmp(token, "(Low)"))

C'est bizarre, tu peux coller le contenu de la console ?

bin ouais, avec une bonne colle de poisson on peut coller les éléments d'une console ... et tout ce qu'elle contient si on ne l'a pas vidée :wink: tout bon ébéniste sait ça !

[EDIT]
désolé, je me suis cru dans "Le Bar", je me suis lâché ... mais je laisse, je fête la réception de ma défonceuse Festool
(après tout, je ne serai pas le 1er à pourrir un topic)
[/EDIT]

J'ai rajouter ce code,je l'ai trouvé sur le forum, pour vider le contenu

strncpy( Json, "{\"", sizeof(Json) );
Json[sizeof(Json)-1] = 0;

ça ne change a rien, le if n’enlève pas les mots Cool ou Low, si je met une seul condition la ça enlève bien le mot seul.