Philipp Kontsarenko
6 611
Блоги

Как мы сделали колокольчик, который звенит при поступлении оплаты за размещение вакансий

Инструкция старшего электрика vc.ru.

Поделиться

В избранное

В избранном

В конце 2017 года на vc.ru появился сервис «Вакансии». Работает он так: пользователь заполняет форму вакансии и оплачивает банковской картой 5 тысяч рублей за размещение объявления. После этого деньги замораживаются на счету, пока модератор не одобрит вакансию.

Во время одного из обсуждений Владислав Сергеевич пошутил, что было бы круто сделать устройство, которое будет уведомлять о новых заявках — чтобы предупредить модератора, да и вообще, чтобы в офисе радостнее было работать.

В голове сначала нарисовалась картина из будней Уолл-стрит, когда трейдер звонит в колокол при удачной сделке.

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

Что еще нужно

Помимо колокольчика, который я купил в «Комус», нужен был компьютер, который бы мог отвечать за всю логику. У нашего арт-директора как раз был Raspberry Pi, который он однажды дал мне для экспериментов и который я специально забыл ему вернуть.

Далее нужен двигатель, который бы приводил в действие колокольчик. Для этих целей прекрасно подходит соленоид — в отличие от обычных моторчиков у него поступательное, а не круговое движение, и работает он в режиме включен или выключен. Кроме того, соленоид маленький по своему размеру и прекрасно помещается внутри настольного колокольчика. То, что нам нужно.

Еще нужен диод, транзистор и резистор для того, чтобы соединить соленоид с Raspberry. Но об этом чуть позже.

Сначала заказал не тот соленоид — слишком мощный. Но потом исправился.

1. Готовим Raspberry Pi

На Raspberry я установил стандартную операционную систему Raspberry NOOBS. У нее есть привычный графический интерфейс, который не понадобится, и предустановленные приложения, которые почти не будут использоваться. Главное, что пригодится — терминал.

ОС Raspberry Pi

Так как устройство будет находиться в Москве, а сам я пока живу в Петербурге, сразу после установки операционной системы настроил инструменты для удаленного управления Raspberry:

  1. VNC — позволяет подключаться к рабочему столу Raspberry Pi через облако. Установлен по умолчанию, достаточно только зарегистрироваться.
  2. Dataplicity — доступ к командной строке Raspberry через интернет. Устанавливается при помощи одной команды, которая генерируется при регистрации на сайте Dataplicity.
  3. Git — для того, чтобы удобно загружать написанный код на Raspberry. Устанавливается при помощи команды sudo apt-get install git. Сам код я разместил на Github. Для того, чтобы скопировать его на Raspberry, нужно ввести команду git clone и URL-адрес хранилища Github. В моём случае git clone http://github.com/kontsarenko/raspberry-bell. Для последующего обновления кода — git pull.

2. Берем паяльник в руки

В моем случае подзаголовок немножко другой: покупаем паяльник и гуглим, как им пользоваться.

Мне повезло: в интернете я нашел готовую схему с Raspberry Pi и небольшим соленоидом, который не требует дополнительного источника питания и полностью работает на мощностях микрокомпьютера.

Перерисовал схему так, чтобы было понятно таким гуманитариям, как я:

Что на схеме:

  1. Резистор 1 кОм.
  2. Транзистор TIP120 Darlington NPN.
  3. Диод 1N4004.
  4. Соленоид 5V.

GND, 5V и GPIO — это выходы на плате Raspberry Pi, к которым подключается вся схема. Для моей модели B расположение выходов на компьютере выглядит вот так:

У каждого GPIO-выхода есть свой номер. Я подключил схему к контакту номер 18 (просто потому, что могу). Если не вдаваться в технические подробности, то вся схема работает так: на выход GPIO мы с помощью специального скрипта отправляем сигнал, он «включает» схему и приводит в действие соленоид. Затем отключаем сигнал на GPIO, соленоид возвращается на своё место.

Сначала я собрал схему на монтажной плате, чтобы можно было проверить её работу:

2. Пишем бота для анализа Slack

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

