Controlador doméstico Arduino con Alexa: Automatización inteligente simplificada
Componentes y suministros
| Arduino Yun | × | 1 |
| Controlador de relé de 4 canales para I2C (ControlEverything.com) | × | 1 |
| Sensor de temperatura y humedad DHT11 (4 pines) | × | 1 |
| Resistencia 10k ohm | × | 2 |
| Zumbador SparkFun RedBot | × | 1 |
| Transistor NPN de propósito general | × | 1 |
| Convertidor DC-DC Buck LM2596 | × | 1 |
| Amazon Alexa Echo Dot | × | 1 |
| Shield Proto de Arduino | × | 1 |
| Webcam USB | × | 1 |
| Caja de derivación blanca 200mmx155mmx80mm | × | 1 |
Herramientas y máquinas necesarias
- Soldador (genérico)
Aplicaciones y servicios en línea
- Arduino IDE
- Amazon Alexa Skills Kit
- Amazon Web Services AWS Lambda
- API PubNub Publish/Subscribe
Sobre este proyecto
Visión general
Cuando Amazon lanzó al mercado Alexa y dispositivos como Amazon Echo Dot, abrió un número infinito de opciones para crear un gran Hogar Inteligente controlado por comandos de voz usando lenguaje natural.
Este proyecto crea un Controlador Doméstico Arduino que puede conectar muchos sensores y dispositivos a internet y puedes controlarlos usando una skill de Amazon Alexa.
Puedes instalar y habilitar mi skill "Controlador Doméstico Arduino" el paso fácil, o puedes crear tu propia skill guiado por este tutorial.
Por ahora controlaremos:
- Cuatro luces en habitación, garaje, cocina y salón.
- Sensor de temperatura y humedad.
- Alarma de zumbador.
- Webcam para tomar foto de seguridad y enviar por email.
Puedes ver el Controlador Doméstico Arduino en acción en este video demo corto. Para demo y propósitos de video uso cuatro LEDs en protoboard simulando bombillas en cada habitación de la casa.
Si quieres usar módulos remotos para activar tus luces, puedes ver mi proyecto complementario Módulos Remotos Controlador Doméstico Arduino en esta URL.
Diagrama de bloques
En la imagen del diagrama de bloques podemos ver los cuatro componentes principales de este proyecto:
- Amazon Echo Dot para recibir comandos de voz y enviarlos a AWS (Amazon Web Service).
- AWS con una Skill de Amazon y una Función Lambda para interpretar todos los comandos. El nombre de la skill es "Controlador Doméstico Arduino", puedes activarla más tarde.
- Un Broker MQTT usando PubNub(c) cloud. Este broker recibirá los mensajes de control en dos canales, uno para establecer valores y otro para leer valores de sensores. No necesitas crear una cuenta en PubNub, puedes usar mi cuenta para propósitos de demo.
- Controlador Doméstico usando Arduino Yun. Usaremos Arduino Yun porque tiene shield ethernet dentro y una pequeña máquina Linux donde ejecutaremos Python para manejar algunas acciones. Controla relés para luces, lee sensor de temperatura y humedad, enciende zumbador para alarma y manipula una webcam para tomar foto de seguridad.
Para módulos remotos, ve mi proyecto complementario Módulos Remotos Controlador Doméstico Arduino en esta URL.
Instalar todo el software necesario
En este punto puedes tomar dos opciones: una para propósitos de demo, usa mi skill de Alexa, instálala y úsala; u opción dos, puedes crear tu skill personal.
Navega por la app de Alexa con este url, en esa selecciona la sección Skills en el menú, busca Arduino y en la lista verás la skill con nombre "Controlador Doméstico Arduino", haz clic en la tarjeta de la skill y haz clic en el botón "Habilitar" para instalar.
O necesitas ir a la tienda de Skills de Amazon usando este enlace y presionar el botón "Habilitar".
Necesitas vincular tu cuenta de Amazon porque usaremos tu dirección de email como ID para todos los comandos enviados a Arduino. Nota: no usaremos esta dirección para enviar emails, solo la usaremos como ID.
La skill está instalada y vinculada a la cuenta de Amazon y conectada a mi función lambda en la nube de AWS.
1.- Crear una skill
Necesitas registrarte y crear una cuenta de desarrollador gratuita en https://developer.amazon.com/home.html
1.1.- Una vez logueado, ve a la opción de menú Alexa y selecciona en Alexa Skills Kit el botón "Empezar".
1.2.- Luego haz clic en el botón "Añadir una nueva Skill" para crear una nueva skill.
1.3.- En la sección Crear una nueva Skill de Alexa debes:
- Seleccionar: Modelo de interacción personalizado
- Idioma Inglés EE.UU.
- Nombre TestSkill es el nombre de la skill para buscar en la tienda.
- Nombre de invocación Test Skill es el nombre para comenzar comandos de voz como Alexa Pregunta, Test Skill para encender alarma
- Todos los campos globales establecer en opción No
- Hacer clic en "Guardar"
La nueva skill fue creada y verás un nuevo campo Application Id:
amzn1.ask.skill.6e22e052-c32f-433c-8d39-dc94a77a4adb
Se usa para vincular entre la skill y la función lambda, la usaremos más tarde en la sección 2.5 del tutorial.
1.4.- Modelo de Interacción: aquí defines cómo interactúas con la skill basada en la definición de intents, slots y utterances.
En la opción de menú Modelo de Interacción copia y pega este esquema JSON en Intent Schema.
{
"intents": [
{
"slots": [
{ "name": "light", "type": "States" },
{ "name": "which", "type": "HabRooms" }
],
"intent": "LightIntent"
},
{
"slots": [
{ "name": "alarm", "type": "States" }
],
"intent": "AlarmIntent"
},
{ "intent": "TakePhotoIntent" },
{ "intent": "GetTemperatureIntent" },
{ "intent": "GetHumidityIntent" },
{ "intent": "AboutIntent" },
{ "intent": "AMAZON.HelpIntent" },
{ "intent": "AMAZON.CancelIntent" },
{ "intent": "AMAZON.StopIntent" }
]
}
Define algunos slots necesarios como States y HabRooms en Tipos de Slot Personalizados.
Define todos los utterances como un modelo de conversación en Sample Utterances, copia y pega esta lista.
LightIntent Turn {which} light {light}
LightIntent Set {which} light {light}
AlarmIntent Turn alarm {alarm}
TakePhotoIntent Take a Photo
TakePhotoIntent Take Security Photo
GetTemperatureIntent Read Temperature
GetHumidityIntent Read Humidity
AboutIntent Tell me about
AboutIntent About
Antes de continuar con la siguiente sección, Configuración, necesitamos haber creado nuestra Función Lambda porque necesitamos vincular tanto la skill como la función lambda.
2.- Crear una Función Lambda
Necesitas registrarte y crear una cuenta en AWS Console usando url https://aws.amazon.com/console/
2.1.- Selecciona Servicios en el menú superior y Lambda en la barra de menú izquierda.
2.2.- Selecciona en la barra izquierda Funciones y haz clic en el botón "Crear función".
2.3.- Establece estos datos:
- Clic en Crear desde cero
- Nombre: TestSkillLambda
- Runtime: Node.js 6.10
- Rol: Crear rol personalizado
Esto abrirá una nueva ventana donde debes seleccionar los siguientes valores:
- Rol IAM: Lambda_Basic_Execution
- Nombre de política: "Crear nueva política de rol" luego edita la política y pega lo siguiente:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"iot:UpdateThingShadow"
],
"Resource": "*"
}
]
}
Para guardar presiona el botón "Añadir" y regresa a la página Crear Función y selecciona lambda_basic_execution en el campo Rol existente.
2.4.- La función TestSkillLambda fue creada y verás su página de diseñador.
2.5.- Selecciona desde la barra de menú izquierda Alexa Skills Kit y agrégalo al área delimitada add triggers.
Haz clic en la caja Alexa Skills Kit y desplázate hacia abajo a la opción Configure triggers, selecciona Habilitar y en el campo Skill ID copia y pega el valor Application ID guardado antes, ver sección 1.3 del tutorial.
En este momento estamos vinculando la función lambda con la skill usando el Application o Skill ID.
Presiona el botón "Guardar" y Alexa Skills Kit se guardan y la función lambda conoce la skill y están vinculadas.
2.6.- Desplázate hacia abajo a la sección Function code y establece los campos:
- Tipo de entrada de código: Subir un archivo .zip
- Runtime: Node.js 6.10
- Presiona el botón "Subir" para subir el código de la función usando el archivo data.zip.
El editor de código se abrirá y verás las carpetas y archivos subidos.
Selecciona el archivo index.js que contiene toda la implementación de la función lambda.
Debes cambiar la línea 23, copia y pega el mismo Application ID usado antes en la sección 1.3 del tutorial.
Presiona el botón "Guardar" y la función lambda fue activada para recibir comandos de la skill.
var APP_ID = amzn1.ask.skill.6e22e052-c32f-433c-8d39-dc94a77a4adb
En la parte superior de la página sobre el botón "Guardar" verás el ARN (Amazon Resource Name), es el ID de la función lambda que usaremos en la sección Configuración en la página de la Skill.
3.- Volver a la definición de la Skill
3.1.- Selecciona la sección Configuración, en EndPoint selecciona AWS Lambda ARN, copia y pega la cadena ARN de arriba en el campo Default. Esta es la última acción para vincular la skill y la función lambda, la skill conoce la función lambda y están vinculadas.
3.2.- Desplázate hacia abajo a la sección Vinculación de cuenta y copia las dos primeras Redirect URLs, las necesitas para configurar el perfil de seguridad.
Antes de continuar con la Configuración de la skill, necesitamos definir un perfil de seguridad usado para vincular la skill y la cuenta de Amazon en la App de Alexa.
4.- Crear Perfil de Seguridad
En la misma consola de desarrollador usada para crear una skill, selecciona Apps & Services y Login with Amazon y presiona el botón "Crear un Nuevo Perfil de Seguridad".
4.1.- La página Gestión de Perfil de Seguridad te permite crear un perfil con toda la seguridad OAuth 2.0 para vincular la skill con tu cuenta de Amazon.
4.2.- Rellena todos los campos con estos datos:
- Nombre del Perfil de Seguridad: TestSkillProfile
- Descripción del Perfil de Seguridad: Perfil usado por TestSkill
- URL de Aviso de Privacidad y Consentimiento: https://www.amazon.com/gp/help/customer/display.html?nodeId=201809740 (este es un ejemplo, debes usar el tuyo)
- Haz clic en el botón "Guardar".
4.3.- Cuando guardes todos los datos o edites el perfil de seguridad, dos nuevos campos muestran datos importantes: Client ID y Client Secret. Los necesitas para la configuración final de la skill.
4.4.- Define las URLs de lista blanca, selecciona la pestaña Configuración Web.
- Orígenes Permitidos: https://layla.amazon.com y https://pitangui.amazon.com
- URLs de Retorno Permitidas: añade las dos primeras URLs de la sección 3.2
5.- Finalizar creación de la Skill
5.1.- Regresa a la definición de la skill, selecciona la sección Configuración y desplázate hacia abajo a Vinculación de Cuenta.
- ¿Permites a los usuarios crear una cuenta: Seleccionar Sí
- URL de Autorización: https://www.amazon.com/ap/oa/?redirect_url=UUUUUU Donde hay "UUUUUU" necesitarás reemplazar esto con una de las Redirect URLs de más abajo en la página. El enlace terminará pareciéndose a esto https://www.amazon.com/ap/oa/?redirect_url=https://layla.amazon.com/api/skill/link/UUUUUU
- Client Id: copiar y pegar Client Id de la sección 4.3.
- Alcance: profile, ver explicación en esta url.
5.2.- Continúa con la Vinculación de Cuenta:
- Tipo de Concesión de Autorización: Auth Code Grant
- URI de Token de Acceso: https://api.amazon.com/auth/o2/token
- Client Secret: copiar y pegar Client Secret de la sección 4.3.
- URL de Política de Privacidad: https://www.amazon.com/gp/help/customer/display.html?nodeId=201809740 (este es un ejemplo, debes usar el tuyo)
- Haz clic en los botones "Guardar" y "Siguiente"
5.3.- Los Campos Globales es la sección usada para documentar la skill.
- Seleccionar categoría donde encontrar la skill en la tienda cuando esté certificada, "Hogar Inteligente"
- Instrucciones de prueba
- La skill estará disponible en todos los países.
- Descripción corta
- Descripción completa de la skill
- Frases de ejemplo
- Algunas palabras clave que definen la skill
- Icono Png o Jpg 108x108 píxeles
- Icono Png o Jpg 512x512 píxeles
5.4.- Última sección Privacidad y Cumplimiento
6.- Instalar TestSkill en la App de Alexa
6.1- Cuando guardes la skill, puedes ir a la App de Alexa en https://alexa.amazon.com/, selecciona en la barra de menú izquierda la opción Skills, haz clic en el botón arriba a la derecha "Tus skills" y el filtro Dev Skills verás la tarjeta TestSkill. Nota el mensaje de vinculación de cuenta requerido.
6.2.- Si haces clic en la tarjeta, la página de descripción de TestSkill muestra toda la información sobre la skill, haz clic en el botón "Habilitar".
6.3.- Debido a la definición de vinculación de cuenta requerida, serás redirigido a la página de credenciales de login de Amazon para vincular la skill con tu cuenta de Amazon.
Si la info de login es validada, verás esta página indicando que la skill está vinculada con tu cuenta de Amazon.
6.4.- La skill está terminada, instalada y vinculada a tu cuenta de Amazon y conectada a la función Lambda.
Puedes probar diciendo Alexa, pregunta a Test Skill y verás la bienvenida al Controlador Doméstico Arduino porque todos los diálogos son los mismos.
Configurar Arduino Yun
Si es la primera vez que usas Arduino Yun, necesitas prepararlo antes de subir el sketch.
Sugiero ver la guía o tutorial de Greg Baugues "Empezando con Arduino Yun – el Arduino con WiFi". Gracias al usuario de Hackster @BenEagen por encontrar esta guía.
Para tomar foto y enviar email con ella, necesitamos instalar software adicional. También vamos a probar la cámara USB para ver si los drivers funcionan correctamente. Por favor, conecta la webcam USB en el puerto USB de Arduino Yun.
Para hacer eso, conecta a Arduino Yun con una terminal:
ssh root@tuYunName.local
La contraseña por defecto es arduino.
Si la conexión es correcta verás el prompt de Linux OpenWRT.
Instalar software de generación de imágenes
Empieza con una actualización del gestor de paquetes:
opkg update
Instala los drivers UVC:
opkg install kmod-video-uvc
Instala el paquete python-openssl:
opkg install python-openssl
También necesitamos la utilidad fswebcam que usaremos para tomar fotos desde la terminal:
opkg install fswebcam
Asegúrate de que la tarjeta SD está montada en Arduino Yun, puedes probarlo ejecutando este comando:
mount
Si ves en la lista de dispositivos una como /dev/sda1 on /mnt/sda1 type vfat, la tarjeta SD está OK.
Para probar la cámara y tomar una foto, es muy fácil. Simplemente escribe:
cd /mnt/sda1
fswebcam test.png
Deberías ver alguna información mostrada, junto con algunos errores, pero no te preocupes por ellos. Lo importante es ver estas líneas:
--- Opening /dev/video0... Trying source module v4l2... /dev/video0 opened.
Para comprobar que la foto se tomó correctamente, quita la tarjeta SD del Arduino Yun y léela usando tu computadora. Deberías ver la foto apareciendo en la raíz de la tarjeta SD "test.png".
Simplemente ábrela para asegurarte de que se tomó correctamente y que no está corrupta.
Instalar software de envío de email
Con la SD en tu computadora, copia el archivo python AHC_SendEmail.py y cambia tu email y contraseña de una cuenta de gmail en las líneas 11, 12 y 13; si tienes otro proveedor de email, cambia la información del servidor en la línea 36.
Extrae la SD de la computadora e insértala en la ranura SD del Arduino Yun. En la terminal conectada a Arduino Yun, ejecuta los comandos:
cd /mnt/sda1
python /mnt/sda1/AHC_SendEmail.py /mnt/sda1/ test.png
Si todo está bien, debes recibir un email con tu foto.
Conectar todos los dispositivos a Arduino Yun
Basado en el esquema electrónico, conecta todos los dispositivos, especialmente el sensor DHT11 porque lo necesitamos para leer temperatura y humedad, y el zumbador para probar el sonido de alarma.
Instalar el archivo del sketch ArduinoHomeMQTT.ino
He creado un archivo libraries.zip con todas las librerías necesarias para este archivo, puedes descargarlo desde mi sitio de GitHub y descomprimirlo en el directorio de librerías del Arduino IDE.
Librerías incluidas en libraries.zip dentro de la carpeta ArduinoHomeMQTT:
- ArduinoJson → usado para manipular contenido JSON
- DHT_sensor_library → usado para manejar sensor DHT
- pubsubclient-master → usado para conectar, publicar y suscribirse a PubNub(c)
Abre Arduino IDE 1.6.x, en herramientas selecciona "Placa: Arduino Yun".
Carga el archivo ArduinoHomeMQTT.ino y en el IDE modifica la línea 16 con tu email de Amazon usado cuando vinculaste la cuenta en la App de Alexa skill habilitada.
Esta opción identifica tu controlador cuando AWS envía mensaje MQTT al broker.
Cambia la línea 50 con tu uuid para identificar tu controlador en PubNub(c), puedes ir a este sitio y copiar y pegar el uuid generado en línea.
Ahora guarda y sube el sketch y cuando abras la ventana del monitor del Arduino IDE podrás ver Arduino Yun conectado al broker PubNub(c) e sensor inicializado.
Probar todos los utterances desde Alexa Echo Dot
La skill de Alexa "Controlador Doméstico Arduino" maneja esta lista de utterances, puedes verlas en la App de Alexa skill en la sección de descripción. Puedes probar todas y ver en el monitor serie del Arduino ID todos los mensajes recibidos y enviados al broker PubNub(c).
Control de luces:
==> "Alexa, pide a arduino home que encienda la luz de la habitación"
==> "Alexa, pide a arduino home que apague la luz de la habitación"
==> "Alexa, pide a arduino home que encienda la luz de la cocina"
==> "Alexa, pide a arduino home que apague la luz de la cocina"
==> "Alexa, pide a arduino home que encienda la luz del garaje"
==> "Alexa, pide a arduino home que apague la luz del garaje"
==> "Alexa, pide a arduino home que encienda la luz del salón"
==> "Alexa, pide a arduino home que apague la luz del salón"
Control de alarma:
==> "Alexa, pide a arduino home que encienda la alarma"
==> "Alexa, pide a arduino home que apague la alarma"
Escanear Temperatura y Humedad:
==> "Alexa, pide a arduino home que lea la temperatura"
==> "Alexa, pide a arduino home que lea la humedad"
Tomar una foto de seguridad:
==> "Alexa, pide a arduino home que tome una foto"
Acerca de y Ayuda:
==> "Alexa, pide a arduino home acerca de"
==> "Alexa, pide a arduino home ayuda"
Detalles del software
Puedes descargar todos los archivos para este proyecto desde mi sitio de Github.
Carpetas contienen explicación
- ArduinoHomeMQTT → archivo ino y librerías para Arduino Yun Controlador Doméstico
- lambda → Función Lambda en Node.js para desplegar en AWS Lambda, incluye todos los node_modules necesarios, ver opción 2 en instalar todo el software.
- python → archivo python para enviar email con foto adjunta.
- schematic → archivo esquemático electrónico Fritzing(c).
Flujo de trabajo del Controlador Doméstico Arduino te muestra cómo interactúan los archivos.
- Amazon Echo Dot envía comando de voz y es recibido por skill Controlador Doméstico Arduino.
- La skill llama a la función Lambda archivo index.js.
- El archivo de función lambda está desarrollado en Node.Js, usa algunos node modules y está alojado en Amazon Web Service (AWS).
- La función lambda interpreta todos los intents y los convierte a mensaje MQTT JSON y lo envía al broker PubNub(c). Este mensaje tiene el formato:
{ "topic" : Topic_xxxx, "command" : on or off, "id" : email address }
El topic Topic_xxxx puede ser:
Topic_room → encender/apagar luz de habitación
Topic_livingroom → encender/apagar luz de salón
Topic_kitchen → encender/apagar luz de cocina
Topic_garage → encender/apagar luz de garaje
Topic_alarm → encender/apagar alarma
Topic_temperature → leer temperatura
Topic_humidity → leer humedad
Topic_photo → tomar y enviar foto por email
El comando puede ser on o off.
El mensaje se envía usando el canal AHC_IOC_01. El canal AHC_IOC_02 se usa para recibir valores de temperatura o humedad.
El sketch de Arduino Yun ArduinoHomeMQTT.ino se conecta al broker y se suscribe o publica en canales y recibe o envía mensajes.
Usando un bridge, el sketch de Arduino se comunica con Linux OpenWRT para conexión wan o lan y para ejecutar algunos comandos.
Si Arduino necesita enviar un email, usa el archivo python AHC_SendEmail.py; si necesita tomar una foto, llama al programa fswebcam ubicado dentro de Linux OpenWRT.
Detalles de hardware
El corazón del hardware es el Arduino Yun.
Usa varios pines digitales para controlar cada dispositivo:
Pin 2: conectado al sensor DHT11
Pin 8: activar alarma de zumbador con ayuda de transistor NPN
Pin 9: controlar luz de habitación
Pin 10: controlar luz de cocina
Pin 11: controlar luz de garaje
Pin 12: controlar luz de salón
La webcam está conectada al puerto USB.
Para alimentar todos los dispositivos, el controlador usa 12 voltios DC y convierte a 5 voltios usando un convertidor DC a DC.
Hice un shield de Arduino usando el Arduino Proto Shield con todos los conectores e interfaz electrónica para sensor, alarma de zumbador y fuente de alimentación. Tiene espacio para nuevos sensores para extender el controlador.
Para demo y propósitos de video uso cuatro LEDs en protoboard simulando bombillas en cada habitación de la casa.
Pon el Arduino Yun, Proto shield, Relés y regulador de alimentación dentro de una caja de plástico con alarma, webcam y sensor fuera, y haz todas las conexiones como se menciona en el esquema electrónico.
Gracias por leer esta guía, aprecio tu tiempo. Si tienes alguna sugerencia, por favor contáctame.
Hice este proyecto en memoria de mi Papá, él falleció el año pasado, D.E.P. Papá.
Código
ArduinoHomeMQTT.ino Arduino
Software Arduino Yun para Controlador Doméstico
// ArduinoHomeMQTT // v2.1 // Copyright (C)2018 Jose Cruz. All right reserved // web: https://sites.google.com/view/raeiot/home #include#include #include #include #include // Tu email de Amazon vinculado en la skill #define MyID "TU EMAIL DE AMAZON VINCULADO EN LA APP ALEXA" // Pin de datos del sensor DHT11 #define DHTPIN 2 // Tipo de sensor DHT 11 #define DHTTYPE DHT11 // Inicializar sensor DHT DHT dht(DHTPIN, DHTTYPE); // Pin de control de alarma #define alarm 8 // Pines de control de luces #define room_light 9 #define kitchen_light 10 #define garage_light 11 #define livingroom_light 12 // Dirección y puerto del servidor MQTT PubNub int mqtt_server_port = 1883; const char* mqtt_server = "mqtt.pndsn.com"; // Topic de suscripción const char* topic = "AHC_IOT_01"; // Topic de publicación const char* topic2 = "AHC_IOT_02"; // ID de publicador PubNub // pub-c-e93def7f-95aa-475a-aa60-cc3cd32ee8a7/ // ID de suscriptor PubNub // sub-c-ec04dbbc-0893-11e8-8e75-cea83f8405bb/ // UUID generado en línea https://www.uuidgenerator.net/ // ID de cliente PubNub // clientId = pubID + subID + uuid; const char* clientId = "pub-c-e93def7f-95aa-475a-aa60-cc3cd32ee8a7/sub-c-ec04dbbc-0893-11e8-8e75-cea83f8405bb/TU UUID GENERADO"; // Definir cliente ethernet Yun YunClient ethClient; // Definir cliente pub y sub PubNub PubSubClient client(ethClient); // Proceso de foto Process picture; // Nombre de archivo String filename; // Ruta para archivo de imagen String path = "/mnt/sda1/"; // Crear archivo de imagen y enviar por email void TakePhoto() { filename = ""; picture.runShellCommand("date +%s"); while (picture.running()); while (picture.available() > 0) { char c = picture.read(); filename += c; } filename.trim(); filename += ".jpg"; // Tomar foto picture.runShellCommand("/usr/bin/fswebcam -i 0 --jpeg 95 --no-banner --fps 1 -S 1 -r 352x288 --save " + path + filename); while (picture.running()); // Enviar por email picture.runShellCommand("python /mnt/sda1/AHC_SendEmail.py " + path + " " + filename); while (picture.running()); } // Enviar temperatura void SendTemperature() { char cstr[16]; float t = dht.readTemperature(); client.publish(topic2, itoa(t, cstr, 10)); } // Enviar humedad void SendHumidity() { char cstr[16]; float h = dht.readHumidity(); client.publish(topic2, itoa(h, cstr, 10)); } // Función callback para manejo de mensajes recibidos 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(); StaticJsonBuffer<200> jsonBuffer; JsonObject& root = jsonBuffer.parseObject((char[])payload); String alexa_topic = root["topic"]; String alexa_command = root["command"]; String alexa_id = root["id"]; if (alexa_id.equals(MyID)) { if (alexa_topic.endsWith("Topic_room")) { digitalWrite(room_light, (alexa_command.endsWith("on") ? LOW : HIGH)); } else if (alexa_topic.endsWith("Topic_kitchen")) { digitalWrite(kitchen_light, (alexa_command.endsWith("on") ? LOW : HIGH)); } else if (alexa_topic.endsWith("Topic_garage")) { digitalWrite(garage_light, (alexa_command.endsWith("on") ? LOW : HIGH)); } else if (alexa_topic.endsWith("Topic_living room")) { digitalWrite(livingroom_light, (alexa_command.endsWith("on") ? LOW : HIGH)); } else if (alexa_topic.endsWith("Topic_temperature")) { SendTemperature(); } else if (alexa_topic.endsWith("Topic_humidity")) { SendHumidity(); } else if (alexa_topic.endsWith("Topic_alarm")) { digitalWrite(alarm, (alexa_command.endsWith("on") ? HIGH : LOW)); } else if (alexa_topic.endsWith("Topic_photo")) { TakePhoto(); } } } // Reconectar al broker MQTT si se pierde la conexión void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect(clientId)) { Serial.println("MQTT broker connected"); client.subscribe(topic); } else { Serial.print("Failed, rc = "); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Bridge.begin(); delay(2000); Serial.begin(115200); Serial.println("Init Arduino Home Controller v2.1..."); pinMode(alarm, OUTPUT); pinMode(room_light, OUTPUT); pinMode(kitchen_light, OUTPUT); pinMode(garage_light, OUTPUT); pinMode(livingroom_light, OUTPUT); digitalWrite(room_light, HIGH); digitalWrite(kitchen_light, HIGH); digitalWrite(garage_light, HIGH); digitalWrite(livingroom_light, HIGH); // Definir broker MQTT PubNub client.setServer(mqtt_server, mqtt_server_port); client.setCallback(callback); client.connect(clientId); Serial.println("Connected to PubNub MQTT broker OK ..."); client.subscribe(topic); Serial.println("Suscribe to topic at MQTT broker Ok ..."); dht.begin(); // Esperar inicialización del sensor delay(4000); Serial.println("DHT sensor Ok ..."); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); }
AHC_SendEmail.py Python
Archivo para instalar en Arduino Yun OpenWRT Linux para ayudar a enviar email con foto adjunta
import smtplib
import sys
import time
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders
fromaddr = "joseacruzp@gmail.com"
toaddr = "joseacruzp@gmail.com"
emailpassword = "TU CONTRASEÑA"
subject = "Arduino Home Controller by Alexa Skill"
body = "Photo taken in " + time.strftime('%a, %d %b %Y %H:%M:%S %Z(%z)')
filedir = sys.argv[1]
filename = sys.argv[2]
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = subject
msg.attach(MIMEText(body, 'plain'))
attachment = open(filedir + filename, "rb")
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(part)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, emailpassword)
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
index.js JavaScript
Función AWS Lambda si seleccionas opción 2, crear tu propia skill
// Alexa SDK para Controlador Doméstico Arduino
// Copyright (c) 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Use is subject to license terms.
// Jose Cruz https://sites.google.com/view/jriot
// Definir conexión a PubNub
var PubNub = require("pubnub");
var pubnub = new PubNub({
ssl: true,
publish_key: "pub-c-e93def7f-95aa-475a-aa60-cc3cd32ee8a7",
subscribe_key: "sub-c-ec04dbbc-0893-11e8-8e75-cea83f8405bb",
uuid: "TU UUID"
});
// Definir canal PubNub
var channel = 'AHC_IOT_01';
// Usado para recibir algunos valores (temperatura, humedad)
var channel2 = 'AHC_IOT_02';
// Definir estados de slot para luz y alarma encender/apagar
var slotStates = ['on', 'off'];
// App ID para la skill
var APP_ID = 'TU APP ID PARA LA SKILL';
// Prototipo AlexaSkill y funciones helper
var AlexaSkill = require('./AlexaSkill');
var ArduinoHomeSkill = function() {
AlexaSkill.call(this, APP_ID);
};
// Listener para suscribir y recibir temperatura y humedad
var mqttListener;
var access_token;
var url;
var https = require("https");
function SendMessage(topicname, commandvalue, speechOutput, iresponse) {
https.get(url, res => {
res.setEncoding("utf8");
let body = "";
res.on("data", data => { body += data; });
res.on("end", () => {
pubnub.publish({
channel: channel,
message: {
"topic": topicname,
"command": commandvalue,
"id": JSON.parse(body).email
}
}).then((response) => {
console.log("message Published w/ timetoken", response.timetoken);
if (speechOutput) iresponse.tell(speechOutput);
}).catch((error) => {
console.log("publishing failed w/ status: ", error);
iresponse.ask("Sorry, I didn't catch what you said");
});
});
});
}
/// Extender AlexaSkill
ArduinoHomeSkill.prototype = Object.create(AlexaSkill.prototype);
ArduinoHomeSkill.prototype.constructor = ArduinoHomeSkill;
ArduinoHomeSkill.prototype.eventHandlers.onSessionStarted = function(sessionStartedRequest, session) {
console.log("ArduinoHomeSkill onSessionStarted requestId: " + sessionStartedRequest.requestId + ", sessionId: " + session.sessionId);
pubnub.removeListener(mqttListener);
pubnub.unsubscribeAll();
};
// Invocado por palabra de invocación "Arduino Home"
ArduinoHomeSkill.prototype.eventHandlers.onLaunch = function(launchRequest, session, response) {
console.log("ArduinoHomeSkill onLaunch requestId: " + launchRequest.requestId + ", sessionId: " + session.sessionId);
if (session.user.accessToken == undefined) {
response.tellWithCardLink('To start using this skill, please use the companion app to authenticate on Amazon.');
return;
}
var speechOutput = "Welcome to Arduino Home Controller. What would you like to do?";
var repromptText = "I am ready";
response.ask(speechOutput, repromptText);
};
ArduinoHomeSkill.prototype.eventHandlers.onSessionEnded = function(sessionEndedRequest, session) {
console.log("ArduinoHomeSkill onSessionEnded requestId: " + sessionEndedRequest.requestId + ", sessionId: " + session.sessionId);
console.log("End...");
};
// Definir todos los manejadores de intent
ArduinoHomeSkill.prototype.intentHandlers = {
"AboutIntent": function(intent, session, response) {
var myText;
console.log("in about");
myText = "Arduino Home Controller skill te permite controlar dispositivos conectados a internet. Controla luces en habitación, cocina, garaje o salón, lee sensor de temperatura para escanear temperatura del hogar, lee sensor de humedad para escanear humedad del hogar, usa webcam para tomar foto de seguridad del hogar y enviarla por email y activa una alarma para alertar algunos eventos. Usa el sitio PubNub para manipular todos los mensajes enviados por Alexa con función Lambda. Por favor, revisa la información en la página de la skill para más detalles. ¿Qué te gustaría hacer?";
response.ask(myText);
return;
},
"LightIntent": function(intent, session, response) {
var slotHabRooms = ['room', 'kitchen', 'garage', 'living room'];
var lightSlot = intent.slots.light;
var lightSlotValue = lightSlot ? lightSlot.value : "";
var whichSlot = intent.slots.which;
var whichSlotValue = whichSlot ? whichSlot.value : "";
if (lightSlotValue && whichSlotValue && slotStates.indexOf(lightSlotValue.toLowerCase()) > -1 && slotHabRooms.indexOf(whichSlotValue.toLowerCase()) > -1) {
SendMessage('Topic_' + whichSlotValue, lightSlotValue, "The light is now " + lightSlotValue, response);
} else {
response.ask("Sorry, I didn't catch what you said");
}
},
"AlarmIntent": function(intent, session, response) {
var alarmSlot = intent.slots.alarm;
var alarmSlotValue = alarmSlot ? alarmSlot.value : "";
if (alarmSlotValue && slotStates.indexOf(alarmSlotValue.toLowerCase()) > -1) {
SendMessage('Topic_alarm', alarmSlotValue, "The alarm is now " + alarmSlotValue, response);
} else {
response.ask("Sorry, I didn't catch what you said");
}
},
"TakePhotoIntent": function(intent, session, response) {
SendMessage('Topic_photo', 'take', "Taken home photo ", response);
},
"GetTemperatureIntent": function(intent, session, response) {
mqttListener = {
status: function(statusEvent) {},
message: function(message) {
console.log("Receive=", message);
var myText = "Inside Temperature is " + message.message + " degrees C";
response.tell(myText);
},
presence: function(presenceEvent) {}
};
pubnub.addListener(mqttListener);
pubnub.subscribe({ channels: [channel2] });
SendMessage('Topic_temperature', 'Ok', null, response)
},
"GetHumidityIntent": function(intent, session, response) {
mqttListener = {
status: function(statusEvent) {},
message: function(message) {
console.log("Receive=", message);
var myText = "Inside Humidity is " + message.message + " %";
response.tell(myText);
},
presence: function(presenceEvent) {}
};
pubnub.addListener(mqttListener);
pubnub.subscribe({ channels: [channel2] });
SendMessage('Topic_humidity', 'Ok', null, response)
},
"AMAZON.HelpIntent": function(intent, session, response) {
response.ask("Con Arduino Home Controller skill y Alexa puedes controlar dispositivos conectados a internet usando un Arduino Yun o Arduino con Ethernet Shield. Por favor, revisa la información en la página de la skill para más detalles. ¿Qué te gustaría hacer?");
},
"AMAZON.StopIntent": function(intent, session, response) {
response.tell("Thanks for using Arduino Home Controller. Bye see you later");
},
"AMAZON.CancelIntent": function(intent, session, response) {
response.tell("Thanks for using Arduino Home Controller. Bye see you later");
},
default: function(intent, session, response) {
response.ask("Try again");
},
};
// Crear el manejador que responde a la petición de Alexa
exports.handler = function(event, context) {
try {
access_token = event['context']['System']['user']['accessToken'];
url = 'https://api.amazon.com/user/profile?access_token=' + access_token;
} catch (error) {
console.log(error);
}
var ArduinoHomeControl = new ArduinoHomeSkill();
ArduinoHomeControl.execute(event, context);
};
Github
https://github.com/jcruzp/ArduinoHomeController
Esquemas
Placa principal con relés, sensor de temperatura y humedad, alarma de zumbador y webcam.
Proceso de manufactura
- Sistema de Iluminación DMX Controlado por Web – Controlador Maestro Arduino
- Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- Pixel Chaser: Juego LED Interactivo de Un Toque con Arduino Nano
- Sistema inteligente de riego para plantas con Arduino Nano
- Levitación magnética repulsiva con Arduino: Circuito simple y guía DIY
- Kit controlador para display fluorescente al vacío (VFD) basado en Arduino
- Robot Asistente Doméstico Autónomo "O'nine" – Integración ROS, Alexa y Brazo Robótico
- Pong Neón en Matriz NeoPixel con Arduino Nano
- Controlador Probador Arduino DMX-512 – Kit Completo de Componentes para Control de Iluminación Fiable
- Juego Ruleta LED DIY: Crea un Arcade para Una Persona con Arduino Nano