Skip to content

Входной NFC-считыватель undef.space

Notifications You must be signed in to change notification settings

undefspace/rfid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

undef_rfid

RFID-считыватель undef.space

Что делает?

  • впускает админов в спейс по картам MIFARE;
  • сообщает о входе и неудачных попытках входа в админской беседе;
  • сообщает о статусе механической задвижки в админской беседе.

Документация

Устройство состоит из:

  • отладочной платы на базе ESP32-C3;
  • NFC-считывателя на базе PN532;
  • платы реле;
  • держателя, закрепляющего устройство на внутренней стороне стены.

Использование

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

Администрирование

Чтобы использовать встроенный REPL, подключите устройство по USB и откройте монитор порта (например, при помощи idf.py monitor --no-reset -p /dev/ttyUSB0). Если любая из команд add, remove или list используется впервые за последние пять минут, нужно будет ввести пароль. Используйте help, чтобы узнать список команд с аргументами.

Формат credential:

  • T<10 цифр> - карта Тройка;
  • U<8 hex-цифр> - любая карта с 4-байтовым UID;
  • U<14 hex-цифр> - любая карта с 7-байтовым UID.

Hex-значения прописываются в нижнем регистре: например, не U1234ABCD, а U1234abcd.

Сборка

Держатель

Текущий держатель сделан из дерева, он примерно соответствует модели в bracket.scad.

Электроника

Соберите детектор задвижки согласно схеме в main/latch.c. Подключите всё к отладочной плате согласно распиновке в main/include/config.h.

Прошивка

Написана на C с использованием ESP-IDF. Чтобы собрать прошивку:

  • установите ESP-IDF
  • склонируйте репозиторий
  • скачайте зависимости: git submodule update --recursive
  • создайте файл main/include/secrets.h со следующим содержанием:
    #pragma once
    #define WIFI_SSID  "название сети"
    #define WIFI_PASS  "пароль сети"
    #define HASS_KEY   "ключ API HomeAssistant"
    #define REPL_PASS  "пароль от REPL"
    #define TG_KEY     "ключ API Telegram"
    #define TG_CHAT_ID "-123456789"
  • получите ключи шифрования и подписи:
    • если собираете новое устройство, сгенерируйте ключи: espsecure.py generate_flash_encryption_key keys/flash.bin, espsecure.py generate_signing_key --version 1 keys/sign.pem
    • если работаете с уже собранным устройством, получите их от админов и поместите в папку keys (файлы flash.bin и sign.pem)
  • соберите проект и загрузите прошивку:
    • в самый первый раз: idf.py build flash monitor
    • в последующие разы, в т.ч. для уже собранного устройства: ./flash.sh

Стиль кода

Форматирование:

  • отступы: 4 пробела;
  • используйте SCREAMING_SNAKE_CASE для макросов, snake_case для всего остального;
  • названия символов и типов начинайте с названия файла, например http_init в http.c;
  • названия статических символов начинайте с нижнего подчёркивания, например _http_urlencode в http.c;
  • названия типов завершайте на _t, например http_message_t в http.c;
  • не ставьте пробел между ключевым словом и скобкой, а открывающуюся фигурную скобку ставьте на той же строке, например if(condition) {;
  • подключайте внешние файлы в угловых скобках, а файлы проекта - в кавычках, например #include <esp_log.h>, но #include "http.h";
  • ставьте звёздочки в типах слева, например void* ptr, а не void *ptr;
  • ставьте void в сигнатуре функции без аргументов, например void http_init(void),
  • разделяйте подключения на секции: внешние и внутренние, например:
    #include <driver/rmt_tx.h>
    #include <driver/gpio.h>
    #include <esp_timer.h>
    #include <esp_log.h>
    
    #include "config.h"
    #include "latch.h"
    #include "http.h"

Архитектура:

  • инициализируйте оборудование и стейт в _init функциях, например http_init;
  • циклы задач реализуйте в _task функциях, например http_task;
  • не запускайте задачи в инициализаторах, делайте это в app_main;
  • старайтесь не использовать глобальные переменные для обмена данными между файлами - передавайте их через вызовы функций, очереди, буфера и прочие примитивы синхронизации;
  • передавайте данные между задачами через очереди в стиле Erlang - каждая задача имеет одну входную очередь с определённым форматом сообщений.