Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Alexa ingeschakelde USB-stroomschakelaar

Componenten en benodigdheden

Arduino MKR1000
× 1
0.1uF 0805 Condensator
× 8
LED (generiek)
× 4
Druk op de knop (lang)
× 4
INA219 (soic 8)
× 1
LM3526M
× 2
USB-aansluiting (verticaal)
× 4
1k 0805 weerstand
× 4
0.1 Ohm Current Sense-weerstand
× 1
1uF 0805 Condensator
× 1

Benodigde gereedschappen en machines

3D-printer (algemeen)
Soldeerbout (algemeen)

Apps en online services

Amazon Alexa Alexa Skills Kit
Tinamous
Amazon Web Services AWS Lambda

Over dit project

Alexa, zet de ThingyStick aan...

Achtergrond

Steeds meer apparaten worden gevoed door USB, veel van deze zijn "domme" apparaten zonder internetverbinding of domotica-opties (bijv. LED-verlichting), hoe kunnen we ze op afstand automatiseren of bedienen? Misschien een USB-voeding aangesloten op een netschakelaar, dat is een beetje overdreven, vooral als we 4 apparaten afzonderlijk willen bedienen!

Met dit project kun je de stroomtoevoer naar USB-apparaten via internet regelen en door de Tinamous SmartHome Skill voor Alexa te gebruiken, kun je spraakbesturing inschakelen voor je domme USB-apparaten.

Momenteel zijn er maar heel weinig apparaten op de markt om USB-stroom op afstand te regelen, toen ik aan dit project begon, vond ik er geen (in het VK), maar een paar zijn onlangs verschenen als onderdeel van multi-bende-outlets (ja, het idee lang geleden begonnen, in een melkwegstelsel ver weg), zijn deze niet door bekende fabrikanten van domotica, maar door merkloze fabrikanten (bijv. ZLD-34UK), dus we hebben de kwestie van wiens apparaatcloud ze gebruiken, gaan de gegevens naar China en terug, wat gebeurt er als die fabrikant niet meer bestaat, hoe veilig is het, hoe bruikbaar is de software, zal het volgende week in de recyclingdoos liggen, en veel van de andere normale zorgen van apparaten met internetverbinding, om nog maar te zwijgen van niet hackbaar zijn op dezelfde manier als een open source Arduino-aangedreven apparaat kan zijn.

Gebruiksscenario's

Voorbeelden van USB-apparaten die we mogelijk willen bedienen:

  • Lampjes met USB-voeding
  • Kindle Fire/Chrome cast sticks (vooral in kinderkamers om te voorkomen dat ze tv kijken)
  • USB-luchtbevochtigers
  • Echo Dot (laat Alexa zichzelf uitschakelen voor de nacht? of start het apparaat gewoon opnieuw op)
  • Ontwikkelingsborden. Moet je dat project opnieuw opstarten omdat je codes in een oneindige lus zijn geraakt?
  • Apparaten die moeilijk toegankelijk zijn maar af en toe opnieuw moeten worden opgestart (bijv. sensoren in de loft).
  • Apparaten geïnstalleerd bij de klant waar we ervoor willen zorgen dat deze van stroom worden voorzien (door het stroomverbruik en de ingangsspanning te meten)

Eenvoudige stroomregeling: Via internet ingeschakelde stroomschakeling, hetzij via Alexa-spraakbesturing of andere opdrachten via Tinamous. Aan en Uit.

Slimme stroomregeling: Veel USB-lampen hebben aanraakbedieningen om de lamp aan te zetten, wat betekent dat we het licht niet op afstand kunnen inschakelen, maar we kunnen het wel uitschakelen, en vaak is dat alles wat we willen (proberen te slapen, een lamp aan laten staan Uitgaan, wilt u dat alle lichten uit zijn?).

Zodra we Alexa echter hebben gebruikt om de USB-lamp uit te schakelen, moeten we Alexa vragen om de lamp aan te zetten voordat we hem kunnen inschakelen, dat is gewoon dom. Als Smart Power is ingeschakeld, schakelt het uit-commando de lamp een paar seconden uit voordat de stroomtoevoer naar het apparaat wordt hersteld. Genoeg om de lamp uit te zetten, maar ook om daarna normaal te functioneren.

Timer-automatisering: Laat je apparaten op gezette tijden automatisch uitschakelen. Kinderen kijken te laat naar Amazon TV op de vuurpijl? Laat de USB-voeding automatisch om 20.00 uur afsluiten.

