Const String variables inside a header file are not initialized on import

I have a config.h file that contains all the default values for everything that can be configured. Some things can be changed by the user and some are just constants for classes in my project. Here are some examples of variables inside the config.h file:

#include <Arduino.h>

// * Not changable in UI *

// The software version of the NodeMCU

const String Config_Version = "0.0";

// * Not changable in UI *

// The unique serial code of the NodeMCU

const String Config_SerialCode = "1";


// * Changable in UI *

// On means the speaker beeps if the temperature or humidity gets out of range

const bool Config_Speaker_On = true;

// * Changable in UI *

// The default name this sensor is associated with.

const String Config_Network_SensorName = "Senzor 1";

// * Not Changable in UI *

// The endpoint where the app sends the request to get the current temperature and humidity.

const String Config_NetworkAccessPoint_GetDataEndpoint = "/get-data";

And i have another class named ConfigurationManager that in the constructor it checks inside the spiffs if there is a Configuration file (where there are only the values that are not declared inside the class as constant and can be changed by the user) and if yes it takes those values from there and if not it sets them as the values in the config.h. The constant values not changable by the user are initialized with values from config.h in the header of the class directly.

header:

#pragma once

#include <Arduino.h>
#include <ArduinoJson.h>
#include <FS.h>

#include "Config.h"
#include "ExceptionManager.h"

class ConfigurationManager
{
  public:
    ConfigurationManager(ExceptionManager & Exceptions);
    ~ConfigurationManager() = default;

    bool SaveExists() const;
    void Load();
    void Save() const;
    void Reset();
    
    DynamicJsonDocument GetAsJSON() const;
    void SetFromJSON(const DynamicJsonDocument & ConfigurationJSON);
    bool IsConfigurationJSONValid(const DynamicJsonDocument & ConfigurationJSON) const;

    const String Version = Config_Version;
    const String SerialCode = Config_SerialCode;
    const unsigned short Package = Config_Package;
    const String UniqueUserToken = Config_UniqueUserToken.c_str();
    const String UniquePasswordToken = Config_UniquePasswordToken;

    unsigned short Pin_TemperatureSensor;
    unsigned short Pin_SwitchButton;
    unsigned short Pin_Speaker;
    unsigned short Pin_HumiditySensor;

    const unsigned int Timing_Restart = Config_Timing_Restart;
    const unsigned int Timing_SendDataToServer = Config_Timing_SendDataToServer;

    const String Memory_ConfigurationFilename = Config_Memory_ConfigurationFilename;
    const unsigned int Memory_JSONConfigurationSize = Config_Memory_JSONConfigurationSize;

    const unsigned int Tasks_ExpectedTaskNumber = Config_Tasks_ExpectedTaskNumber;

    unsigned short TemperatureSensor_Unit;
    const unsigned int TemperatureSensor_ReadingCooldown = Config_TemperatureSensor_ReadingCooldown;
    const unsigned int TemperatureSensor_AcceptableWarnings = Config_TemperatureSensor_AcceptableWarnings;

    const unsigned int SwitchButton_DebounceDelay = Config_SwitchButton_DebounceDelay;

    bool Speaker_On;

    const unsigned short (*Speaker_Alarm)[2] = Config_Speaker_Alarm;
    const unsigned short Speaker_AlarmSteps = Config_Speaker_AlarmSteps;