Каждый раз, когда пользователь оплачивает вакансию, к нам в Slack приходит уведомление типа «💰 Оплачена вакансия». Бот должен увидеть его и привести в действие соленоид.

На Github можно найти сотни Slack-ботов на Python, умеющих реагировать на сообщения в чатах. Я взял один из них за основу и адаптировал для нашей специфики — получился скрипт slack.py.

  • Для работы Slack-бота нужно установить дополнительную библиотеку slackclient на Raspberry. Это можно сделать при помощи команды pip install slackclient в терминале.
  • Вместо config['token'] нужно указать токен для Slack-канала. Для этого нужно сначала создать бота в Slack и скопировать сгенерированный сервисом ключ. И не забудьте добавить бота в нужный канал в мессенджере.
  • В строчке print (message.encode('UTF-8').lower().find('💰 Оплачена')) вместо 💰 Оплачена можно указать любую другую фразу, на которую должен реагировать бот.
  • import ding — здеcь мы указываем название скрипта, который будет приводить в действие соленоид.
Создание бота в Slack

Всё, основной скрипт готов. Он анализирует сообщения в Slack и при обнаружении соответствия вызывает второй — ding.py, который и приводит в действие соленоид.

3. Скрипт для соленоида

Он простой:

  • Цифра в строчке GPIO.setup(18,GPIO.OUT) — это как раз выход, к которому подключен соленоид. В моём случае, это 18-й коннектор.
  • Строчка GPIO.output(18,1) устанавливает «высокое состояние» для выхода. То есть приводит в действие всю схему.
  • Строчка GPIO.output(18,0) возвращает выход к изначальному состоянию.
  • time.sleep(0.1) — устанавливает длительность паузы в работе скрипта.

Если схема собрана правильно, то при выполнении в терминале команды python ding.py соленоид включится на долю секунды и вернется обратно к своему изначальному состоянию. То есть ударит в колокольчик и вернется на прежнее место.

Аналогично можно проверить работу скрипта slack.py — python slack.py. Если всё ок, то добавляем его в автозагрузку, чтобы при включении Raspberry скрипт запускался автоматически. Делаем это через crontab:

crontab -e

В конце открывшегося файла добавляем команду, в которой указываем путь к скрипту:

@reboot python /home/pi/raspberry-bell/slack.py

Можно перезагружать устройство.

4. Собираем всё вместе

Теперь нужно собрать все элементы вместе и придать продукту товарный вид. Для этих целей прекрасно подошла коробка с новогодними подарками от Mail.ru Group.

Красим её в черный цвет, сверлим три отверстия в крышке: два — для крепления колокольчика, одно — для провода от соленоида.

Одно большое отверстие делаем в корпусе для провода питания.

Соленоид приклеиваем при помощи двустороннего скотча прямо к ножке звонка:

Берем в руки паяльник и соединяем все элементы схемы вместе. Для изоляции я использовал термоусадочные трубки (посоветовали в магазине) и, конечно же, изоленту (посоветовал личный опыт). Получилось компактно:

Транзистор, резистор и диод где-то внутри

Проверяем:

Версия со звуком:

Ах, да. Самое главное забыл:

  • Весь код тут.
  • Можно адаптировать колокольчик для любых целей — например, чтобы уведомлять о новых вопросах в онлайн-чате.
  • За помощь спасибо Пете Савченко и Андрею Потетюрину.
{ "author_name": "Philipp Kontsarenko", "author_type": "self", "tags": [], "comments": 58, "likes": 70, "favorites": 42, "is_advertisement": false, "section_name": "blog", "id": "33597", "is_wide": "1" }
{ "is_needs_advanced_access": false }

Комментарии Комм.

Популярные

По порядку

0

Прямой эфир

Подписаться на push-уведомления
[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "bscsh", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223676-0", "render_to": "inpage_VI-223676-0-1104503429", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=bugf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudx", "p2": "ftjf" } } }, { "id": 16, "label": "Кнопка в шапке мобайл", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byzqf", "p2": "ftwx" } } } ]