#include #include #include "configuration.h" #include "display.h" #include "logger.h" extern logging::Logger logger; Configuration::Configuration() { _filePath = "/tracker_config.json"; if (!SPIFFS.begin(false)) { Serial.println("SPIFFS Mount Failed"); return; } readFile(SPIFFS, _filePath.c_str()); } void Configuration::readFile(fs::FS &fs, const char *fileName) { StaticJsonDocument<2800> data; File configFile = fs.open(fileName, "r"); DeserializationError error = deserializeJson(data, configFile); if (error) { Serial.println("Failed to read file, using default configuration"); } JsonArray BeaconsArray = data["beacons"]; for (int i = 0; i < BeaconsArray.size(); i++) { Beacon bcn; bcn.callsign = BeaconsArray[i]["callsign"].as(); bcn.callsign.toUpperCase(); bcn.gpsEcoMode = BeaconsArray[i]["gpsEcoMode"].as(); bcn.symbol = BeaconsArray[i]["symbol"].as(); bcn.overlay = BeaconsArray[i]["overlay"].as(); bcn.micE = BeaconsArray[i]["micE"].as(); bcn.comment = BeaconsArray[i]["comment"].as(); bcn.smartBeaconState = BeaconsArray[i]["smartBeacon"]["active"].as(); bcn.slowRate = BeaconsArray[i]["smartBeacon"]["slowRate"].as(); bcn.slowSpeed = BeaconsArray[i]["smartBeacon"]["slowSpeed"].as(); bcn.fastRate = BeaconsArray[i]["smartBeacon"]["fastRate"].as(); bcn.fastSpeed = BeaconsArray[i]["smartBeacon"]["fastSpeed"].as(); bcn.minTxDist = BeaconsArray[i]["smartBeacon"]["minTxDist"].as(); bcn.minDeltaBeacon = BeaconsArray[i]["smartBeacon"]["minDeltaBeacon"].as(); bcn.turnMinDeg = BeaconsArray[i]["smartBeacon"]["turnMinDeg"].as(); bcn.turnSlope = BeaconsArray[i]["smartBeacon"]["turnSlope"].as(); beacons.push_back(bcn); } display.showSymbol = data["display"]["showSymbol"].as(); display.ecoMode = data["display"]["ecoMode"].as(); display.timeout = data["display"]["timeout"].as(); display.turn180 = data["display"]["turn180"].as(); winlink.password = data["winlink"]["password"].as(); bme.active = data["bme"]["active"].as(); bme.temperatureCorrection = data["bme"]["temperatureCorrection"].as(); bme.sendTelemetry = data["bme"]["sendTelemetry"].as(); notification.ledTx = data["notification"]["ledTx"].as(); notification.ledTxPin = data["notification"]["ledTxPin"].as(); notification.ledMessage = data["notification"]["ledMessage"].as(); notification.ledMessagePin = data["notification"]["ledMessagePin"].as(); notification.ledFlashlight = data["notification"]["ledFlashlight"].as(); notification.ledFlashlightPin = data["notification"]["ledFlashlightPin"].as(); notification.buzzerActive = data["notification"]["buzzerActive"].as(); notification.buzzerPinTone = data["notification"]["buzzerPinTone"].as(); notification.buzzerPinVcc = data["notification"]["buzzerPinVcc"].as(); notification.bootUpBeep = data["notification"]["bootUpBeep"].as(); notification.txBeep = data["notification"]["txBeep"].as(); notification.messageRxBeep = data["notification"]["messageRxBeep"].as(); notification.stationBeep = data["notification"]["stationBeep"].as(); notification.lowBatteryBeep = data["notification"]["lowBatteryBeep"].as(); notification.shutDownBeep = data["notification"]["shutDownBeep"].as(); JsonArray LoraTypesArray = data["lora"]; for (int j = 0; j < LoraTypesArray.size(); j++) { LoraType loraType; loraType.frequency = LoraTypesArray[j]["frequency"].as(); loraType.spreadingFactor = LoraTypesArray[j]["spreadingFactor"].as(); loraType.signalBandwidth = LoraTypesArray[j]["signalBandwidth"].as(); loraType.codingRate4 = LoraTypesArray[j]["codingRate4"].as(); loraType.power = LoraTypesArray[j]["power"].as(); loraTypes.push_back(loraType); } ptt.active = data["pttTrigger"]["active"].as(); ptt.io_pin = data["pttTrigger"]["io_pin"].as(); ptt.preDelay = data["pttTrigger"]["preDelay"].as(); ptt.postDelay = data["pttTrigger"]["postDelay"].as(); ptt.reverse = data["pttTrigger"]["reverse"].as(); simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"].as(); sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"].as(); path = data["other"]["path"].as(); nonSmartBeaconRate = data["other"]["nonSmartBeaconRate"].as(); rememberStationTime = data["other"]["rememberStationTime"].as(); maxDistanceToTracker = data["other"]["maxDistanceToTracker"].as(); standingUpdateTime = data["other"]["standingUpdateTime"].as(); sendAltitude = data["other"]["sendAltitude"].as(); sendBatteryInfo = data["other"]["sendBatteryInfo"].as(); bluetoothType = data["other"]["bluetoothType"].as(); bluetoothActive = data["other"]["bluetoothActive"].as(); disableGPS = data["other"]["disableGPS"].as(); configFile.close(); } bool Configuration::validateConfigFile(const String& currentBeaconCallsign) { if (currentBeaconCallsign.indexOf("NOCALL") != -1) { logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Config", "Change all your callsigns in 'data/tracker_config.json' and upload it via 'Upload File System image'"); show_display("ERROR", "Callsigns = NOCALL!", "---> change it !!!", 2000); return true; } else { return false; } } bool Configuration::validateMicE(const String& currentBeaconMicE) { String miceMessageTypes[] = {"111", "110", "101", "100", "011", "010", "001" , "000"}; int arraySize = sizeof(miceMessageTypes) / sizeof(miceMessageTypes[0]); bool validType = false; for (int i = 0; i < arraySize; i++) { if (currentBeaconMicE == miceMessageTypes[i]) { validType = true; } } return validType; }