Recordatorio de llaves para Smart Home

Recordatorio de llaves para Smart Home

home-automationnode-redhacksonoffmqtt
home-automationnode-redhacksonoffmqtt

Hace poco me quedé fuera del apartamento, afortunadamente era horario normal y pude pedirle al conserje que me abriera la puerta, si esto sucede después de las 10:00 p. m., según las políticas recientes, me cobrarían 100 USD en multas.

Como estaba trabajando en mi smart home, pensé que sería buena idea que la casa me advirtiera cada vez que estoy a punto de salir sin mis llaves, y asi comenzó una semana de investigación.

aqui un video de como funciona:

La investigación comenzó en primer lugar fijando objetivos, el colgador de llaves que informa al smart home si las llaves están presentes deberá:

Como ya tengo experiencia en la construcción de proyectos con el microprocesador ESP8266, opté por este microprocesador, la única diferencia esta vez es que necesita consumir la menor cantidad de energía posible ya que funcionará con una batería pequeña como una CR2032 que tiene una capacidad de alrededor 220 mAh.

Esto significa que cuando no esté en uso, utilizará una cantidad muy pequeña de energía o, preferiblemente, nada de energía para que la batería asi dure más de un año.

Para lograr esto, mi primera suposición fue usar una función del ESP8266 llamada “Deep-Sleep” (“Sueño profundo”) que, de acuerdo con la tabla de consumo de energía en la hoja de datos, es solo 20 uA cuando está en Deep-Sleep

Consumo de energia en distintos modos
Consumo de energia en distintos modos

Esto es muy simple de hacer, el ESP8266 solo necesita conectarse a la red wifi, envíar un mensaje a través de MQTT a mi servidor local (que se ejecuta en una Raspberry Pi 4) y luego entra en Deep-Sleep hasta que se active nuevamente.

Pero, ¿cómo puedo activar un colgador de llaves? Mi primera suposición fue una solución mecánica en la que se activa una especie de palanca cada vez que las llaves se cuelgan como un interruptor de límite.

Un interruptor de límite
Un interruptor de límite

Asi, cuando se cuelgan las llaves, activará el microprocesador y enviará el mensaje.

Tengo una idea mejor, ¿y si el interruptor en lugar de dar una señal al microprocesador le da energía al microprocesador?, de esta manera cuando las llaves no están presentes el circuito no consumirá energía, genial.

Esto resuelve el 50% del problema de energía, no hay consumo de energía cuando las llaves no están presentes y solo 20uA cuando las llaves están presentes, ¿hay alguna forma de consumir energía solo cuando las teclas están siendo colgadas?

Esto es lo que se me ocurrió:

Diagrama mecanico para un boton de pulso
Diagrama mecanico para un boton de pulso

La idea es tener una forma de hacer rodar una rueda que presione un botón al colgar o sacar las llaves, de esta manera solo consume energía al cambiar de estado, ¡perfecto!

Pero hay un problema, la pulsación del botón será de corta duración y no le dará suficiente tiempo (y energía) al ESP8266 para conectarse al wifi y enviar el mensaje, ya que solo conectarse al wifi puede demorar unos 5 segundos, de vuelta al pizarron…

En este punto de la investigación, vi este video del brillante ingeniero Andreas Spiess en el que habla sobre una forma de presionar un botón y hacer que el microprocesador se enganche en el circuito de alimentación y se desconecte automáticamente cuando termina la tarea.

De esta forma, la pulsación del botón (1) alimentará el ESP8266, el cual activará el MOSFET (3) para que la energía pase de la batería (4) al ESP (5), luego se podrá soltar el botón y el ESP8266 todavía tendrá energía para hacer una tarea más larga como conectarse a wifi y enviar el mensaje (imagen tomada del video de Andreas).

Circuito con el MOSFET
Circuito con el MOSFET

Aquí está el video de esta idea siendo explicada:

¡Esta es una solución muy inteligente! Así que tomé un chip ESP01 que no estaba haciendo nada y programé un programa rápido para enviar un mensaje MQTT y pude construir un prototipo funcional, aquí hay un video de cómo funciona

En el momento en que hice funcionar este prototipo, un montón de sensores llegaron por correo de Aliexpress, sensores de movimiento, botones y sensores de puerta, todos ellos usan el protocolo Zigbee para la comunicación.

Sensores Sonoff
Sensores Sonoff

Entonces tuve una idea: ¿por qué no tomar un sensor de puerta y adaptarlo para que sea mi colgador de llaves?

Solo necesito poner un imán en el llavero, así que comencé a modelar una carcasa impresa en 3D que sostiene el circuito con una pequeña tuerca M3 que es lo suficientemente ferromagnética para atraer un imán adherido a mi llavero.

Circuito Sonoff
Circuito Sonoff
Imprimiendo la carcasa
Imprimiendo la carcasa
Una tuerca M3 es puesta para el iman de mi llavero
Una tuerca M3 es puesta para el iman de mi llavero
El circuito dentro de la carcasa
El circuito dentro de la carcasa
Un iman puesto en el llavero
Un iman puesto en el llavero
Llaves puestas y detectadas
Llaves puestas y detectadas

¡Y listo!, ahora el sensor envía un mensaje a la Raspberry Pi cuando está cerrada (llaves puestas) y cuando está abierta (llaves tomadas) como si fuera una puerta, enviando el evento a mi instancia de Red-Node.

