Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Interrupteur d'alimentation USB compatible Alexa

Composants et fournitures

Arduino MKR1000
× 1
Condensateur 0.1uF 0805
× 8
LED (générique)
× 4
Appuyez sur le bouton (Long)
× 4
INA219 (soic 8)
× 1
LM3526M
× 2
Prise USB (verticale)
× 4
Résistance 1k 0805
× 4
Résistance de détection de courant 0,1 Ohm
× 1
Condensateur 1uF 0805
× 1

Outils et machines nécessaires

Imprimante 3D (générique)
Fer à souder (générique)

Applications et services en ligne

Kit de compétences Amazon Alexa Alexa
Tinamous
Amazon Web Services AWS Lambda

À propos de ce projet

Alexa, allume le ThingyStick...

Contexte

De plus en plus d'appareils sont alimentés par USB, beaucoup d'entre eux ont tendance à être des appareils « stupides » sans connectivité Internet ni options de domotique (par exemple, les lumières LED), comment pouvons-nous les automatiser ou les contrôler à distance ? Peut-être une alimentation USB branchée sur un interrupteur secteur, c'est un peu exagéré, surtout si on veut 4 appareils contrôlés individuellement !

Ce projet vous permet de contrôler l'alimentation des appareils alimentés par USB via Internet, et en utilisant la compétence Tinamous SmartHome pour Alexa, vous pouvez activer le contrôle vocal pour vos appareils USB stupides.

Actuellement, il y a très peu d'appareils sur le marché pour contrôler l'alimentation USB à distance, quand j'ai commencé ce projet, je n'en ai trouvé aucun (au Royaume-Uni), mais quelques-uns sont récemment apparus dans le cadre de prises multi-gang (oui, l'idée commencé il y a longtemps, dans une galaxie lointaine), ce ne sont pas des fabricants de domotique bien connus, mais plutôt des fabricants sans marque (c'est-à-dire ZLD-34UK) Chine et retour, que se passe-t-il si ce fabricant n'existe plus, à quel point est-il sécurisé, à quel point le logiciel est-il utilisable, sera-t-il dans la boîte de recyclage la semaine prochaine, et bon nombre des autres préoccupations normales des appareils connectés à Internet, sans parler de non être piratable de la même manière qu'un appareil open source alimenté par Arduino peut l'être.

Cas d'utilisation

Exemples de périphériques alimentés par USB que nous pourrions souhaiter contrôler :

  • Lumières alimentées par USB
  • Bâtons de fonte Kindle Fire/Chrome (surtout dans les chambres des enfants pour les empêcher de regarder la télévision)
  • Humidificateurs USB
  • Echo Dot (faire qu'Alexa s'éteigne pour la nuit ? ou simplement redémarrer l'appareil)
  • Conseils de développement. Besoin de redémarrer ce projet parce que vos codes sont entrés dans une boucle infinie ?
  • Périphériques difficiles d'accès mais nécessitant un redémarrage occasionnel (c'est-à-dire des capteurs dans le grenier).
  • Appareils installés chez le client où nous voulons nous assurer qu'il est alimenté (en mesurant la consommation de courant et la tension d'entrée)

Contrôle de la puissance simple : Commutation d'alimentation activée par Internet, via la commande vocale Alexa ou d'autres commandes via Tinamous. Allumé et éteint.

Contrôle intelligent de l'alimentation : De nombreuses lampes USB ont des commandes tactiles pour allumer la lampe, ce qui signifie que nous ne pouvons pas allumer la lumière à distance, mais nous pouvons l'éteindre, et la plupart du temps c'est tout ce que nous voulons (essayer de dormir, laisser une lampe allumée ? Sortir, vouloir que toutes les lumières s'éteignent ?).

Cependant, une fois que nous avons utilisé Alexa pour éteindre la lampe USB, nous devons ensuite demander à Alexa d'allumer la lampe avant de pouvoir l'allumer, c'est tout simplement idiot. Lorsque l'alimentation intelligente est activée, la commande d'arrêt éteint la lampe pendant quelques secondes avant de rétablir l'alimentation de l'appareil. De quoi éteindre la lampe, mais aussi permettre un fonctionnement normal après.

Automatisation de la minuterie : Mettez vos appareils hors tension automatiquement à des heures définies. Les enfants qui regardent Amazon TV sur le feu restent trop tard ? Coupez automatiquement l'alimentation USB à 20h.

Surveillance de l'alimentation : Si vous développez du matériel alimenté par USB, vous voudrez peut-être savoir combien de courant votre appareil consomme, en particulier lorsqu'il est allumé pour la première fois, ou vous voudrez peut-être profiler la charge de la batterie. Avec l'INA219 embarqué, vous pouvez surveiller la consommation de courant (j'ai réussi un échantillonnage d'environ 1 kHz avec peu d'effort). La chute de tension sur les câbles USB à courant élevé peut également être un problème, l'INA219 surveille l'alimentation de l'appareil afin que nous puissions avertir d'une basse tension. Un bornier est également fourni pour permettre l'utilisation de courants plus élevés et de câbles plus gros.

Panne de courant : En utilisant l'option batterie sur le MKR 1000, nous pouvons surveiller la tension d'alimentation USB et envoyer des notifications en cas de panne de l'alimentation d'entrée. Cela peut être utile pour les solutions distantes (hors site) qui utilisent l'alimentation USB mais nécessitent un peu de surveillance supplémentaire, ou tout simplement comme une simple détection de panne d'alimentation secteur pour votre maison.

Matériel

Ce projet est assez simple, un Arduino MKR1000 au cœur, une commutation d'alimentation USB utilisant deux LM3526M pour fournir une commutation latérale élevée et une détection de défaut (basse tension, surintensité), ainsi qu'une surveillance de l'alimentation (tension et courant) à l'aide d'un INA219, et enfin LED et commutateurs pour les options de contrôle local.

J'ai fait fabriquer un PCB sur DirtyPCBs.com, vous pouvez également envoyer le fichier .brd à OSHPark.com pour en faire également. La prise Arduino a des plaquettes de circuit imprimé de chaque côté de chaque broche pour permettre le piratage. par exemple. vous pouvez facilement ajouter des capteurs pour les conditions environnementales ou un petit écran OLED pour afficher la tension et le courant.

Dans le référentiel github, il existe une option à 2 et 4 ports. Attention au PCB 2 ports car j'ai foiré et je me suis trompé dans la disposition de la prise USB (ils sont à l'envers - mauvaise polarité !).

Victoire des griffes de la défaite :

Il s'avère que le montage du connecteur USB à l'arrière de la carte est en fait une bonne solution et signifie que les connexions des broches étaient correctes (cependant, pour la carte à 2 ports, cela signifie également que l'écran en soie est du mauvais côté !). L'Arduino avec des en-têtes dans une prise était un peu poussé pour l'espace avec la hauteur requise pour sortir les prises USB du boîtier, donc cela a mieux fonctionné, j'ai décidé de refaire la carte avec des prises, des interrupteurs et des LED à l'envers côté et d'ajouter deux ports supplémentaires, d'où la création de la version à quatre ports (de plus, j'avais horriblement aligné les LED sur les 2 ports, donc ça a aussi été corrigé !).

Leur très peu d'empêchement d'être étendu à un commutateur à 6 ou 8 ports, bien que les LED et les commutateurs puissent avoir besoin d'être supprimés ou améliorés.

Le schéma semble beaucoup plus complexe à construire qu'il ne l'est. Beaucoup de résistances sont optionnelles. Les résistances R23, 19, 27 et 26 sont toutes des pull-ups pour les commutateurs, de même que R20-22, R14 et R15 sont des pull-ups pour le contrôle USB et la détection des défauts. Tout cela peut être fait via le mode de broche INPUT_PULLUP dans l'Arduino, cependant si vous vouliez mettre l'Arduino en veille à faible consommation et utiliser des interruptions pour le réveiller, vous souhaiterez peut-être les remplir afin qu'ils ne flottent pas (et ne rebondissent pas) .

J'ai également ajouté des résistances optionnelles autour des lignes USB D+/D-. Ceux-ci peuvent être installés pour indiquer à l'appareil la quantité d'énergie qu'il peut utiliser, mais pour de nombreux appareils stupides, ils sont de toute façon ignorés. En dessous, seul R24 pour la limitation de courant LED est réellement nécessaire. R2-5 et R28 sont laissés vides.

Les LED et les interrupteurs sont également totalement facultatifs. Si vous voulez juste un boîtier autonome qui contrôle l'USB à distance, n'ajoutez pas ces pièces.

Entrée d'alimentation

Ce contrôleur peut être alimenté via trois options.

La première est l'option "Interne" (broches JP6 1 et 2 connectées), l'alimentation USB est prise à partir de la broche 5V de l'Arduino (et donc du connecteur USB Arduino). Cependant, cela ne doit être utilisé que pour les charges de faible puissance.

Les autres options sont pour l'alimentation externe (JP6 broches 2 et 3 connectées), vous pouvez ensuite connecter 5V via J2 (le micro connecteur USB intégré) ou JP8 (un bornier). Vous ne devez pas utiliser les deux options en même temps. L'alimentation externe est également acheminée vers la broche Arduino VIn, de sorte qu'elle n'aura pas non plus besoin de sa propre option d'alimentation.

Pour les points bonus, l'installation de résistances 0R sur R10 et R11, ainsi que J2 donne un passage USB pour USB 3 afin que nous puissions redémarrer un périphérique connecté par USB, très pratique lors du développement de matériel et vous ne voulez pas user vos prises USB sur le PC !

Enceinte

Un boîtier imprimable en 3D est inclus avec ce projet. Il utilise des inserts thermiques M3 pour les connexions PCB et couvercle, bien que les tolérances sur le couvercle soient suffisamment bonnes pour un ajustement par friction.

Le couvercle comprend quelques options.

  • Avec ou sans compartiment à piles.
  • Avec ou sans pieds (ou trous de montage pour permettre la fixation du boîtier sur une surface).

De même, le boîtier de base peut être configuré (à l'aide d'OpenSCAD) pour inclure des ouvertures pour chacune des trois sources d'alimentation.

Il a fallu quelques essais pour obtenir le bon boîtier. Comment versionnez-vous vos impressions ? Mes échantillons du fan club Rigid.Ink m'ont été très utiles.

Se connecter à Tinamous

Nous utilisons l'Arduino MKR1000 pour contrôler les prises, nous avons donc une connectivité WiFi. Si vous êtes nouveau sur cette carte, vous devrez ajouter l'option de carte à votre IDE Arduino.

Nous allons utiliser le serveur Tinamous MQTT pour nous connecter, principalement parce que c'est génial, mais aussi, peut-être parce que je suis le fondateur/développeur/fabricant de thé ! Nous nous abonnerons au sujet de publication d'état pour les messages envoyés à l'appareil. (c'est-à-dire le sujet "Status.To").

Avant de commencer le codage, nous devons nous assurer que l'Arduino dispose du dernier firmware ainsi que des certificats SSL requis pour obtenir une connexion sécurisée à Tinamous. Évidemment, si vous préférez, vous pouvez l'adapter à votre propre serveur MQTT local et ne pas trop vous soucier de la sécurité.

Étape 1

Ouvrez l'IDE Arduino et chargez le FirmwareUpdater croquis du menu d'exemples WiFi101. Téléchargez-le sur votre appareil.

Étape 2

Une fois téléchargé, sélectionnez WiFi101 Firmware Updater depuis les Outils menu.

Étape 3

Testez votre connexion puis Mettre à jour le Firmware . Une fois cela fait, utilisez Ajouter un domaine et ajoutez tinamous.com pour s'assurer que l'Arduino a les bons certificats SSL en place. Appuyez sur le Télécharger les certificats vers le module WiFi bouton pour télécharger les certificats.

Étape 4

Maintenant, nous pouvons écrire notre propre firmware. Vous trouverez les fichiers attachés à ce projet et également dans le référentiel GitHub (GitHub aura la dernière version).

Nous utiliserons le client WiFi101 et MQTT pour votre croquis Arduino.

Sélectionnez l'option MQTT par Joel Gaehwiler.

Le fichier secrets.h doit être renseigné avec vos paramètres WiFi et Tinamous MQTT, je n'ai pas inclus ma copie pour des raisons évidentes.

Paramètres du serveur Wi-Fi et MQTT :

#define SECRET_SSID "Votre SSID"#define SECRET_PASS "Votre mot de passe SSID"/************************ Configuration de Tinamous MQTT *********************************/#define MQTT_SERVER ".tinamous.com"#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch."#define MQTT_PASSWORD "Votre mot de passe entre ici."#define MQTT_CLIENT_ID "UsbSwitch"#define DEVICE_USERNAME "UsbSwitch" 

Si vous n'êtes pas encore inscrit sur Tinamous, vous pouvez créer votre propre compte gratuitement ici. Lorsque vous vous inscrivez, on vous demande un nom de compte/d'organisation, cela devient votre propre espace privé de Tinamous, vous pouvez inviter d'autres membres dans cet espace (y compris Alexa) et partager vos appareils avec votre groupe.

Ci-dessous, j'appelle mon compte "AlexaExample", c'est ce que je devrai inclure dans la configuration MQTT, et mon compte Tinamous est sur https://AlexaExample.Tinamous.com

Étape 5

Ensuite, nous devons ajouter notre appareil. Sur la page Tinamous Devices, cliquez sur le bouton Ajouter.

Par conséquent, les paramètres Tinamous MQTT de mon appareil ressemblent à ceci...

/****************************** Configuration de Tinamous MQTT *************** ******************/#define MQTT_SERVER "AlexaExample.tinamous.com"#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch.AlexaExample"#define MQTT_PASSWORD "Mon mot de passe super secret qui n'est pas du tout le mot de passe...."#define MQTT_CLIENT_ID "UsbSwitch"#define DEVICE_USERNAME "UsbSwitch" 

C'est notre compte et appareil Tinamous activés. Vous pouvez ajouter plus d'appareils ici si vous le souhaitez, mettez simplement à jour les paramètres MQTT pour DEVICE_USERNAME et MQTT_USERNAME (MQTT n'envoie pas d'informations d'en-tête comme http, donc Tinamous n'a aucune idée du sous-domaine que vous utilisez, nous devons donc spécifier le compte dans le nom d'utilisateur).

Étape 6

Téléchargez le code joint sur vos appareils (avec votre fichier secrets.h mis à jour). Prenez un moment pour regarder le fichier TinamousMQTTClient.ino, il gère nos interactions MQTT, et avec cela les commandes Alexa qui sont envoyées à notre appareil.

Nous devons utiliser le WiFiSSLClient pour SSL. Si vous souhaitez utiliser un serveur MQTT local sans SSL, vous pouvez utiliser le client WiFi standard et descendre au port 1883, mais pour tout ce qui est basé sur Internet, utilisez le client SSL.

Il faut aussi réserver un peu plus que le buffer par défaut pour le client MQTT, ici on réserve 4096 octets.

WiFiSSLCient networkClient ; MQTTClient mqttClient (4096);  

Nous utilisons mqttClient.begin pour configurer le client et spécifier un gestionnaire de fonction dans onMessage qui est appelé lorsqu'un message est reçu du serveur MQTT.

 mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, networkClient); // Traiter les messages reçus. mqttClient.onMessage(messagereçu); 

Et puis nous pouvons nous connecter et nous abonner au sujet qui nous intéresse. Ici, vous voyez que nous nous sommes abonnés à "Tinamous/V1/Status.To/UsbSwitch", nous recevrons des messages envoyés à @UsbSwitch à partir de la chronologie de Tinamous. C'est ainsi que nous recevrons les messages d'Alexa.

if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { if (mqttClient.lastError() ==LWMQTT_CONNECTION_DENIED) { // Cette erreur est due au fait que votre nom d'utilisateur ou mot de passe est incorrect } if (mqttClient. lastError() ==-6) { // Cette erreur est probablement due au fait que vous n'avez pas ajouté le certificat SSL. } // Force un délai avant de réessayer le délai de connexion (10000); return false;}// Connexion réussie. Abonnez-vous maintenant au sujet mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME); 

Vous pouvez considérer la chronologie de Tinamous comme une version privée de Twitter pour vous et vos appareils, ils peuvent utiliser MQTT ou l'API REST (ou l'un des bots) pour voir les messages qui leur sont envoyés et agir en conséquence, ainsi que publier messages en retour.

Nous avons encore un peu de travail à faire dans Tinamous pour activer l'intégration d'Alexa, mais pour l'instant, nous pouvons tester notre appareil et notre firmware en utilisant la chronologie et en envoyant des messages.

Si vous utilisez la compétence Tinamous SmartHome, c'est tout le codage nécessaire.

La compétence Tinamous Smart Home pour Alexa

La compétence Tinamous Smart Home est actuellement en attente d'approbation pour être publiée (au moment de la rédaction, les doigts croisés, elle est maintenant dans le magasin...). Pour créer votre propre commutateur USB, vous pouvez simplement utiliser cette compétence lorsqu'elle est disponible.

La compétence est en fait très générique, elle ne sait rien des appareils ni de la façon de lui parler. Nous appliquons des balises aux appareils dans Tinamous et la compétence créera un appareil approprié dans le compte Alexa, vous pouvez donc utiliser cette compétence et Tinamous pour activer vocalement l'un de vos propres projets avec seulement quelques lignes de code sur l'appareil.

Cependant, vous souhaiterez peut-être modifier les choses ou écrire votre propre compétence afin que je partage les détails de mon développement.

J'ai écrit la compétence en C# pour .Net Core 2.0, elle a en fait été développée pour mon projet de ventilateur intelligent BOFF, mais pour ce projet je l'ai étendue pour permettre à un appareil d'avoir plusieurs sorties (ports) et pour chacun d'être une première classe citoyen dans les appareils Alexa Smart Home.

Tout le code (y compris certains tests !) est dans le référentiel Tinamous SmartHome, clonez, téléchargez ou affichez simplement comme vous le souhaitez. J'ai utilisé Visual Studio 2017 avec les outils AWS installés pour aider à pousser la compétence vers Lambda.

Le cadre désérialise le message de directive entrant d'Alexa en objets auxquels nous pouvons accéder via le code, les actions appropriées sont prises en fonction de l'espace de noms des en-têtes et du nom de la directive, puis une réponse appropriée est renvoyée.

Les principaux messages d'intérêt sont :

  • Lien de compte
  • Découverte
  • Rapport d'état
  • Contrôle de l'alimentation

Liaison de compte :

Ceci est géré par Alexa pour nous, après avoir ajouté la compétence à notre compte, Alexa demandera une authentification, nous sommes redirigés vers la page d'autorisation de Tinamous pour permettre à l'appareil d'accéder à notre compte. Ici, vous devez entrer votre nom de compte (AlexaExample dans ce cas), votre nom d'utilisateur (Steve) et votre mot de passe (non, je ne le dis pas !)

Découverte :

Une fois votre compte lié, Alexa vous invite à effectuer la découverte, la compétence interroge ensuite Tinamous pour les appareils marqués avec "Alexa.SmartDevice ". Les appareils sans cela sont simplement ignorés.

Ces balises sont appliquées en modifiant l'appareil à partir de la page Appareils dans Tinamous.

Si l'appareil est également marqué avec "MultiPort " chaque port est énuméré et un appareil est également ajouté pour ceux-ci. Nous appliquons également des balises basées sur les directives Alexa prises en charge par notre appareil, ici c'est juste "Alexa.PowerController " et aussi une balise pour indiquer dans quelle catégorie l'appareil doit être affiché dans l'application, ici j'ai utilisé "SmartPlug ".

D'autres interfaces sont disponibles, comme Alexa.BrightnessController, mais ce n'est pas si utile ici. Consultez le fichier readme du référentiel pour plus de détails.

Pour que notre appareil MultiPort expose des ports individuels à Alexa, nous devons configurer les variables d'état, également sur la page de modification de l'appareil.

PortCount indique le nombre de ports de l'appareil, puis "Port-1".."Port-n" donne les noms qu'Alexa utilisera pour les ports. Tout port sans nom sera ignoré. Vous pouvez facilement modifier le nom du port ici et relancer la découverte pour mettre Alexa à jour.

Lors de la découverte, la compétence recherchera également un champ étiqueté, nommé ou étiqueté « powerState » ou « powerState-port-n » selon le cas. Si ce champ est trouvé, il est attribué en tant que capacité prise en charge pour l'appareil (plus d'informations à ce sujet dans le rapport d'état).

Rapport d'état

Au cours de la phase de découverte, nous avons indiqué à Alexa les capacités de notre appareil. La compétence par défaut indique à Alexa que celles-ci peuvent être demandées. Alexa enverra donc une demande StateReport pour obtenir les valeurs de celles-ci.

Nous avons un dernier ensemble de balises à appliquer pour prendre en charge cela, cette fois aux champs des appareils. Une fois que votre appareil envoie des données (c'est le message senml qui est transmis à MQTT dans le code Arduino), Tinamous créera des champs pour l'appareil. Nous pouvons ensuite utiliser l'option Avancé de la liste des champs pour modifier cela. L'utilisation de l'option de balise est la plus polyvalente car cela signifie que nous n'avons pas besoin d'obtenir le nom de champ correct dans le micrologiciel ou de le bloquer si nous voulons le renommer.

Si les champs spécifiques au port ne sont pas trouvés, Alexa reviendra au champ non spécifique au port (ici nommé powerState).

Contrôle de l'alimentation

Notre appareil ne sera d'aucune utilité dans Alexa sans cela ! Alexa enverra deux directives à notre Skill "TurnOn" et "TurnOff". Le point d'entrée de la fonction principale pour la compétence recherche d'abord l'espace de noms (Alexa.PowerController), puis confie le travail à la classe de contrôleur appropriée (PowerController.cs).

La compétence publie ensuite simplement un message d'état sur la chronologie de Tinamous.

Par exemple :

@UsbSwitch Activer

ou

@UsbSwitch Activer le port-1

Les autres interfaces prises en charge sont gérées de manière presque identique. C'est alors à notre appareil de surveiller ce message d'état et d'effectuer une action. Alexa peut alors relire l'état à l'aide d'un StateReport.

C'est ainsi que fonctionne la compétence. Il ne nous reste plus qu'à le transmettre à AWS Lambda et à créer une entrée Skill sur la console Alexa pour lui donner réellement accès à Alexa.

Création de la fonction AWS Lambda :

J'ai utilisé les outils AWS dans Visual Studio pour pousser la compétence compilée vers Lambda. Mais nous devons d'abord créer le Lambda.

Conseil de pro : Créez le Lambda dans la zone AWS appropriée pour la langue que vous prenez en charge. L'anglais (Royaume-Uni) doit cibler eu-ouest (Irlande).

Créez une nouvelle fonction lambda à partir de zéro. Les plans existants sont limités et obsolètes (ne prenant en charge que la V2 de l'interface SmartHome qui est très différente et obsolète - nous utilisons la V3).

Vous devrez créer un nouveau rôle pour permettre à Lambda d'accéder aux ressources dont il a besoin. Ici, nous sélectionnons les microservices simples par défaut (cela donne en fait plus que ce dont nous avons besoin). Si vous constatez que vous n'obtenez pas de journaux dans Cloud Watch, vous devrez peut-être également donner les autorisations de rôle pour cela via la section IAM.

Ensuite, nous devons publier les binaires de Visual Studio. Une fois les outils AWS installés, faites un clic droit sur le projet et sélectionnez "Publier sur AWS Lambda..."

Remplissez ensuite les détails de l'expression Lambda et appuyez sur Télécharger...

Une fois téléchargé, nous pouvons exécuter des tests sur le Lambda pour nous assurer qu'il fonctionne. Ensuite, nous devons « Publier une nouvelle version » dans la liste déroulante Actions.

Une fois publié, nous devons donner à nos compétences les autorisations pour y accéder,

Cliquez sur le déclencheur "Alexa Smart Home" et entrez l'identifiant de la compétence (nous ne l'avons pas encore cependant....)

Création de la compétence sur la console Alexa :

Avec notre Lambda presque prête à fonctionner, nous devons nous diriger vers la console de développement de compétences et créer une entrée pour celle-ci. Ouvrez https://developer.amazon.com, sélectionnez Alexa Skills Kit et ajoutez une nouvelle Skill.

Sélectionnez Smart Home Skill API, la langue que vous souhaitez cibler (par exemple, l'anglais (Royaume-Uni) pour nous au Royaume-Uni) et sélectionnez la version de charge utile V3 (préférée).

Sur la page de configuration, nous entrons dans les détails les plus intéressants. Entrez l'ARN Lambda de notre version Lambda (en haut à droite de l'écran). Il devrait se terminer par quelque chose comme :1 ou :2 ou :5246 (si vous avez déjà essayé;-) ).

Alors que dans Lambda, nous pouvons également coller « ID d'application » ou « ID de compétence » ou « ID » ou quel que soit son nom aujourd'hui à partir de la compétence, il devrait ressembler à quelque chose comme amzn1.ask.skill.2_______________50.

Assurez-vous de cliquer sur Enregistrer une fois que vous avez ajouté l'ID d'application. Dans l'ancienne console, vous pouvez trouver l'identifiant dans l'en-tête sous le nom de la compétence, dans la nouvelle, euh, ouvrez une nouvelle fenêtre, revenez à la liste des compétences de la console et cliquez sur le lien approprié. (c'est comme s'ils n'avaient jamais utilisé la console pour créer une compétence).

Pour activer la liaison de compte, nous avons besoin d'une application OAuth créée chez Tinamous, cela se fait à l'aide d'Alexa Bot. Rendez-vous sur la page Bots de votre compte Tinamous et ajoutez un Bot Alexa. Une fois que vous avez créé cela, la boîte de dialogue vous donnera tous les détails dont vous avez besoin pour configurer la liaison de compte.

NB :Si vous utilisez la (bientôt...) Skill Tinamous SmartHome publiée, vous n'avez pas besoin d'Alexa Bot.

L'application créée par le bot permettra à tout autre titulaire de compte Tinamous d'utiliser votre skill et de lier son compte. Naturellement, vous n'êtes pas obligé de publier votre compétence et vous pouvez la garder privée, et ils ne pourront rien voir dans votre compte Tinamous.

De même, si vous utilisez un autre cloud d'appareil (sérieusement, pourquoi feriez-vous cela ;-) ), vous devrez alors saisir les détails de leur application OAuth.

Sur la page de test, assurez-vous que votre compétence est définie sur « Oui » pour « Afficher cette compétence dans l'application Alexa ».

Enregistrez et rendez-vous sur alexa.amazon.co.uk (ou celui qui convient à votre région), ou apparemment leur application aussi.....

Cliquez sur « Compétences », puis en haut à droite, « Vos compétences », puis «  COMPÉTENCES DE DÉVELOPPEMENT », vous devriez voir votre compétence répertoriée avec un marqueur vert pour indiquer qu'il s'agit d'une compétence de développement.

L'option "Alexa, éteignez la lumière USB" et les informations de compétence supplémentaires lorsque vous les sélectionnez sont configurées sur la page "Informations de publication", vous pouvez saisir les informations pendant le développement sans avoir à vous lancer dans la publication complète.

Si vous devez mettre à jour le code de compétence, téléchargez la nouvelle fonction Lambda, créez une nouvelle version, rajoutez le déclencheur SmartHome et l'ID de compétence, puis collez la fonction Lambda versionnée dans la console de compétences (vous pourrez peut-être utiliser un lambda versionné, mais cela n'a pas fonctionné lorsque j'ai essayé - bien qu'il y ait eu beaucoup d'autres choses sur lesquelles je me suis également trompé à ce moment-là).

Succès !

Avec notre code de compétence exécuté dans Lambda et la compétence installée dans notre compte Alexa, nous pouvons exécuter la découverte, puis commencer à contrôler les appareils.

Vous pouvez cliquer sur les journaux CloudWatch pour voir les informations de journal écrites par votre compétence.

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".

Code

  • 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(); retard (10000); renvoie faux ; } 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. retard (10000); renvoie faux ; } 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."); retourner; } } // 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); renvoie vrai ; } sprintf(buffer, "turn off port-%01d", port + 1); if (payload.indexOf(buffer)> 0) { Serial.print("Turn off port "); Serial.println(port); setUsb(port, false); renvoie vrai ; } } // No port specified, turn on all. if (payload.indexOf("turn on")> 0) { allOn(); renvoie vrai ; } if (payload.indexOf("turn off")> 0) { allOff(); renvoie vrai ; } 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." ); renvoie vrai ; } 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; channel  
WiFiClient.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); // attend 10 secondes pour la connexion :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("Adresse 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(); retourner; } 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 ""

Pièces et boîtiers personnalisés

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.

Schémas

Send this off to OSHPark or DirtyPCBs to get your own one made. arduinostandaloneusbswitch-4port_q16AoF01Aq.brd arduinostandaloneusbswitch-v2_Xd45dtjndI.sch
GitHub USB Power Switcher Repository
You want:Arduino/StandAlone/ folder and the 4 port version.https://github.com/ThingySticks/USBPowerSwitcher

Processus de fabrication

  1. Instruction de commutateur C #
  2. Les chargeurs de batterie offrent une plus grande densité de puissance, une charge plus rapide
  3. Capteur de panne de courant
  4. Interrupteur d'alimentation AC contrôlé par SMS Raspberry Pi/Hologram
  5. Énergie éolienne
  6. Guide des marteaux électriques
  7. Qu'est-ce qu'une presse automatique ?
  8. Qu'est-ce qu'un Power Chuck ?
  9. Un guide rapide des mandrins électriques