Update: 2024-03-07

Esp32 Fritzbox Wlan Präsenzmelder als Arduino Tab.

Damit dein Esp32 mit der Fritz!Box kommunizieren kann, benötigt er Zugriff über das TR-064 Protokoll.
Dafür muss im Administrationsmenü der Fritz!Box (http//fritz.box) unter ”Heimnetz” → “Netzwerk” → “Netzwerkeinstellungen” der Haken bei “Zugriff für Anwendungen zulassen” gesetzt sein.

Praesenz.ino

// ****************************************************************
// Arduino IDE Tab Esp32 Fritzbox Wlan Präsenzmelder Modular
// created: Jens Fleischer, 2024-03-07
// last mod: Jens Fleischer, 2024-03-07
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp32
// Software: Esp32 Arduino Core 2.0.0 - 2.0.14
// Getestet auf: ESP32 NodeMCU-32s
/******************************************************************
  Copyright (c) 2024 Jens Fleischer. All rights reserved.

  This file is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  This file is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*******************************************************************/
// Diese Version von Wlan Präsenzmelder sollte als Tab eingebunden werden.
// #include <WebServer.h> oder #include <WiFi.h> muss im Haupttab aufgerufen werden.
// Dieie Funktion "presence();" muss im loop(); aufgerufen werden.
/**************************************************************************************/

#include <tr064.h>          // https://github.com/Aypac/Arduino-TR-064-SOAP-Library

const String FRITZBOX_USER = "admin";                        // default, ggf. anpassen
const char FRITZBOX_PASS[] = "Passwort deiner Fritzbox";     // <-- ändern
const char FRITZBOX_IP[] = "192.168.178.1";                  // default, ggf. anpassen
const int FRITZBOX_PORT = 49000;                             // default, ggf. anpassen
const char* USERIP[] = {"192.168.178.45", "192.168.178.48", "192.168.178.51"}; // IPs aller Geräte die gescannt werden sollen eingeben.

TR064 connection(FRITZBOX_PORT, FRITZBOX_IP, FRITZBOX_USER, FRITZBOX_PASS);

bool presence() {
  static auto init {0};
  if (!init++) connection.init();
  static byte counter {0};
  static uint32_t previousMillis;
  uint32_t currentMillis {millis()};
  if (currentMillis - previousMillis >= 20000) {
    previousMillis = currentMillis;
    counter = 0;
    for (auto &ip : USERIP) if (connecttr064(ip)) counter++;
    DEBUG_F("Geräte im Wlan: %d\n", counter);                // Aktuelle Anzahl Aktiver Verbindungen, aus obiger Liste.
  }
  return counter;
}

bool connecttr064(String ip) {
  String params[][2] = {"NewIPAddress", ip};
  String req[][2] = {"NewActive", ""};
  connection.action("urn:dslforum-org:service:Hosts:1", "X_AVM-DE_GetSpecificHostEntryByIp", params, 1, req, 2);
  if (req[0][1].isEmpty()) {                                 // Verbindung fehlgeschlagen oder IP nicht vergeben.
    DEBUG_P("Fritzbox TR-064 SOAP Anfrage nicht erfolgreich!");
  }
  return req[0][1].toInt();
}

Es ist erforderlich den zu überwachenden Geräten eine feste IP durch die Fritzbox zuzuteilen.
Unter ”Heimnetz” → “Netzwerk” → “Netzwerkverbindungen” → "Bearbeiten/Details" der Haken bei “Diesem Netzwerkgerät immer die gleiche IPv4-Adresse zuweisen.” gesetzt sein.

Beispiel:

***************** LED Anwesenheitssimulator ******************

void loop() {
  ........
  bool present = presence();
  const uint32_t TIME_OFF = 1e2;
  const uint32_t TIME_ON = 1e4;
  present ? digitalWrite(LED_PIN, LOW) : digitalWrite(LED_PIN, millis() % (TIME_OFF + TIME_ON) >= TIME_ON);
  ......
}
Beispiel:

****************** Lüftung bei Anwesenheit *******************
void loop() {
  .....
  presence() ? digitalWrite(Ventilation_Pin, HIGH) : digitalWrite(Ventilation_Pin, LOW);
  ....
}