산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Alexa 지원 USB 전원 스위치

구성품 및 소모품

Arduino MKR1000
× 1
0.1uF 0805 커패시터
× 8
LED(일반)
× 4
버튼 누르기(긴)
× 4
INA219(soic 8)
× 1
LM3526M
× 2
USB 소켓(수직)
× 4
1k 0805 저항기
× 4
0.1옴 전류 감지 저항기
× 1
1uF 0805 커패시터
× 1

필요한 도구 및 기계

3D 프린터(일반)
납땜 인두(일반)

앱 및 온라인 서비스

Amazon Alexa Alexa 기술 키트
티나무스
Amazon Web Services AWS Lambda

이 프로젝트 정보

Alexa, ThingyStick을 켜십시오...

배경

점점 더 많은 장치가 USB로 구동되며, 이들 중 다수는 인터넷 연결이나 홈 자동화 옵션(예:LED 조명)이 없는 "멍청한" 장치인 경향이 있습니다. 어떻게 원격으로 자동화하거나 제어할 수 있습니까? 아마도 USB 공급 장치가 주 전원 스위치에 연결되어 있을 수 있습니다. 특히 4개의 장치를 개별적으로 제어하려는 경우에는 다소 무리입니다!

이 프로젝트를 통해 인터넷을 통해 USB 전원 공급 장치에 대한 전원 공급을 제어할 수 있으며 Alexa용 Tinamous SmartHome Skill을 사용하여 멍청한 USB 장치에 대한 음성 제어를 활성화할 수 있습니다.

현재 시장에서 USB 전원을 원격으로 제어할 수 있는 장치는 거의 없습니다. 이 프로젝트를 시작했을 때 영국에서는 찾지 못했지만 최근에 멀티 갱 콘센트의 일부로 몇 대가 나타났습니다(예, 아이디어 오래전에 시작하여 멀리 떨어진 은하계에서), 이들은 잘 알려진 홈 오토메이션 제조업체가 아니라 브랜드가 없는 제조업체(예:ZLD-34UK)에 의한 것이므로 그들이 사용하는 장치 클라우드의 문제가 있습니다. 중국과 그 뒤로, 해당 제조업체가 더 이상 존재하지 않으면 어떻게 되는지, 얼마나 안전한지, 소프트웨어가 얼마나 사용 가능한지, 다음 주에 재활용 상자에 들어갈 것인지, 그리고 인터넷에 연결된 장치에 대한 다른 많은 일반적인 문제는 말할 것도 없습니다. 오픈 소스 Arduino 기반 장치와 같은 방식으로 해킹 가능합니다.

사용 사례

제어할 수 있는 USB 전원 장치의 예:

