Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Выключатель питания USB с поддержкой Alexa

Компоненты и расходные материалы

Arduino MKR1000
× 1
Конденсатор 0805 0,1 мкФ
× 8
LED (общий)
× 4
Нажмите кнопку (длинная)
× 4
INA219 (soic 8)
× 1
LM3526M
× 2
USB-разъем (вертикальный)
× 4
резистор 1 кОм 0805
× 4
резистор датчика тока 0,1 Ом
× 1
Конденсатор 0805 1 мкФ
× 1

Необходимые инструменты и машины

3D-принтер (общий)
Паяльник (общий)

Приложения и онлайн-сервисы

Amazon Alexa Alexa Skills Kit
Tinamous
Amazon Web Services AWS Lambda

Об этом проекте

Алекса, включи ThingyStick ...

Фон

Все больше и больше устройств получают питание от USB, многие из них, как правило, являются «глупыми» устройствами без подключения к Интернету или без опций домашней автоматизации (например, светодиодные фонари). Как мы можем автоматизировать или управлять ими удаленно? Возможно, USB-источник питания подключен к сетевому выключателю, это немного избыточно, особенно если мы хотим, чтобы 4 устройства управлялись индивидуально!

Этот проект позволяет вам управлять подачей питания на устройства с питанием от USB через Интернет, а с помощью Tinamous SmartHome Skill for Alexa вы можете включить голосовое управление для своих глупых USB-устройств.

В настоящее время на рынке очень мало устройств для удаленного управления питанием USB, когда я начинал этот проект, я не нашел ни одного (в Великобритании), но недавно появилась пара как часть розеток с несколькими группами (да, идея началось очень давно, в далекой галактике), это не известные производители домашней автоматизации, а производители небрендированных производителей (например, ZLD-34UK), поэтому у нас есть вопрос, чье облако устройств они используют, собираются ли данные Китай и обратно, что произойдет, если этого производителя больше не будет, насколько он безопасен, насколько можно использовать программное обеспечение, будет ли оно отправлено на утилизацию на следующей неделе, и многие другие обычные проблемы, связанные с устройствами, подключенными к Интернету, не говоря уже о том, чтобы можно взломать так же, как и устройство с открытым исходным кодом, работающее на Arduino.

Примеры использования

Примеры устройств с питанием от USB, которыми мы можем захотеть управлять:

  • Индикаторы с питанием от USB
  • Литые палочки Kindle Fire / Chrome (особенно в детских комнатах, чтобы они не смотрели телевизор).
  • USB-увлажнители
  • Echo Dot (заставить Alexa выключиться на ночь? или просто перезагрузите устройство)
  • Доски для разработки. Вам нужно перезагрузить этот проект, потому что ваш код зациклился?
  • Устройства, к которым трудно получить доступ, но которые необходимо время от времени перезагружать (например, датчики на чердаке).
  • Устройства, установленные на территории клиента, где мы хотим обеспечить его питание (путем измерения потребления тока и входного напряжения).

Простое управление питанием: Возможность переключения питания через Интернет с помощью голосового управления Alexa или других команд через Tinamous. Включение и выключение.

Интеллектуальное управление питанием: Многие USB-лампы имеют сенсорное управление для включения лампы, что означает, что мы не можем включить свет удаленно, но мы можем выключить его, и большую часть времени это все, что нам нужно (пытаясь заснуть, оставив лампу включенной. «Выхожу, хотите, чтобы весь свет погас?).

Однако, как только мы использовали Alexa для выключения USB-лампы, мы должны попросить Alexa включить лампу, прежде чем мы сможем включить ее, это просто глупо. При включенном интеллектуальном питании команда выключения отключит питание лампы на несколько секунд перед восстановлением питания устройства. Достаточно выключить лампу, но и разрешить нормальную работу после.

Автоматизация таймера: Ваши устройства автоматически отключаются в установленное время. Дети смотрят Amazon TV в огне слишком поздно? Автоматическое отключение USB-кабеля в 20:00.

Контроль мощности: Если вы разрабатываете оборудование с питанием от USB, возможно, вам захочется узнать, какой ток потребляет ваше устройство, особенно при первом включении, или вы можете захотеть профилировать зарядку аккумуляторной батареи. С помощью встроенного INA219 вы можете контролировать потребление тока (я без особых усилий справился с дискретизацией около 1 кГц). Падение напряжения на USB-выводах при высоком токе также может быть проблемой, INA219 контролирует питание устройства, чтобы мы могли предупредить о низком напряжении. Также предусмотрена клеммная колодка, позволяющая использовать более высокие токи и кабели большего диаметра.

