vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.97k stars 726 forks source link

Assigning dynamic topics for MQTT #812

Closed yilmazyurdakul closed 1 week ago

yilmazyurdakul commented 3 weeks ago

Hi,

We are using this amazing library for post and get requests, MQTT connection and SMS. Works like a charm!

We only have one issue and we are struggling to solve it. We have MQTT topics like "const char* topicDoor = "FleetLink/devices/I2ROZBE3OT/door";" and these topics are hardcoded now. We need to assign deviceID (I2ROZBE3OT in this example) and generate topics in void setup.

we keep the internalID in SPIFFS and call it in void setup. we can assign deviceID and apiKey. apiKey is out of topic. There is no problem with that one. Here is the code for this action.

` if (!SPIFFS.exists(deviceIdFile)) { File f = SPIFFS.open(deviceIdFile, "w"); if (!f) { Serial.println("File open failed"); } else { f.println("AAAAAAAAAA"); // Default internalId f.println("00000000-0000-0000-0000-000000000000"); // Default apiKey f.close(); internalIdStr = "AAAAAAAAAA"; // Set default ID in the String apiKey = "00000000-0000-0000-0000-000000000000"; //default............... } } else { File f = SPIFFS.open(deviceIdFile, "r"); if (f) { Serial.println("Reading data from file:"); internalIdStr = f.readStringUntil('\n'); // Read internalId apiKey = f.readStringUntil('\n'); // Read apiKey internalIdStr.trim(); // Remove any newline or spaces apiKey.trim(); f.close();

  Serial.print("Internal ID: ");
  Serial.println(internalIdStr);
  Serial.print("API Key: ");
  Serial.println(apiKey);
} else {
  Serial.println("File open failed");
}

}

internalId = internalIdStr.c_str(); Serial.println(internalId);`

We tried almost any converting method to assign these topics but no success. Then we realized something strange. If we add this code block only for one topic, it works. If i try to add another topic, it fails.

` char* topicDoorTemp = new char[50]; // Allocate enough memory snprintf(topicDoorTemp, 50, "FleetLink/devices/%s/door", internalId);

topicDoor = topicDoorTemp;`

Fail meaning the system keeps saying mqtt connected, and disconnected repeatedly.

I cant share all the code, there is 1500 lines of code. I will simplify the system for this issue and share it after doing it. I am just hoping to find a solution before doing that.

This is the serial handler works fine. I am sharing to show how i assign the internalID

`void serialHandler() { if (Serial.available()) { String inputData = Serial.readStringUntil('\n'); // Read the entire input line inputData.trim(); // Remove any trailing newlines or spaces

// Check if the input starts with '{', which indicates it's a JSON string
if (inputData.startsWith("{") && inputData.endsWith("}")) {
  // Attempt to parse the JSON input
  StaticJsonDocument<2048> doc;
  DeserializationError error = deserializeJson(doc, inputData);

  if (error) {
    Serial.println("Failed to parse JSON input: " + String(error.c_str()));
    return;
  }
  SPIFFS.remove(deviceConfig);
  // Open SPIFFS file to save the received JSON
  File file = SPIFFS.open(deviceConfig, "w");
  if (!file) {
    Serial.println("Failed to open file for writing.");
    return;
  }

  // Serialize the JSON and write it to the file
  if (serializeJson(doc, file) == 0) {
    Serial.println("Failed to write JSON to file.");
  } else {
    Serial.println("JSON configuration saved to deviceConfig.json.");
    printFile(deviceConfig);
  }

  file.close();
  return;
}

// If not JSON, process as Internal ID and API Key
if (inputData.length() != 47) {
  Serial.println("Invalid input length. Please enter Internal ID and API Key in the correct format.");
  return;
}

int commaIndex = inputData.indexOf(',');  // Find the comma separator

if (commaIndex == 10 && commaIndex < inputData.length() - 1) {
  // Extract internalId and apiKey from the input
  internalIdStr = inputData.substring(0, commaIndex);
  apiKey = inputData.substring(commaIndex + 1);

  internalIdStr.trim();  // Remove any trailing spaces
  apiKey.trim();         // Remove any trailing spaces

  if (internalIdStr.length() == 10 && apiKey.length() == 36 && isStringAlphaNumeric(internalIdStr) && validateApiKeyFormat(apiKey)) {
    internalId = internalIdStr.c_str();

    File f = SPIFFS.open(deviceIdFile, "w");
    if (f) {
      f.println(internalId);  // Save internalId on the first line
      f.println(apiKey);      // Save apiKey on the second line
      f.close();
      Serial.println("New Internal ID and API Key saved.");
    } else {
      Serial.println("Failed to save new data.");
    }

    Serial.println("New Internal ID: ");
    Serial.println(internalId);
    Serial.println("New API Key: ");
    Serial.println(apiKey);
  } else {
    Serial.println("Invalid format for Internal ID or API Key.");
  }
} else {
  Serial.println("Invalid input format. Please enter in this format: internalId,apiKey");
}

} }`

Also I am having the same problem by assigning SMS_TARGET from a variable dynamic.

[x ] I have read the Troubleshooting section of the ReadMe

What type of issues is this?

[x ] Question or request for help

Modem: Main processor board: TinyGSM version:

Thanks. I can provide additional info, debug or code block after preparing it, i need to make a simpler project to do it.

mirhamza708 commented 2 weeks ago

Please first go through the steps of how to put your code in github so other people can read it. Your code here is unreadable and for me at least, I wont be able to help.

digicyc commented 1 week ago

One question, is it possible you're trying to connect to the broker more than once?

yilmazyurdakul commented 1 week ago

I solved the issue. Thanks for your time. i will share the snippet.

// Initialize topicDoor static char topicDoorBuffer[34]; snprintf(topicDoorBuffer, sizeof(topicDoorBuffer), "FleetLink/devices/%s/door", internalId); topicDoor = topicDoorBuffer;

after resetting the board, code started to work. Also i realized that i was having some timing issue about reading spiffs. I am not sure about that problem but its just a theory.

The good thing is "problem solved!"

Thanks