<울>
  • USB 전원 조명
  • <울>
  • Kindle Fire/Chrome 캐스트 스틱(특히 어린이 방에서 TV 시청을 중지)
  • <울>
  • USB 가습기
  • <울>
  • Echo Dot(Alexa가 밤에 자동으로 종료되도록 하시겠습니까? 아니면 기기를 재부팅만 하시겠습니까?)
  • <울>
  • 개발 보드. 코드가 무한 루프에 빠져 프로젝트를 재부팅해야 합니까?
  • <울>
  • 접근하기 어렵지만 가끔 재부팅해야 하는 기기(예:다락방의 센서)
  • <울>
  • 전원이 공급되는지 확인하려는 클라이언트 구내에 설치된 장치(전류 소비 및 입력 전압 측정)
  • 간단한 전원 제어: Alexa 음성 제어 또는 Tinamous를 통한 기타 명령을 통한 인터넷 사용 전원 전환. 켜기 및 끄기.

    스마트 전원 제어: 많은 USB 램프에는 램프를 켤 수 있는 터치 컨트롤이 있습니다. 즉, 원격으로 조명을 켤 수는 없지만 끌 수 있으며 많은 시간 동안 우리가 원하는 전부입니다(잠자기 위해 ? 외출, 모든 조명을 끄시겠습니까?).

    그러나 Alexa를 사용하여 USB 램프를 끄고 나면 램프를 켜기 전에 Alexa에게 램프를 켜도록 요청해야 합니다. 이는 어리석은 일입니다. 스마트 전원이 활성화된 상태에서 끄기 명령은 장치에 전원을 복원하기 전에 몇 초 동안 램프 전원을 끕니다. 램프를 끄는 데 충분하지만 이후에는 정상 작동도 가능합니다.

    타이머 자동화: 설정한 시간에 기기의 전원이 자동으로 꺼지도록 합니다. 불에 타서 아마존 TV를 보는 아이들은 늦게까지 스틱? 오후 8시에 USB 공급이 자동으로 종료되도록 합니다.

    전력 모니터링: USB 전원 하드웨어를 개발하는 경우 특히 처음 스위치를 켤 때 장치가 얼마나 많은 전류를 소비하는지 알고 싶거나 배터리 팩 충전을 프로파일링하고 싶을 수 있습니다. 온보드 INA219를 사용하면 전류 소비를 모니터링할 수 있습니다(저는 거의 노력 없이 약 1kHz 샘플링을 관리했습니다). 고전류에서 USB 리드의 전압 강하는 문제가 될 수 있습니다. INA219는 장치에 대한 전원을 모니터링하여 저전압에 대해 경고할 수 있습니다. 더 높은 전류와 더 큰 케이블을 사용할 수 있도록 단자대도 제공됩니다.

    정전: MKR 1000의 배터리 옵션을 사용하여 USB 공급 전압을 모니터링하고 입력 전원에 장애가 발생하면 알림을 보낼 수 있습니다. 이것은 USB 전원을 사용하지만 약간의 추가 모니터링이 필요한 원격(오프사이트) 솔루션에 유용할 수 있습니다.

    하드웨어

    이 프로젝트는 매우 간단합니다. 핵심은 Arduino MKR1000이고 2개의 LM3526M을 사용하는 USB 전원 스위칭은 INA219를 사용한 전력 모니터링(전압 및 전류)과 함께 하이 사이드 스위칭 및 오류 감지(저전압, 과전류)를 제공하고 마지막으로 로컬 제어 옵션용 LED 및 스위치.

    DirtyPCBs.com에서 PCB를 만들었습니다. .brd 파일을 OSHpark.com으로 보내 일부도 만들 수 있습니다. Arduino 소켓에는 해킹을 허용하기 위해 각 핀의 양쪽에 PCB 패드가 있습니다. 예를 들어 환경 조건에 대한 센서를 추가하거나 전압 및 전류를 표시하는 소형 OLED 디스플레이를 쉽게 추가할 수 있습니다.

    github 저장소에는 2포트와 4포트 옵션이 있습니다. 내가 망쳤습니다 2포트 PCB에 주의하세요. USB 소켓 레이아웃이 잘못되었습니다(뒤에서 앞으로 - 잘못된 극성). !).

    승리 패배의 입에서:

    보드 뒷면에 고정된 USB를 장착하는 것은 실제로 좋은 솔루션이며 핀 연결이 정확함을 의미합니다(그러나 2 포트 보드의 경우 실크 스크린이 잘못된 쪽에 있음을 의미합니다!). 소켓에 헤더가 있는 Arduino는 USB 소켓을 인클로저에서 꺼내는 데 필요한 높이로 공간을 위해 약간 밀려서 실제로 더 잘 작동했습니다. 저는 소켓, 스위치 및 LED가 있는 보드를 반대로 하기로 결정했습니다. 측면에 2개의 추가 포트를 추가하기 위해 4개의 포트 버전이 생성되었습니다(또한 2개의 포터에 LED를 끔찍하게 정렬하여 수정했습니다!).

    LED와 스위치를 삭제하거나 개선해야 할 수도 있지만 6 또는 8 포트 스위처로 확장되는 것을 막는 것은 거의 없습니다.

    회로도는 훨씬 더 복잡해 보입니다. 많은 저항은 선택 사항입니다. 저항 R23, 19, 27 및 26은 모두 스위치용 풀업이며, 마찬가지로 R20-22, R14 및 R15는 USB 제어 및 오류 감지용 풀업입니다. 이것들은 모두 Arduino의 INPUT_PULLUP 핀 모드를 통해 수행할 수 있습니다. 그러나 Arduino를 저전력 절전 모드로 전환하고 인터럽트를 사용하여 깨우고 싶다면 이것들을 채우고 싶을 수 있습니다. .

    또한 USB D+/D- 라인 주위에 선택적 저항을 추가했습니다. 이것은 장치가 사용할 수 있는 전력의 양을 알려주기 위해 장착될 수 있지만 많은 멍청한 장치의 경우 어쨌든 무시됩니다. LED 전류 제한을 위한 R24 이하만 실제로 필요합니다. R2-5 및 R28은 비어 있습니다.

    LED와 스위치도 완전히 선택 사항입니다. USB를 원격으로 제어하는 ​​독립형 상자만 원하는 경우 해당 부품을 추가하지 마십시오.

    전원 입력

    이 컨트롤러는 세 가지 옵션을 통해 전원을 공급할 수 있습니다.

    첫 번째는 "내부" 옵션(JP6 핀 1 및 2 연결됨)이며 USB 전원은 Arduino의 5V 핀(따라서 Arduino USB 커넥터)에서 가져옵니다. 그러나 이것은 저전력 부하에만 사용해야 합니다.

    다른 옵션은 외부 전원(JP6 핀 2 및 3 연결)을 위한 것이므로 J2(온보드 USB 마이크로 커넥터) 또는 JP8(터미널 블록)을 통해 5V를 연결할 수 있습니다. 두 옵션을 동시에 사용하면 안 됩니다. 외부 전원도 Arduino VIn 핀으로 연결되므로 자체 전원 옵션도 필요하지 않습니다.

    보너스 포인트의 경우, 0R 저항을 R10 및 R11에 장착하고 J2는 USB 3에 대한 USB 통과를 제공하므로 USB 연결 장치를 재부팅할 수 있습니다. 하드웨어를 개발할 때 매우 편리하며 USB 소켓이 마모되는 것을 원하지 않습니다. PC!

    인클로저

    이 프로젝트에는 3D 인쇄 가능한 인클로저가 포함되어 있습니다. 덮개의 허용 오차가 마찰 끼워맞춤에 충분하지만 PCB 및 덮개 연결을 위해 M3 히트핏 인서트를 사용합니다.

    뚜껑에는 몇 가지 옵션이 있습니다.

    <울>
  • 배터리 구획이 있거나 없는.
  • <울>
  • 발이 있거나 없음(상자를 표면에 고정할 수 있는 장착 구멍이라고도 함).
  • 마찬가지로 베이스 박스는 3개의 전원 소스 각각에 대한 개구부를 포함하도록 구성할 수 있습니다(OpenSCAD 사용).

    인클로저를 올바르게 만드는 데 몇 번의 작업이 필요했습니다. 인쇄물의 버전을 어떻게 관리합니까? Rigid.Ink 팬클럽에서 가져온 샘플이 매우 유용했습니다.

    Tinamous에 연결하기

    Arduino MKR1000을 사용하여 콘센트를 제어하므로 WiFi 연결이 가능합니다. 이 보드를 처음 사용하는 경우 Arduino IDE에 보드 옵션을 추가해야 합니다.

    우리는 Tinamous MQTT 서버를 사용하여 연결할 것입니다. 주로 그것이 굉장하기 때문이기도 하지만 아마도 제가 창립자/개발자/차 메이커이기 때문일 것입니다! 장치로 전송된 메시지에 대한 상태 게시물 주제를 구독합니다. (즉, "Status.To" 주제).

    코딩을 시작하기 전에 Arduino에 최신 펌웨어와 Tinamous에 대한 보안 연결에 필요한 SSL 인증서가 있는지 확인해야 합니다. 분명히 원하는 경우 이를 자체 로컬 MQTT 서버에 적용할 수 있으며 보안에 대해 크게 걱정하지 않아도 됩니다.

    1단계

    Arduino IDE를 열고 FirmwareUpdater를 로드합니다. WiFi101 예제 메뉴에서 스케치합니다. 기기에 업로드하세요.

    2단계

    업로드되면 WiFi101 펌웨어 업데이터를 선택합니다. 도구에서 메뉴.

    3단계

    연결을 테스트한 다음 펌웨어 업데이트 . 완료되면 도메인 추가를 사용하세요. 버튼을 누르고 tinamous.com을 추가합니다. Arduino에 올바른 SSL 인증서가 있는지 확인합니다. WiFi 모듈에 인증서 업로드를 누릅니다. 버튼을 눌러 인증서를 업로드하세요.

    4단계

    이제 자체 펌웨어를 작성할 수 있습니다. 이 프로젝트와 GitHub 저장소에 첨부된 파일을 찾을 수 있습니다(GitHub에는 최신 버전이 있습니다).

    WiFi101 및 MQTT 클라이언트를 Arduino 스케치에 사용합니다.

    조엘 개윌러의 MQTT 옵션을 선택하세요.

    secret.h 파일은 WiFi 및 Tinamous MQTT 설정으로 채워져야 합니다. 명백한 이유로 제 사본을 포함하지 않았습니다.

    WiFi 및 MQTT 서버 설정:

    #define SECRET_SSID "귀하의 SSID#define SECRET_PASS "SSID 비밀번호"/************************* Tinamous MQTT 설정 *********************************/#define MQTT_SERVER ".tinamous.com#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch.#define MQTT_PASSWORD "여기에 비밀번호를 입력하세요."#define MQTT_CLIENT_ID "UsbSwitch#define DEVICE_USERNAME "UsbSwitch" 

    아직 Tinamous에 등록하지 않았다면 여기에서 무료 계정을 만들 수 있습니다. 등록할 때 계정/조직 이름을 묻는 메시지가 표시됩니다. 이 영역은 Tinamous의 개인 영역이 되며 다른 구성원을 해당 영역(Alexa 포함)에 초대하고 기기를 그룹과 공유할 수 있습니다.

    아래에서 내 계정을 "AlexaExample"이라고 부릅니다. 이것이 MQTT 설정에 포함해야 하는 항목이며 Tinamous 계정은 https://AlexaExample.Tinamous.com에 있습니다.

    5단계

    다음으로 장치를 추가해야 합니다. Tinamous Devices 페이지에서 추가 버튼을 클릭합니다.

    따라서 내 장치에 대한 Tinamous MQTT 설정은 다음과 같습니다...

    <사전><코드>/**************************** Tinamous MQTT 설정 *************** ******************/#define MQTT_SERVER "AlexaExample.tinamous.com#define MQTT_SERVERPORT 8883 #define MQTT_USERNAME "UsbSwitch.AlexaExample#define MQTT_PASSWORD "내 슈퍼 비밀 암호 완전히 Passw0rd가 아닙니다...."#define MQTT_CLIENT_ID "UsbSwitch#define DEVICE_USERNAME "UsbSwitch"

    그것이 우리의 Tinamous 계정과 장치가 활성화된 것입니다. 원하는 경우 여기에 더 많은 장치를 추가할 수 있습니다. DEVICE_USERNAME 및 MQTT_USERNAME에 대한 MQTT 설정을 업데이트하기만 하면 됩니다(MQTT는 http와 같은 헤더 정보를 보내지 않으므로 Tinamous는 사용 중인 하위 도메인을 알지 못하므로 다음을 지정해야 합니다. 사용자 이름의 계정).

    6단계

    첨부된 코드를 기기에 업로드합니다(업데이트된 secrets.h 파일 포함). TinamousMQTTClient.ino 파일을 잠시 살펴보십시오. 이 파일은 MQTT 상호 작용을 처리하고 이와 함께 장치로 전송되는 Alexa 명령을 처리합니다.

    SSL용 WiFiSSLClient를 사용해야 합니다. SSL 없이 로컬 MQTT 서버를 사용하려면 일반 WiFi 클라이언트를 사용하고 포트 1883으로 드롭다운할 수 있지만 인터넷 기반의 경우 SSL 클라이언트를 사용하세요.

    또한 MQTT 클라이언트를 위한 기본 버퍼보다 ​​조금 더 예약해야 합니다. 여기서 4096바이트를 예약합니다.

    WiFiSSLClient 네트워크클라이언트; MQTT클라이언트 mqtt클라이언트(4096);  

    mqttClient.begin을 사용하여 클라이언트를 설정하고 MQTT 서버에서 메시지를 수신할 때 호출되는 onMessage에 함수 핸들러를 지정합니다.

    <사전><코드> mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, 네트워크 클라이언트); // 수신된 메시지를 처리합니다. mqttClient.onMessage(messageReceived);

    그리고 나서 우리는 우리가 관심 있는 주제에 연결하고 구독할 수 있습니다. 여기에서 우리가 "Tinamous/V1/Status.To/UsbSwitch"를 구독한 것을 볼 수 있습니다. 우리는 Tinamous 타임라인에서 @UsbSwitch로 보내는 메시지를 받을 것입니다. 이것이 Alexa로부터 메시지를 받는 방법입니다.

    if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { if (mqttClient.lastError() ==LWMQTT_CONNECTION_DENIED) { // 이 오류는 사용자 이름 또는 비밀번호가 잘못되었기 때문입니다 } if (mqttClient. lastError() ==-6) { // 이 오류는 SSL 인증서를 추가하지 않았기 때문에 발생했을 가능성이 큽니다. } // 연결을 재시도하기 전에 강제로 지연 지연(10000); return false;}// 성공적인 연결. 이제 mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME); 주제를 구독하십시오. 

    Tinamous 타임라인은 귀하와 귀하의 장치를 위한 Twitter의 비공개 버전으로 생각할 수 있습니다. 그들은 MQTT 또는 REST API(또는 봇 중 하나)를 사용하여 전송된 메시지를 보고 조치를 취하고 게시할 수 있습니다. 다시 메시지를 보냅니다.

    Alexa 통합을 활성화하기 위해 Tinamous에서 해야 할 일이 조금 더 있지만 지금은 타임라인을 사용하고 메시지를 전송하여 장치와 펌웨어를 테스트할 수 있습니다.

    Tinamous SmartHome 기술을 사용하는 경우 필요한 모든 코딩입니다.

    Alexa를 위한 Tinamous Smart Home Skill

    Tinamous Smart Home Skill은 현재 출판 승인을 기다리고 있습니다. 자신만의 USB 스위처를 만들려면 이 기술을 사용할 수 있을 때 사용하면 됩니다.

    이 기술은 실제로 매우 일반적이며 장치나 통신 방법에 대해 알지 못합니다. Tinamous의 장치에 태그를 적용하면 해당 기술이 Alexa 계정에 적절한 장치를 생성하므로 이 기술과 Tinamous를 사용하여 장치에서 몇 줄의 코드로 자신의 프로젝트 중 하나를 음성으로 활성화할 수 있습니다.

    그러나 변경하거나 자신의 기술을 작성하기를 원할 수 있으므로 내 개발에 대한 세부 정보를 공유하겠습니다.

    .Net Core 2.0용 C#으로 기술을 작성했습니다. 실제로 내 BOFF 스마트 팬 프로젝트를 위해 개발되었지만 이 프로젝트에서는 장치에 많은 콘센트(포트)가 있고 각각이 일급이 되도록 확장했습니다. Alexa Smart Home 장치의 시민입니다.

    모든 코드(일부 테스트 포함!)는 Tinamous SmartHome 저장소에 있으며 원하는 대로 복제, 다운로드 또는 보기만 하면 됩니다. AWS 도구가 설치된 Visual Studio 2017을 사용하여 Lambda에 기술을 푸시하는 데 도움이 되었습니다.

    프레임워크는 Alexa에서 들어오는 지시문 메시지를 코드를 통해 액세스할 수 있는 객체로 역직렬화하고 헤더 네임스페이스와 지시문 이름을 기반으로 적절한 조치를 취한 다음 적절한 응답을 반환합니다.

    주요 관심 메시지는 다음과 같습니다.

    <울>
  • 계정 연결
  • <울>
  • 발견
  • <울>
  • 상태 보고서
  • <울>
  • 전원 제어
  • 계정 연결:

    이것은 Alexa가 처리합니다. 계정에 스킬을 추가하면 Alexa가 인증을 요청하고 디바이스가 계정에 액세스할 수 있도록 Tinamous Authorize 페이지로 이동합니다. 여기에 계정 이름(이 경우 AlexaExample), 사용자 이름(Steve) 및 비밀번호(아니요, 말하지 않겠습니다!)를 입력해야 합니다.

    발견:

    계정이 연결되면 Alexa는 검색을 수행하라는 메시지를 표시하고 기술은 Tinamous에 "Alexa.SmartDevice 태그가 지정된 장치를 쿼리합니다. ". 이것이 없는 장치는 단순히 무시됩니다.

    이 태그는 Tinamous의 Devices 페이지에서 장치를 편집하여 적용됩니다.

    장치에 "MultiPort 태그도 있는 경우 " 각 포트가 열거되고 이에 대한 장치도 추가됩니다. 또한 장치가 지원하는 Alexa 지시문을 기반으로 태그를 적용합니다. 여기서는 "Alexa.PowerController입니다. " 및 앱에서 기기가 표시되어야 하는 카테고리를 나타내는 태그도 있습니다. 여기서는 "SmartPlug를 사용했습니다. ".

    Alexa.BrightnessController와 같은 다른 인터페이스를 사용할 수 있지만 여기서는 그다지 유용하지 않습니다. 자세한 내용은 저장소 추가 정보를 참조하십시오.

    MultiPort 장치가 개별 포트를 Alexa에 노출하려면 장치 편집 페이지에서도 상태 변수를 설정해야 합니다.

    PortCount는 장치에 있는 포트 수를 나타내고 "Port-1".."Port-n"은 Alexa가 포트에 사용할 이름을 제공합니다. 이름이 없는 포트는 무시됩니다. 여기에서 포트 이름을 쉽게 변경하고 검색을 다시 실행하여 Alexa를 업데이트할 수 있습니다.

    검색하는 동안 기술은 적절하게 "powerState" 또는 "powerState-port-n"이라는 태그가 지정되거나 이름이 지정되거나 레이블이 지정된 필드도 찾습니다. 이 필드가 발견되면 장치에 대해 지원되는 기능으로 할당됩니다(자세한 내용은 상태 보고서 참조).

    상태 보고서

    발견 단계에서 우리는 Alexa에게 기기에 어떤 기능이 있는지 알렸고, 기술은 기본적으로 Alexa에게 이러한 기능을 요청할 수 있다고 알려주므로 Alexa는 이러한 값을 가져오기 위해 StateReport 요청을 보냅니다.

    이를 지원하기 위해 이번에는 장치 필드에 적용할 마지막 태그 세트가 하나 있습니다. 장치가 데이터를 보내면(아두이노 코드에서 MQTT를 통해 푸시되는 senml 메시지임) Tinamous는 장치에 대한 필드를 생성합니다. 그런 다음 필드 목록에서 고급 옵션을 사용하여 이를 편집할 수 있습니다. 태그 옵션을 사용하면 펌웨어에서 필드 이름을 올바로 가져올 필요가 없고 이름을 바꾸려는 경우 멈출 필요가 없기 때문에 가장 다용도로 사용할 수 있습니다.

    포트별 필드를 찾을 수 없는 경우 Alexa는 비포트별 필드(여기서는 powerState)로 대체합니다.

    전원 제어

    이것이 없으면 Alexa에서 우리 장치를 사용할 수 없습니다! Alexa는 스킬 "TurnOn" 및 "TurnOff"에 두 가지 지시문을 보냅니다. 기술의 주요 기능 진입점은 먼저 네임스페이스(Alexa.PowerController)를 찾은 다음 적절한 컨트롤러 클래스(PowerController.cs)에 작업을 넘깁니다.

    그런 다음 기술은 Tinamous 타임라인에 상태 메시지를 게시하기만 하면 됩니다.

    예:

    @UsbSwitch 켜기

    또는

    @UsbSwitch 포트-1 켜기

    지원되는 다른 인터페이스는 거의 동일한 방식으로 처리됩니다. 그런 다음 이 상태 메시지를 확인하고 작업을 수행하는 것은 장치에 달려 있습니다. 그런 다음 Alexa는 StateReport를 사용하여 상태를 다시 읽을 수 있습니다.

    그래야 스킬이 작동합니다. 이제 AWS Lambda에 푸시하고 Alexa 콘솔에 Skill 항목을 생성하여 실제로 Alexa에 액세스 권한을 부여하기만 하면 됩니다.

    AWS Lambda 함수 생성:

    Visual Studio 내에서 AWS 도구를 사용하여 컴파일된 기술을 Lambda에 푸시했습니다. 하지만 먼저 Lambda를 생성해야 합니다.

    전문가 팁: 지원하는 언어에 대해 적절한 AWS 영역에서 Lambda를 생성합니다. 영어(영국)는 eu-west(아일랜드)를 타겟팅해야 합니다.

    처음부터 새 람다 함수를 만듭니다. 기존 청사진은 제한적이고 구식입니다(매우 다르고 더 이상 사용되지 않는 SmartHome 인터페이스의 V2만 지원합니다. 우리는 V3을 사용하고 있습니다).

    Lambda가 필요한 리소스에 액세스할 수 있도록 새 역할을 생성해야 합니다. 여기서는 Simple Microservices를 기본값으로 선택합니다(실제로 필요한 것보다 더 많은 것을 제공함). Cloud Watch에서 로그를 얻지 못하는 경우 IAM 섹션을 통해 이에 대한 역할 권한을 부여해야 할 수도 있습니다.

    그런 다음 Visual Studio에서 바이너리를 게시해야 합니다. AWS 도구가 설치된 상태에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 "AWS Lambda에 게시..."를 선택합니다.

    그런 다음 Lambda 표현식에 대한 세부 정보를 입력하고 Upload...를 누르십시오.

    업로드되면 Lambda에서 몇 가지 테스트를 실행하여 실행되는지 확인할 수 있습니다. 그런 다음 작업 드롭다운에서 "새 버전 게시"를 해야 합니다.

    게시되면 이에 액세스할 수 있는 권한을 Skill에 부여해야 합니다.

    "Alexa Smart Home" 트리거를 클릭하고 기술 ID를 입력합니다(아직 해당 ID가 없습니다....)

    Alexa 콘솔에서 스킬 생성:

    Lambda가 거의 준비되었으므로 Skill 개발자 콘솔로 이동하여 실제로 항목을 생성해야 합니다. https://developer.amazon.com을 열고 Alexa Skills Kit를 선택하고 새 Skill을 추가하십시오.

    타겟팅하려는 언어(예:영국의 경우 영어(UK))인 Smart Home Skill API를 선택하고 V3(선호하는) 페이로드 버전을 선택합니다.

    구성 페이지에서 더 흥미로운 세부 정보를 얻습니다. 버전이 지정된 Lambda(화면 오른쪽 상단)에서 Lambda ARN을 입력합니다. :1 또는 :2 또는 :5246과 같이 끝나야 합니다(몇 번 했다면;-)).

    Lambda에서 "애플리케이션 ID", "스킬 ID" 또는 "ID"를 붙여넣을 수도 있지만 현재 기술에서 호출되는 이름은 무엇이든 amzn1.ask.skill.2_______________50과 같아야 합니다.

    애플리케이션 ID를 추가한 후 저장을 클릭해야 합니다. 이전 콘솔에서는 기술 이름 아래의 헤더에서 ID를 찾을 수 있고, 새에서는 erm에서 새 창을 열고 콘솔 기술 목록으로 돌아가서 적절한 링크를 클릭할 수 있습니다. (실제로 기술을 만들기 위해 콘솔을 사용하지 않은 것과 같습니다).

    계정 연결을 활성화하려면 Tinamous에서 생성된 OAuth 애플리케이션이 필요하며 이는 Alexa Bot을 사용하여 수행됩니다. Tinamous 계정 봇 페이지로 이동하여 Alexa 봇을 추가하십시오. 생성하면 계정 연결을 구성하는 데 필요한 모든 세부 정보가 대화 상자에 표시됩니다.

    주의:(곧...) 게시된 Tinamous SmartHome 기술을 사용하는 경우 Alexa 봇이 필요하지 않습니다.

    봇이 만든 애플리케이션을 통해 다른 Tinamous 계정 소유자가 귀하의 기술을 사용하고 계정을 연결할 수 있습니다. 당연히 당신은 당신의 기술을 공개할 필요가 없으며 당신은 그것을 비공개로 유지할 수 있고 그들은 당신의 Tinamous 계정에서 아무 것도 볼 수 없을 것입니다.

    마찬가지로 다른 장치 클라우드를 사용하는 경우(진지하게도 그렇게 하는 이유;-)) OAuth 애플리케이션 세부정보를 입력해야 합니다.

    테스트 페이지에서 "이 기술을 Alexa 앱에 표시"에 대해 기술이 "예"로 설정되어 있는지 확인합니다.

    저장하고 alexa.amazon.co.uk(또는 해당 지역에 적합한 것)로 이동하거나 분명히 그들의 앱이기도 합니다.....

    "Skills"를 클릭한 다음 오른쪽 상단의 "Your Skills"를 클릭한 다음 "DEV SKILLS"를 클릭하면 해당 기술이 개발 기술임을 나타내는 녹색 마커와 함께 나열되어야 합니다.

    "알렉사, USB 불 꺼줘", 추가 스킬 정보 선택 시 "게시 정보" 페이지에 구성되어 있어, 전체 퍼블리싱에 갈 필요 없이 개발 중에 정보를 입력할 수 있습니다.

    스킬 코드를 업데이트해야 하는 경우 새 Lambda 함수를 업로드하고 새 버전을 생성하고 SmartHome 트리거와 스킬 ID를 다시 추가한 다음 버전이 지정된 Lambda 함수를 스킬 콘솔에 붙여넣습니다(비 버전이 지정된 람다, 하지만 시도했을 때 작동하지 않았습니다. 그 당시에 내가 잘못 알고 있었던 다른 많은 것들이 있었지만).

    성공!

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

    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • 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); 직렬.println(); 지연(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()); 직렬.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. 지연(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()); 직렬.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."); 반품; } } // 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); 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); true를 반환합니다. } } // No port specified, turn on all. if (payload.indexOf("turn on")> 0) { allOn(); true를 반환합니다. } if (payload.indexOf("turn off")> 0) { allOff(); 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." ); 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:"); Serial.println(ssid); // Connect to WPA/WPA2 network:status =WiFi.begin(ssid, pass); // 연결을 위해 10초 대기: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("IP 주소:"); 직렬.println(ip); 직렬.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("밀리초"); } 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(); 반품; } 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 ""

    맞춤형 부품 및 인클로저

    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.

    회로도

    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

    제조공정

    1. C# switch 문
    2. 더 높은 전력 밀도와 더 빠른 충전을 제공하는 배터리 충전기
    3. 정전 센서
    4. Raspberry Pi / 홀로그램 SMS 제어 AC 전원 스위치
    5. 풍력 발전
    6. 파워 해머 가이드
    7. 자동 파워 프레스 란 무엇입니까?
    8. 파워척이란?
    9. 파워척에 대한 빠른 가이드
    10. 수력발전의 이해