Сбой питания: Используя опцию аккумулятора на MKR 1000, мы можем контролировать напряжение питания USB и отправлять уведомления, если входное питание пропало. Это может быть полезно для удаленных (удаленных) решений, использующих питание от USB, но требующих небольшого дополнительного мониторинга, или просто как простое обнаружение сбоя сетевого питания в вашем доме.

Аппаратное обеспечение

Этот проект довольно прост:в основе лежит Arduino MKR1000, переключение питания USB с использованием двух LM3526M для обеспечения переключения высокого напряжения и обнаружения неисправностей (низкое напряжение, перегрузка по току), а также мониторинг мощности (напряжения и тока) с использованием INA219 и, наконец, Светодиоды и переключатели для опций местного управления.

У меня была печатная плата, сделанная на DirtyPCBs.com, вы также можете отправить файл .brd на OSHPark.com, чтобы сделать еще несколько. Разъем Arduino имеет контактные площадки для печатных плат по обе стороны от каждого контакта, чтобы обеспечить возможность взлома. например вы можете легко добавить датчики для определения условий окружающей среды или небольшой OLED-дисплей для отображения напряжения и тока.

В репозитории github есть вариант с 2 и 4 портами. Будьте осторожны с двухпортовой печатной платой, так как я напортачил и неправильно расположили разъем USB (они расположены задом наперед - неправильная полярность !).

Победа из пасти поражения:

Как оказалось, установка USB-разъема на задней панели платы на самом деле является хорошим решением и означала, что контакты были правильными (однако для платы с 2 портами это также означает, что шелкография находится не на той стороне!). Arduino с разъемами в розетке немного уступил место с высотой, необходимой для извлечения USB-разъемов из корпуса, поэтому на самом деле это сработало лучше, я решил переделать плату с розетками, переключателями и светодиодами на обратной стороне сторона и добавить два дополнительных порта, поэтому была создана версия с четырьмя портами (кроме того, у меня были ужасно выровнены светодиоды на двух портах, так что это тоже было исправлено!).

Их очень мало мешает распространению этого на коммутатор с 6 или 8 портами, хотя светодиоды и переключатели, возможно, придется отказаться от или улучшить.

Схема выглядит намного сложнее, чем она есть на самом деле. Многие резисторы не являются обязательными. Резисторы R23, 19, 27 и 26 являются подтягивающими для переключателей, аналогично R20-22, R14 и R15 - подтягивающими для управления USB и обнаружения неисправностей. Все это можно сделать через режим вывода INPUT_PULLUP в Arduino, однако, если вы хотите перевести Arduino в спящий режим с низким энергопотреблением и использовать прерывания для его пробуждения, вы можете заполнить их, чтобы они не плавали (и не подпрыгивали) .

Я также добавил дополнительные резисторы вокруг линий USB D + / D-. Их можно установить, чтобы сообщить устройству, сколько энергии оно может использовать, но для многих глупых устройств они все равно игнорируются. Ниже на самом деле нужен только R24 для ограничения тока светодиода. R2-5 и R28 остаются пустыми.

Светодиоды и переключатели также не являются обязательными. Если вам просто нужен автономный блок, который удаленно управляет USB, не добавляйте эти части.

Потребляемая мощность

Этот контроллер можно запитать тремя способами.

Первый - это вариант «Internal» (подключены контакты 1 и 2 JP6), питание USB берется с контакта 5V Arduino (и, следовательно, от разъема Arduino USB). Однако это следует использовать только для нагрузок малой мощности.

Другие варианты предназначены для внешнего питания (подключены контакты 2 и 3 JP6), затем вы можете подключить 5 В через J2 (встроенный микроразъем USB) или JP8 (клеммная колодка). Не следует использовать оба варианта одновременно. Внешнее питание также направляется на вывод Arduino VIn, поэтому ему также не понадобится отдельный источник питания.

В качестве бонусных баллов установка резисторов 0R на R10 и R11, а также J2 дает USB-проход для USB 3, поэтому мы можем перезагрузить подключенное USB-устройство, что очень удобно при разработке оборудования, и вы не хотите изнашивать свои USB-разъемы. ПК!

Корпус

Корпус для 3D-печати включен в этот проект. В нем используются вставки M3 с подогревом для соединений печатной платы и крышки, хотя допуски на крышке достаточно хороши для посадки с трением.

Крышка включает в себя несколько опций.

  • С аккумуляторным отсеком или без него.
  • На ножках или без них (также называемых монтажными отверстиями, позволяющими закрепить коробку на поверхности).

Точно так же базовый блок можно настроить (с помощью OpenSCAD), чтобы он имел отверстия для каждого из трех источников питания.

Чтобы сделать корпус правильным, потребовалось несколько усилий. Как вы редактируете свои отпечатки? Мне очень пригодились мои образцы из фан-клуба Rigid.Ink.

Подключение к Tinamous

Мы используем Arduino MKR1000 для управления розетками, поэтому у нас есть подключение к Wi-Fi. Если вы новичок в этой плате, вам необходимо добавить ее в свою Arduino IDE.

Мы собираемся использовать для подключения сервер Tinamous MQTT, в основном потому, что он потрясающий, но также, может быть, потому, что я основатель / разработчик / производитель чая! Мы подпишемся на тему сообщения о статусе для сообщений, отправленных на устройство. (т. е. тема "Status.To").

Перед началом кодирования нам необходимо убедиться, что на Arduino установлена ​​последняя версия прошивки, а также необходимые сертификаты SSL для безопасного подключения к Tinamous. Очевидно, что если вы предпочитаете, вы можете адаптировать это к своему собственному локальному серверу MQTT и не беспокоиться так сильно о безопасности.

Шаг 1

Откройте IDE Arduino и загрузите FirmwareUpdater . скетч из меню примеров WiFi101. Загрузите это на свое устройство.

Шаг 2

После загрузки выберите Средство обновления прошивки WiFi101 . из Инструменты меню.

Шаг 3

Проверьте соединение, затем Обновите прошивку . . Как только это будет сделано, используйте Добавить домен . кнопку и добавьте tinamous.com чтобы убедиться, что у Arduino есть правильные сертификаты SSL. Нажмите Загрузить сертификаты в модуль Wi-Fi . кнопку для загрузки сертификатов.

Шаг 4

Теперь мы можем написать собственную прошивку. Вы найдете файлы, прикрепленные к этому проекту, а также в репозитории GitHub (у GitHub будет последняя версия).

Мы будем использовать WiFi101 и клиент MQTT для вашего скетча Arduino.

Выберите вариант MQTT by Joel Gaehwiler.

Файл secretts.h должен быть заполнен вашими настройками WiFi и Tinamous MQTT, я не включил свою копию по очевидным причинам.

Настройки сервера WiFi и MQTT:

  #define SECRET_SSID "Your SSID" #define SECRET_PASS "Your SSIDs Password" / ************************ Установка 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" UsbSwitch 

Если вы еще не зарегистрировались в Tinamous, вы можете создать здесь свою бесплатную учетную запись. Когда вы регистрируетесь, вас просят ввести имя учетной записи / организации, это становится вашей частной областью Tinamous, вы можете приглашать других участников в эту область (включая Alexa) и делиться своими устройствами с вашей группой.

Ниже я называю свою учетную запись «AlexaExample», это то, что мне нужно включить в настройку MQTT, а моя учетная запись Tinamous находится по адресу https://AlexaExample.Tinamous.com

Шаг 5

Далее нам нужно добавить наше устройство. На странице Tinamous Devices нажмите кнопку "Добавить".

Следовательно, настройки Tinamous MQTT для моего устройства выглядят примерно так ...

  / ************************* Настройка Tinamous MQTT *************** ****************** / # определить 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. Вы можете добавить сюда больше устройств, если хотите, просто обновите настройки MQTT для DEVICE_USERNAME и MQTT_USERNAME (MQTT не отправляет информацию заголовка, такую ​​как http, поэтому Tinamous не знает, какой поддомен вы используете, поэтому нам нужно указать аккаунт в имени пользователя).

Шаг 6

Загрузите прикрепленный код на свои устройства (вместе с обновленным файлом secrets.h). Найдите минутку, чтобы взглянуть на файл TinamousMQTTClient.ino, он обрабатывает наши взаимодействия MQTT, а вместе с ним и команды Alexa, которые отправляются на наше устройство.

Нам нужно использовать WiFiSSLClient для SSL. Если вы хотите использовать локальный сервер MQTT без SSL, вы можете использовать обычный WiFi-клиент и перейти к порту 1883, но для всего, основанного на Интернете, используйте SSL-клиент.