    String Network_SensorName;
    const unsigned short Network_DataSize = Config_Network_DataSize;
    const String NetworkAccessPoint_SSID = Config_NetworkAccessPoint_SSID;
    String NetworkAccessPoint_Password;
    const unsigned short NetworkAccessPoint_WebServerPort = Config_NetworkAccessPoint_WebServerPort;
    const String NetworkAccessPoint_WebServerIP = Config_NetworkAccessPoint_WebServerIP;
    const String NetworkAccessPoint_SubnetMask = Config_NetworkAccessPoint_SubnetMask;
    const String NetworkAccessPoint_GatewayIP = Config_NetworkAccessPoint_GatewayIP;
    const String NetworkAccessPoint_GetVersionEndpoint = Config_NetworkAccessPoint_GetVersionEndpoint;
    const String NetworkAccessPoint_GetDataEndpoint = Config_NetworkAccessPoint_GetDataEndpoint;
    const String NetworkAccessPoint_GetExceptionsEndpoint = Config_NetworkAccessPoint_GetExceptionsEndpoint;
    const String NetworkAccessPoint_GetConfigurationEndpoint = Config_NetworkAccessPoint_GetConfigurationEndpoint;
    const String NetworkAccessPoint_PostConfigurationEndpoint = Config_NetworkAccessPoint_PostConfigurationEndpoint;
    const String NetworkAccessPoint_PostAdvancedConfigurationEndpoint = Config_NetworkAccessPoint_PostAdvancedConfigurationEndpoint;
    const unsigned short NetworkAccessPoint_ExceptionByteNumber = Config_NetworkAccessPoint_ExceptionByteNumber;
    const unsigned short NetworkAccessPoint_VersionSerialByteNumber = Config_NetworkAccessPoint_VersionSerialByteNumber;
    String NetworkClient_SSID;
    String NetworkClient_Password;
    String NetworkClient_Domain;
    unsigned short NetworkClient_Port;
    String NetworkClient_Endpoint;
  private:
    ExceptionManager & _Exceptions;
};

cpp:

#include "ConfigurationManager.h"

/*-------------------------[   Public   ]-------------------------*/

ConfigurationManager::ConfigurationManager(ExceptionManager & Exceptions): _Exceptions(Exceptions)
{
  if(!SPIFFS.begin())
  {
    this -> _Exceptions.Add(Exception::Memory_Initialization);
    return;
  }

  if(this -> SaveExists())
  {
    this -> Load();
  }
  else
  {
    this -> Reset();
  }
}

bool ConfigurationManager::SaveExists() const
{
  return SPIFFS.exists(this -> Memory_ConfigurationFilename);
}

void ConfigurationManager::Load()
{
  if(!this -> SaveExists()) 
  {
    return;
  }

  File ConfigurationFile = SPIFFS.open(this -> Memory_ConfigurationFilename, "r");

  if(!ConfigurationFile)
  {
    this -> _Exceptions.Add(Exception::Memory_Open);
    return;
  }

  size_t ConfigurationSize = ConfigurationFile.size();
  std::unique_ptr <char[]> ConfigurationJSONBuffer(new char[ConfigurationSize]);
  size_t BytesRead = ConfigurationFile.readBytes(ConfigurationJSONBuffer.get(), ConfigurationSize);
  ConfigurationFile.close();

  if(BytesRead != ConfigurationSize)
  {
    this -> _Exceptions.Add(Exception::Memory_Read);
    return;
  }

  DynamicJsonDocument ConfigurationJSON(this -> Memory_JSONConfigurationSize);

  if(deserializeJson(ConfigurationJSON, ConfigurationJSONBuffer.get()) != DeserializationError::Ok)
  {
    this -> _Exceptions.Add(Exception::Memory_CorruptConfiguration);
    return;
  }

  this -> SetFromJSON(ConfigurationJSON);  
}

void ConfigurationManager::Save() const
{
  File ConfigurationFile = SPIFFS.open(this -> Memory_ConfigurationFilename, "w");

  if(!ConfigurationFile)
  {
    this -> _Exceptions.Add(Exception::Memory_Open);
    return;
  }

  if(serializeJson(this -> GetAsJSON(), ConfigurationFile) == 0)
  {
    this -> _Exceptions.Add(Exception::Memory_InvalidConfiguration);
    ConfigurationFile.close();
    return;
  }

  ConfigurationFile.close();
}

void ConfigurationManager::Reset()
{
  this -> Pin_TemperatureSensor = Config_Pin_TemperatureSensor;
  this -> Pin_SwitchButton = Config_Pin_SwitchButton;
  this -> Pin_Speaker = Config_Pin_Speaker;
  this -> Pin_HumiditySensor = Config_Pin_HumiditySensor;

  this -> TemperatureSensor_Unit = Config_TemperatureSensor_Unit;

  this -> Speaker_On = Config_Speaker_On;

  this -> Network_SensorName = Config_Network_SensorName;

  this -> NetworkAccessPoint_Password = Config_NetworkAccessPoint_Password;
  this -> NetworkClient_SSID = Config_NetworkClient_SSID;
  this -> NetworkClient_Password = Config_NetworkClient_Password;
  this -> NetworkClient_Domain = Config_NetworkClient_Domain;
  this -> NetworkClient_Port = Config_NetworkClient_Port;
  this -> NetworkClient_Endpoint = Config_NetworkClient_Endpoint;
}

DynamicJsonDocument ConfigurationManager::GetAsJSON() const
{
  DynamicJsonDocument ConfigurationJSON(this -> Memory_JSONConfigurationSize);

  ConfigurationJSON["Pin_TemperatureSensor"] = this -> Pin_TemperatureSensor;
  ConfigurationJSON["Pin_SwitchButton"] = this -> Pin_SwitchButton;
  ConfigurationJSON["Pin_Speaker"] = this -> Pin_Speaker;
  ConfigurationJSON["Pin_HumiditySensor"] = this -> Pin_HumiditySensor;

  ConfigurationJSON["TemperatureSensor_Unit"] = this -> TemperatureSensor_Unit;

  ConfigurationJSON["Speaker_On"] = this -> Speaker_On;
  
  ConfigurationJSON["Network_SensorName"] = this -> Network_SensorName;
  ConfigurationJSON["NetworkAccessPoint_Password"] = this -> NetworkAccessPoint_Password;
  ConfigurationJSON["NetworkClient_SSID"] = this -> NetworkClient_SSID;
  ConfigurationJSON["NetworkClient_Password"] = this -> NetworkClient_Password;
  ConfigurationJSON["NetworkClient_Domain"] = this -> NetworkClient_Domain;
  ConfigurationJSON["NetworkClient_Port"] = this -> NetworkClient_Port;
  ConfigurationJSON["NetworkClient_Endpoint"] = this -> NetworkClient_Endpoint;

  return ConfigurationJSON;
}

void ConfigurationManager::SetFromJSON(const DynamicJsonDocument & ConfigurationJSON)
{
  if(!this -> IsConfigurationJSONValid(ConfigurationJSON))
  {
    this -> _Exceptions.Add(Exception::Memory_CorruptConfiguration);
    return;
  }

  this -> Pin_TemperatureSensor = ConfigurationJSON["Pin_TemperatureSensor"];
  this -> Pin_SwitchButton = ConfigurationJSON["Pin_SwitchButton"];
  this -> Pin_Speaker = ConfigurationJSON["Pin_Speaker"];
  this -> Pin_HumiditySensor = ConfigurationJSON["Pin_HumiditySensor"];

  this -> TemperatureSensor_Unit = ConfigurationJSON["TemperatureSensor_Unit"];

  this -> Speaker_On = ConfigurationJSON["Speaker_On"];

  this -> Network_SensorName = ConfigurationJSON["Network_SensorName"].as<String>();
  this -> NetworkAccessPoint_Password = ConfigurationJSON["NetworkAccessPoint_Password"].as<String>();
  this -> NetworkClient_SSID = ConfigurationJSON["NetworkClient_SSID"].as<String>();
  this -> NetworkClient_Password = ConfigurationJSON["NetworkClient_Password"].as<String>();
  this -> NetworkClient_Domain = ConfigurationJSON["NetworkClient_Domain"].as<String>();
  this -> NetworkClient_Port = ConfigurationJSON["NetworkClient_Port"];
  this -> NetworkClient_Endpoint = ConfigurationJSON["NetworkClient_Endpoint"].as<String>();
}

bool ConfigurationManager::IsConfigurationJSONValid(const DynamicJsonDocument & ConfigurationJSON) const
{
  return(
    ConfigurationJSON.containsKey("Pin_TemperatureSensor") and 
    ConfigurationJSON.containsKey("Pin_SwitchButton") and 
    ConfigurationJSON.containsKey("Pin_Speaker") and 
    ConfigurationJSON.containsKey("Pin_HumiditySensor") and 
    ConfigurationJSON.containsKey("TemperatureSensor_Unit") and 
    ConfigurationJSON.containsKey("Speaker_On") and 
    ConfigurationJSON.containsKey("Network_SensorName") and 
    ConfigurationJSON.containsKey("NetworkAccessPoint_Password") and 
    ConfigurationJSON.containsKey("NetworkClient_SSID") and 
    ConfigurationJSON.containsKey("NetworkClient_Password") and 
    ConfigurationJSON.containsKey("NetworkClient_Domain") and 
    ConfigurationJSON.containsKey("NetworkClient_Port") and 
    ConfigurationJSON.containsKey("NetworkClient_Endpoint")
  );
}

The problem i face is that when i try to print the values from the config in the setup only the variables that are not of type String have values

#include "ExceptionManager.h"
#include "ConfigurationManager.h"

ExceptionManager Exceptions;
ConfigurationManager Config(Exceptions);
// after this i pass the Config instance by refference to other classes and use a .begin() method in those classes called inside the setup().

void setup()
{
  Serial.begin(115200);
  
  Serial.println("Debug: ");
  
  // Initialized at the class definition as constants (not user changable)
  Serial.println(Config.Package); // unsinged short (the value shown is correct)
  Serial.println(Config.NetworkAccessPoint_SSID); // String (the value shown is empty string)
  
  // Initialized in the class constructor either from file or config.h
  Serial.println(Config.Pin_TemperatureSensor);  // unsinged short (the value shown is correct)
  Serial.println(Config.UniqueUserToken); // String  (the value shown is empty string)
}

How do i fix the problem with the String variables in the configuration as if i make the Config instance inside the setup() everything works fine but i need it to be global so i can pass it to the other classes

I have a config.h file in my Arduino project that contains default values and constants for various configurations. Some of these values are String variables. However, when I import the header file and try to access these String variables in my sketch, they appear to be uninitialized (empty strings).

Here are some examples of the variables defined in Config.h:

#include <Arduino.h>

// Constants not changable in UI
const String Config_Version = "0.0";
const String Config_SerialCode = "1";

// Variables changable in UI
const bool Config_Speaker_On = true;
const String Config_Network_SensorName = "Senzor 1";
const String Config_NetworkAccessPoint_GetDataEndpoint = "/get-data";

I also have a class called ConfigurationManager that reads a configuration file and initializes the class variables. The ConfigurationManager constructor checks if the configuration file exists in the SPIFFS file system. If it exists, it reads the values from the file; otherwise, it sets the values from Config.h as defaults. The ConfigurationManager class has String variables that correspond to the ones defined in Config.h.

However, when I try to print these variables in the setup() function, the String variables show up as empty strings. Other non-String variables are initialized correctly.

#include "ExceptionManager.h"
#include "ConfigurationManager.h"

ExceptionManager Exceptions;
ConfigurationManager Config(Exceptions);

void setup() {
  Serial.begin(115200);
  
  Serial.println("Debug:");
  
  // Initialized at the class definition as constants (not user changable)
  Serial.println(Config.Package); // unsigned short (correct value displayed)
  Serial.println(Config.NetworkAccessPoint_SSID); // String (empty string displayed)
  
  // Initialized in the class constructor either from file or config.h
  Serial.println(Config.Pin_TemperatureSensor); // unsigned short (correct value displayed)
  Serial.println(Config.UniqueUserToken); // String (empty string displayed)
}

I need to access these String variables globally in my project, so creating the Config`instance inside the setup() function is not an option even thou that initialized the String variables as expected.

Can anyone help me understand why the String variables are not initialized properly when using a global instance of the ConfigurationManager class? Is there a way to fix this issue?

ConfigurationManager.h:

#pragma once

#include <Arduino.h>
#include <ArduinoJson.h>
#include <FS.h>

#include "Config.h"
#include "ExceptionManager.h"

class ConfigurationManager
{
  public:
    ConfigurationManager(ExceptionManager & Exceptions);
    ~ConfigurationManager() = default;

    bool SaveExists() const;
    void Load();
    void Save() const;
    void Reset();
    
    DynamicJsonDocument GetAsJSON() const;
    void SetFromJSON(const DynamicJsonDocument & ConfigurationJSON);
    bool IsConfigurationJSONValid(const DynamicJsonDocument & ConfigurationJSON) const;

    const String Version = Config_Version;
    const String SerialCode = Config_SerialCode;
    const unsigned short Package = Config_Package;
    const String UniqueUserToken = Config_UniqueUserToken.c_str();
    const String UniquePasswordToken = Config_UniquePasswordToken;

    unsigned short Pin_TemperatureSensor;
    unsigned short Pin_SwitchButton;
    unsigned short Pin_Speaker;
    unsigned short Pin_HumiditySensor;

    const unsigned int Timing_Restart = Config_Timing_Restart;
    const unsigned int Timing_SendDataToServer = Config_Timing_SendDataToServer;

    const String Memory_ConfigurationFilename = Config_Memory_ConfigurationFilename;
    const unsigned int Memory_JSONConfigurationSize = Config_Memory_JSONConfigurationSize;

    const unsigned int Tasks_ExpectedTaskNumber = Config_Tasks_ExpectedTaskNumber;

    unsigned short TemperatureSensor_Unit;
    const unsigned int TemperatureSensor_ReadingCooldown = Config_TemperatureSensor_ReadingCooldown;
    const unsigned int TemperatureSensor_AcceptableWarnings = Config_TemperatureSensor_AcceptableWarnings;

    const unsigned int SwitchButton_DebounceDelay = Config_SwitchButton_DebounceDelay;

    bool Speaker_On;

    const unsigned short (*Speaker_Alarm)[2] = Config_Speaker_Alarm;
    const unsigned short Speaker_AlarmSteps = Config_Speaker_AlarmSteps;

    String Network_SensorName;
    const unsigned short Network_DataSize = Config_Network_DataSize;
    const String NetworkAccessPoint_SSID = Config_NetworkAccessPoint_SSID;
    String NetworkAccessPoint_Password;
    const unsigned short NetworkAccessPoint_WebServerPort = Config_NetworkAccessPoint_WebServerPort;
    const String NetworkAccessPoint_WebServerIP = Config_NetworkAccessPoint_WebServerIP;
    const String NetworkAccessPoint_SubnetMask = Config_NetworkAccessPoint_SubnetMask;
    const String NetworkAccessPoint_GatewayIP = Config_NetworkAccessPoint_GatewayIP;
    const String NetworkAccessPoint_GetVersionEndpoint = Config_NetworkAccessPoint_GetVersionEndpoint;
    const String NetworkAccessPoint_GetDataEndpoint = Config_NetworkAccessPoint_GetDataEndpoint;
    const String NetworkAccessPoint_GetExceptionsEndpoint = Config_NetworkAccessPoint_GetExceptionsEndpoint;
    const String NetworkAccessPoint_GetConfigurationEndpoint = Config_NetworkAccessPoint_GetConfigurationEndpoint;
    const String NetworkAccessPoint_PostConfigurationEndpoint = Config_NetworkAccessPoint_PostConfigurationEndpoint;
    const String NetworkAccessPoint_PostAdvancedConfigurationEndpoint = Config_NetworkAccessPoint_PostAdvancedConfigurationEndpoint;
    const unsigned short NetworkAccessPoint_ExceptionByteNumber = Config_NetworkAccessPoint_ExceptionByteNumber;
    const unsigned short NetworkAccessPoint_VersionSerialByteNumber = Config_NetworkAccessPoint_VersionSerialByteNumber;
    String NetworkClient_SSID;
    String NetworkClient_Password;
    String NetworkClient_Domain;
    unsigned short NetworkClient_Port;
    String NetworkClient_Endpoint;
  private:
    ExceptionManager & _Exceptions;
};

ConfigurationManager.cpp:

#include "ConfigurationManager.h"

/*-------------------------[   Public   ]-------------------------*/

ConfigurationManager::ConfigurationManager(ExceptionManager & Exceptions): _Exceptions(Exceptions)
{
  if(!SPIFFS.begin())
  {
    this -> _Exceptions.Add(Exception::Memory_Initialization);
    return;
  }

  if(this -> SaveExists())
  {
    this -> Load();
  }
  else
  {
    this -> Reset();
  }
}

bool ConfigurationManager::SaveExists() const
{
  return SPIFFS.exists(this -> Memory_ConfigurationFilename);
}

void ConfigurationManager::Load()
{
  if(!this -> SaveExists()) 
  {
    return;
  }

  File ConfigurationFile = SPIFFS.open(this -> Memory_ConfigurationFilename, "r");

  if(!ConfigurationFile)
  {
    this -> _Exceptions.Add(Exception::Memory_Open);
    return;
  }

  size_t ConfigurationSize = ConfigurationFile.size();
  std::unique_ptr <char[]> ConfigurationJSONBuffer(new char[ConfigurationSize]);
  size_t BytesRead = ConfigurationFile.readBytes(ConfigurationJSONBuffer.get(), ConfigurationSize);
  ConfigurationFile.close();

  if(BytesRead != ConfigurationSize)
  {
    this -> _Exceptions.Add(Exception::Memory_Read);
    return;
  }

  DynamicJsonDocument ConfigurationJSON(this -> Memory_JSONConfigurationSize);

  if(deserializeJson(ConfigurationJSON, ConfigurationJSONBuffer.get()) != DeserializationError::Ok)
  {
    this -> _Exceptions.Add(Exception::Memory_CorruptConfiguration);
    return;
  }

  this -> SetFromJSON(ConfigurationJSON);  
}

void ConfigurationManager::Save() const
{
  File ConfigurationFile = SPIFFS.open(this -> Memory_ConfigurationFilename, "w");

  if(!ConfigurationFile)
  {
    this -> _Exceptions.Add(Exception::Memory_Open);
    return;
  }

  if(serializeJson(this -> GetAsJSON(), ConfigurationFile) == 0)
  {
    this -> _Exceptions.Add(Exception::Memory_InvalidConfiguration);
    ConfigurationFile.close();
    return;
  }

  ConfigurationFile.close();
}

void ConfigurationManager::Reset()
{
  this -> Pin_TemperatureSensor = Config_Pin_TemperatureSensor;
  this -> Pin_SwitchButton = Config_Pin_SwitchButton;
  this -> Pin_Speaker = Config_Pin_Speaker;
  this -> Pin_HumiditySensor = Config_Pin_HumiditySensor;

  this -> TemperatureSensor_Unit = Config_TemperatureSensor_Unit;

  this -> Speaker_On = Config_Speaker_On;

  this -> Network_SensorName = Config_Network_SensorName;

  this -> NetworkAccessPoint_Password = Config_NetworkAccessPoint_Password;
  this -> NetworkClient_SSID = Config_NetworkClient_SSID;
  this -> NetworkClient_Password = Config_NetworkClient_Password;
  this -> NetworkClient_Domain = Config_NetworkClient_Domain;
  this -> NetworkClient_Port = Config_NetworkClient_Port;
  this -> NetworkClient_Endpoint = Config_NetworkClient_Endpoint;
}

DynamicJsonDocument ConfigurationManager::GetAsJSON() const
{
  DynamicJsonDocument ConfigurationJSON(this -> Memory_JSONConfigurationSize);

  ConfigurationJSON["Pin_TemperatureSensor"] = this -> Pin_TemperatureSensor;
  ConfigurationJSON["Pin_SwitchButton"] = this -> Pin_SwitchButton;
  ConfigurationJSON["Pin_Speaker"] = this -> Pin_Speaker;
  ConfigurationJSON["Pin_HumiditySensor"] = this -> Pin_HumiditySensor;

  ConfigurationJSON["TemperatureSensor_Unit"] = this -> TemperatureSensor_Unit;

  ConfigurationJSON["Speaker_On"] = this -> Speaker_On;
  
  ConfigurationJSON["Network_SensorName"] = this -> Network_SensorName;
  ConfigurationJSON["NetworkAccessPoint_Password"] = this -> NetworkAccessPoint_Password;
  ConfigurationJSON["NetworkClient_SSID"] = this -> NetworkClient_SSID;
  ConfigurationJSON["NetworkClient_Password"] = this -> NetworkClient_Password;
  ConfigurationJSON["NetworkClient_Domain"] = this -> NetworkClient_Domain;
  ConfigurationJSON["NetworkClient_Port"] = this -> NetworkClient_Port;
  ConfigurationJSON["NetworkClient_Endpoint"] = this -> NetworkClient_Endpoint;

  return ConfigurationJSON;
}

void ConfigurationManager::SetFromJSON(const DynamicJsonDocument & ConfigurationJSON)
{
  if(!this -> IsConfigurationJSONValid(ConfigurationJSON))
  {
    this -> _Exceptions.Add(Exception::Memory_CorruptConfiguration);
    return;
  }

  this -> Pin_TemperatureSensor = ConfigurationJSON["Pin_TemperatureSensor"];
  this -> Pin_SwitchButton = ConfigurationJSON["Pin_SwitchButton"];
  this -> Pin_Speaker = ConfigurationJSON["Pin_Speaker"];
  this -> Pin_HumiditySensor = ConfigurationJSON["Pin_HumiditySensor"];

  this -> TemperatureSensor_Unit = ConfigurationJSON["TemperatureSensor_Unit"];

  this -> Speaker_On = ConfigurationJSON["Speaker_On"];

  this -> Network_SensorName = ConfigurationJSON["Network_SensorName"].as<String>();
  this -> NetworkAccessPoint_Password = ConfigurationJSON["NetworkAccessPoint_Password"].as<String>();
  this -> NetworkClient_SSID = ConfigurationJSON["NetworkClient_SSID"].as<String>();
  this -> NetworkClient_Password = ConfigurationJSON["NetworkClient_Password"].as<String>();
  this -> NetworkClient_Domain = ConfigurationJSON["NetworkClient_Domain"].as<String>();
  this -> NetworkClient_Port = ConfigurationJSON["NetworkClient_Port"];
  this -> NetworkClient_Endpoint = ConfigurationJSON["NetworkClient_Endpoint"].as<String>();
}

bool ConfigurationManager::IsConfigurationJSONValid(const DynamicJsonDocument & ConfigurationJSON) const
{
  return(
    ConfigurationJSON.containsKey("Pin_TemperatureSensor") and 
    ConfigurationJSON.containsKey("Pin_SwitchButton") and 
    ConfigurationJSON.containsKey("Pin_Speaker") and 
    ConfigurationJSON.containsKey("Pin_HumiditySensor") and 
    ConfigurationJSON.containsKey("TemperatureSensor_Unit") and 
    ConfigurationJSON.containsKey("Speaker_On") and 
    ConfigurationJSON.containsKey("Network_SensorName") and 
    ConfigurationJSON.containsKey("NetworkAccessPoint_Password") and 
    ConfigurationJSON.containsKey("NetworkClient_SSID") and 
    ConfigurationJSON.containsKey("NetworkClient_Password") and 
    ConfigurationJSON.containsKey("NetworkClient_Domain") and 
    ConfigurationJSON.containsKey("NetworkClient_Port") and 
    ConfigurationJSON.containsKey("NetworkClient_Endpoint")
  );
}

Thank you in advance for your assistance.

@dexter1111, please do not cross-post. Threads merged.

String are instances of a class and you don't control the order of initialisation. They might be initialized after your ConfigurationManager instance as it's a global variable

➜ you should not rely on the constructor to get a complex initialisation done. have a begin() method where you move all the stuff you were doing in the constructor and call that in setup. At that point you are sure that all initialisation have been completed

also I would not have variables defined in a .h. You should only declare them extern in the .h and have a .cpp where you define them. This way you'll be sure to instantiate those only once.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.