Make a function also work when offline

Created a Blynk code to turn on or off a relay based on a value set using Blynk server.
if V0 = 1, the code will accept a 4 digit password to turn on the relay.
if V0 = 0 (or anything else), the code will accept any key presses in the key board to turn on the relay.
I am using ESP8266 to run this project.
The problem is if the internet goes down, nothing will work.

I just want any key pressed on the keypad to turn on the relay if there is no internet / server connectivity.

I tried many things, but most of the time it wont work or the board wont be able to connect to the Blynk server. Chat GPT couldn’t help even after hours of trying.

Following is a working code which accepts password 1234 followed by # if V0 is set to 1.
else if V0 = 0, any key is accepted as password. I need this function to be also able to work even if there is no internet. I hope someone will help.


#define BLYNK_TEMPLATE_ID "ccccccxxxxxxxcccccco"
#define BLYNK_TEMPLATE_NAME "NodeMCU"
#define BLYNK_DEVICE_NAME "NodeMCU"

#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

#include "BlynkEdgent.h"
#include <Keypad.h>

const byte numRows = 4; 
const byte numCols = 4; 

char keyMap[numRows][numCols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[numRows] = {D1, D2, D3, D4};
byte colPins[numCols] = {D5, D6, D7, D8};

Keypad keypad = Keypad(makeKeymap(keyMap), rowPins, colPins, numRows, numCols);
const String password = "1234";
bool passwordCorrect = false;
const int relayPin = 16; // D0
bool relayActivated = false;
unsigned long relayActivationTime = 0;
const unsigned long relayDuration = 5000; // 5 seconds

bool acceptPassword = false; // Flag to accept or reject password

BLYNK_WRITE(V0)
{
  int value = param.asInt();
  Serial.print("V0 write: ");
  Serial.println(value);
  
  acceptPassword = (value == 1); // Update the flag based on the value written to V0
  passwordCorrect = false; // Reset the password check after each attempt
}

void checkPassword()
{
  char key = keypad.getKey();

  if (key) {
    Serial.print("Key pressed: ");
    Serial.println(key);

    if (acceptPassword) {
      if (key == '#') {
        if (passwordCorrect && !relayActivated) {
          digitalWrite(relayPin, LOW); // Turn on the relay (set pin 16 - D0 - LOW) if password matches
          relayActivationTime = millis(); // Record the relay activation time
          relayActivated = true;
          Serial.println("Relay turned ON");
        } else {
          Serial.println("Invalid password or relay already activated");
        }
        passwordCorrect = false; // Reset the password check after each attempt
      } else {
        if (key == password.charAt(0)) {
          passwordCorrect = false;
        } else if (passwordCorrect) {
          passwordCorrect = false;
        } else {
          passwordCorrect = true;
        }
      }
    } else {
      digitalWrite(relayPin, LOW); // Turn on the relay (set pin 16 - D0 - LOW) for any keypress when acceptPassword is false
      relayActivationTime = millis(); // Record the relay activation time
      relayActivated = true;
      Serial.println("Relay turned ON (No password required)");
    }
  }
  
  // Check if it's time to turn off the relay
  if (relayActivated && millis() - relayActivationTime >= relayDuration) {
    digitalWrite(relayPin, HIGH); // Turn off the relay (set pin 16 - D0 - HIGH)
    relayActivated = false;
    Serial.println("Relay turned OFF");
  }
}


BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V0);
}

void setup()
{
  Serial.begin(115200);
  delay(100);
  
  pinMode(relayPin, OUTPUT); // Initialize digital pin 16 (D0) as an output pin for the relay
  digitalWrite(relayPin, HIGH); // Turn off the relay initially

  BlynkEdgent.begin();
}

void loop()
{
  BlynkEdgent.run();
  checkPassword(); // Check keypad input
}


Is there a reason why you’re using the Edgent example as the basis for this sketch?

Pete.

I am new to all these, have little experience. I saw an example and trying to modify it, thats it. Let me know if there are any better options.

That’s difficult without knowing if you want any of the Edgent features such as dynamic provisioning and Blynk.Air.

Pete.

no I need no other functions.
I just need the app and webhook features to work.
so that I can control the behavior and log data.
I don’t even know what dynamic provisioning and Blynk.Air are!!!

Can you explain more about the Webhook you’re using, and where it’s logging data to?
Which virtual datastream is the webhook linked to?

Obviously that functionality won’t work if the device is offline.

Also, why are you synchronising the V0 datastream at startup, what is the purpose of this in the functionality of the lock?

Pete.

no, just forget the webhook / data logging function.
this relay will be controlling a door lock, so just imagine, if the internet goes down, wont be able to unlock the door!
power failure can be fixed by adding battery backup.
I just want an offline funtion to enable relay on any key press.

Okay, well if you search the forum there are some old examples of how to do this offline functionality.

The important parts are that you need to manage the WiFi connection yourself, in a non-blocking way, and use Blynk.config() and Blynk.connect rather than Blynk.begin.

You can specify a timeout in the Blynk.config command, rather than allowing the default of around 18 seconds. The lock won’t work during the connection timeout period.

You need to ensure that Blynk.run() isn’t executed when you aren’t connected to Blynk, otherwise the timeout period will kick-in each time, making the lock unusable. This requires a Blynk.connected() check in the void loop.

If you aren’t connected to WiFi or Blynk then you’ll need to do reconnection attempts every so often to get the device back online.

Pete.