Нам также нужно зарезервировать для клиента MQTT немного больше буфера по умолчанию, здесь мы резервируем 4096 байт.

  WiFiSSLClient networkClient; MQTTClient mqttClient (4096);  

Мы используем mqttClient.begin для настройки клиента и указываем обработчик функции в onMessage, который вызывается при получении сообщения от сервера MQTT.

  mqttClient.begin (MQTT_SERVER, MQTT_SERVERPORT, networkClient); // Обрабатываем полученные сообщения. mqttClient.onMessage (messageReceived);  

А затем мы можем подключиться и подписаться на интересующую нас тему. Здесь вы видите, что мы подписались на «Tinamous / V1 / Status.To / UsbSwitch», мы будем получать сообщения, отправленные на @UsbSwitch из временной шкалы Tinamous. Вот как мы будем получать сообщения от Alexa.

  if (! mqttClient.connect (MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {if (mqttClient.lastError () ==LWMQTT_CONNECTION_DENIED) {// Эта ошибка вызвана неправильным именем пользователя ifClient (или паролем mqtt}. lastError () ==-6) {// Эта ошибка, скорее всего, связана с тем, что вы не добавили сертификат SSL. } // Задержка перед повторной попыткой подключения delay (10000); return false;} // Успешное соединение. Теперь подпишитесь на тему mqttClient.subscribe ("/ Tinamous / V1 / Status.To /" DEVICE_USERNAME);  

Вы можете думать о временной шкале Tinamous как о частной версии Twitter для вас и ваших устройств, они могут использовать MQTT или REST API (или одного из ботов), чтобы просматривать отправленные им сообщения и действовать в соответствии с ними, а также публиковать сообщения. сообщения обратно.

В Tinamous у нас есть еще немного работы, чтобы включить интеграцию с Alexa, но пока мы можем протестировать наше устройство и прошивку, используя временную шкалу и отправляя сообщения.

Если вы используете навык Tinamous SmartHome, это все, что вам нужно.

Умение умного дома Tinamous для Alexa

Навык умного дома Tinamous в настоящее время ожидает утверждения для публикации (на момент написания, скрестив пальцы, он сейчас в магазине ...). Чтобы сделать свой собственный USB-переключатель, вы можете просто использовать этот навык, когда он доступен.

Навык на самом деле очень общий, он ничего не знает об устройствах или о том, как с ними разговаривать. Мы применяем теги к устройствам в Tinamous, и этот навык создаст соответствующее устройство в учетной записи Alexa, следовательно, вы можете использовать этот навык и Tinamous для голосового включения одного из ваших собственных проектов с помощью всего нескольких строк кода на устройстве.

Однако вы можете что-то изменить или написать свой собственный навык, поэтому я поделюсь подробностями своего развития.

Я написал навык на C # для .Net Core 2.0, на самом деле он был разработан для моего проекта умного вентилятора BOFF, но для этого проекта я расширил его, чтобы позволить устройству иметь много выходов (портов) и для каждого из них быть первоклассным гражданин в устройствах Alexa Smart Home.

Весь код (включая некоторые тесты!) Находится в репозитории Tinamous SmartHome, клонируйте, загружайте или просто просматривайте как хотите. Я использовал Visual Studio 2017 с установленными инструментами AWS, чтобы помочь овладеть навыками Lambda.

Платформа десериализует входящее сообщение директивы от Alexa в объекты, к которым мы можем получить доступ через код, соответствующие действия предпринимаются на основе пространства имен заголовков и имени директивы, а затем возвращается соответствующий ответ.

Основные интересные сообщения:

  • Связь с аккаунтом
  • Открытие
  • Государственный отчет
  • Управление питанием

Привязка аккаунта:

За нас этим занимается Alexa, после того как мы добавим навык в нашу учетную запись, Alexa запросит аутентификацию, мы перейдем на страницу авторизации Tinamous, чтобы устройство могло получить доступ к нашей учетной записи. Здесь вам нужно ввести имя вашей учетной записи (в данном случае AlexaExample), имя пользователя (Steve) и пароль (нет, я не говорю!)

Открытие:

Как только ваша учетная запись будет привязана, Alexa предложит выполнить обнаружение, затем навык запрашивает у Tinamous устройства, помеченные тегом « Alexa.SmartDevice ". Устройства без этого просто игнорируются.

Эти теги применяются путем редактирования устройства на странице «Устройства» в Tinamous.

Если устройство также помечено тегом " MultiPort " "каждый порт перечисляется, и для него также добавляется устройство. Мы также применяем теги на основе директив Alexa, поддерживаемых нашим устройством, здесь это просто" Alexa.PowerController "а также тег, чтобы указать, в какой категории должно отображаться устройство в приложении, здесь я использовал" SmartPlug ".

Доступны и другие интерфейсы, например Alexa.BrightnessController, но здесь это не так полезно. Подробнее см. В файле readme для репозитория.

Чтобы наше многопортовое устройство могло открывать отдельные порты для Alexa, нам необходимо настроить переменные состояния, также на странице редактирования устройства.

PortCount указывает количество портов на устройстве, затем «Port-1» .. «Port-n» задает имена, которые Alexa будет использовать для портов. Любой порт без имени будет проигнорирован. Вы можете легко изменить имя порта здесь и повторно запустить обнаружение, чтобы обновить Alexa.

Во время обнаружения навык также будет искать поле, помеченное, названное или помеченное «powerState» или «powerState-port-n», в зависимости от ситуации. Если это поле найдено, оно назначается поддерживаемой функцией для устройства (подробнее об этом в Отчете о состоянии).

Государственный отчет

На этапе обнаружения мы сообщили Alexa, какие возможности есть у нашего устройства, по умолчанию навык сообщает Alexa, что они могут быть запрошены, поэтому Alexa отправит запрос StateReport, чтобы получить для них значения.

У нас есть последний набор тегов, которые нужно применить для поддержки этого, на этот раз к полям устройств. Как только ваше устройство отправляет данные (это сообщение senml, которое передается через MQTT в коде Arduino), Tinamous создаст поля для устройства. Затем мы можем использовать опцию Advanced из списка полей, чтобы отредактировать это. Использование тега является наиболее универсальным, поскольку это означает, что нам не нужно указывать правильное имя поля в прошивке или зависать, если мы хотим его переименовать.

Если поля, относящиеся к порту, не найдены, Alexa вернется к полю, не относящемуся к порту (здесь называется powerState).

Контроль мощности

Без этого наше устройство не будет использоваться в Alexa! Alexa отправит нашему навыку две директивы «TurnOn» и «TurnOff». Основная точка входа в функцию для навыка сначала ищет пространство имен (Alexa.PowerController), а затем передает задание соответствующему классу контроллера (PowerController.cs).

Затем навык просто публикует статусное сообщение на временной шкале Tinamous.

Например:

@UsbSwitch Включить

или

@UsbSwitch Включите порт-1

Остальные поддерживаемые интерфейсы обрабатываются практически идентично. Затем наше устройство должно следить за этим статусным сообщением и выполнять действие. Затем Alexa может считывать состояние с помощью StateReport.

Вот как работает навык. Теперь нам просто нужно отправить его в AWS Lambda и создать запись Skill в консоли Alexa, чтобы предоставить Alexa к нему доступ.

Создание функции AWS Lambda:

Я использовал инструменты AWS в Visual Studio, чтобы передать скомпилированный навык в Lambda. Но сначала нам нужно создать лямбду.

Совет: Создайте Lambda в соответствующей области AWS для поддерживаемого вами языка. Английский (Великобритания) должен быть ориентирован на запад ЕС (Ирландия).

Создайте новую лямбда-функцию с нуля. Существующие схемы ограничены и устарели (поддерживает только V2 интерфейса SmartHome, который сильно отличается и устарел - мы используем V3).

Вам нужно будет создать новую роль, чтобы разрешить Lambda доступ к нужным ресурсам. Здесь мы выбираем простые микросервисы по умолчанию (на самом деле они уступают больше, чем нам нужно). Если вы обнаружите, что не получаете журналы в Cloud Watch, вам также может потребоваться предоставить разрешения роли для этого в разделе IAM.

Затем нам нужно опубликовать двоичные файлы из Visual Studio. Установив инструменты AWS, щелкните проект правой кнопкой мыши и выберите «Опубликовать в AWS Lambda ...»

Затем введите данные лямбда-выражения и нажмите "Загрузить ...

".

После загрузки мы можем запустить несколько тестов на Lambda, чтобы убедиться, что она работает. Затем нам нужно «Опубликовать новую версию» из раскрывающегося списка «Действия».

После публикации нам необходимо предоставить нашим навыкам разрешение на доступ к этому,

Нажмите на триггер «Alexa Smart Home» и введите идентификатор навыка (у нас его пока нет ....)

Создание навыка на консоли Alexa:

Поскольку наша Lambda почти готова к работе, нам нужно перейти в консоль разработчика навыков и фактически создать для нее запись. Откройте https://developer.amazon.com, выберите Alexa Skills Kit и добавьте новый навык.

Выберите Smart Home Skill API, язык, на который вы хотите настроить таргетинг (например, английский (Великобритания) для нас в Великобритании), и выберите версию полезной нагрузки V3 (предпочтительную).

На странице конфигурации мы переходим к более интересным деталям. Введите Lambda ARN из нашей версированной Lambda (вверху справа на экране). Он должен заканчиваться примерно так:1 или:2 или:5246 (если у вас было несколько ходов;-)).

В то время как в Lambda мы также можем вставить «Идентификатор приложения», или «Идентификатор умения», или «Идентификатор», или как там он сейчас называется, из умения, он должен выглядеть примерно так:amzn1.ask.skill.2 _______________ 50.

Обязательно нажмите «Сохранить» после добавления идентификатора приложения. В старой консоли вы можете найти идентификатор в заголовке под названием навыка, в новой, э-э, откройте новое окно, вернитесь к списку навыков консоли и щелкните соответствующую ссылку. (это как если бы они никогда не использовали консоль для создания навыка).

Чтобы включить привязку учетной записи, нам понадобится приложение OAuth, созданное в Tinamous, это делается с помощью Alexa Bot. Перейдите на страницу ботов вашей учетной записи Tinamous и добавьте бота Alexa. После того, как вы создадите это диалоговое окно, вы получите все сведения, необходимые для настройки привязки учетных записей.

NB:Если вы используете (скоро будет ...) опубликованный навык Tinamous SmartHome, вам не нужен Alexa Bot.

Приложение, созданное ботом, позволит любым другим владельцам учетных записей Tinamous использовать ваши навыки и связать свои учетные записи. Естественно, вам не нужно публиковать свои навыки, и вы можете сохранить их в секрете, и они не смогут ничего видеть в вашей учетной записи Tinamous.

Точно так же, если вы используете другое облако устройств (серьезно, зачем вам это делать;-)), вам нужно будет ввести данные их приложения OAuth.

На странице "Тест" убедитесь, что для вашего навыка установлено значение "Да" для параметра "Показать этот навык в приложении Alexa".

Сохраните и перейдите на сайт alexa.amazon.co.uk (или тот, который подходит для вашего региона), или, очевидно, их приложение тоже .....

Щелкните «Навыки», затем вверху справа «Ваши навыки», а затем «НАВЫКИ РАЗРАБОТЧИКА», вы должны увидеть свой навык в списке с зеленым маркером, чтобы указать, что это навык развития.

«Alexa, выключи USB-светильник» и дополнительная информация о навыках, когда вы ее выбираете, настраиваются на странице «Публикационная информация», вы можете вводить информацию во время разработки, не выполняя полную публикацию.

Если вам нужно обновить код навыка, загрузите новую лямбда-функцию, создайте новую версию, повторно добавьте триггер SmartHome и идентификатор навыка, затем вставьте версионную лямбда-функцию в консоль навыков (возможно, вы сможете использовать не- 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".

Код

  • 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 (); задержка (10000); вернуть ложь; } 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. задержка (10000); вернуть ложь; } 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."); возвращение; } } // 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); вернуть истину; } sprintf(buffer, "turn off port-%01d", port + 1); if (payload.indexOf(buffer)> 0) { Serial.print("Turn off port "); Serial.println(port); setUsb(port, false); вернуть истину; } } // No port specified, turn on all. if (payload.indexOf("turn on")> 0) { allOn(); вернуть истину; } if (payload.indexOf("turn off")> 0) { allOff(); вернуть истину; } 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." ); вернуть истину; } 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); // wait 10 seconds for connection:delay(10000); } // you're connected now, so print out the data:Serial.println("You're connected to the network"); printCurrentNet(); printWiFiData();}// ---------------------------------------// WiFivoid printWiFiData() { // print your WiFi shield's IP address:IPAddress ip =WiFi.localIP(); Serial.print ("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(); возвращение; } 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#
  2. Зарядные устройства для аккумуляторов обеспечивают большую удельную мощность, более быструю зарядку
  3. Датчик отключения электроэнергии
  4. Raspberry Pi / Hologram SMS Controlled AC Power Switch
  5. Сила ветра
  6. Руководство по силовым молотам
  7. Что такое автоматический силовой пресс?
  8. Что такое силовой патрон?
  9. Краткое руководство по силовым патронам
  10. Понимание гидроэнергетики