/** * IotWebConf03CustomParameters.ino -- IotWebConf is an ESP8266/ESP32 * non blocking WiFi/AP web configuration library for Arduino. * https://github.com/prampec/IotWebConf * * Copyright (C) 2018 Balazs Kelemen * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ /** * Example: Custom parameters * Description: * In this example it is shown how to attach your custom parameters * to the config portal. Your parameters will be maintained by * IotWebConf. This means, they will be loaded from/saved to EEPROM, * and will appear in the config portal. * Note the configSaved and formValidator callbacks! * (See previous examples for more details!) * * Hardware setup for this example: * - An LED is attached to LED_BUILTIN pin with setup On=LOW. * - [Optional] A push button is attached to pin D2, the other leg of the * button should be attached to GND. */ #include #include #include #include "Button2.h" WiFiUDP udp; WiFiClient espClient; PubSubClient client(espClient); boolean needMqttConnect = false; boolean needReset = false; unsigned long lastMqttConnectionAttempt = 0; void wifiConnected(); #define MSG_BUFFER_SIZE (50) char msg[MSG_BUFFER_SIZE]; // -- Initial name of the Thing. Used e.g. as SSID of the own Access Point. const char thingName[] = "BADBell"; // -- Initial password to connect to the Thing, when it creates an own Access Point. const char wifiInitialApPassword[] = "bell4home"; #define STRING_LEN 128 #define NUMBER_LEN 32 // -- Configuration specific key. The value should be modified if config structure was changed. #define CONFIG_VERSION "dem2" // -- When CONFIG_PIN is pulled to ground on startup, the Thing will use the initial // password to buld an AP. (E.g. in case of lost password) #define CONFIG_PIN 2 // -- Status indicator pin. // First it will light up (kept LOW), on Wifi connection it will blink, // when connected to the Wifi it will turn off (kept HIGH). #define STATUS_PIN LED_BUILTIN #define BELL_PIN 12 // Pin 12 as default #define MINIMAL_GAP 30*1000 // 30 seconds between rings #define IMPULS 250 // minimal press of button unsigned long last_sended = 0; // last transmit of message // -- Callback method declarations. void configSaved(); boolean formValidator(); void handleRoot(); void sendRingPacket(); void sendPacket(); DNSServer dnsServer; WebServer server(80); char mqttServerValue[STRING_LEN]; char ipParamValue[STRING_LEN]; char portParamValue[NUMBER_LEN]; char bellParamValue[NUMBER_LEN]; IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); IotWebConfParameter mqttServerParam = IotWebConfParameter("MQTT server", "mqttServer", mqttServerValue, STRING_LEN,"text","BADnet-gw.lan","BADnet-gw.lan",NULL); IotWebConfParameter ipParam = IotWebConfParameter("Mulicast ip param", "ipParam", ipParamValue, STRING_LEN,"text","224.1.2.3","224.1.2.3",NULL); IotWebConfSeparator separator1 = IotWebConfSeparator(); IotWebConfParameter portParam = IotWebConfParameter("Port param", "portParam", portParamValue, NUMBER_LEN, "number", "1025..65535", "1234", "min='1025' max='65535' step='1'"); // -- We can add a legend to the separator IotWebConfSeparator separator2 = IotWebConfSeparator("Calibration factor"); IotWebConfParameter bellParam = IotWebConfParameter("Bell number param", "bellParam", bellParamValue, NUMBER_LEN, "number", "1", "1", "step='1'"); Button2 buttonBELL = Button2(BELL_PIN,INPUT_PULLDOWN,true,IMPULS); void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Switch on the LED if an 1 was received as first character if ((char)payload[0] == '1') { sendPacket(); } } void change(Button2& btn) { if (btn.isPressed()) { Serial.println("released"); if (millis() - last_sended < MINIMAL_GAP) { Serial.println("Minimal gap not meeted"); return; } sendPacket(); } } void wifiConnected() { needMqttConnect = true; } void setup() { Serial.begin(115200); Serial.println(); Serial.println("Starting up..."); // iotWebConf.setStatusPin(STATUS_PIN); // iotWebConf.setConfigPin(CONFIG_PIN); iotWebConf.addParameter(&mqttServerParam); iotWebConf.addParameter(&ipParam); iotWebConf.addParameter(&separator1); iotWebConf.addParameter(&portParam); iotWebConf.addParameter(&separator2); iotWebConf.addParameter(&bellParam); iotWebConf.setConfigSavedCallback(&configSaved); iotWebConf.setWifiConnectionCallback(&wifiConnected); iotWebConf.setFormValidator(&formValidator); iotWebConf.getApTimeoutParameter()->visible = true; // -- Initializing the configuration. boolean validConfig = iotWebConf.init(); if (!validConfig) { mqttServerValue[0] = '\0'; } // -- Set up required URL handlers on the web server. server.on("/", handleRoot); server.on("/ring", sendRingPacket); server.on("/config", []{ iotWebConf.handleConfig(); }); server.onNotFound([](){ iotWebConf.handleNotFound(); }); pinMode(BELL_PIN, INPUT); digitalWrite(BELL_PIN, LOW); buttonBELL.setChangedHandler(change); Serial.println("Ready."); } boolean reconnect() { unsigned long now = millis(); if (1000 > now - lastMqttConnectionAttempt) { // Do not repeat within 1 sec. return false; } Serial.println("Connecting to MQTT server..."); // Create a random client ID String clientId = "ESP32Client-BELL"; clientId += String(bellParamValue); // Attempt to connect if (client.connect(clientId.c_str())) { Serial.println("connected"); // Once connected, publish an announcement... client.subscribe("home/bell/sendring"); return true; } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 1 seconds"); // Wait 5 seconds before retrying lastMqttConnectionAttempt = now; return false; } } void loop() { // -- doLoop should be called as frequently as possible. iotWebConf.doLoop(); client.loop(); buttonBELL.loop(); if (needMqttConnect) { client.setServer(mqttServerValue, 1883); client.setCallback(callback); if (reconnect()) { needMqttConnect = false; } } else if ((iotWebConf.getState() == IOTWEBCONF_STATE_ONLINE) && (!client.connected())) { Serial.println("MQTT reconnect"); client.setServer(mqttServerValue, 1883); client.setCallback(callback); reconnect(); } } /** * Handle web requests to "/" path. */ void handleRoot() { // -- Let IotWebConf test and handle captive portal requests. if (iotWebConf.handleCaptivePortal()) { // -- Captive portal request were already served. return; } String s = ""; s += "WIFI BELL FOR BAD HOMEBell for Wifi"; s += "
    "; s += "
  • MQTT server address: "; s += mqttServerValue; s += "
  • Multicast IP value: "; s += ipParamValue; s += "
  • Port of multicast message: "; s += atoi(portParamValue); s += "
  • Bell number: "; s += atoi(bellParamValue); s += "
"; s += "Go to configure page to change values.
"; s += "Go to ring Send ring packet."; s += "\n"; server.send(200, "text/html", s); } void sendPacket() { IPAddress multicast; multicast.fromString(ipParamValue); Serial.print("sendUDP : "); // convert string to char array char msg[255]; sprintf(msg,"BELL:%s",bellParamValue); Serial.println(msg); udp.beginMulticast(multicast, atoi(portParamValue)); udp.beginMulticastPacket(); udp.write((uint8_t *)msg,7); udp.endPacket(); udp.flush(); udp.stop(); client.publish("home/bell/ring", msg); last_sended = millis(); } void sendRingPacket() { sendPacket(); server.send(200, "text/html", "Packet sended"); } void configSaved() { Serial.println("Configuration was updated."); } boolean formValidator() { Serial.println("Validating form."); boolean valid = true; // match state object MatchState ms; String ip = server.arg(ipParam.getId()); char ips[128]; // what we are searching (the target) ip.toCharArray(ips,128); ms.Target (ips); // set its address Serial.println (ips); char result = ms.Match ("[0-9\\.]+"); //char result = ms.Match ("(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"); Serial.println(result); if (result <= 0) { ipParam.errorMessage = "Please provide IP addrerss!"; valid = false; } return valid; }