Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

load external yaml file #3

Open
thijstriemstra opened this issue Oct 13, 2022 · 7 comments
Open

load external yaml file #3

thijstriemstra opened this issue Oct 13, 2022 · 7 comments

Comments

@thijstriemstra
Copy link

thijstriemstra commented Oct 13, 2022

Would be great to have an example that shows how to load a yaml file that is embedded on the device, e.g. a config.yaml.

would also like to know if it's possible to load a yaml file; modify structure (with a simple physical button to toggle a boolean value for example) and save back as a yaml file?

@tobozo
Copy link
Owner

tobozo commented Oct 13, 2022

hi, thanks for your feedback 👍

if you're on esp32/esp8266 here's a snippet using fs::FS I'll be adding to the example folder soon

otherwise please specify your preferred architecture/device (and eventually filesystem)

the suggested approach to manage a config,yml file is deserializing the YAML into a JsonObject, then use ArduinoJson accessors to manipulate the data, then serialize back to YAML

with esp32/8266 arduino packages, the fs::File object can be used as a Stream, so the syntax is straightforfard and stays the same for Serial, HTTPClient, or any object that inherits from the Stream class.

#include <ArduinoJson.h>
#include <YAMLDuino.h>

#include <FS.h>
#include <SD.h>


void setup()
{
  Serial.begin(115200);

  if( ! SD.begin( SS ) ) {
    Serial.println("Could not start the SD");
    return;
  }

  fs::File file = SD.open("/config.yml");

  if( !file ) {
    Serial.println("Can't open file for reading");
    return;
  }

  DynamicJsonDocument json_doc(file.size()*2);

  auto err = deserializeYml( json_doc, file ); // convert yaml to json

  file.close();

  if( err ) {
    Serial.printf("Unable to deserialize YAML to JsonDocument: %s\n", err.c_str() );
    return;
  }

  JsonObject myConfig = json_doc.as<JsonObject>();

  myConfig["blah"] = "new value";

  file = SD.open("/config.yaml", FILE_WRITE);

  if( !file ) {
    Serial.println("Can't open file for writing");
    return;
  }

  size_t bytes_out = serializeYml( myConfig, file );

  file.close();

  Serial.printf("Written %d bytes\n", bytes_out );
}

void loop()
{

}

@thijstriemstra
Copy link
Author

if you're on esp32/esp8266

Correct. But I'd also like to use it on Teensy 3.6 and 4.x.

I'll be adding to the example folder soon

Thanks!

@tobozo
Copy link
Owner

tobozo commented Oct 14, 2022

Teensy 3.6 and 4.x.

I don't have such legendary items, but the cores seem to implement fs::FS so it shouldn't be very different.

The library may need some modifications though as it currently only supports the boards listed in the Readme, it may need some additional #if defined ARDUINO_TEENSY40 || defined ARDUINO_TEENSY36 or whatever macros the teensy core generates for Arduino.

Please let me know how this went, I'll be happy to add these boards to the supported devices list.

@tobozo
Copy link
Owner

tobozo commented Oct 15, 2022

I have just published version 1.2.5, there's a new example based on M5Stack (to keep the code simple) with an action button that toggles a boolean value and updates the yaml file.

@tobozo
Copy link
Owner

tobozo commented Nov 10, 2022

hey @thijstriemstra I managed to order two teensy 4.1 units 🥳 , I also found a package URL to use instead of the faulty installer, and patched the library to compile with teensy core, changes are visible on the 1.3.0 branch.

I can't test the library until next tuesday delivery though, if you have the opportunity could you try to flash the updated test.ino sketch from the examples folder and provide the output from Serial console?

@GYBeccaria
Copy link

GYBeccaria commented Nov 11, 2022

Hi, thank you @tobozo, you are doing a great job!
BTW about this issue, this is what works for me:

void Yaml2Json()
{
  File file = LittleFS.open(config_file);
    
  if( !file ) 
    Serial.println("Can't open test file for writing :-(");
  
  size_t filesize = file.size();
  char string[filesize]; 
  file.read((uint8_t *)string, sizeof(string));
  string[filesize] = '\0';
  file.close();

  String yaml_str_file = string;
  Serial.println();
  Serial.println("YAML File input: ");
  Serial.println(yaml_str_file);

  StringStream yaml_stream( yaml_str_file );
  String json_string;
  StringStream json_stream_output( json_string );
  serializeYml( yaml_stream, json_stream_output, YAMLParser::OUTPUT_JSON_PRETTY );
 
  StaticJsonDocument<512> doc;
  DeserializationError error = deserializeJson(doc, json_stream_output);  

  if (error)
    Serial.println(F("Failed to read file, using default configuration"));
... 

@tobozo
Copy link
Owner

tobozo commented Nov 11, 2022

thanks @GYBeccaria

it should also work without storing the file content in a string

String json_string;
StringStream json_stream_output( json_string );

File file = LittleFS.open(config_file);
if( file ) { 
  serializeYml( (Stream*)&file, json_stream_output, YAMLParser::OUTPUT_JSON_PRETTY );
  file.close();

  // deserialize ...

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants