
bool setConfig(char* param, char* value) {
  // sets the corresponding config variable for 'param' to new value
  // does not trigger saving to flash
  // does not distinguish between config and config2 as this is only split on flash and web-interface

  Serial.print("setConfig - '");
  Serial.print(param);
  Serial.print("' to '");
  Serial.print(value);
  Serial.println("'");

  //confdata
  if ( strcmp(param, "devName") == 0 ) {
    strlcpy(deviceName, value, 31);
    //    deviceName[30] = '\0';
  }
  else if ( strcmp(param, "httpUser") == 0 ) {
    strlcpy(http_user, value, 31);
  }
  else if ( strcmp(param, "httpPass") == 0 ) {
    strlcpy(http_pass, value, 31);
  }
  else if ( strcmp(param, "mqttHost") == 0 ) {
    strlcpy(mqtt_server, value, 41);
    //mqtt_server[40] = '\0';
  }
  else if ( strcmp(param, "mqttPort") == 0 ) {
    mqtt_port = atoi(value);
  }
  else if ( strcmp(param, "mqttUser") == 0 ) {
    strlcpy(mqtt_user, value, 31);
  }
  else if ( strcmp(param, "mqttPass") == 0 ) {
    strlcpy(mqtt_pass, value, 31);
  }
  else if ( strcmp(param, "inTop") == 0 ) {
    strlcpy(mqtt_topic_in, value, 51);
  }
  else if ( strcmp(param, "outTop") == 0 ) {
    strlcpy(mqtt_topic_out, value, 51);
  }
  else if ( strcmp(param, "outRet") == 0 ) {
    if (atoi(value) == 1) mqtt_outRetain = true;
    else mqtt_outRetain = false;
  }
  else if ( strcmp(param, "willTop") == 0 ) {
    strlcpy(mqtt_willTopic, value, 51);
  }
  else if ( strcmp(param, "willQos") == 0 ) {
    int tmpval = atoi(value);
    if (tmpval >= 0 && tmpval <= 2) mqtt_willQos = tmpval;
  }
  else if ( strcmp(param, "willRet") == 0 ) {
    if (atoi(value) == 1) mqtt_willRetain = true;
    else mqtt_willRetain = false;
  }
  else if ( strcmp(param, "willMsg") == 0 ) {
    strlcpy(mqtt_willMsg, value, 31);
  }
  else if ( strcmp(param, "domOutTop") == 0 ) {
    strlcpy(domoticz_out_topic, value, 51);
  }
  else if ( strcmp(param, "allOnOffTop") == 0 ) {
    strlcpy(mqtt_allOnOffTopic, value, 51);
  }

  //confdata2
  else if ( strcmp(param, "btnRet") == 0 ) {
    if (atoi(value) == 1) mqtt_btnRetain = true;
    else mqtt_btnRetain = false;
  }
  else if ( strcmp(param, "top1") == 0 ) {
    strlcpy(mqtt_topic_out_1, value, 51);
  }
  else if ( strcmp(param, "top2") == 0 ) {
    strlcpy(mqtt_topic_out_2, value, 51);
  }
  else if ( strcmp(param, "top3") == 0 ) {
    strlcpy(mqtt_topic_out_3, value, 51);
  }
  else if ( strcmp(param, "topHld1") == 0 ) {
    strlcpy(mqtt_topic_out_hold_1, value, 51);
  }
  else if ( strcmp(param, "topHld2") == 0 ) {
    strlcpy(mqtt_topic_out_hold_2, value, 51);
  }
  else if ( strcmp(param, "topHld3") == 0 ) {
    strlcpy(mqtt_topic_out_hold_3, value, 51);
  }
  else if ( strcmp(param, "pld1") == 0 ) {
    strlcpy(mqtt_payload_out_1, value, 31);
  }
  else if ( strcmp(param, "pld2") == 0 ) {
    strlcpy(mqtt_payload_out_2, value, 31);
  }
  else if ( strcmp(param, "pld3") == 0 ) {
    strlcpy(mqtt_payload_out_3, value, 31);
  }
  else if ( strcmp(param, "pldHld1") == 0 ) {
    strlcpy(mqtt_payload_out_hold_1, value, 31);
  }
  else if ( strcmp(param, "pldHld2") == 0 ) {
    strlcpy(mqtt_payload_out_hold_2, value, 31);
  }
  else if ( strcmp(param, "pldHld3") == 0 ) {
    strlcpy(mqtt_payload_out_hold_3, value, 31);
  }
  else if ( strcmp(param, "domIdx1") == 0 ) {
    domoticzIdx[0] = atoi(value);
  }
  else if ( strcmp(param, "domIdx2") == 0 ) {
    domoticzIdx[1] = atoi(value);
  }
  else if ( strcmp(param, "domIdx3") == 0 ) {
    domoticzIdx[2] = atoi(value);
  }
  else if ( strcmp(param, "hld1ToRel") == 0 ) {
    hldToRel[0] = atoi(value);
  }
  else if ( strcmp(param, "hld2ToRel") == 0 ) {
    hldToRel[1] = atoi(value);
  }
  else if ( strcmp(param, "hld3ToRel") == 0 ) {
    hldToRel[2] = atoi(value);
  }

  // confdatahw
  else if ( strcmp(param, "debtime") == 0 ) {
    debounceTime = atoi(value);
  }
  else if ( strcmp(param, "hldtime") == 0 ) {
    buttonHoldTime = atoi(value);
  }
  else if ( strcmp(param, "ioRel1") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) relais_pins[0] = io;
    else Serial.println("ioRel1 - false IO number, not set");
  }
  else if ( strcmp(param, "ioRel2") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) relais_pins[1] = io;
    else Serial.println("ioRel2 - false IO number, not set");
  }
  else if ( strcmp(param, "ioRel3") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) relais_pins[2] = io;
    else Serial.println("ioRel3 - false IO number, not set");
  }
  else if ( strcmp(param, "ioBtn1") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) buttons_pins[0] = io;
    else Serial.println("ioBtn1 - false IO number, not set");
  }
  else if ( strcmp(param, "ioBtn2") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) buttons_pins[1] = io;
    else Serial.println("ioBtn2 - false IO number, not set");
  }
  else if ( strcmp(param, "ioBtn3") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) buttons_pins[2] = io;
    else Serial.println("ioBtn3 - false IO number, not set");
  }

  else if ( strcmp(param, "ioLed1") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) leds_pins[0] = io;
    else Serial.println("ioLed1 - false IO number, not set");
  }
  else if ( strcmp(param, "ioLed2") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) leds_pins[1] = io;
    else Serial.println("ioLed2 - false IO number, not set");
  }
  else if ( strcmp(param, "ioLed3") == 0 ) {
    int io = atoi(value);
    if ( io == 0 || io == 2 || io == 4 || io == 5 || io == 12 || io == 13 || io == 14 ) leds_pins[2] = io;
    else Serial.println("ioLed3 - false IO number, not set");
  }
  else if ( strcmp(param, "invRel1") == 0 ) {
    if (atoi(value) == 1) relais_invert[0] = true;
    else relais_invert[0] = false;
  }
  else if ( strcmp(param, "invRel2") == 0 ) {
    if (atoi(value) == 1) relais_invert[1] = true;
    else relais_invert[1] = false;
  }
  else if ( strcmp(param, "invRel3") == 0 ) {
    if (atoi(value) == 1) relais_invert[2] = true;
    else relais_invert[2] = false;
  }
  else if ( strcmp(param, "invBtn1") == 0 ) {
    if (atoi(value) == 1) button_invert[0] = true;
    else button_invert[0] = false;
  }
  else if ( strcmp(param, "invBtn2") == 0 ) {
    if (atoi(value) == 1) button_invert[1] = true;
    else button_invert[1] = false;
  }
  else if ( strcmp(param, "invBtn3") == 0 ) {
    if (atoi(value) == 1) button_invert[2] = true;
    else button_invert[2] = false;
  }
  else if ( strcmp(param, "invLed1") == 0 ) {
    if (atoi(value) == 1) led_invert[0] = true;
    else led_invert[0] = false;
  }
  else if ( strcmp(param, "invLed2") == 0 ) {
    if (atoi(value) == 1) led_invert[1] = true;
    else led_invert[1] = false;
  }
  else if ( strcmp(param, "invLed3") == 0 ) {
    if (atoi(value) == 1) led_invert[2] = true;
    else led_invert[2] = false;
  }
  else if ( strcmp(param, "puls1") == 0 ) {
    relais_impulse[0] = atoi(value);
  }
  else if ( strcmp(param, "puls2") == 0 ) {
    relais_impulse[1] = atoi(value);
  }
  else if ( strcmp(param, "puls3") == 0 ) {
    relais_impulse[2] = atoi(value);
  }
  else if ( strcmp(param, "enaRel1") == 0 ) {
    if (atoi(value) == 1) relais_enabled[0] = true;
    else relais_enabled[0] = false;
  }
  else if ( strcmp(param, "enaRel2") == 0 ) {
    if (atoi(value) == 1) relais_enabled[1] = true;
    else relais_enabled[1] = false;
  }
  else if ( strcmp(param, "enaRel3") == 0 ) {
    if (atoi(value) == 1) relais_enabled[2] = true;
    else relais_enabled[2] = false;
  }
  else if ( strcmp(param, "enaBtn1") == 0 ) {
    if (atoi(value) == 1) button_enabled[0] = true;
    else button_enabled[0] = false;
  }
  else if ( strcmp(param, "enaBtn2") == 0 ) {
    if (atoi(value) == 1) button_enabled[1] = true;
    else button_enabled[1] = false;
  }
  else if ( strcmp(param, "enaBtn3") == 0 ) {
    if (atoi(value) == 1) button_enabled[2] = true;
    else button_enabled[2] = false;
  }
  else if ( strcmp(param, "enaLed1") == 0 ) {
    if (atoi(value) == 1) led_enabled[0] = true;
    else led_enabled[0] = false;
  }
  else if ( strcmp(param, "enaLed2") == 0 ) {
    if (atoi(value) == 1) led_enabled[1] = true;
    else led_enabled[1] = false;
  }
  else if ( strcmp(param, "enaLed3") == 0 ) {
    if (atoi(value) == 1) led_enabled[2] = true;
    else led_enabled[2] = false;
  }
}

void printConfig() {
  // prints current config vars to serial
  Serial.println("\nconfdata:");
  Serial.print("devName: ");
  Serial.println(deviceName);
  Serial.print("httpUser: ");
  Serial.println(http_user);
  Serial.print("httpPass: ");
  Serial.println(http_pass);
  Serial.print("mqttHost: ");
  Serial.println(mqtt_server);
  Serial.print("mqttPort: ");
  Serial.println(mqtt_port);
  Serial.print("mqttUser: ");
  Serial.println(mqtt_user);
  Serial.print("mqttPass: ");
  Serial.println(mqtt_pass);
  Serial.print("inTop: ");
  Serial.println(mqtt_topic_in);
  Serial.print("outTop: ");
  Serial.println(mqtt_topic_out);
  Serial.print("outRet: ");
  Serial.println(mqtt_outRetain);
  Serial.print("willTop: ");
  Serial.println(mqtt_willTopic);
  Serial.print("willQos: ");
  Serial.println(mqtt_willQos);
  Serial.print("willRet: ");
  Serial.println(mqtt_willRetain);
  Serial.print("willMsg: ");
  Serial.println(mqtt_willMsg);
  Serial.print("domOutTop: ");
  Serial.println(domoticz_out_topic);
  Serial.print("allOnOffTop: ");
  Serial.println(mqtt_allOnOffTopic);
  Serial.println();
}
void printConfig2() {
  Serial.println("\nconfdata2:");
  Serial.print("btnRet: ");
  Serial.println(mqtt_btnRetain);
  Serial.print("top1: ");
  Serial.println(mqtt_topic_out_1);
  Serial.print("top2: ");
  Serial.println(mqtt_topic_out_2);
  Serial.print("top3: ");
  Serial.println(mqtt_topic_out_3);
  Serial.print("pld1: ");
  Serial.println(mqtt_payload_out_1);
  Serial.print("pld2: ");
  Serial.println(mqtt_payload_out_2);
  Serial.print("pld3: ");
  Serial.println(mqtt_payload_out_3);
  Serial.print("topHld1: ");
  Serial.println(mqtt_topic_out_hold_1);
  Serial.print("topHld2: ");
  Serial.println(mqtt_topic_out_hold_2);
  Serial.print("topHld3: ");
  Serial.println(mqtt_topic_out_hold_3);
  Serial.print("pldHld1: ");
  Serial.println(mqtt_payload_out_hold_1);
  Serial.print("pldHld2: ");
  Serial.println(mqtt_payload_out_hold_2);
  Serial.print("pldHld3: ");
  Serial.println(mqtt_payload_out_hold_3);
  Serial.print("domIdx1: ");
  Serial.println(domoticzIdx[0]);
  Serial.print("domIdx2: ");
  Serial.println(domoticzIdx[1]);
  Serial.print("domIdx3: ");
  Serial.println(domoticzIdx[2]);
  Serial.print("hld1ToRel: ");
  Serial.println(hldToRel[0]);
  Serial.print("hld2ToRel: ");
  Serial.println(hldToRel[1]);
  Serial.print("hld3ToRel: ");
  Serial.println(hldToRel[2]);
  Serial.println();
}
void printConfigHw() {
  Serial.println("\nconfdatahw:");
  Serial.print("debtime: ");
  Serial.println(debounceTime);
  Serial.print("holdtime: ");
  Serial.println(buttonHoldTime);
  Serial.print("enaRel1: ");
  Serial.println(relais_enabled[0]);
  Serial.print("enaRel2: ");
  Serial.println(relais_enabled[1]);
  Serial.print("enaRel3: ");
  Serial.println(relais_enabled[2]);
  Serial.print("enaBtn1: ");
  Serial.println(button_enabled[0]);
  Serial.print("enaBtn2: ");
  Serial.println(button_enabled[1]);
  Serial.print("enaBtn3: ");
  Serial.println(button_enabled[2]);
  Serial.print("enaLed1: ");
  Serial.println(led_enabled[0]);
  Serial.print("enaLed2: ");
  Serial.println(led_enabled[1]);
  Serial.print("enaLed3: ");
  Serial.println(led_enabled[2]);
  Serial.print("ioRel1: ");
  Serial.println(relais_pins[0]);
  Serial.print("ioRel2: ");
  Serial.println(relais_pins[1]);
  Serial.print("ioRel3: ");
  Serial.println(relais_pins[2]);
  Serial.print("ioBtn1: ");
  Serial.println(buttons_pins[0]);
  Serial.print("ioBtn2: ");
  Serial.println(buttons_pins[1]);
  Serial.print("ioBtn3: ");
  Serial.println(buttons_pins[2]);
  Serial.print("ioLed1: ");
  Serial.println(leds_pins[0]);
  Serial.print("ioLed2: ");
  Serial.println(leds_pins[1]);
  Serial.print("ioLed3: ");
  Serial.println(leds_pins[2]);
  Serial.print("invRel1: ");
  Serial.println(relais_invert[0]);
  Serial.print("invRel2: ");
  Serial.println(relais_invert[1]);
  Serial.print("invRel3: ");
  Serial.println(relais_invert[2]);
  Serial.print("invBtn1: ");
  Serial.println(button_invert[0]);
  Serial.print("invBtn2: ");
  Serial.println(button_invert[1]);
  Serial.print("invBtn3: ");
  Serial.println(button_invert[2]);
  Serial.print("invLed1: ");
  Serial.println(led_invert[0]);
  Serial.print("invLed2: ");
  Serial.println(led_invert[1]);
  Serial.print("invLed3: ");
  Serial.println(led_invert[2]);
  Serial.print("puls1: ");
  Serial.println(relais_impulse[0]);
  Serial.print("puls2: ");
  Serial.println(relais_impulse[1]);
  Serial.print("puls3: ");
  Serial.println(relais_impulse[2]);
  Serial.println();
}

bool loadConfig() { // loadConfig 1
  if (SPIFFS.exists("/conf.json")) {
    File configFile = SPIFFS.open("/conf.json", "r");
    if (!configFile) {
      Serial.println("ERR: Failed to open file /conf.json");
      return false;
    }
    else {
      Serial.println("file /conf.json opened");
      size_t size = configFile.size();

      Serial.print("file size: ");
      Serial.println(size);

      //      Serial.println("file content:");
      //
      //      while (configFile.available()) {
      //        //Lets read line by line from the file
      //        String line = configFile.readStringUntil('\n');
      //        Serial.println(line);
      //      }
      //      Serial.println();

      if (size > 1000) {
        Serial.println("Config file size is too large");
        return false;
      }

      Serial.println("allocate buffer");
      // Allocate a buffer to store contents of the file.
      std::unique_ptr<char[]> buf(new char[size]);

      Serial.println("read file bytes to buffer");
      // We don't use String here because ArduinoJson library requires the input
      // buffer to be mutable. If you don't use ArduinoJson, you may as well
      // use configFile.readString instead.
      configFile.readBytes(buf.get(), size);

      StaticJsonBuffer<1050> jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(buf.get());

      if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
      }

      strlcpy(deviceName, json["devName"] | "", 31);
      strlcpy(http_user, json["httpUser"] | "", 31);
      strlcpy(http_pass, json["httpPass"] | "", 31);
      strlcpy(mqtt_server, json["mqttHost"] | "", 41);
      mqtt_port = atoi(json["mqttPort"] | "");
      strlcpy(mqtt_user, json["mqttUser"] | "", 31);
      strlcpy(mqtt_pass, json["mqttPass"] | "", 31);
      strlcpy(mqtt_topic_in, json["inTop"] | "", 51);
      strlcpy(mqtt_topic_out, json["outTop"] | "", 51);

      if (atoi(json["outRet"] | "") == 1) mqtt_outRetain = true;
      else mqtt_outRetain = false;

      strlcpy(mqtt_willTopic, json["willTop"] | "", 51);
      mqtt_willQos = atoi(json["willQos"] | "0");

      if (atoi(json["willRet"] | "") == 1) mqtt_willRetain = true;
      else mqtt_willRetain = false;

      strlcpy(mqtt_willMsg, json["willMsg"] | "", 31);
      strlcpy(domoticz_out_topic, json["domOutTop"] | "", 51);
      strlcpy(mqtt_allOnOffTopic, json["allOnOffTop"] | "", 51);

      Serial.println("Loaded config values:");
      printConfig();
      return true;
    }
    configFile.close();
  }
  else {
    Serial.println("file /config.json file does not exist");
    return false;
  }


} // loadConfig 1

bool loadConfig2() {
  if (SPIFFS.exists("/conf2.json")) {
    File configFile = SPIFFS.open("/conf2.json", "r");
    if (!configFile) {
      Serial.println("ERR: Failed to open file /conf2.json");
      return false;
    }
    else {
      Serial.println("file /conf2.json opened");
      size_t size = configFile.size();
      Serial.print("file size: ");
      Serial.println(size);
      if (size > 1000) {
        Serial.println("Config file size is too large");
        return false;
      }

      // Allocate a buffer to store contents of the file.
      std::unique_ptr<char[]> buf(new char[size]);

      // We don't use String here because ArduinoJson library requires the input
      // buffer to be mutable. If you don't use ArduinoJson, you may as well
      // use configFile.readString instead.
      configFile.readBytes(buf.get(), size);

      StaticJsonBuffer<1050> jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(buf.get());

      if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
      }

      if (atoi(json["btnRet"] | "") == 1) mqtt_btnRetain = true;
      else mqtt_btnRetain = false;

      strlcpy(mqtt_topic_out_1, json["top1"] | "", 51);
      strlcpy(mqtt_topic_out_2, json["top2"] | "", 51);
      strlcpy(mqtt_topic_out_3, json["top3"] | "", 51);
      strlcpy(mqtt_topic_out_hold_1, json["topHld1"] | "", 51);
      strlcpy(mqtt_topic_out_hold_2, json["topHld2"] | "", 51);
      strlcpy(mqtt_topic_out_hold_3, json["topHld3"] | "", 51);
      strlcpy(mqtt_payload_out_1, json["pld1"] | "", 31);
      strlcpy(mqtt_payload_out_2, json["pld2"] | "", 31);
      strlcpy(mqtt_payload_out_3, json["pld3"] | "", 31);
      strlcpy(mqtt_payload_out_hold_1, json["pldHld1"] | "", 31);
      strlcpy(mqtt_payload_out_hold_2, json["pldHld2"] | "", 31);
      strlcpy(mqtt_payload_out_hold_3, json["pldHld3"] | "", 31);
      domoticzIdx[0] = atoi(json["domIdx1"] | "");
      domoticzIdx[1] = atoi(json["domIdx2"] | "");
      domoticzIdx[2] = atoi(json["domIdx3"] | "");

      hldToRel[0] = atoi(json["hld1ToRel"] | "");
      hldToRel[1] = atoi(json["hld2ToRel"] | "");
      hldToRel[2] = atoi(json["hld3ToRel"] | "");

      Serial.println("Loaded config values:");
      printConfig2();
      return true;
    }
  }
  else {
    Serial.println("file /conf2.json file does not exist");
    return false;
  }
} //loadConfig2

bool loadConfigHw() {
  if (SPIFFS.exists("/confhw.json")) {
    File configFile = SPIFFS.open("/confhw.json", "r");
    if (!configFile) {
      Serial.println("ERR: Failed to open file /confhw.json");
      return false;
    }
    else {
      Serial.println("file /confhw.json opened");
      size_t size = configFile.size();
      Serial.print("file size: ");
      Serial.println(size);
      if (size > 1000) {
        Serial.println("Config file size is too large");
        return false;
      }

      // Allocate a buffer to store contents of the file.
      std::unique_ptr<char[]> buf(new char[size]);

      // We don't use String here because ArduinoJson library requires the input
      // buffer to be mutable. If you don't use ArduinoJson, you may as well
      // use configFile.readString instead.
      configFile.readBytes(buf.get(), size);

      StaticJsonBuffer<1050> jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(buf.get());

      if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
      }

      debounceTime = atoi(json["debtime"] | "");
      buttonHoldTime = atoi(json["hldtime"] | "");
      relais_pins[0] = atoi(json["ioRel1"] | "");
      relais_pins[1] = atoi(json["ioRel2"] | "");
      relais_pins[2] = atoi(json["ioRel3"] | "");
      buttons_pins[0] = atoi(json["ioBtn1"] | "");
      buttons_pins[1] = atoi(json["ioBtn2"] | "");
      buttons_pins[2] = atoi(json["ioBtn3"] | "");
      leds_pins[0] = atoi(json["ioLed1"] | "");
      leds_pins[1] = atoi(json["ioLed2"] | "");
      leds_pins[2] = atoi(json["ioLed3"] | "");

      if (atoi(json["enaRel1"] | "") == 1) relais_enabled[0] = true;
      else relais_enabled[0] = false;
      if (atoi(json["enaRel2"] | "") == 1) relais_enabled[1] = true;
      else relais_enabled[1] = false;
      if (atoi(json["enaRel3"] | "") == 1) relais_enabled[2] = true;
      else relais_enabled[2] = false;

      if (atoi(json["enaBtn1"] | "") == 1) button_enabled[0] = true;
      else button_enabled[0] = false;
      if (atoi(json["enaBtn2"] | "") == 1) button_enabled[1] = true;
      else button_enabled[1] = false;
      if (atoi(json["enaBtn3"] | "") == 1) button_enabled[2] = true;
      else button_enabled[2] = false;

      if (atoi(json["enaLed1"] | "") == 1) led_enabled[0] = true;
      else led_enabled[0] = false;
      if (atoi(json["enaLed2"] | "") == 1) led_enabled[1] = true;
      else led_enabled[1] = false;
      if (atoi(json["enaLed3"] | "") == 1) led_enabled[2] = true;
      else led_enabled[2] = false;

      if (atoi(json["invRel1"] | "") == 1) relais_invert[0] = true;
      else relais_invert[0] = false;
      if (atoi(json["invRel2"] | "") == 1) relais_invert[1] = true;
      else relais_invert[1] = false;
      if (atoi(json["invRel3"] | "") == 1) relais_invert[2] = true;
      else relais_invert[2] = false;

      if (atoi(json["invBtn1"] | "") == 1) button_invert[0] = true;
      else button_invert[0] = false;
      if (atoi(json["invBtn2"] | "") == 1) button_invert[1] = true;
      else button_invert[1] = false;
      if (atoi(json["invBtn3"] | "") == 1) button_invert[2] = true;
      else button_invert[2] = false;

      if (atoi(json["invLed1"] | "") == 1) led_invert[0] = true;
      else led_invert[0] = false;
      if (atoi(json["invLed2"] | "") == 1) led_invert[1] = true;
      else led_invert[1] = false;
      if (atoi(json["invLed3"] | "") == 1) led_invert[2] = true;
      else led_invert[2] = false;

      relais_impulse[0] = atoi(json["puls1"] | "");
      relais_impulse[1] = atoi(json["puls2"] | "");
      relais_impulse[2] = atoi(json["puls3"] | "");

      Serial.println("Loaded config values:");
      printConfigHw();
      return true;
    }
  }
  else {
    Serial.println("file /confhw.json file does not exist");
    return false;
  }
}//loadConfigHw


bool saveConfig() { // safeConfig
  StaticJsonBuffer<1050> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();

  json["devName"] = deviceName;
  json["httpUser"] = http_user;
  json["httpPass"] = http_pass;
  json["mqttHost"] = mqtt_server;
  json["mqttPort"] = mqtt_port;
  json["mqttUser"] = mqtt_user;
  json["mqttPass"] = mqtt_pass;
  json["inTop"] = mqtt_topic_in;
  json["outTop"] = mqtt_topic_out;
  json["outRet"] = mqtt_outRetain;
  json["willTop"] = mqtt_willTopic;
  json["willQos"] = mqtt_willQos;
  json["willRet"] = mqtt_willRetain;
  json["willMsg"] = mqtt_willMsg;
  json["domOutTop"] = domoticz_out_topic;
  json["allOnOffTop"] = mqtt_allOnOffTopic;
  
  yield();

  File configFile = SPIFFS.open("/conf.json", "w");
  if (!configFile) {
    Serial.println("Failed to open conf file for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
} // safeConfig


bool saveConfig2() { // safeConfig2
  StaticJsonBuffer<1050> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();

  json["btnRet"] = mqtt_btnRetain;
  json["top1"] = mqtt_topic_out_1;
  json["top2"] = mqtt_topic_out_2;
  json["top3"] = mqtt_topic_out_3;
  json["pld1"] = mqtt_payload_out_1;
  json["pld2"] = mqtt_payload_out_2;
  json["pld3"] = mqtt_payload_out_3;
  json["topHld1"] = mqtt_topic_out_hold_1;
  json["topHld2"] = mqtt_topic_out_hold_2;
  json["topHld3"] = mqtt_topic_out_hold_3;
  json["pldHld1"] = mqtt_payload_out_hold_1;
  json["pldHld2"] = mqtt_payload_out_hold_2;
  json["pldHld3"] = mqtt_payload_out_hold_3;
  json["domIdx1"] = domoticzIdx[0];
  json["domIdx2"] = domoticzIdx[1];
  json["domIdx3"] = domoticzIdx[2];
  json["hld1ToRel"] = hldToRel[0];
  json["hld2ToRel"] = hldToRel[1];
  json["hld3ToRel"] = hldToRel[2];

  yield();

  File configFile = SPIFFS.open("/conf2.json", "w");
  if (!configFile) {
    Serial.println("Failed to open conf2 file for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
} // safeConfig2

bool saveConfigHw() { // safeConfigHw
  StaticJsonBuffer<1050> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();

  json["debtime"] = debounceTime;
  json["hldtime"] = buttonHoldTime;
  json["enaRel1"] = relais_enabled[0];
  json["enaRel2"] = relais_enabled[1];
  json["enaRel3"] = relais_enabled[2];
  json["enaBtn1"] = button_enabled[0];
  json["enaBtn2"] = button_enabled[1];
  json["enaBtn3"] = button_enabled[2];
  json["enaLed1"] = led_enabled[0];
  json["enaLed2"] = led_enabled[1];
  json["enaLed3"] = led_enabled[2];
  json["ioRel1"] = relais_pins[0];
  json["ioRel2"] = relais_pins[1];
  json["ioRel3"] = relais_pins[2];
  json["ioBtn1"] = buttons_pins[0];
  json["ioBtn2"] = buttons_pins[1];
  json["ioBtn3"] = buttons_pins[2];
  json["ioLed1"] = leds_pins[0];
  json["ioLed2"] = leds_pins[1];
  json["ioLed3"] = leds_pins[2];
  json["invRel1"] = relais_invert[0];
  json["invRel2"] = relais_invert[1];
  json["invRel3"] = relais_invert[2];
  json["invBtn1"] = button_invert[0];
  json["invBtn2"] = button_invert[1];
  json["invBtn3"] = button_invert[2];
  json["invLed1"] = led_invert[0];
  json["invLed2"] = led_invert[1];
  json["invLed3"] = led_invert[2];
  json["puls1"] = relais_impulse[0];
  json["puls2"] = relais_impulse[1];
  json["puls3"] = relais_impulse[2];
  yield();

  File configFile = SPIFFS.open("/confhw.json", "w");
  if (!configFile) {
    Serial.println("Failed to open confhw file for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
} // safeConfigHw

void checkSaveConfigTriggered() {
  if (saveConfigToFlash) {
    saveConfigToFlash = false;
    saveConfig();
  }
  if (saveConfig2ToFlash) {
    saveConfig2ToFlash = false;
    saveConfig2();
  }
  if (saveConfigHwToFlash) {
    saveConfigHwToFlash = false;
    saveConfigHw();
  }
}

void deleteConfig() {
  Serial.println("deleting configuration");
  if (SPIFFS.remove("/formatComplete.txt")) {
    Serial.println("config will be deleted after reboot");
    delay(100);
    ESP.restart();
  }
}

