Go Down

Topic: Comment transformer une chaîne après séparation en JSON?  (Read 701 times) previous topic - next topic

noam76

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:
Quote
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
Code: [Select]
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:
Quote
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 :
Quote
{
"Power": Off,
"Mode": 1,
"Temp": 25,
"Fan": 1,
"Turbo": Off,
"Quiet": Off,
"XFan": Off,
"Ion": Off,
"Light": On,
"Swing(H)": Off,
"Swing(V)": On
}

lesept

A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

noam76

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 ?

lesept

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.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

noam76

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 ?

noam76

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.

al1fch

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 :
Code: [Select]

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

ça pourrait faciliter le travail...

jfs59

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.
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours.

Lao Tseu.

lesept

Sinon, tu fais ça "à la main", tu dois juste transformer
Code: [Select]
Power: Offen
Code: [Select]
"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.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

noam76

Merci pour vos conseil .

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 :
Code: [Select]

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

ça pourrait faciliter le travail...
Je vais voir ça si cela me convient

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.

Sinon, tu fais ça "à la main", tu dois juste transformer
Code: [Select]
Power: Off
en
Code: [Select]
"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.

lesept

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

Code: [Select]
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 :
Quote
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...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).


noam76

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
Code: [Select]
#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)
 }
}

noam76

le serial moniteur avec les erreurs
Quote
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

al1fch

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

Go Up