Cuando se abre la puerta principal, verifica si las llaves están colgadas, si es así, le dice a mi Google Home que diga "¡No olvides tus llaves!", y si se toman las llaves, dirá "¡Bienvenido!" (ya que podemos inferir que estoy afuera si las llaves no estan puestas), también, como extra, estoy reproduciendo un pequeño sonido de notificación cada vez que se cuelgan las llaves como una forma de confirmarme, me encanta cómo suena (ver video al principio)

Así es como se ve el flujo de Node-Red:

Flujo de Node-Red para la automatizacion de recordatorio de las llaves
Flujo de Node-Red para la automatizacion de recordatorio de las llaves

Y aquí está la exportación JSON para que puedas importarla en tu instancia de Node-Red

[{"id":"099487586f45f55c","type":"mqtt in","z":"fec4b49ba92fcb02","name":"","topic":"zigbee2mqtt/main_door_contact_sensor","qos":"2","datatype":"json","broker":"d038737d9ec4f893","nl":false,"rap":true,"rh":0,"inputs":0,"x":190,"y":1360,"wires":[["75fa75f9290d2321","80b2102ecaacff89"]]},{"id":"75fa75f9290d2321","type":"switch","z":"fec4b49ba92fcb02","name":"contact is false","property":"payload.contact","propertyType":"msg","rules":[{"t":"false"}],"checkall":"true","repair":false,"outputs":1,"x":500,"y":1400,"wires":[["96c415c7e6adc921"]]},{"id":"80b2102ecaacff89","type":"switch","z":"fec4b49ba92fcb02","name":"contact is true","property":"payload.contact","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":500,"y":1360,"wires":[[]]},{"id":"96c415c7e6adc921","type":"api-current-state","z":"fec4b49ba92fcb02","name":"","server":"a7e32585d87233f4","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.main_door_contact_sensor_key_holder_contact","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":870,"y":1400,"wires":[["7a88cbe45a8a0840","e1b158241ac56f2d"]]},{"id":"7a88cbe45a8a0840","type":"switch","z":"fec4b49ba92fcb02","name":"off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1230,"y":1400,"wires":[["5ac241fbc71c819a"]]},{"id":"e1b158241ac56f2d","type":"switch","z":"fec4b49ba92fcb02","name":"on","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1230,"y":1460,"wires":[["43963f905f72ddd8"]]},{"id":"5ac241fbc71c819a","type":"api-call-service","z":"fec4b49ba92fcb02","name":"","server":"a7e32585d87233f4","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.living_room_speaker"],"data":"{\"volume_level\": 1.0}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1410,"y":1400,"wires":[["b2af8179aa7c7953"]]},{"id":"43963f905f72ddd8","type":"api-call-service","z":"fec4b49ba92fcb02","name":"","server":"a7e32585d87233f4","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.living_room_speaker"],"data":"{\"volume_level\": 1.0}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1410,"y":1460,"wires":[["58259eec96fc6553"]]},{"id":"b2af8179aa7c7953","type":"api-call-service","z":"fec4b49ba92fcb02","name":"Joe, Don't forget your keys!","server":"a7e32585d87233f4","version":5,"debugenabled":false,"domain":"tts","service":"google_translate_say","areaId":[],"deviceId":[],"entityId":["media_player.living_room_speaker"],"data":"{\t   \"message\":\"Joe, Don't forget your keys!\",\t   \"cache\": \"true\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1700,"y":1400,"wires":[[]]},{"id":"58259eec96fc6553","type":"api-call-service","z":"fec4b49ba92fcb02","name":"Welcome!","server":"a7e32585d87233f4","version":5,"debugenabled":false,"domain":"tts","service":"google_translate_say","areaId":[],"deviceId":[],"entityId":["media_player.living_room_speaker"],"data":"{\t   \"message\":\"Welcome!\",\t   \"cache\": \"true\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1640,"y":1460,"wires":[[]]},{"id":"376c8512cb3712ff","type":"mqtt in","z":"fec4b49ba92fcb02","name":"","topic":"zigbee2mqtt/main_door_contact_sensor_key_holder","qos":"2","datatype":"json","broker":"d038737d9ec4f893","nl":false,"rap":true,"rh":0,"inputs":0,"x":230,"y":1480,"wires":[["4486b9ce45a6f9c2"]]},{"id":"4486b9ce45a6f9c2","type":"switch","z":"fec4b49ba92fcb02","name":"contact is true","property":"payload.contact","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":520,"y":1480,"wires":[["fc1a27b69e93bc3f"]]},{"id":"fc1a27b69e93bc3f","type":"reusable","z":"fec4b49ba92fcb02","name":"","target":"set media player idle","outputs":1,"x":720,"y":1480,"wires":[["6f8a259d3efb8e8a"]]},{"id":"6f8a259d3efb8e8a","type":"api-call-service","z":"fec4b49ba92fcb02","name":"notification_sound.wav","server":"a7e32585d87233f4","version":5,"debugenabled":false,"domain":"media_player","service":"play_media","areaId":[],"deviceId":[],"entityId":["media_player.living_room_speaker"],"data":"{\"media_content_id\":\"http://192.168.1.80/notification_sound.wav\",\"media_content_type\":\"audio/mp3\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":940,"y":1480,"wires":[[]]},{"id":"d038737d9ec4f893","type":"mqtt-broker","name":"","broker":"mosquitto","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"a7e32585d87233f4","type":"server","name":"Home Assistant","version":2,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30"}]