En zo geschiede.
Zie het onderstaande, voor de geïnteresseerden als die er zijn, want ik kan er nou niet bepaald omheen dat dit topic wel een beetje een onbehulpzaam karakter heeft, want de aflopen 2 weken is er slechts één iemand die een reactie op mijn vragen heeft gegeven..Toch wilde ik de eindoplossing delen voor het geval er nog iemand is die dit ook wil doen en toevallig hier terecht komt.
Uiteindelijk is alles retour gegaan en heb ik een D340P opgehangen.
Deze gevoed met een POE-injector en de bestaande gong wordt gewoon met de 8 Volt trafo uit de meterkast gevoed. Deze kon ik probleemloos integreren in mijn Synology surveillance station.
In de D340P webhooks geactiveerd. De gebruikte ESP32 is een
SBC-ESP32-RM01 welke afkomstig is van Joy-IT en deze kun je met een
BC-ESP8266-Prog USB-adapter programmeren. Deze heeft een 2x4 pin header en hier steek je de ESP32-C6-Mini-1 module op. Alles bij elkaar via Conrad voor net geen 23 euro. Vervolgens kun je die met Arduino IDE programmeren. Ik had hier nog niet eerder mee gewerkt, maar had het redelijk snel door van hoe of wat. Ik wilde iets wat kant en klaar was. Er zijn legio ESP modules welke je al dan wel of niet kunt gaan solderen etc. Daar had ik geen zin in. Dit was niet al te duur en voldoet precies aan wat ik ervan nodig had. Let wel: er zit geen AC-DC adapter bij, ik had er zelf nog 1 liggen, maar anders moet je er 1 mee bestellen. 5 tot 12V DC, stroom is niet opgegeven, maar 1A zal zeker ruim voldoende zijn. Ik heb hier 12V 1A in gebruik, de draadjes even een laagje soldeertin geven, want als het zachte kern draad is krijg je het er amper in.
Het spul weggewerkt in een elektradoosje en klaar. Mooie van deze module is dat hij een oogje heeft op elke hoek, dus die heb ik op van die moederbord studs geschroefd welke op hun beurt weer in het plastic doosje geschroefd zitten. De deurbel wordt ingedrukt: webhook wordt verzonden naar de ESP module, relais schakelt om, de gong doet zijn ding-dong klingel en het relais schakelt weer terug. En dit i.c.m. meegeleverde Reolink 868 MHz chime die elders in huis ook zijn klingel doet.
In de meterkast:
Het relais met de ESP module zelf:
Ok, maar hoe dan?
Ga in de webinterface van de D340P naar het menu Surveillance > Push. Op die pagina zie je onder For Developer de knop webhook. Daar voeg je een regel toe. Kies customize, voer de tekst gong in en voeg het IP-adres in van de ESP32: http://
JOUW-ESP32-IP/webhook?key=
JOUW-KEY Het is handig om in de router het ESP32 op basis van Mac adres onder DHCP een statisch ip te laten toewijzen, want deze moet niet veranderen want dan werkt je webhook niet. In mijn geval zag ik wel in de DHCP table welk IP-adres er was uitgedeeld aan "iets" maar niet het Mac adres. Mocht je dezelfde situatie hebben en je weet wel het IP maar niet Het Mac: deze kun je via cmd achterhalen: arp -a
IP-ADRES-ESP32
Dan de ESP32 module.
Deze moet je voeden met een 5 tot max 12-Volt DC adapter. Joy-IT heeft een standaard script welke je kunt uploaden. Hiermee krijgt de module een webinterface met een paar buttons welke via de browser te benaderen en te bedienen is:
/f/image/EJ5PWPk2ZOQmdMCayJo77CGA.png?f=fotoalbum_large)
Als de module (voor welke reden dan ook) spanningsloos raakt dan valt het relais automatisch terug in een rust stand (dat is COM-NO). Wanneer er spanning op komt gaat het relais standaard in COM-NC modes. Dus dan sluit je de gong aan op COM-NO omdat anders je gong constant onder spanning staat. Alleen bij uitval van het ESP (kapotte voeding o.i.d) dan komt de gong óók constant onder spanning. Dus dat moest iets anders. Ik heb er een regel in het script dat het relais bij opstarten in de rust stand blijft, mocht de voeding weg vallen dan blijft de gong stil. Daarom sluit je de gong aan op COM en NO. Ter controle: als je hier een multimeter op zet: zowel met en zonder de DC-voeding erop meet je geen continuïteit tussen deze 2 aansluitingen. Precies wat je (of in ieder geval ik) wil.
Zie onderstaand script. Deze kun je middels Arduino IDE uploaden.
Wel even een paar zaken edditen:
Regel 8 en 9: eigen SSID en WW invoeren van je WLAN
Regel 15: eigen key opgeven welke je ook in de webhooks van reolink hebt gebruikt
Regel 153: hier ook de key invoeren.
Regel 39: hier kun je de standaard vertraging tussen relais aan-uit veranderen, standaard is 500ms. Kun je korter of langer maken naar gelang je wenst.
#include <WiFi.h>
#include <WebServer.h>
// =========================
// WiFi access details
// =========================
const char* ssid = "SSID-NAAM";
const char* password = "SSID-WACHTWOORD";
// =========================
// Webhook security
// =========================
const char* webhookKey = "JOUW-KEY";
// =========================
// Relay
// =========================
const int relayPin = 9;
// =========================
// Web server
// =========================
WebServer server(80);
// =========================
// Relay status
// =========================
bool relayState = false;
// =========================
// Gong settings
// =========================
const unsigned long GONG_PULSE_TIME = 500;
// =========================
// Gong state
// =========================
bool gongActive = false;
unsigned long gongStartTime = 0;
// =========================
// Gong queue
// =========================
unsigned int gongQueue = 0;
// =========================
// Webhook counter
// =========================
unsigned long webhookCounter = 0;
// =========================
// Function declarations
// =========================
void handleRoot();
void handleRelayOn();
void handleRelayOff();
void handleRelayToggle();
void handleStatus();
void handleWebhook();
void handleGongTest();
void startGong();
void updateGong();
void setRelay(bool state);
// =========================
// SETUP
// =========================
void setup() {
Serial.begin(115200);
// Relay pin
pinMode(relayPin, OUTPUT);
// Relay off initially
// OFF = COM-NC
setRelay(false);
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// =========================
// Web server routes
// =========================
server.on("/", handleRoot);
server.on("/relay/on", handleRelayOn);
server.on("/relay/off", handleRelayOff);
server.on("/relay/toggle", handleRelayToggle);
server.on("/status", handleStatus);
// Reolink webhook
server.on("/webhook", HTTP_ANY, handleWebhook);
// Manual gong test
server.on("/gong/test", handleGongTest);
// Start web server
server.begin();
// Force relay to safe state after boot
// OFF = COM-NC
setRelay(false);
Serial.println("Web server started");
Serial.println("Relay forced OFF after boot");
Serial.println("Webhook URL:");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/webhook?key=JOUW-KEY");
}
// =========================
// LOOP
// =========================
void loop() {
server.handleClient();
updateGong();
}
// =========================
// RELAY CONTROL
// =========================
void setRelay(bool state) {
relayState = state;
digitalWrite(relayPin, state ? LOW : HIGH);
}
// =========================
// START GONG
// =========================
void startGong() {
// Queue new gong if current gong is active
if (gongActive) {
gongQueue++;
Serial.print("Gong queued. Queue: ");
Serial.println(gongQueue);
return;
}
Serial.println("GONG PULSE START");
// ON = COM-NO
setRelay(true);
gongActive = true;
gongStartTime = millis();
}
// =========================
// UPDATE GONG
// =========================
void updateGong() {
if (!gongActive) {
return;
}
unsigned long now = millis();
if (now - gongStartTime >= GONG_PULSE_TIME) {
// OFF = COM-NC
setRelay(false);
gongActive = false;
Serial.println("GONG PULSE COMPLETE");
// Start next queued gong
if (gongQueue > 0) {
gongQueue--;
Serial.print("Starting queued gong. Remaining: ");
Serial.println(gongQueue);
startGong();
}
}
}
// =========================
// MAIN WEB PAGE
// =========================
void handleRoot() {
String html = "<!DOCTYPE html>";
html += "<html lang='nl'>";
html += "<head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<title>ESP32 Gong Controller</title>";
html += "<style>";
html += "body {";
html += "font-family: Arial, sans-serif;";
html += "text-align: center;";
html += "margin: 50px;";
html += "}";
html += ".button {";
html += "background-color: #4CAF50;";
html += "border: none;";
html += "color: white;";
html += "padding: 15px 32px;";
html += "text-align: center;";
html += "text-decoration: none;";
html += "display: inline-block;";
html += "font-size: 16px;";
html += "margin: 4px 2px;";
html += "cursor: pointer;";
html += "border-radius: 4px;";
html += "}";
html += ".button.off {";
html += "background-color: #f44336;";
html += "}";
html += ".button.gong {";
html += "background-color: #2196F3;";
html += "}";
html += ".status {";
html += "font-size: 20px;";
html += "margin: 20px;";
html += "padding: 20px;";
html += "border-radius: 10px;";
html += "}";
html += ".status.on {";
html += "background-color: #d4edda;";
html += "color: #155724;";
html += "}";
html += ".status.off {";
html += "background-color: #f8d7da;";
html += "color: #721c24;";
html += "}";
html += "</style>";
html += "</head>";
html += "<body>";
html += "<h1>ESP32 Gong Controller</h1>";
// Relay status
html += "<div class='status ";
html += relayState ? "on" : "off";
html += "'>";
html += "Relay Status: ";
html += relayState ? "ON" : "OFF";
html += "</div>";
// Relay buttons
html += "<a href='/relay/on' class='button'>Relay ON</a>";
html += "<a href='/relay/off' class='button off'>Relay OFF</a>";
html += "<a href='/relay/toggle' class='button'>Relay Toggle</a>";
html += "<br><br>";
// Gong test
html += "<a href='/gong/test' class='button gong'>TEST GONG</a>";
// Auto refresh
html += "<script>";
html += "setTimeout(function(){ location.reload(); }, 5000);";
html += "</script>";
html += "</body>";
html += "</html>";
server.send(200, "text/html", html);
}
// =========================
// RELAY ON
// =========================
void handleRelayOn() {
gongActive = false;
setRelay(true);
Serial.println("Relay ON");
server.sendHeader("Location", "/");
server.send(302, "text/plain", "");
}
// =========================
// RELAY OFF
// =========================
void handleRelayOff() {
gongActive = false;
setRelay(false);
Serial.println("Relay OFF");
server.sendHeader("Location", "/");
server.send(302, "text/plain", "");
}
// =========================
// RELAY TOGGLE
// =========================
void handleRelayToggle() {
gongActive = false;
setRelay(!relayState);
Serial.print("Relay ");
Serial.println(relayState ? "ON" : "OFF");
server.sendHeader("Location", "/");
server.send(302, "text/plain", "");
}
// =========================
// STATUS
// =========================
void handleStatus() {
String json = "{\"relay\": ";
json += relayState ? "true" : "false";
json += "}";
server.send(200, "application/json", json);
}
// =========================
// REOLINK WEBHOOK
// =========================
void handleWebhook() {
Serial.println();
Serial.println("Webhook received!");
// Check secret key
if (!server.hasArg("key")) {
Serial.println("Webhook rejected - no key");
server.send(403, "text/plain", "Forbidden");
return;
}
if (server.arg("key") != webhookKey) {
Serial.println("Webhook rejected - invalid key");
server.send(403, "text/plain", "Forbidden");
return;
}
Serial.println("Webhook key accepted");
webhookCounter++;
Serial.print("Webhook counter: ");
Serial.println(webhookCounter);
Serial.println("Triggering gong");
startGong();
server.send(200, "text/plain", "Gong triggered");
}
// =========================
// MANUAL GONG TEST
// =========================
void handleGongTest() {
Serial.println();
Serial.println("Manual gong test");
startGong();
server.send(200, "text/plain", "Gong test triggered");
}
[
Voor 106% gewijzigd door
Disaster-Master op 19-07-2026 22:03
]