Proyecto de cerradura IOT cloud

Hola Amig@s,

Hoy les traigo un proyecto personal que estuve pensando hacer durante bastante tiempo. Se trata de un dispositivo utilizando una MCU NodeMCU basado en el chip ESP8266, un lector RFID y un relay que permite controlar cualquier tipo de dispositivo que funcione a 220v. En este artículo utilizaré una lampara de mesa en reemplazo de una cerradura electrónica.

Intentaré documentar todo el proceso, que a priori parece muy simple pero de simple tiene muy poco.

Esquema funcional

A continuación podrán ver un pequeño esquema de todos los sistemas que intervienen en el proyecto.

Funcionamiento

El lector RFID recibe el valor almacenado en la llave rfid o tarjeta rfid. Ese valor se lo envía al NODEMCU, el MCU dispone de un pequeño cliente web que se conecta a la ip del servidor que está en la nube y le pasa mediante un comando GET, el valor de la key al web service, disponible en dicho servidor. El webservice a su vez se conecta a una base de datos Oracle XE que está instalada localmente en el servidor de la nube de Azure y consulta si dicha KEY está en los registros. Si la KEY existe, el web service devuelve el resultado en una estructura JSON. El JSON viaja de vuelta al MCU y éste lo deserializa (descompone en valores), teniendo así la posibilidad de realizar acciones. Eso cuando el resultado es correcto. Cuando el WS consulta una KEY y la BBDD no devuelve datos, también se devuelve una estructura JSON, aunque distinta a la correcta. Por ende, podemos controlar que debe hacer el NODEMCU según que respuestas.

Si el resultado es válido, es decir si la key existe, el NODEMCU activará un relay y hará un beep largo utilizando el buzzer.

Por el contrario emitirá dos beeps pero no activará nada mas.

Esquema API

Ahora Bien, lo siguiente es diseñar un pequeño circuito para interconectar el NODEMCU, el lector RFID, un soporte para colocar el relay, un buzzer y un par de accesorios.

Esquema de conexión

Como pueden observar el esquema es super sencillo, solo hay que interconectar los GPIO’s en los puntos correspondientes y poco más.

Una vez que me ha llegado el PCB desde la fábrica, he reunido todos los componentes que voy a utilizar en una foto.

Restful API PHP

Para que el cliente del NODEMCU pueda comunicarse, debemos crear un pequeño webservice en PHP. Su tarea será, recibir un valor desde el cliente con un GET, guardarlo y utilizarlo como BIND en una consulta SQL que estará conectada a una base de datos Oracle XE. Dependiendo de su valor generará uno u otro resultado con salida en formato JSON.

if(isset($_GET['myhashkey']))
{
$mihaskey = $_GET['myhashkey'];
}

$db = new \Oracle\Db("LLAVECLOUD", "CONSULTA");
$sql = "SELECT NOMBRE, APELLIDO, HASHKEY, STATUS FROM USUARIOS WHERE HASHKEY = :varmihashkey";
$res = $db->execFetchAll($sql, "",
array(
array(":varmihashkey", $mihaskey, -1)));
$i=0;
$return_arr = array();
$row_array = array();
if(count($res)>0){ //HAY DATOS?
foreach ($res as $rows) {
$row_array['NOMBRE'] = $rows['NOMBRE'];
$row_array['APELLIDO'] = $rows['APELLIDO'];
$row_array['HASHKEY'] = $rows['HASHKEY'];
$row_array['STATUS'] = $rows['STATUS'];
if ($row_array['STATUS']==100) $row_array['ACCEDER']='SI';
$row_array['BEEP']='1';
$row_array['MOTIVO']='HASH VALIDA';
array_push($return_arr,$row_array);
}}
else { //SINO
$row_array['MOTIVO'] = 'NO EXISTE ESA HASHKEY O NO HAY DATOS';
$row_array['ACCEDER'] = 'NO';
$row_array['BEEP'] = '2';
array_push($return_arr,$row_array);
}
echo str_replace('[', '', str_replace(']', '', json_encode($return_arr, JSON_PRETTY_PRINT)));

Resultado correcto

    {
        "NOMBRE": "Eduardo",
        "APELLIDO": "Arana",
        "HASHKEY": "15411017826",
        "STATUS": "100",
        "ACCEDER": "SI",
        "BEEP": "1",
        "MOTIVO": "HASH VALIDA"
    }

Resultado incorrecto

    {
        "MOTIVO": "NO EXISTE ESA HASHKEY O NO HAY DATOS",
        "ACCEDER": "NO",
        "BEEP": "2"
    }

Seguridad en la conexión

Obviamente no hemos tenido en cuenta la seguridad para este EJEMPLO, dado que para hacerlo bien, deberíamos validar el cliente (NODEMCU) contra el webservice utilizando un TOKEN o usuario y contraseña, una conexión SSL y un puerto específico.

Código del MCU

A continuación podrán encontrar un pequeño código de ejemplo donde puede verse como se realiza la petición, se recibe la respuesta, y se deserializa el json para obtener los valores de dicha respuesta. Este ejemplo está basado en el que se incluye en la librería del Arduino IDE llamado BasicHTTPClient.ino, lo he utilizado como prueba de concepto.

if (tag != NULL)
      {
        Serial.println("Consultando la hashkey: " + tag);

        Serial.print("[HTTP] begin...\n");
        // configure traged server and url
        http.begin(client, "http://" SERVER_IP "/key.php?myhashkey=" + tag); //HTTP
        http.addHeader("Content-Type", "application/json");

        Serial.print("[HTTP] POST...\n");
        // start connection and send HTTP header and body
        int httpCode = http.POST("{\"hashkey\":\"764EB1A6FE9D4809\"}");

        // httpCode will be negative on error
        if (httpCode > 0) {
          //Serial.printf("[HTTP] POST... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK) {
            const String& payload = http.getString();

            //json definition
            DynamicJsonDocument doc(1024);
            deserializeJson(doc, payload);

            //json array

            const char* minombre = doc["NOMBRE"];
            const char* miapellido = doc["APELLIDO"];
            const char* mihashkey = doc["HASHKEY"];
            const char* miestado = doc["STATUS"];
            const char* miacceder = doc["ACCEDER"];
            int buzzer = doc["BEEP"];
            const char* mimotivo = doc["MOTIVO"];

            //serial output
            Serial.print("Nombre:");
            Serial.println(minombre);
            Serial.print("Apellido:");
            Serial.println(miapellido);
            Serial.print("Hashkey:");
            Serial.println(mihashkey);
            Serial.print("Estado:");
            Serial.println(miestado);
            Serial.print("Acceso:");
            Serial.println(miacceder);
            Serial.print("buzzer:");
            Serial.println(buzzer);
            Serial.print("Motivo:");
            Serial.println(mimotivo);

            if (buzzer > 1) { //if key not found
              digitalWrite(redled, LOW) ; //Turn on the red led
              tone(Passive_buzzer, 987) ; //LA note ...
              delay (200);
              tone(Passive_buzzer, 687) ; //LA note ...
              delay (200);
              noTone(Passive_buzzer) ; //Turn off tone()
              digitalWrite(redled, HIGH) ; //Turn off the red led
            } else { //if key found
              digitalWrite(greenled, LOW) ; //Turn on the green led
              tone(Passive_buzzer, 523) ; //DO note 523 Hz
              delay (200);
              noTone(Passive_buzzer) ; //Turn off tone()
              digitalWrite(greenled, HIGH) ; //Turn off the green led

              digitalWrite(relay, HIGH);
              delay(10000);
              digitalWrite(relay, LOW);
              noTone(Passive_buzzer) ; //Turn off tone()
            }

          }
        } else {
          Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

Video demostrativo

He subido un video donde puede verse el funcionamiento del dispositivo. He utilizado una lampara para simular una cerradura eléctrica, pero es muy sencillo de conectar cualquier otra cosa que necesitemos controlar y validar contra un web service.

Espero que les haya resultado curioso.

Salu2.

Edu.

Entradas relacionadas