Power monitoring: Als u USB-aangedreven hardware aan het ontwikkelen bent, wilt u misschien weten hoeveel stroom uw apparaat verbruikt, vooral wanneer het voor het eerst wordt ingeschakeld, of u wilt misschien het opladen van een batterij profileren. Met de ingebouwde INA219 kun je het stroomverbruik volgen (ik heb met weinig moeite ongeveer 1kHz-sampling beheerd). Spanningsval op USB-kabels bij hoge stroomsterkte kan ook een probleem zijn, de INA219 bewaakt de stroomtoevoer naar het apparaat zodat we kunnen waarschuwen voor lage spanning. Er is ook een aansluitblok voorzien om hogere stromen en grotere kabels mogelijk te maken.

Stroomstoring: Door de batterijoptie op de MKR 1000 te gebruiken, kunnen we de USB-voedingsspanning bewaken en meldingen verzenden als de ingangsstroom is uitgevallen. Dit kan handig zijn voor externe (off-site) oplossingen die USB-stroom gebruiken maar een beetje extra bewaking nodig hebben, of gewoon als een eenvoudige detectie van een stroomstoring voor uw huis.

Hardware

Dit project is vrij eenvoudig, een Arduino MKR1000 in het hart, USB-stroomschakeling met behulp van twee LM3526M's voor hoge zijwaartse schakeling en foutdetectie (lage spanning, overstroom), samen met stroombewaking (spanning en stroom) met behulp van een INA219, en tot slot LED's en schakelaars voor lokale bedieningsopties.

Ik heb een PCB laten maken bij DirtyPCBs.com, je kunt het .brd-bestand ook naar OSHPark.com sturen om er ook een te laten maken. De Arduino-socket heeft pcb-pads aan weerszijden van elke pin om hacking mogelijk te maken. bijv. je zou gemakkelijk wat sensoren kunnen toevoegen voor omgevingscondities, of een klein OLED-scherm om spanning en stroom weer te geven.

In de github-repository is er een optie met 2 poorten en 4 poorten. Pas op met de 2-poorts PCB, want Ik heb het verknoeid en kreeg de lay-out voor de USB-aansluiting verkeerd (ze zijn achterstevoren - verkeerde polariteit !).

Overwinning uit de kaken van de nederlaag:

Het blijkt dat het monteren van de USB-socked op de achterkant van het bord eigenlijk een mooie oplossing is en betekende dat de pinverbindingen correct waren (maar voor het 2-poorts bord betekent dit ook dat de zeefdruk aan de verkeerde kant zit!). De Arduino met headers in een socket was een beetje geduwd voor ruimte met de vereiste hoogte om de USB-sockets uit de behuizing te krijgen, dus het werkte eigenlijk beter, ik besloot het bord opnieuw te doen met sockets, schakelaars en LED's aan de achterkant kant en om twee extra poorten toe te voegen, vandaar dat de versie met vier poorten is gemaakt (ook had ik de LED's vreselijk uitgelijnd op de 2-porter, dus dat is ook opgelost!).

Er is weinig dat de uitbreiding naar een 6- of 8-poorts switcher tegenhoudt, hoewel de LED's en schakelaars mogelijk moeten worden verwijderd of verbeterd.

Het schema ziet er veel complexer uit om te bouwen dan het is. Veel van de weerstanden zijn optioneel. Weerstanden R23, 19, 27 en 26 zijn allemaal pull-ups voor de schakelaars, evenals R20-22, R14 &R15 zijn pull-ups voor de USB-besturing en foutdetectie. Deze kunnen allemaal worden gedaan via de INPUT_PULLUP-pinmodus in de Arduino, maar als je de Arduino in de slaapstand met laag vermogen wilt zetten en interrupts wilt gebruiken om hem te wekken, wil je deze misschien vullen zodat ze niet zweven (en rondspringen) .

Ik heb ook optionele weerstanden toegevoegd rond de USB D+/D- lijnen. Deze kunnen worden aangebracht om het apparaat te vertellen hoeveel stroom het kan gebruiken, maar voor veel domme apparaten worden deze toch genegeerd. Hieronder is eigenlijk alleen R24 voor de LED stroombegrenzing nodig. R2-5 en R28 zijn leeg gelaten.

De LED's en schakelaars zijn ook volledig optioneel. Als je alleen een stand-alone box wilt die USB op afstand bestuurt, voeg die onderdelen dan niet toe.

Voedingsinvoer

Deze controller kan via drie opties worden gevoed.

De eerste is de "Interne" optie (JP6 pinnen 1 &2 aangesloten), USB-stroom wordt afgenomen van de 5V-pin van de Arduino (en dus van de Arduino USB-connector). Dit mag echter alleen worden gebruikt voor belastingen met een laag vermogen.

De andere opties zijn voor externe voeding (JP6 pinnen 2 &3 aangesloten), u kunt dan 5V aansluiten via J2 (de ingebouwde USB-microconnector) of JP8 (een aansluitblok). U moet niet beide opties tegelijkertijd gebruiken. De externe voeding wordt ook naar de Arduino VIn-pin geleid, zodat deze ook geen eigen voedingsoptie nodig heeft.

Voor bonuspunten, het monteren van 0R-weerstanden op R10 en R11, evenals J2 geeft USB-doorvoer voor USB 3, zodat we een via USB aangesloten apparaat opnieuw kunnen opstarten, erg handig bij het ontwikkelen van hardware en u wilt uw USB-aansluitingen niet verslijten de pc!

Behuizing

Bij dit project wordt een 3D-afdrukbare behuizing meegeleverd. Het maakt gebruik van M3 heatfit-inserts voor PCB- en dekselverbindingen, hoewel de toleranties op het deksel goed genoeg zijn voor een wrijvingspassing.

Het deksel bevat een aantal opties.

  • Met of zonder batterijcompartiment.
  • Met of zonder voetjes (ook wel montagegaten genoemd om de doos aan een oppervlak te kunnen bevestigen).

Evenzo kan de basisdoos worden geconfigureerd (met behulp van OpenSCAD) met openingen voor elk van de drie stroombronnen.

Het kostte wat moeite om de behuizing goed te krijgen. Hoe versier je je afdrukken? Mijn samples van de Rigid.Ink fanclub kwamen goed van pas.

Verbinding maken met Tinamous

We gebruiken de Arduino MKR1000 om de stopcontacten te bedienen, dus we hebben wifi-connectiviteit. Als dit bord nieuw voor je is, moet je de bordoptie toevoegen aan je Arduino IDE.

We gaan de Tinamous MQTT-server gebruiken om verbinding mee te maken, vooral omdat het geweldig is, maar ook, misschien omdat ik de oprichter/ontwikkelaar/theemaker ben! We abonneren ons op het statusberichtonderwerp voor berichten die naar het apparaat worden verzonden. (d.w.z. het onderwerp "Status.Aan").

Voordat we beginnen met coderen, moeten we ervoor zorgen dat de Arduino de nieuwste firmware en de vereiste SSL-certificaten heeft om een ​​veilige verbinding met Tinamous te krijgen. Het is duidelijk dat als je wilt, je dit kunt aanpassen aan je eigen lokale MQTT-server en je niet zo druk hoeft te maken over de beveiliging.

Stap 1

Open de Arduino IDE en laad de FirmwareUpdater schets uit het WiFi101-voorbeeldmenu. Upload dit naar je apparaat.

Stap 2

Selecteer na het uploaden WiFi101 Firmware Updater van de Extra menu.

Stap 3

Test uw verbinding en Firmware bijwerken . Zodra dat is gebeurd, gebruikt u het Domein toevoegen en voeg tinamous.com . toe om ervoor te zorgen dat de Arduino de juiste SSL-certificaten heeft. Druk op de Upload Certificaten naar WiFi-module om de certificaten te uploaden.

Stap 4

Nu kunnen we onze eigen firmware schrijven. Je vindt de bestanden die bij dit project zijn gevoegd en ook in de GitHub-repository (GitHub heeft de nieuwste versie).

We gebruiken de WiFi101- en MQTT-client voor je Arduino-schets.

Selecteer de optie MQTT door Joel Gaehwiler.

Het bestand secrets.h moet worden ingevuld met je WiFi- en Tinamous MQTT-instellingen, ik heb mijn exemplaar om voor de hand liggende redenen niet toegevoegd.

WiFi- en MQTT-serverinstellingen:

#define SECRET_SSID "Uw SSID"#define SECRET_PASS "Uw SSIDs-wachtwoord"/************************* Tinaous MQTT-configuratie *******************************/#define MQTT_SERVER ".tinamous.com"#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch."#define MQTT_PASSWORD "Uw wachtwoord komt hier binnen." #define MQTT_CLIENT_ID "UsbSwitch"#define DEVICE_USERNAME "UsbSwitch" 

Als je je nog niet hebt geregistreerd bij Tinamous, kun je hier je eigen gratis account aanmaken. Wanneer u zich registreert, wordt u gevraagd om een ​​account-/organisatienaam, dit wordt uw eigen privégedeelte van Tinamous, u kunt andere leden uitnodigen voor dat gedeelte (inclusief Alexa) en uw apparaten delen met uw groep.

Hieronder noem ik mijn account "AlexaExample", dit is wat ik moet opnemen in de MQTT-configuratie, en mijn Tinamous-account bevindt zich op https://AlexaExample.Tinamous.com

Stap 5

Vervolgens moeten we ons apparaat toevoegen. Klik op de pagina Tinamoes-apparaten op de knop Toevoegen.

Vandaar dat de Tinamous MQTT-instellingen voor mijn apparaat er ongeveer zo uitzien...

/************************* Tinaous MQTT-configuratie *************** ****************/#define MQTT_SERVER "AlexaExample.tinamous.com"#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch.AlexaExample"#define MQTT_PASSWORD "Mijn supergeheime wachtwoord dat helemaal niet Passw0rd...."#define MQTT_CLIENT_ID "UsbSwitch"#define DEVICE_USERNAME "UsbSwitch" 

Dat is ons Tinamous-account en apparaat ingeschakeld. Je kunt hier meer apparaten toevoegen als je dat wilt, update gewoon de MQTT-instellingen voor DEVICE_USERNAME en MQTT_USERNAME (MQTT verzendt geen header-informatie zoals http, dus Tinamous heeft geen idee welk subdomein je gebruikt, daarom moeten we de account in de gebruikersnaam).

Stap 6

Upload de bijgevoegde code naar uw apparaten (met uw bijgewerkte secrets.h-bestand). Neem even de tijd om naar het bestand TinamousMQTTClient.ino te kijken, dit verwerkt onze MQTT-interacties en daarmee de Alexa-commando's die naar ons apparaat worden gestuurd.

We moeten de WiFiSSLClient voor SSL gebruiken. Als je een lokale MQTT-server zonder SSL wilt gebruiken, kun je de gewone WiFi-client gebruiken en naar poort 1883 gaan, maar voor alles wat op internet is gebaseerd, gebruik je de SSL-client.

We moeten ook iets meer reserveren dan de standaardbuffer voor de MQTT-client, hier reserveren we 4096 bytes.

WiFiSSSLient netwerkClient; MQTTClient mqttClient(4096);  

We gebruiken de mqttClient.begin om de client in te stellen en een functie-handler in onMessage op te geven die wordt aangeroepen wanneer een bericht wordt ontvangen van de MQTT-server.

 mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, netwerkClient); // Behandel ontvangen berichten. mqttClient.onMessage(messageReceived); 

En dan kunnen we verbinding maken en ons abonneren op de onderwerpen waarin we geïnteresseerd zijn. Hier zie je dat we ons hebben geabonneerd op "Tinamous/V1/Status.To/UsbSwitch", we zullen berichten ontvangen die zijn verzonden naar @UsbSwitch vanaf de tijdlijn van Tinamous. Dit is hoe we berichten van Alexa ontvangen.

if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { if (mqttClient.lastError() ==LWMQTT_CONNECTION_DENIED) { // Deze fout is omdat uw gebruikersnaam of wachtwoord onjuist is } if (mqtttttError() ==LWMQTT_CONNECTION_DENIED) lastError() ==-6) { // Deze fout is hoogstwaarschijnlijk omdat je het SSL-certificaat niet hebt toegevoegd. } // Forceer een vertraging voordat u de verbindingsvertraging (10000) opnieuw probeert; return false;}// Succesvolle verbinding. Abonneer u nu op het onderwerp mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME); 

Je kunt de Tinamous-tijdlijn zien als een privéversie van Twitter voor jou en je apparaten, ze kunnen MQTT of de REST API (of een van de bots) gebruiken om de berichten te zien die naar hen zijn verzonden en ernaar te handelen, evenals om berichten te plaatsen berichten terug.

We hebben nog wat werk te doen in Tinamous om Alexa-integratie mogelijk te maken, maar voorlopig kunnen we ons apparaat en onze firmware testen door de tijdlijn te gebruiken en berichten te verzenden.

Als u de Tinamous SmartHome-vaardigheid gebruikt, is dat alle codering die nodig is.

De Tinamous Smart Home-vaardigheid voor Alexa

De Tinamous Smart Home Skill is momenteel in afwachting van goedkeuring om te worden gepubliceerd (op het moment van schrijven is het nu in de winkel...). Om je eigen USB-switcher te maken, kun je deze vaardigheid gewoon gebruiken wanneer deze beschikbaar is.

De vaardigheid is eigenlijk heel generiek, hij weet niets over de apparaten of hoe ermee te praten. We passen tags toe op de apparaten in Tinamous en de vaardigheid zal een geschikt apparaat maken in het Alexa-account, daarom zou je deze vaardigheid en Tinamous kunnen gebruiken om een ​​van je eigen projecten in te schakelen met slechts een paar regels code op het apparaat.

Het kan echter zijn dat je dingen wilt veranderen of je eigen vaardigheden wilt schrijven, dus ik zal de details van mijn ontwikkeling met je delen.

Ik schreef de vaardigheid in C# voor .Net Core 2.0, het is eigenlijk ontwikkeld voor mijn BOFF smart fan-project, maar voor dit project heb ik het uitgebreid zodat een apparaat veel stopcontacten (poorten) kan hebben en voor elk een eersteklas burger in Alexa Smart Home-apparaten.

Alle code (inclusief enkele tests!) bevindt zich in de Tinamous SmartHome-repository, kloon, download of bekijk het gewoon zoals je wilt. Ik gebruikte Visual Studio 2017 met de AWS-tools geïnstalleerd om de vaardigheid naar Lambda te pushen.

Het framework deserialiseert het binnenkomende instructiebericht van Alexa in objecten waartoe we toegang hebben via de code, passende acties worden ondernomen op basis van de headernaamruimte en de instructienaam, en vervolgens wordt een passend antwoord geretourneerd.

De belangrijkste berichten van belang zijn:

  • Account koppelen
  • Ontdekking
  • Statusrapport
  • Power Control

Account koppelen:

Dit wordt voor ons afgehandeld door Alexa, nadat we de vaardigheid aan ons account hebben toegevoegd, zal Alexa om authenticatie vragen, we worden naar de Tinamous Authorize-pagina gebracht zodat het apparaat toegang heeft tot ons account. Hier moet je je accountnaam (AlexaExample in dit geval), gebruikersnaam (Steve) en wachtwoord invoeren (nee, dat zeg ik niet!)

Ontdekking:

Zodra je account is gekoppeld, vraagt ​​Alexa om detectie uit te voeren, waarna de vaardigheid Tinamous vraagt ​​naar apparaten die zijn getagd met "Alexa.SmartDevice ". Apparaten zonder dit worden gewoon genegeerd.

Deze tags worden toegepast door het apparaat te bewerken vanaf de pagina Apparaten in Tinamous.

Als het apparaat ook is getagd met "MultiPort " elke poort wordt opgesomd en er wordt ook een apparaat voor toegevoegd. We passen ook tags toe op basis van de Alexa-richtlijnen die ons apparaat ondersteunt, hier is het gewoon "Alexa.PowerController " en ook een tag om aan te geven onder welke categorie het apparaat in de app moet worden weergegeven, hier heb ik "SmartPlug gebruikt ".

Er zijn andere interfaces beschikbaar, zoals Alexa.BrightnessController, maar dat is hier niet zo handig. Zie de leesmij van de repository voor meer details.

Om ervoor te zorgen dat ons MultiPort-apparaat individuele poorten blootstelt aan Alexa, moeten we de staatsvariabelen instellen, ook op de pagina met het apparaat bewerken.

PortCount geeft het aantal poorten aan dat het apparaat heeft, vervolgens geeft "Port-1".."Port-n" de namen die Alexa voor de poorten zal gebruiken. Elke poort zonder naam wordt genegeerd. Je kunt hier eenvoudig de naam van de poort wijzigen en de ontdekking opnieuw uitvoeren om Alexa te updaten.

Tijdens de ontdekking zoekt de vaardigheid ook naar een veld dat is getagd, genoemd of gelabeld als 'powerState' of 'powerState-port-n', al naar gelang van toepassing. Als dit veld wordt gevonden, wordt het toegewezen als een ondersteunde mogelijkheid voor het apparaat (meer hierover in Statusrapport).

Staatsrapport

Tijdens de ontdekkingsfase hebben we Alexa verteld welke mogelijkheden ons apparaat heeft, de standaard vaardigheid om Alexa te vertellen dat deze kunnen worden aangevraagd, daarom zal Alexa een StateReport-verzoek sturen om de waarden hiervoor te krijgen.

We moeten nog een laatste set tags toepassen om dit te ondersteunen, dit keer op de apparatenvelden. Zodra uw apparaat gegevens verzendt (dat is het senml-bericht dat in de Arduino-code over MQTT wordt gepusht), maakt Tinamous velden voor het apparaat. We kunnen dan de optie Geavanceerd uit de lijst met velden gebruiken om dit te bewerken. Het gebruik van de tag-optie is het meest veelzijdig, omdat het betekent dat we de veldnaam niet correct in de firmware hoeven te krijgen of vast te zitten als we de naam willen wijzigen.

Als de poortspecifieke velden niet worden gevonden, valt Alexa terug naar het niet-poortspecifieke veld (hier powerState genoemd).

Vermogensregeling

Ons apparaat zal zonder dit niet worden gebruikt in Alexa! Alexa stuurt twee instructies naar onze vaardigheid "TurnOn" en "TurnOff". Het belangrijkste functie-ingangspunt voor de vaardigheid zoekt eerst naar de naamruimte (Alexa.PowerController) en geeft de taak vervolgens door aan de juiste controllerklasse (PowerController.cs).

De vaardigheid publiceert vervolgens eenvoudig een statusbericht op de tijdlijn van Tinamous.

Bijvoorbeeld:

@UsbSwitch Inschakelen

of

@UsbSwitch Zet poort-1 aan

De andere ondersteunde interfaces worden op bijna identieke wijze afgehandeld. Het is dan aan ons apparaat om op deze statusmelding te letten en een actie uit te voeren. Alexa kan dan de staat teruglezen met behulp van een StateReport.

Zo werkt de vaardigheid. Nu hoeven we het alleen maar naar AWS Lambda te pushen en een vaardigheidsitem op de Alexa-console te maken om Alexa er daadwerkelijk toegang toe te geven.

De AWS Lambda-functie maken:

Ik heb de AWS-tools in Visual Studio gebruikt om de gecompileerde vaardigheid naar Lambda te pushen. Maar eerst moeten we de Lambda maken.

Pro-tip: Maak de Lambda in het juiste AWS-gebied voor de taal die u ondersteunt. Engels (VK) moet eu-west (Ierland) targeten.

Maak een nieuwe lambda-functie vanuit het niets. De bestaande blauwdrukken zijn beperkt en verouderd (alleen ondersteuning van V2 van de SmartHome-interface, die heel anders en verouderd is - we gebruiken V3).

U moet een nieuwe rol maken om de Lambda toegang te geven tot de benodigde bronnen. Hier selecteren we Simple Microservices als standaard (het geeft eigenlijk veel meer dan we nodig hebben). Als u merkt dat u geen logboeken krijgt in Cloud Watch, moet u mogelijk ook de rolmachtigingen daarvoor geven via de IAM-sectie.

Vervolgens moeten we de binaire bestanden van Visual Studio publiceren. Nadat de AWS-tools zijn geïnstalleerd, klikt u met de rechtermuisknop op het project en selecteert u "Publiceren naar AWS Lambda..."

Vul vervolgens de details voor de Lambda-expressie in en klik op Uploaden...

Eenmaal geüpload, kunnen we enkele tests uitvoeren op de Lambda om ervoor te zorgen dat deze werkt. Vervolgens moeten we "Nieuwe versie publiceren" in de vervolgkeuzelijst Acties.

Na publicatie moeten we onze vaardigheidsrechten geven om toegang te krijgen,

Klik op de "Alexa Smart Home"-trigger en voer de vaardigheids-ID in (die hebben we echter nog niet...)

De vaardigheid creëren op de Alexa-console:

Met onze Lambda bijna klaar voor gebruik, moeten we naar de console voor vaardigheidsontwikkelaars gaan en er daadwerkelijk een vermelding voor maken. Open https://developer.amazon.com, selecteer Alexa Skills Kit en voeg een nieuwe vaardigheid toe.

Selecteer Smart Home Skill API, de taal die u wilt targeten (bijvoorbeeld Engels (VK) voor ons in het VK) en selecteer V3 (voorkeur) payload-versie.

Op de configuratiepagina gaan we in op de meer interessante details. Voer de Lambda ARN in van onze Lambda met versiebeheer (rechtsboven op het scherm). Het zou ongeveer moeten eindigen als :1 of :2 of :5246 (als je er een paar hebt gehad;-) ).

Terwijl we in Lambda ook de "Applicatie-ID" of "Vaardigheids-ID" of "ID" kunnen plakken of hoe het vandaag de dag heet vanuit de vaardigheid, zou het er ongeveer zo uit moeten zien als amzn1.ask.skill.2_______________50.

Zorg ervoor dat u op Opslaan klikt zodra u de toepassings-ID hebt toegevoegd. In de oude console kun je de id in de kop onder de vaardigheidsnaam vinden, in de nieuwe, erm, open een nieuw venster, ga terug naar de consolevaardighedenlijst en klik op de juiste link. (het is alsof ze de console nooit hebben gebruikt om daadwerkelijk een vaardigheid te maken).

Om accountkoppeling mogelijk te maken, hebben we een OAuth-toepassing nodig die is gemaakt bij Tinamous, dit wordt gedaan met behulp van de Alexa Bot. Ga naar je Tinamoes-account Bots-pagina en voeg een Alexa Bot toe. Als je dat eenmaal hebt gemaakt, geeft het dialoogvenster je alle details die je nodig hebt om accountkoppeling te configureren.

NB:Als je de (binnenkort...) gepubliceerde Tinamous SmartHome-vaardigheid gebruikt, heb je geen Alexa Bot nodig.

Met de applicatie die door de bot is gemaakt, kunnen andere Tinamous-accounthouders uw vaardigheden gebruiken en hun account koppelen. Natuurlijk hoef je je vaardigheden niet te publiceren en je kunt het privé houden, en ze zullen niets in je Tinamous-account kunnen zien.

Evenzo, als u een andere apparaatcloud gebruikt (serieus, waarom zou u dat doen;-) ), dan moet u hun OAuth-toepassingsdetails invoeren.

Zorg ervoor dat op de testpagina uw vaardigheid is ingesteld op "Ja" voor "Toon deze vaardigheid in de Alexa-app".

Sla op en ga naar alexa.amazon.co.uk (of degene die geschikt is voor uw regio), of blijkbaar ook een app .....

Klik op "Vaardigheden", dan rechtsboven op "Jouw vaardigheden" en vervolgens op "DEV VAARDIGHEDEN", ​​je zou je vaardigheid moeten zien verschijnen met een groene markering om aan te geven dat het een ontwikkelingsvaardigheid is.

De "Alexa, zet het usb-licht uit", en aanvullende vaardigheidsinformatie wanneer u deze selecteert, is geconfigureerd op de pagina "Publicatiegegevens", u kunt de informatie tijdens de ontwikkeling invoeren zonder volledig te hoeven publiceren.

Als u de vaardigheidscode moet bijwerken, uploadt u de nieuwe Lambda-functie, maakt u een nieuwe versie, voegt u de SmartHome-trigger en vaardigheids-ID opnieuw toe, en plakt u de versie van de Lambda-functie in de vaardigheidsconsole (mogelijk kunt u een niet- 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".

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); Serieel.println(); vertraging (10000); return false; } 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()); Serieel.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. vertraging (10000); return false; } 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()); Serieel.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."); opbrengst; } } // 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; 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:"); Serieel.println(ssid); // Connect to WPA/WPA2 network:status =WiFi.begin(ssid, pass); // wacht 10 seconden op verbinding:vertraging (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("IP-adres:"); Serieel.println(ip); Serieel.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:"); Serieel.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(); opbrengst; } 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 ""

Aangepaste onderdelen en behuizingen

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.

Schema's

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

Productieproces

  1. Stroombronnen
  2. C# switch-instructie
  3. Batterijladers bieden een grotere vermogensdichtheid, sneller opladen
  4. Sensor voor stroomuitval
  5. Raspberry Pi / Hologram SMS-gestuurde wisselstroomschakelaar
  6. Windkracht
  7. Gids voor krachthamers
  8. Wat is een automatische powerpers?
  9. Wat is een Power Chuck?
  10. Een beknopte handleiding voor Power Chucks
  11. Hydro-elektrische energie begrijpen