dawidchyrzynski / arduino-home-assistant

ArduinoHA allows to integrate an Arduino/ESP based device with Home Assistant using MQTT.
https://dawidchyrzynski.github.io/arduino-home-assistant/
GNU Affero General Public License v3.0
490 stars 118 forks source link

Example for dynamic configurationUrl based on current IP #243

Open Routhinator opened 6 months ago

Routhinator commented 6 months ago

I've been trying to set the configuration URL on startup dynamically, however the only working code I've managed to get to compile results in a bytes object instead of a string, which breaks the HA integration.

Can someone add an example on how to achieve this?

// Setup vars
String localIP;
const char* url;

...
  // In Setup
  // Set device as a Wi-Fi Station
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to Wi-Fi..");
  }
  localIP = WiFi.localIP().toString();

  Serial.print("Sensor IP Address: ");
  Serial.println(localIP);
  Serial.println();

  url = String(String("http://") + localIP).c_str();
  device.setConfigurationUrl(String(url).c_str());

This results in the following in the MQTT messages:

{"cu":"��?"}

Unfortunately I've not found a way to combine an IPAddress variable with a const like "http://" without all the String().c_str() conversions, and from the Serial.println I can verify the IP is properly set in the string...

Routhinator commented 6 months ago

Ok I finally got something that works. Took some fiddling around, I need to refresh my understanding of var types and pointers in C++ it seems.

// Setup vars
String localIP;
char url[20];

...
void setup() {
...
  // Set device as a Wi-Fi Station
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to Wi-Fi..");
  }
  localIP = WiFi.localIP().toString();

  Serial.print("Sensor IP Address: ");
  Serial.println(localIP);
  Serial.println();

   sprintf(url, "http://%s", localIP.c_str());
   Serial.println(url);
   device.setConfigurationUrl(url);

...
}

Which produces the proper configuration URL value:

{
...
  "cu": "http://192.168.1.99"
...
}
romoloman commented 4 months ago

This works too

char c_url[23];
String url="http://";
url.concat(WiFi.localIP().toString());
strcpy(c_url,url.c_str());
device.setConfigurationUrl(c_url);

but

String url="http://";
url.concat(WiFi.localIP().toString());
device.setConfigurationUrl(url.c_str());

doesn't

Please note that in your code char url[20] maybe short.... http:// = 7 chars xxx.xxx.xxx.xxx = 15 chars so the worst condition cu can be 22 chars + \0 so 23 chars

Also your code may be simplified using

char url[23];
sprintf(url, "http://%s", WiFi.localIP().toString().c_str());
device.setConfigurationUrl(url);