Skip to content
  • Категории
  • Главная
  • Документация
  • Последние
  • Пользователи
Collapse
  1. Главная
  2. Блоги сообщества Raspberry Pi
  3. Система верификации пользователей посредством RFID карт с отправкой сообщений в Telegram

Система верификации пользователей посредством RFID карт с отправкой сообщений в Telegram

Запланировано Прикреплена Закрыта Перенесена Блоги сообщества Raspberry Pi
2 Сообщения 1 Posters 147 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • piP Не в сети
    piP Не в сети
    pi
    написал в отредактировано pi
    #1

    Сегодня речь пойдет о системе верификации пользователей, которая в будущем сможет стать (и станет, я надеюсь) полноценной системой двухфакторной верификации пользователей. В качестве первого фактора будем использовать RFID карту, в качестве второго - распознавание лица пользователя с помощью OpenCV. На данный момент второй фактор работает в ручной режиме и фото отправляется в Телеграм оператору. Но автор топика активно работает над адаптацией каскада Хаара для распознавания лиц. И, как знать, может скоро и выйдет еще одна статья. Не будем загадывать. Все равно в одну статью это все не уместить. Поэтому начнем. Кому интересно - добро пожаловать под кат.

    1. Схемотехническое проектирование

    1.1 Лирическое отступление

    Я считаю, что наш ГОСТ вполне имеет право на жизнь. И, если следовать порядку проектирования, описанному в нем, то процесс разработки и поддержки любого реального проекта становится проще и понятнее любому члену команды. По крайней мере это точно касается маленьких проектов вроде этого, особенно если не заниматься занудством до невозможности и не пытаться соблюсти его кругом и всюду.

    1.2 Непосредственно проектирование

    Проектирование устройства было начато с разработки электрической структурной схемы, представленной ниже. Из схемы видно, что устройство состоит из трёх основных блоков: Raspberry Pi, модуля считывания RFID карт RFID-RC522 и WEB-камеры.

    Монитор - не обязательная вещь. На него просто будут выводиться логи вроде "Карта №... Доступ разрешен".

    Выбор считывателя ничем не обоснован. Взял тот, что был под рукой.

    abc99339-e08a-4461-907d-e6f71bc48f26-image.png

    Процесс работы устройства выглядит следующим образом: пользователь прикладывает RFID карту к считывателю, Raspberry Pi проверяет разрешен ли доступ для владельца карты, если доступ разрешен, то делается фотография web-камерой. Информация о владельце карты (для примера, у нас будет ID карты) и фотография автоматически отправляются оператору устройства на заранее сконфигурированный номер в Telegram. Если пользователю данной карты доступ запрещен, то фотографирования не происходит, выдается сообщение «Доступ запрещен!» и сообщение не отправляется.

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

    При отправке Telegram-боту сообщения вида /photo в ответ оператор получает последнее фото с камеры.

    При отправке Telegram-боту сообщения вида /text в ответ, для примера, будем выводить информацию о том какой пользователь воспользовался системой последним (прошел через турникет, например).

    2. Разработка ПО

    2.1 Структура ПО

    В начале я хотел написать свой модуль ядра для работы с SPI, но про это можно написать целую отдельную статью. Да и зачем?? Если есть готовый. Может когда-нибудь в академических целях...

    Поэтому использовать мы будем стандартный драйвер spi_bcm2708.

    По умолчанию он занесен в blacklist ввиду не использования его большинством пользователей. Поэтому комментируем соответствующую строчку в соответствующем файле. Это делается так:

    sudo nano /etc/modprobe.d/raspi-blacklist.conf
    

    в этом файле комментируем строку

    blacklist spi-bcm2708
    

    Модуль активировали.

    Хотел написать библиотеку для работы с этим модулем. Но и тут не получилось выпендриться. Уже есть готовая.

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

    Следующий набор команд установит все, что нам потребуется (git, разумеется, уже должен быть установлен):

    sudo apt-get install python-dev
    git clone https://github.com/lthiery/SPI-Py.git
    cd SPI-Py
    sudo python setup.py install
    git clone https://github.com/rasplay/MFRC522-python.git
    

    Писать будем на языке python. Работать будем в директории MFRC522-python.

    cd MFRC522-python
    

    Структура нашего проекта представлена на рисунке ниже.
    39f23ef5-797b-4ec3-8829-e741445ea7a6-image.png

    Взаимодействие со считывателем RFID карт осуществляется через стандартный модуль ядра spi_bcm2708. Основные функции работы с SPI из userspace реализованы в библиотеке SPI-Py. По средствам этой библиотеки модуль чтения запускает опрос считывателя. Конфигурация модуля чтения RFID меток (регистры, функции для работы) реализованы в модуле конфигурации. В нем же хранится конфигурация Telegram бота (token). После считывания RFID метки модуль чтения обращается к модулю фото. В ответ получает фото пользователя, которое направляется в модуль отправки сообщений для отправки оператору в Telegram вместе с информацией о пользователе.

    Раз уж мы решили использовать OpenCV для распознавания лиц, то осуществлять захват изображения с камеры тоже будем с её помощью. OpenCV ставится на Raspberry Pi ровно также как и на любую другую Linux-машину. Описывать процесс её установки в рамках топика не вижу смысла. Мануал по установке есть на официальном сайте, просто повторяем шаги и всё.

    Далее будет описана реализация основного функционала. А полный код проекта будет доступен по ссылке в конце статьи.

    Опрос RFID считывателя происходит в бесконечном цикле вида:

    while continue_reading:
      (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) # Опрашиваем RFID считыватель
      if status == MIFAREReader.MI_OK: # Если обнаружена карта
        print "Card detected" 
      (status,backData) = MIFAREReader.MFRC522_Anticoll()
      if status == MIFAREReader.MI_OK: 
        print "Card read UID: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4])
        if (( backData == cardA ) or ( backData == cardB ) or ( backData == cardC )): # Сравниваем для примера с тремя захардкоженными идентификаторами трёх билетиков московского метро
          print "welcome"
          ### Получаем снимок с камеры через OpenCv ###
          capture = cv.CaptureFromCAM(0)
          frame = cv.QueryFrame(capture)
          cv.SaveImage("../../../Camera/telegram/image/ny.jpg", frame)
          del(capture)
          ### ####
          ### Запись файла с информацией о пользователе ####
          f1 = open("../../../Camera/telegram/text1.txt", 'wb')
          f1.write("The")
          if ( backData == cardB ):
              f1.write("User with cardB is comming")
          elif ( backData == cardA ):
              f1.write("User whith cardA is comming")
          ### ####
          # запуск отправки в Телеграм     
          os.system('python3 telegram.py') 
        else:
          print "wrong Card"
    

    Я постарался максимально закомментировать код дабы исключить пояснения в основном тексте статьи. С остальными фрагментами кода буду поступать аналогично.

    Теперь надо зарегистрировать Telegram-бота. Простейший мануал опять же есть на официальном сайте и пересказывать его шаги в этой статье я не буду. Ещё есть документация и примеры исходных кодов для интересующихся.

    Требуемый нам функционал реализуем так:

    ### Отправка текcтовой информации ###
    def mes ():
            f = open('../../../Camera/telegram/text1.txt')
            bot.send_message(<тут ваш идентификатор>, f.read())
            return 0
    ### Отправка фото ###
    def photo ():
            photo = open('../../../Camera/telegram/image/ny.jpg', 'rb')
            bot.send_photo(<тут ваш идентификатор>, photo)
            return 0
    mes()
    photo()
    

    Вместо <тут ваш идентификатор> вписываем идентификатор абонента, которому отсылаем сообщение.

    Осталось реализовать ответы бота на сообщения. Для этого надо создать обработчики соответствующих команд /photo и /text:

    ### Обработка команды /text ###
    @bot.message_handler(commands=['text'])
    def mes (message):
            f = open('../../../Camera/telegram/text1.txt') # файл с информацией, который сохраняли ранее
            bot.send_message(message.chat.id, f.read()) # отправка
            return 0
    ### Обработка команды /photo ###
    @bot.message_handler(commands=['photo'])
    def photo (message):
            photo = open('../../../Camera/telegram/image/ny.jpg', 'rb') # фото, которое сохраняли ранее
            print(message.chat.id)
            bot.send_photo(message.chat.id, photo) # отправка
    

    Реализацию основных частей рассмотрели.

    3. Макет

    На основании п.1 и п.2 был разработан макет устройства, представленный на фото ниже. В качестве RFID карт использовались билеты для проезда в Московском метрополитене.

    d3d2b26c-cac4-442b-bfeb-866d36243006-image.png

    2c0cd1db-9634-4ae0-abef-edbc518f65ab-image.png

    К Raspberry Pi подключен RFID считыватель по интерфейсу SPI согласно таблице представленной ниже. WEB-камера подключается к USB-порту, расположенному на плате. Взаимодействие с сетью (API сервера Telegram) осуществляется через Ethernet порт.

    Таблица подключения RFID считывателя RC522 к Raspberry Pi

    RPi пин	RC522 пин
    
    1	Vcc
    6	GND
    19	MOSI
    21	MISO
    22	RST
    23	SCK
    24	NSS
    

    На этом статья подходит в концу. Полный код проекта доступен в моем репозитории на github . Не забываем вписывать ваш токен для Telegram-бота в файле config.py, а также вписывать свой идентификатор абонента, которому надо посылать фото и информацию.

    P.S.

    Статья написана для участия в конкурсе т.к. своей Rasberry Pi не имею. Для реализации этого проекта взял у друга на пару месяцев первую Raspberry.

    Да, разработка - процесс неспешный. Тем более, что проектом занимаюсь исключительно в свободное время.

    1 ответ Последний ответ
    0
    • piP Не в сети
      piP Не в сети
      pi
      написал в отредактировано
      #2

      Здравствуйте! Есть аналогичный вашему проект, может Вы сталкивались со следующей ситуацией:

      Платформа – Raspberry
      Pi 3 , OS Raspbian
      с графической оболочкой.

      Скрипт написан на Python 2.7 – Read_sim_QQ.py (https://github.com/PaulLos/RPi-QQ.git)

      Данная программа считывает данные с бесконтактной карты
      через RFID считыватель
      подключенный к GPIO через
      SPI.

      Аналогично вот этому примеру - https://www.raspberrypi-spy.co.uk/2018/02/rc522-rfid-tag-read-raspberry-pi/

      В чикле считывания программа передает данные карты на наш
      сервер.

      Проблема в следующем:

      При запуске скрипта командой из терминального окна запуск
      программы происходит не всегда корректно, а именно программа стартует, но
      считывание не всегда начинается.

      Было замечено, что если после включения или рестарта системы
      проходит достаточно большое время более 5 минут, то скрипт работает стабильно,
      но если запустить программу сразу после старта системы, например через минуту,
      то скрипт работает не корректно, но если его прервать CTL>C и запустить заново, то все начинает
      работать корректно. И далее можно неоднократно останавливать  и запускать
      данное ПО - все работает.

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

      Спасибо.

      1 ответ Последний ответ
      0

      • Войти

      • Нет учётной записи? Зарегистрироваться

      • Login or register to search.
      • Первое сообщение
        Последнее сообщение
      0
      • Категории
      • Главная
      • Документация
      • Последние
      • Пользователи