Interruptor de alimentación USB habilitado para Alexa
Componentes y suministros
| × | 1 | ||||
| × | 8 | ||||
| × | 4 | ||||
| × | 4 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 4 | ||||
| × | 4 | ||||
| × | 1 | ||||
| × | 1 |
Herramientas y máquinas necesarias
| ||||
|
Aplicaciones y servicios en línea
| ||||
| ||||
|
Acerca de este proyecto
Alexa, enciende ThingyStick ...
Antecedentes
Cada vez más dispositivos funcionan con USB, muchos de estos tienden a ser dispositivos "tontos" sin conectividad a Internet ni opciones de automatización del hogar (por ejemplo, luces LED), ¿cómo podemos automatizarlos o controlarlos de forma remota? Quizás una fuente USB conectada a un interruptor de red, eso es un poco exagerado, ¡especialmente si queremos 4 dispositivos controlados individualmente!
Este proyecto le permite controlar la fuente de alimentación de los dispositivos alimentados por USB a través de Internet, y al usar Tinamous SmartHome Skill para Alexa, puede habilitar el control de voz para sus dispositivos USB tontos.
Actualmente, hay muy pocos dispositivos en el mercado para controlar la alimentación USB de forma remota, cuando comencé este proyecto no encontré ninguno (en el Reino Unido), pero recientemente han aparecido un par como parte de puntos de venta de múltiples bandas (sí, la idea comenzó hace mucho tiempo, en una galaxia muy lejana), estos no son de fabricantes conocidos de automatización del hogar, sino de fabricantes sin marca (es decir, ZLD-34UK), por lo que tenemos el problema de qué dispositivo en la nube usan, si los datos van a China y viceversa, qué sucede si ese fabricante ya no existe, qué tan seguro es, qué tan utilizable es el software, estará en la caja de reciclaje la semana que viene, y muchas de las otras preocupaciones normales de los dispositivos conectados a Internet, por no hablar de siendo hackeable de la misma manera que lo puede ser un dispositivo de código abierto con Arduino.
Casos de uso
Ejemplos de dispositivos alimentados por USB que podríamos querer controlar:
- Luces alimentadas por USB
- Kindle Fire / Chrome Cast Sticks (especialmente en las habitaciones de los niños para que no vean televisión)
- Humidificadores USB
- Echo Dot (¿hacer que Alexa se apague por la noche? o simplemente reiniciar el dispositivo)
- Tableros de desarrollo. ¿Necesita reiniciar ese proyecto porque sus códigos entraron en un ciclo infinito?
- Dispositivos de difícil acceso pero que deben reiniciarse ocasionalmente (es decir, sensores en el desván).
- Dispositivos instalados en las instalaciones del cliente donde queremos asegurarnos de que esté alimentado (midiendo el consumo de corriente y el voltaje de entrada)
Control de potencia simple: Conmutación de energía habilitada para Internet, ya sea a través del control de voz de Alexa u otros comandos a través de Tinamous. Encendido y apagado.
Control de energía inteligente: Muchas lámparas USB tienen controles táctiles para encender la lámpara, lo que significa que no podemos encender la luz de forma remota, pero podemos apagarla, y muchas veces eso es todo lo que queremos (intentar dormir, dejar una lámpara encendida ? Salir, quieres apagar todas las luces?).
Sin embargo, una vez que hemos usado Alexa para apagar la lámpara USB, tenemos que pedirle a Alexa que encienda la lámpara antes de poder encenderla, eso es una tontería. Con la energía inteligente habilitada, el comando de apagado apagará la lámpara durante unos segundos antes de restaurar la energía al dispositivo. Suficiente para apagar la lámpara, pero también para permitir el funcionamiento normal después.
Automatización del temporizador: Haga que sus dispositivos se apaguen automáticamente a las horas establecidas. ¿Los niños que ven Amazon TV en el fuego se quedan hasta tarde? Haga que el suministro USB se apague automáticamente a las 8 p.m.
Supervisión de energía: Si está desarrollando hardware alimentado por USB, es posible que desee saber cuánta corriente está consumiendo su dispositivo, especialmente cuando se enciende por primera vez, o puede que desee perfilar la carga de la batería. Con el INA219 integrado puede controlar el consumo de corriente (gestioné un muestreo de aproximadamente 1 kHz con poco esfuerzo). La caída de voltaje en los cables USB a alta corriente también puede ser un problema, el INA219 monitorea la energía en el dispositivo para que podamos advertir de bajo voltaje. También se proporciona un bloque de terminales para permitir el uso de corrientes más altas y cables más grandes.
Fallo de energía: Al usar la opción de batería en el MKR 1000, podemos monitorear el voltaje de suministro USB y enviar notificaciones si falla la energía de entrada. Esto podría ser útil para soluciones remotas (fuera del sitio) que usan alimentación USB pero necesitan un poco de monitoreo adicional, o simplemente como una simple detección de falla de energía eléctrica para su casa.
Hardware
Este proyecto es bastante simple, un Arduino MKR1000 en el corazón, conmutación de energía USB usando dos LM3526M para proporcionar conmutación de lado alto y detección de fallas (bajo voltaje, sobrecorriente), junto con monitoreo de energía (voltaje y corriente) usando un INA219, y finalmente LED e interruptores para opciones de control local.
Hice una PCB en DirtyPCBs.com, también puede enviar el archivo .brd a OSHPark.com para que se fabriquen algunas. El zócalo Arduino tiene almohadillas de PCB a cada lado de cada pin para permitir la piratería. p.ej. podría agregar fácilmente algunos sensores para las condiciones ambientales o una pequeña pantalla OLED para mostrar el voltaje y la corriente.
En el repositorio de github hay una opción de 2 puertos y 4 puertos. Tenga cuidado con la PCB de 2 puertos, ya que me equivoqué y obtuve el diseño incorrecto de la toma USB (están de atrás hacia adelante - polaridad incorrecta ) !).
Victoria de las fauces de la derrota:
Resulta que montar el USB en la parte posterior de la placa es en realidad una buena solución y significaba que las conexiones de los pines eran correctas (sin embargo, para la placa de 2 puertos, ¡también significa que la pantalla de seda está en el lado equivocado!). El Arduino con encabezados en un zócalo fue un poco empujado por el espacio con la altura requerida para sacar los enchufes USB del gabinete, por lo que en realidad funcionó mejor, decidí volver a hacer la placa con enchufes, interruptores y LED en el reverso lateral y para agregar dos puertos adicionales, por lo tanto, se creó la versión de cuatro puertos (también, tenía los LED alineados horriblemente en el 2 porter, ¡así que eso también se solucionó!).
Lo suyo es muy poco para evitar que esto se extienda a un conmutador de 6 u 8 puertos, aunque es posible que sea necesario eliminar o mejorar los LED y los conmutadores.
El esquema parece mucho más complejo de construir de lo que es. Muchas de las resistencias son opcionales. Los resistores R23, 19, 27 y 26 son todos pull-ups para los interruptores, del mismo modo R20-22, R14 y R15 son pull-ups para el control USB y la detección de fallas. Todo esto se puede hacer a través del modo de pin INPUT_PULLUP en el Arduino, sin embargo, si desea poner el Arduino en suspensión de baja potencia y usar interrupciones para activarlo, es posible que desee completarlos para que no floten (y reboten) .
También agregué resistencias opcionales alrededor de las líneas USB D + / D-. Estos se pueden instalar para decirle al dispositivo cuánta energía puede usar, pero para muchos dispositivos tontos, estos se ignoran de todos modos. A continuación, solo se necesita R24 para la limitación de corriente del LED. R2-5 y R28 se dejan vacíos.
Los LED y los interruptores también son completamente opcionales. Si solo desea una caja independiente que controle el USB de forma remota, no agregue esas partes.
Entrada de energía
Este controlador se puede alimentar a través de tres opciones.
La primera es la opción "Interna" (pines JP6 1 y 2 conectados), la alimentación USB se toma del pin 5V del Arduino (y por lo tanto del conector USB Arduino). Sin embargo, esto solo debe usarse para cargas de baja potencia.
Las otras opciones son para alimentación externa (pines 2 y 3 de JP6 conectados), luego puede conectar 5 V a través de J2 (el micro conector USB integrado) o JP8 (un bloque de terminales). No debes usar ambas opciones al mismo tiempo. La energía externa también se enruta al pin Arduino VIn, por lo que no necesitará su propia opción de energía también.
Para obtener puntos de bonificación, la instalación de resistencias 0R en R10 y R11, así como J2 proporciona un paso de USB para USB 3 para que podamos reiniciar un dispositivo conectado por USB, muy útil cuando se desarrolla hardware y no desea gastar sus enchufes USB en la PC!
Recinto
Se incluye un gabinete imprimible en 3D con este proyecto. Utiliza insertos de ajuste térmico M3 para conexiones de tapa y PCB, aunque las tolerancias en la tapa son lo suficientemente buenas para un ajuste por fricción.
La tapa incluye algunas opciones.
- Con o sin compartimento para pilas.
- Con o sin pies (también conocidos como orificios de montaje para permitir que la caja se asegure a una superficie).
Asimismo, la caja base se puede configurar (usando OpenSCAD) para incluir aberturas para cada una de las tres fuentes de energía.
Se necesitaron algunos intentos para que el recinto estuviera bien. ¿Cómo versionas tus impresiones? Mis muestras del club de fans de Rigid.Ink fueron muy útiles.
Conectarse a Tinamous
Estamos usando el Arduino MKR1000 para controlar los enchufes, por lo que tenemos conectividad WiFi. Si es nuevo en esta placa, deberá agregar la opción de placa a su IDE de Arduino.
Vamos a utilizar el servidor Tinamous MQTT para conectarnos, principalmente porque es increíble, pero también, ¡quizás porque soy el fundador / desarrollador / fabricante de té! Nos suscribiremos al tema de publicación de estado para los mensajes enviados al dispositivo. (es decir, el tema "Status.To").
Antes de comenzar a codificar, debemos asegurarnos de que Arduino tenga el firmware más reciente, así como los certificados SSL necesarios para obtener una conexión segura a Tinamous. Obviamente, si lo prefiere, puede adaptar esto a su propio servidor MQTT local y no preocuparse tanto por la seguridad.
Paso 1
Abra el IDE de Arduino y cargue el FirmwareUpdater bosquejo del menú de ejemplos de WiFi101. Sube esto a tu dispositivo.
Paso 2
Una vez cargado, seleccione WiFi101 Firmware Updater de las Herramientas menú.
Paso 3
Pruebe su conexión y luego Actualice el firmware . Una vez hecho esto, use la opción Agregar dominio y agrega tinamous.com para asegurarse de que Arduino tenga los certificados SSL correctos en su lugar. Pulsa el módulo Subir certificados a WiFi para cargar los certificados.
Paso 4
Ahora podemos escribir nuestro propio firmware. Encontrarás los archivos adjuntos a este proyecto y también en el repositorio de GitHub (GitHub tendrá la última versión).
Usaremos WiFi101 y MQTT Client para su boceto de Arduino.
Seleccione la opción MQTT by Joel Gaehwiler.
El archivo secrets.h debe completarse con su configuración de WiFi y Tinamous MQTT, no he incluido mi copia por razones obvias.
Configuración del servidor WiFi y MQTT:
#define SECRET_SSID "Your SSID" #define SECRET_PASS "Your SSIDs Password" / ************************ Configuración de Tinamous MQTT ********************************* / # define MQTT_SERVER " .tinamous.com" #define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch. " # define MQTT_PASSWORD "Su contraseña va aquí." # Define MQTT_CLIENT_ID "UsbSwitch" #define DEVICE_USERNAME "UsbSwitch"
Si aún no se ha registrado en Tinamous, puede crear su propia cuenta gratuita aquí. Cuando se registra, se le solicita un nombre de Cuenta / Organización, este se convierte en su propia área privada de Tinamous, puede invitar a otros miembros a esa área (incluida Alexa) y compartir sus dispositivos con su grupo.
A continuación, llamo a mi cuenta "AlexaExample", esto es lo que necesitaré incluir en la configuración de MQTT, y mi cuenta de Tinamous está en https://AlexaExample.Tinamous.com
Paso 5
A continuación, debemos agregar nuestro dispositivo. En la página de Dispositivos Tinamous, haga clic en el botón Agregar.
Por lo tanto, la configuración de Tinamous MQTT para mi dispositivo se parece a esto ...
/ ************************* Configuración de Tinamous MQTT *************** ****************** / # define MQTT_SERVER "AlexaExample.tinamous.com" #define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch.AlexaExample" #define MQTT_PASSWORD "Mi contraseña súper secreta que totalmente no es Passw0rd .... "# define MQTT_CLIENT_ID" UsbSwitch "#define DEVICE_USERNAME" UsbSwitch "
Esa es nuestra cuenta y dispositivo de Tinamous habilitados. Puede agregar más dispositivos aquí si lo desea, simplemente actualice la configuración de MQTT para DEVICE_USERNAME y MQTT_USERNAME (MQTT no envía información de encabezado como http, por lo que Tinamous no tiene idea de qué subdominio está utilizando, por lo tanto, debemos especificar el cuenta en el nombre de usuario).
Paso 6
Sube el código adjunto a tus dispositivos (con tu archivo secrets.h actualizado). Tómese un momento para mirar el archivo TinamousMQTTClient.ino, este maneja nuestras interacciones MQTT, y con eso los comandos de Alexa que se envían a nuestro dispositivo.
Necesitamos usar WiFiSSLClient para SSL. Si desea utilizar un servidor MQTT local sin SSL, puede utilizar el Cliente WiFi normal y acceder al puerto 1883, pero para cualquier cosa basada en Internet, utilice el Cliente SSL.
También necesitamos reservar un poco más que el búfer predeterminado para el cliente MQTT, aquí estamos reservando 4096 bytes.
WiFiSSLClient networkClient; MQTTClient mqttClient (4096);
Usamos mqttClient.begin para configurar el cliente y especificar un controlador de función en onMessage que se llama cuando se recibe un mensaje del servidor MQTT.
mqttClient.begin (MQTT_SERVER, MQTT_SERVERPORT, networkClient); // Manejar los mensajes recibidos. mqttClient.onMessage (messageReceived);
Y luego podemos conectarnos y suscribirnos al tema que nos interesa. Aquí ves que nos hemos suscrito a "Tinamous / V1 / Status.To / UsbSwitch", recibiremos mensajes enviados a @UsbSwitch desde la línea de tiempo de Tinamous. Así es como recibiremos los mensajes de Alexa.
if (! mqttClient.connect (MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {if (mqttClient.lastError () ==LWMQTT_CONNECTION_DENIED) {// Este error se debe a que su nombre de usuario o contraseña son incorrectos} if. lastError () ==-6) {// Es muy probable que este error se deba a que no agregó el certificado SSL. } // Forzar un retraso antes de volver a intentar el retraso de la conexión (10000); return false;} // Conexión exitosa. Ahora suscríbase al tema mqttClient.subscribe ("/ Tinamous / V1 / Status.To /" DEVICE_USERNAME);
Puede pensar en la línea de tiempo de Tinamous como una versión privada de Twitter para usted y sus dispositivos, pueden usar MQTT o la API REST (o uno de los bots) para ver los mensajes que se les envían y actuar en consecuencia, así como publicar mensajes de vuelta.
Tenemos un poco más de trabajo por hacer en Tinamous para habilitar la integración de Alexa, pero por ahora podemos probar nuestro dispositivo y firmware usando la línea de tiempo y enviando mensajes.
Si usa la habilidad Tinamous SmartHome, esa es toda la codificación que se necesita.
La habilidad de Tinamous Smart Home para Alexa
La habilidad Tinamous Smart Home está actualmente pendiente de aprobación para su publicación (en el momento de escribir este artículo, los dedos cruzados están en la tienda ahora ...). Para crear su propio conmutador USB, puede usar esta habilidad cuando esté disponible.
La habilidad es en realidad muy genérica, no sabe nada sobre los dispositivos o cómo hablar con ellos. Aplicamos etiquetas a los dispositivos en Tinamous y la habilidad creará un dispositivo apropiado en la cuenta de Alexa, por lo tanto, puede usar esta habilidad y Tinamous para habilitar por voz uno de sus propios proyectos con solo unas pocas líneas de código en el dispositivo.
Sin embargo, es posible que desee modificar las cosas o escribir su propia habilidad, así que compartiré los detalles de mi desarrollo.
Escribí la habilidad en C # para .Net Core 2.0, en realidad fue desarrollada para mi proyecto de ventilador inteligente BOFF, pero para este proyecto la extendí para permitir que un dispositivo tenga muchas salidas (puertos) y que cada una sea de primera clase ciudadano en dispositivos Alexa Smart Home.
Todo el código (¡incluidas algunas pruebas!) Está en el repositorio de Tinamous SmartHome, clona, descarga o simplemente visualiza como quieras. Usé Visual Studio 2017 con las herramientas de AWS instaladas para ayudar a impulsar la habilidad a Lambda.
El marco deserializa el mensaje de directiva entrante de Alexa en objetos a los que podemos acceder a través del código, se toman las acciones apropiadas en función del espacio de nombres de los encabezados y el nombre de la directiva, y luego se devuelve una respuesta adecuada.
Los principales mensajes de interés son:
- Vinculación de cuenta
- Descubrimiento
- Informe estatal
- Control de energía
Vinculación de cuenta:
Esto lo maneja Alexa por nosotros, después de agregar la habilidad a nuestra cuenta, Alexa solicitará autenticación, se nos lleva a la página de Autorización de Tinamous para permitir que el dispositivo acceda a nuestra cuenta. Aquí debe ingresar su nombre de cuenta (Alexa, ejemplo en este caso), nombre de usuario (Steve) y contraseña (¡no, no lo voy a decir!)
Descubrimiento:
Una vez que su cuenta está vinculada, Alexa le solicita que realice el descubrimiento, la habilidad luego consulta a Tinamous sobre los dispositivos que están etiquetados con " Alexa.SmartDevice ". Los dispositivos sin esto simplemente se ignoran.
Estas etiquetas se aplican editando el dispositivo desde la página Dispositivos en Tinamous.
Si el dispositivo también está etiquetado con " MultiPort "Cada puerto está enumerado y también se agrega un dispositivo para ellos. También aplicamos etiquetas basadas en las directivas de Alexa que admite nuestro dispositivo, aquí es solo" Alexa.PowerController "y también una etiqueta para indicar en qué categoría se debe mostrar el dispositivo en la aplicación, aquí he usado" SmartPlug ".
Hay otras interfaces disponibles, como Alexa.BrightnessController, pero eso no es tan útil aquí. Consulte el archivo Léame del repositorio para obtener más detalles.
Para que nuestro dispositivo MultiPort exponga puertos individuales a Alexa, necesitamos configurar las Variables de estado, también en la página de edición del dispositivo.
PortCount indica la cantidad de puertos que tiene el dispositivo, luego "Port-1" .. "Port-n" da los nombres que Alexa usará para los puertos. Se ignorará cualquier puerto sin nombre. Puede cambiar fácilmente el nombre del puerto aquí y volver a ejecutar el descubrimiento para actualizar Alexa.
Durante el descubrimiento, la habilidad también buscará un campo etiquetado, nombrado o etiquetado como "powerState" o "powerState-port-n", según corresponda. Si se encuentra este campo, se asigna como una capacidad admitida para el dispositivo (más sobre esto en Informe de estado).
Informe estatal
Durante la fase de descubrimiento, le dijimos a Alexa qué capacidades tiene nuestro dispositivo, la habilidad por defecto le dice a Alexa que se pueden solicitar, por lo tanto, Alexa enviará una solicitud StateReport para obtener los valores de estos.
Tenemos un último conjunto de etiquetas que se aplicarán para respaldar esto, esta vez en los campos de dispositivos. Una vez que su dispositivo está enviando datos (ese es el mensaje senml que se envía a través de MQTT en el código Arduino), Tinamous creará campos para el dispositivo. Luego podemos usar la opción Avanzado de la lista de campos para editar esto. Usar la opción de etiqueta es la más versátil, ya que significa que no es necesario que el nombre del campo sea correcto en el firmware o que se quede atascado si queremos cambiarle el nombre.
Si no se encuentran los campos específicos del puerto, Alexa recurrirá al campo no específico del puerto (aquí llamado powerState).
Control de energía
¡Nuestro dispositivo no tendrá ningún uso en Alexa sin esto! Alexa enviará dos directivas a nuestra habilidad "TurnOn" y "TurnOff". El punto de entrada de la función principal para la habilidad primero busca el espacio de nombres (Alexa.PowerController), luego entrega el trabajo a la clase de controlador correspondiente (PowerController.cs).
Luego, la habilidad simplemente publica un mensaje de estado en la línea de tiempo de Tinamous.
Por ejemplo:
@UsbSwitch Activar
o
@UsbSwitch Activar el puerto 1
Las otras interfaces compatibles se manejan de forma casi idéntica. Depende de nuestro dispositivo observar este mensaje de estado y realizar una acción. Luego, Alexa puede leer el estado usando un StateReport.
Así es como funciona la habilidad. Ahora solo tenemos que enviarlo a AWS Lambda y crear una entrada de Habilidad en la consola de Alexa para realmente darle acceso a Alexa.
Creación de la función AWS Lambda:
Usé las herramientas de AWS dentro de Visual Studio para impulsar la habilidad compilada a Lambda. Pero primero tenemos que crear Lambda.
Consejo profesional: Cree Lambda en el área de AWS adecuada para el idioma que admite. El inglés (Reino Unido) debe orientar la publicidad a eu-west (Irlanda).
Cree una nueva función lambda desde cero. Los planos existentes son limitados y desactualizados (solo admiten V2 de la interfaz SmartHome, que es muy diferente y obsoleta; estamos usando V3).
Deberá crear un nuevo rol para permitir que Lambda acceda a los recursos que necesita. Aquí seleccionamos Microservicios simples como predeterminado (en realidad cede más de lo que necesitamos). Si descubre que no está obteniendo registros en Cloud Watch, es posible que también deba ir y otorgar los permisos de función para eso a través de la sección IAM.
Entonces necesitamos publicar los binarios de Visual Studio. Con las herramientas de AWS instaladas, haga clic con el botón derecho en el proyecto y seleccione "Publicar en AWS Lambda ..."
Luego, complete los detalles de la expresión Lambda y presione Cargar ...
Una vez cargado, podemos ejecutar algunas pruebas en Lambda para asegurarnos de que se ejecute. Luego, necesitamos "Publicar nueva versión" desde el menú desplegable Acciones.
Una vez publicado, debemos otorgar a nuestros permisos de Habilidad para acceder a esto,
Haga clic en el disparador "Alexa Smart Home" e ingrese la identificación de la habilidad (aunque todavía no la tenemos ...)
Creando la habilidad en la consola Alexa:
Con nuestro Lambda casi listo para funcionar, debemos ir a la consola de desarrollo de habilidades y crear una entrada para él. Abra https://developer.amazon.com, seleccione Alexa Skills Kit y agregue una nueva Skill.
Seleccione Smart Home Skill API, el idioma al que desea dirigirse (por ejemplo, inglés (Reino Unido) para nosotros en el Reino Unido) y seleccione la versión de carga útil V3 (preferida).
En la página de Configuración nos adentramos en los detalles más interesantes. Ingrese el ARN de Lambda de nuestra versión de Lambda (parte superior derecha de la pantalla). Debería terminar algo como:1 o:2 o:5246 (si ha tenido algunos intentos;-)).
Mientras que en Lambda también podemos pegar la "ID de la aplicación" o la "ID de la habilidad" o la "ID" o como se llame hoy en la habilidad, debería tener un aspecto similar a amzn1.ask.skill.2 _______________ 50.
Asegúrese de hacer clic en Guardar una vez que haya agregado el ID de la aplicación. En la consola anterior, puede encontrar la identificación en el encabezado debajo del nombre de la habilidad, en la nueva, erm, abra una nueva ventana, vuelva a la lista de habilidades de la consola y haga clic en el enlace correspondiente. (es como si nunca hubieran usado la consola para crear una habilidad).
Para habilitar la vinculación de cuentas, necesitamos una aplicación OAuth creada en Tinamous, esto se hace usando Alexa Bot. Dirígete a la página de bots de tu cuenta de Tinamous y agrega un bot de Alexa. Una vez que lo haya creado, el cuadro de diálogo le dará todos los detalles que necesita para configurar la vinculación de la cuenta.
NB:Si está utilizando la habilidad de Tinamous SmartHome publicada (que pronto se publicará ...), no necesita un Alexa Bot.
La aplicación creada por el bot permitirá que cualquier otro titular de una cuenta de Tinamous use su habilidad y vincule su cuenta. Naturalmente, no tienes que publicar tu habilidad y puedes mantenerla privada, y ellos no podrán ver nada en tu cuenta de Tinamous.
Del mismo modo, si usa una nube de dispositivo diferente (en serio, ¿por qué haría eso;-)), entonces deberá ingresar los detalles de su aplicación OAuth.
En la página Prueba, asegúrese de que su habilidad esté configurada en "Sí" para "Mostrar esta habilidad en la aplicación Alexa".
Guarde y diríjase a alexa.amazon.co.uk (o al que sea apropiado para su región), o aparentemente también a la de ellos una aplicación ...
Haz clic en "Habilidades", luego arriba a la derecha, "Tus habilidades" y luego en "HABILIDADES DE DESARROLLO", deberías ver tu habilidad en la lista con un marcador verde para indicar que es una habilidad de desarrollo.
El "Alexa, apaga la luz del usb" y la información adicional de la habilidad cuando la seleccionas está configurada en la página "Información de publicación", puedes ingresar la información durante el desarrollo sin tener que ir por completo a la publicación.
Si necesita actualizar el código de habilidad, cargue la nueva función Lambda, cree una nueva versión, vuelva a agregar el disparador SmartHome y el Id. De habilidad, luego pegue la función Lambda versionada en la consola de habilidades (es posible que pueda usar una que no sea versioned lambda, but it didn't work when I tried - although there were many other things I'd also got wrong at that time).
Success!
With our skill code is running in Lambda and the Skill installed in our Alexa account, we can run discovery, and then start controlling the devices.
You can click over to the CloudWatch logs to see the log information written by your skill.
Skill Debugging &Tips
Alexa provides next to no developer feedback when things go wrong, you can spend ages guessing why Alexa doesn't do as you hoped.
- Avoid most things other than alpha-numerics in your endpointID's (I used * at one stage and everything broke, but not in an obvious way, however # was fine. Go figure!).
- Log everything. Check for logs when you've invoked your skill. No log then it's probably authentication, or your skill isn't authorized for the Lambda expression.
- Use matching AWS and Alexa email accounts.
- Keep the Lambda in the same region as the skill (Ireland for UK skills).
- If your skill is invoked but Alexa isn't responding to it (i.e. not listing devices), your response format is probably wrong.
- If you don't want to use your day to day Alexa account you can use Amazon households to add a second adult account. Note however this appears to be limited to 2 adults, and you can't change it without an epic delay.
- You can ask "Alexa, Switch Profiles" to switch between your developer and regular profiles.
- I hope with the redesign of the Alexa Console some better debugging information will be available. However right now all I see is bigger boxes and a little better validation. Some logs are available but they are just success logs. aka management level feel good metrics, and delayed by 36 hours which isn't helpful for debugging!
One Skill, Any (IoT) Thing!
With the Tinamous SmartHome skill, as long as your (Internet of Things) thing can connect to the Tinamous MQTT server (or is connected via a supported bot) adding Alexa SmartHome control to your thing is simply a few lines of code to handle messages like "Turn On", "Turn Off", "Set brightness 20". Just add the tags in Tinamous, and....
"Alexa, Discover Smart Home Devices".
Código
- AlexaUsbSwitcher.ino
- TinamousMQTTClient.ino
- UsbControl.ino
- WiFiClient.ino
- Secrets.h
AlexaUsbSwitcher.inoArduino
This is the main file.#include#include #include #include // Provide your own Secrets.h with WiFi and Tinamous definitions in it.#include "Secrets.h"// ================================/*#define MAX_USB_PORTS 2// 2 Port board.int led_pin[MAX_USB_PORTS][2] ={{A5, A6},{0,1}};int switch_pin[] ={A0, A1};// Usb switch B channel -> pin 5 ==USB1int usb_enable_pin[] ={2, 5};int usb_fault_pin[] ={3, 4};bool usb_port_state[] ={false, false};bool usb_power_mode[] ={0, 0, 1, 1};*/// ---------------------------------// 4 Port board.#define MAX_USB_PORTS 4// The 2 port board has bi-color LEDs, 4 port doesn't so use same pin......// LEDs:TX, Rx, D7, D6 (1-4)int led_pin[MAX_USB_PORTS][2] ={{14, 14}, {13,13}, {7,7}, {6,6}};int switch_pin[] ={A0, A1, A2, A3};// USB Enable pins, D1, D3, D4, D5 (not in that order)int usb_enable_pin[] ={5, 4, 1, 3};// Single fault pin (D2)int usb_fault_pin[] ={2, 2, 2, 2};bool usb_port_state[] ={false, false, false, false};// Mode:0 - Switch off as requested.// Mode:1 - Switch off, then on after a delay (useful for LED lights that have touch controls).int usb_power_mode[] ={1, 0, 0, 0};// ================================// Automation options.// time (millis) that the USB port should be switched on/off at.// zero indicates ignore.unsigned long usb_power_switch_on_at[] ={0, 0, 0, 0};// Set> 0 to get processed on first loop.// Side effect is switching them off that those in smart power // mode will schedule to come back on again).unsigned long usb_power_switch_off_at[] ={1, 1, 1, 1};// Current monitor INA219Adafruit_INA219 ina219;// Flag to indicate if one or more USB ports has a fault.bool has_usb_fault =false;// Measured power .float shunt_voltage =0;float bus_voltage =0;float current_mA =0;float load_voltage =0;float power_mW =0;// Min/max float max_current_mA =0;float max_busvoltage =0;float min_busvoltage =20;// track power usage.unsigned long last_measurement_time =0;bool power_failed =false;bool over_current =false;// MQTT publishing.// Probably want it quicker when powering devices.// or slower when not!int update_interval_seconds =20;unsigned long next_message_send_at =0;// =================================================// Main setup entry point// =================================================void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); for (int channel=0; channel MAX_USB_PORTS) { return; } // Light up the LED (1..4) based on the setup progress. SetLeds(stage-1 , true, true);}// ===================================================// Main Loop// ===================================================void loop() { // 4 port device, Debug LED is port 4 LED. // if any port 4 is on, then don't switch off the LED. // with all 4 ports off, the debug LED can blink as it likes... if (!hasPoweredPorts()) { digitalWrite(LED_BUILTIN, LOW); } // Check for a fault. bool faulted =false; for (int channel =0; channel max_current_mA) { max_current_mA =current_mA; } if (bus_voltage> max_busvoltage) { max_busvoltage =bus_voltage; } if (bus_voltage 4.5) { Serial.print("External power restored. Bus voltage:"); Serial.print(bus_voltage); Serial.println(" V"); publishTinamousStatus("External power has been restored."); power_failed =false; } if (bus_voltage <4.2 &&!power_failed) { Serial.print("External power failed! Bus voltage:"); Serial.print(bus_voltage); Serial.println(" V."); publishTinamousStatus("External power lost!"); power_failed =true; } if (over_current &¤t_mA <1500) { publishTinamousStatus("Current fault cleared!"); over_current =false; } if (current_mA> 2000 &&!over_current) { // Overload! publishTinamousStatus("Over Current!"); over_current =true; } }void printPowerWide() { Serial.print("Bus Voltage:\t"); Serial.print(bus_voltage); Serial.print(" V\t"); Serial.print("Current:\t"); Serial.print(current_mA); Serial.print(" mA\t"); Serial.print("Max Current:\t"); Serial.print(max_current_mA); Serial.print(" mA\t"); Serial.print("Min Voltage:\t"); Serial.print(min_busvoltage); Serial.print(" V\t"); Serial.print("Max Voltage:\t"); Serial.print(max_busvoltage); Serial.print(" V\t"); Serial.println();}void printPowerSkinny() { Serial.print(bus_voltage); Serial.print("\t"); Serial.print(current_mA); Serial.print("\t\t"); Serial.print(max_current_mA); Serial.print("\t\t"); Serial.print(min_busvoltage); Serial.print("\t"); Serial.print(max_busvoltage); Serial.print("\t"); Serial.print("["); for (int channel=0; channel next_message_send_at) { Serial.println("------------------------"); Serial.println("MQTT publish measurements"); if (power_failed) { // reduce how often we send when the power // has failed to preserve battery power. sentNextPublishAt(update_interval_seconds * 10); } else { sentNextPublishAt(update_interval_seconds); } // And do one as senml... String senml ="{'e':["; // Voltage senml =senml + "{'n':'busVoltage'"; senml =senml + ", 'v':"; senml =senml + String(bus_voltage); senml =senml + ", 'u':'V'}"; // Max voltage senml =senml + ",{'n':'maxBusVoltage'"; senml =senml + ", 'v':"; senml =senml + String(max_busvoltage); senml =senml + ", 'u':'V'}"; // Min voltage senml =senml + ",{'n':'minBusVoltage'"; senml =senml + ", 'v':"; senml =senml + String(min_busvoltage); senml =senml + ", 'u':'V'}"; // Current senml =senml + ",{'n':'Current'"; senml =senml + ", 'v':"; senml =senml + String(current_mA); senml =senml + ", 'u':'mA'}"; // Max current senml =senml + ",{'n':'MaxCurrent'"; senml =senml + ", 'v':'"; senml =senml + String(max_current_mA); senml =senml + "', 'u':'mA'}"; // mAh consumed... senml =senml + ",{'n':'mAh'"; senml =senml + ", 'v':"; senml =senml + String(0); // TODO! senml =senml + ", 'u':'mAh'}"; senml =senml + ",{'n':'powerState"; senml =senml + "', 'bv':"; if (isPowered()) { senml =senml + "true"; } else { senml =senml + "false"; } senml =senml + "}"; for (int channel=0; channel 0 &&onAt 0 &&offAt TinamousMQTTClient.inoArduino
This file handled the MQTT connectivity (i.e. it's the bit that responds to Alexa commands).// ======================================// Tinamous connectivity via MQTT// ======================================#include#include #include "secrets.h"// WiFi and MQTT settings in Secrets.h// Be sure to use WiFiSSLClient for an SSL connection.// for a non ssl (port 1883) use regular WiFiClient.//WiFiClient networkClient; WiFiSSLClient networkClient; // https://github.com/256dpi/arduino-mqtt// Specifying 4096 bytes buffer sizeMQTTClient mqttClient(4096); // If we have been connected since powered up bool was_connected =false;String senml ="";unsigned long nextSendMeasurementsAt =0;// =================================================// Setup the MQTT connection information// =================================================bool setupMqtt() { senml.reserve(4096); Serial.print("Connecting to Tinamous MQTT Server on port:"); Serial.println(MQTT_SERVERPORT); Serial.print("Server:"); Serial.println(MQTT_SERVER); mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, networkClient); // Handle received messages. mqttClient.onMessage(messageReceived); connectToMqttServer();}// =================================================// Connect to the MQTT server. This can be called // repeatedly and will be ignored if already connected// =================================================bool connectToMqttServer() { if (mqttClient.connected()) { return true; } Serial.println("Reconnecting...."); Serial.println("checking wifi..."); if (WiFi.status() !=WL_CONNECTED) { Serial.print("WiFi Not Connected. Status:"); Serial.print(WiFi.status(), HEX); Serial.println (); retraso (10000); falso retorno; } Serial.println("Connecting to MQTT Server..."); if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { Serial.println("Failed to connect to MQTT Server."); Serial.print("Error:"); Serial.print(mqttClient.lastError()); Serial.print(", Return Code:"); Serial.print(mqttClient.returnCode()); Serial.println (); if (mqttClient.lastError() ==LWMQTT_CONNECTION_DENIED) { Serial.println("Access denied. Check your username and password. Username should be 'DeviceName.AccountName' e.g. MySensor.MyHome"); } if (mqttClient.lastError() ==-6) { Serial.println("Check your Arduino has the SSL Certificate loaded for Tinmaous.com"); // Load the Firmware Updater sketch onto the Arduino. // Use the Tools -> WiFi Firmware Updater utility } // Wait 10s before it gets re-tried. retraso (10000); falso retorno; } Serial.println("Connected to Tinamous MQTT!"); mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME); Serial.println("Subscribed to status.to topic."); // Say Hi. publishTinamousStatus("Hello! Usb switch is now connected. @ me with help for help."); was_connected =true; return true;} // =================================================// Loop for mqtt processing.// =================================================void mqttLoop() { // Call anyway, does nothing if already connected. connectToMqttServer(); mqttClient.loop(); }// =================================================// Publish a status message on the Tinamous timeline// =================================================void publishTinamousStatus(String message) { Serial.println("Status:" + message); mqttClient.publish("/Tinamous/V1/Status", message); }// =================================================// Publish measurements using the plain json format// =================================================void publishTinamousJsonMeasurements(String json) { Serial.println("Measurement:" + json); mqttClient.publish("/Tinamous/V1/Measurements/Json", json); }// =================================================// Publish measurements using senml json format// =================================================void publishTinamousSenMLMeasurements(String senml) { Serial.println("SenML Measurement:" + senml); mqttClient.publish("/Tinamous/V1/Measurements/SenML", senml); if (mqttClient.lastError() !=0) { Serial.print("MQTT Error:"); Serial.print(mqttClient.lastError()); Serial.println (); } Serial.println("Done.");}// =================================================// Message received from the MQTT server// =================================================void messageReceived(String &topic, String &payload) { Serial.println("Message from Tinamous on topic:" + topic + " - " + payload); // If it starts with @ it's a status message to this device. if (payload.startsWith("@")) { payload.toLowerCase(); if (handleStatusMessage(payload)) { Serial.println("@ me status message handled."); regreso; } } // Didn't get an expected command, so the message was to us. // Publish a help message. publishTinamousStatus("Hello! Sorry I didn't understand the message. @ me with help for help.");} // =================================================// Message was a Status Post (probably Alexa)// =================================================bool handleStatusMessage(String payload) {char buffer[25]; // for 1..4 (maps to 0..3) for (int port =0; port 0) { Serial.print("Turn on port "); Serial.println(port); setUsb(port, true); return true; } sprintf(buffer, "turn off port-%01d", port + 1); if (payload.indexOf(buffer)> 0) { Serial.print("Turn off port "); Serial.println(port); setUsb(port, false); return true; } } // No port specified, turn on all. if (payload.indexOf("turn on")> 0) { allOn(); return true; } if (payload.indexOf("turn off")> 0) { allOff(); return true; } if (payload.indexOf("help")> 0) { Serial.println("Sending help..."); publishTinamousStatus( "Send a message to me (@" DEVICE_USERNAME ") then:" "'Turn on Port-1' to turn on usb port 1," "'Turn off Port-1' to turn off usb port 1," "'Turn on' to turn on all usb ports," "'Turn off' to turn off all usb ports," " \n* Port number can be 1, 2, 3 or 4." ); return true; } Serial.print("Unknown status message:"); Serial.println(payload); return false;} UsbControl.inoArduino
This file is responsible for the iterations with the USB power switching.// ======================================// USB Port power control// and indication.// ======================================// Determine if one or more of the ports is poweredbool hasPoweredPorts() { for (int channel =0; channelWiFiClient.inoArduino
This file deals with WiFi Connectivity// ======================================// WiFi handling// ======================================#include "Secrets.h" char ssid[] =SECRET_SSID; char pass[] =SECRET_PASS; int status =WL_IDLE_STATUS; void setupWiFi() { Serial.println("Connecting to WiFi..."); // check for the presence of the shield:if (WiFi.status() ==WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue:while (true); } // attempt to connect to WiFi network:while ( status !=WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID:"); Serial.println (ssid); // Connect to WPA/WPA2 network:status =WiFi.begin(ssid, pass); // wait 10 seconds for connection:delay(10000); } // you're connected now, so print out the data:Serial.println("You're connected to the network"); printCurrentNet(); printWiFiData();}// ---------------------------------------// WiFivoid printWiFiData() { // print your WiFi shield's IP address:IPAddress ip =WiFi.localIP(); Serial.print ("Dirección IP:"); Serial.println (ip); Serial.println (ip); // print your MAC address:byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address:"); Serial.print(mac[5], HEX); Serial.print(":"); Serial.print(mac[4], HEX); Serial.print(":"); Serial.print(mac[3], HEX); Serial.print(":"); Serial.print(mac[2], HEX); Serial.print(":"); Serial.print(mac[1], HEX); Serial.print(":"); Serial.println(mac[0], HEX);}void printCurrentNet() { // print the SSID of the network you're attached to:Serial.print("SSID:"); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to:byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID:"); Serial.print(bssid[5], HEX); Serial.print(":"); Serial.print(bssid[4], HEX); Serial.print(":"); Serial.print(bssid[3], HEX); Serial.print(":"); Serial.print(bssid[2], HEX); Serial.print(":"); Serial.print(bssid[1], HEX); Serial.print(":"); Serial.println(bssid[0], HEX); // print the received signal strength:long rssi =WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type:byte encryption =WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println();}String hostName ="www.google.com";void doPing() { Serial.print("Pinging "); Serial.print(hostName); Serial.print(":"); int pingResult =WiFi.ping(hostName); if (pingResult>=0) { Serial.print("SUCCESS! RTT ="); Serial.print(pingResult); Serial.println(" ms"); } else { Serial.print("FAILED! Error code:"); Serial.println(pingResult); }} void reconnectWiFi() { // attempt to reconnect to WiFi network if the connection was lost:while ( status !=WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID:"); Serial.println (ssid); // Connect to WPA/WPA2 network:status =WiFi.begin(ssid, pass); if (status ==WL_CONNECTED) { Serial.print("You're re-connected to the network"); printCurrentNet(); printWiFiData(); regreso; } delay(5000); } }Secrets.hArduino
You need to update this with your own settings.#define SECRET_SSID ""#define SECRET_PASS " "/************************* Tinamous MQTT Setup *********************************/#define MQTT_SERVER " .tinamous.com"#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME " . "#define MQTT_PASSWORD "The devices password"#define MQTT_CLIENT_ID "A random client id"#define DEVICE_USERNAME " " Piezas y carcasas personalizadas
This is the best bet if you don't know how you'll connect. It's got holes for the Arduino, terminal block and additional USB micro.This is the all connectors version, but doesn't include the first layers of text which some printers may struggle with.This is the simplest version and quickest to print.Esquemas
Send this off to OSHPark or DirtyPCBs to get your own one made. arduinostandaloneusbswitch-4port_q16AoF01Aq.brd arduinostandaloneusbswitch-v2_Xd45dtjndI.schGitHub USB Power Switcher Repository
You want:Arduino/StandAlone/ folder and the 4 port version.https://github.com/ThingySticks/USBPowerSwitcher
Proceso de manufactura
- Fuentes de energía
- Declaración de cambio de C#
- Los cargadores de batería ofrecen una mayor densidad de potencia y una carga más rápida
- Sensor de corte de energía
- Interruptor de alimentación de CA controlado por SMS de Raspberry Pi / Hologram
- Energía eólica
- Guía de martillos de potencia
- ¿Qué es una prensa automática?
- ¿Qué es un portabrocas eléctrico?
- Una guía rápida de mandriles eléctricos
- Entendiendo la energía hidroeléctrica