Skip to content

Принципы работы

Какие задачи решают принципы?

Принципы обеспечивают целостность работы системы и определяют, то как Pepeunit взаимодействует с сущностями, которые его составляют, а также определяют стандартное поведение пользователя и Unit

Зависимости

Для чего нужны зависимости приложению Pepeunit?

Зависимости - дополнительные приложения требующиеся для корректной работы Pepeunit

MQTT Broker EMQX

MQTT Broker - обеспечивает прямое взаимодействие через 1883 и 8883 порты между Unit и Backend. Его можно назвать рельсой данных, на которую завязано основное взаимодействие.

Ключевые моменты

Backend выполняет функцию регулятора, а именно:

  1. Авторизация всех Unit для доступа к определённым топикам
  2. Агрегация данных из определённых топиков, согласно политике имён топиков
  3. Управление Unit, при помощи публикации в опредённые топики

Unit могут взаимодействовать напрямую между собой через MQTT Broker, если это определено политиками доступа к топикам, а MQTT Broker в свою очередь запрашивает авторизацию у Backend для каждого из топиков.

Брокер EMQX на два порядка производительней чем Backend, но благодаря системе кэширования авторизации EMQX и кэшированию через Redis, Backend может справится с нагрузкой.

База данных Postgresql

Postgresql - обеспечивает хранение информации о всех сущностях. Также обеспечивает сохранение статистической информации о состояниях UnitNode и данных о существующих Узлах Pepeunit. Взаимодействует напрямую с Backend.

Redis

Redis - обеспечивает кэширование и хранение промежуточной информации о состоянии UnitNode, во время общения Unit c MQTT Broker. Используется также для авторизации Backend в момент подписки на основные топики example.com/+/pepeunit и example.com/+/+/+/pepeunit в MQTT Broker. Взаимодействует напрямую с Backend и MQTT Broker.

Сущности

Что такое сущности в Pepeunit?

Основные элементы системы с которыми взаимодействуют пользователи и физические IoT устройства.

Repo

Repo - это создаваемая пользователем сущность с уникальным именем на Узле, содержащая в себе информацию о репозитории Git.

Репозиторий Git может быть размещён на Узле Gitlab или Github. Pepeunit умеет скачивать не только публичные репозитории, но и закрытые, для этого требуется указать токен доступа до репозитория. Токены доступа хранятся в шифрованном виде и доступны только создателю Repo.

Repo синхронизируется с удалённым репозиторием каждый час. У создателя всегда есть возможность заставить Repo принудительно синхронизироваться по нажатию кнопки.

При настройке Repo требуется указать ветку по умолчанию - это позволит автоматически обновляться отстыкованным Unit, у которых стоит флаг о автоматическом обновлении. Важно отметить, что отстыковать Unit от Repo нельзя пока не указана ветка по умолчанию.

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

Механизм работы обновлений

  1. Происходит автоматическая или ручная инициализация обновления Repo
  2. Pepeunit проверяет schema_example.json и env_example.json в выбранной версии на корректность
  3. Pepeunit последовательно проходит по каждому отстыкованному Unit и актуализирует следующую информацию:
    • schema_example.json в выбранной версии Repo проверяется на наличие нужных категорий топиков. Если топиков нет, то создаётся сущность UnitNode. Если сущность UnitNode существует, но её нет в schema_example.json она будет удалена.
    • env_example.json в версии Repo сверяется с зашифрованным env.json на наличие нужных для работы переменных.
  4. Pepeunit последовательно отправляет каждому подходящему Unit требование об обновлении по OTA, через топик MQTT
  5. Unit видят требование о обновлении, сравнивают версию своей текущей микропрограммы и новой версии от Pepeunit. При не совпадении версий - обновляют свою микропрограмму по OTA. При совпадении версий - игнорируют. Данный этап может быть модифицирован разработчиками так как проходит на стороне Unit

Важно

Repo невозможно удалить, если на него ссылается хотябы один Unit

Unit

Unit - это центральная сущность в Pepeunit, обладающая уникальным именем на Узле, она представляет физичеcкое IoT устройство внутри системы Pepeunit.

Unit можно создать только отстыковав его от Repo - это может сделать любой позователь при наличии доступов - через Frontend или API.

Unit можно настроить, указав будет ли он обновляться автоматически при обновлении Repo или же обновление будет происходить исключительно вручную с указанием Ветки и Коммита.

В момент создания Unit, на основании выбранной версии и schema_example.json - будут сгенерированы UnitNode отвечающие за точки взаимодействия с Unit

Настройка Unit по мимо видимости, доступов и настройки обновлений - включает в себя заполнение файла env.json. Файл является очень важным, так как содержит конфиденциальные данные о подключении физического устройства к Pepeunit, в том числе пароли от WiFi в случае физических устройств по типу esp8266.

Механизм заполнения файла окружения Unit

  1. Пользователь первично видит только те переменные, которые Pepeunit не может заполнить сам, обычно это данные о подключении к WiFi.
  2. Пользователь заполняет значения переменных и отправляет их в Pepeunit
  3. Pepeunit присылает полностью заполненный env.json
  4. Пользователь может внести изменения по своему желанию если это требуется
  5. env.json отправляется в Pepeunit где шифруется и сохраняется до востребования.

Когда настройка виртуального Unit в Pepeunit завершена, следует создать ваше IoT устройство физически. После установки Micropython на ваше устройство, вам нужно загрузить на него микропрограмму. Её можно получить напрямую из интерфейса Unit в вашем Узле Pepeunit.

Вы можете скачать микропрограмму в формате zip или tar, и при помощи вспомогательного ПО загрузить его на устройство IoT c уже предустановленным Micropython, после чего ваше IoT устройство начнёт работу.

UnitNode

UnitNode - это автоматически генерируемые сущности связанные с Unit, они cоздаются на основе файла schema_example.json, который содержится в разных версиях Repo.

Каждая сущность UnitNode может иметь два типа Input или Output. При этом между UnitNode разных Unit, могут быть связи - от одного Output к многим Input. Всё взаимодействие между UnitNode происходит при этом через MQTT Broker. Backend при этом заниматся только авторизацией Unit для доступа до определённых топиков.

Нюансы работы UnitNode

Input тип для UnitNode можно понимать как точку из которой Unit получает данные от внешнего мира. Положить данные в данную точку можно любым из API, которые поддерживаются в Backend.

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

В Output информацию может помещать только сам Unit, которому принадлежит UnitNode. Unit может это осуществить через любой доступный API в Backend.

Output UnitNode с определёнными названиями, могут заставлять Pepeunit накапливать статистику по их состоянию во времени. Это могут быть например датчики температуры - отправляющие сообщения каждую секунду, Pepeunit позволит найти средне часовые температуры.

Backend обновляет значения только у топиков с префиксом /pepeunit в конце. При этом в Postgresql сохраняются только новые значения, по сравнению с ранее пришедшими.


Уровни видимости сущностей

На что влияет уровень видимости?

От уровня видимости сущностей будет зависеть кто их сможет увидеть и/или провзаимодействовать. Всего уровня видимости 3.

Public

  • предоставляет доступ до сущности всем

Internal

  • предоставляет доступ до сущности только авторизованным пользователям Узла или всем Unit

Private

  • предоставляет доступ до сущности только создателю и указанным доверенным пользователям Узла или отдельным Unit у которых есть доступ

Роли

Какую функцию несут роли пользователей в системе?

Роль пользователя влияет на его возможности при использовании Узла Pepeunit.

Admin

Aдминистратор - владелец, выполняющий функции модератора, имеет полномочия полного управления Узлом Pepeunit.

Возможности Администратора

  • блокирование пользователей, при нарушении условий использования Узла
  • блокирование работы отдельных Unit, при нарушении условий использования Узла
  • блокирование взаимодействия Узел-Узел, если это нарушает работу текущего Узла Pepeunit
  • имеет доступ к настройке лимитов для создания Unit
  • имеет доступ ко всем сущностям, но не может получить информацию о зашифрованных данных напрямую через Pepeunit

Очень важно!!!!

Стоит понимать что имея досутп до .env файла Pepeunit, Администратор может расшифровать ваши env.json файлы. Поэтому используйте только Pepeunit Узлы, которым вы можете доверить информацию из своих env.json файлов.

User

Пользователь - человек, зарегистрированный на Узле Pepeunit.

Возможности обычного пользователя

  • имеет доступ к созданию Repo, Unit и UnitNode
  • имеет доступ к сущностям чей уровень видимости Public, Internal или Private если предоставлен доступ

Bot

Внешний агент - обычный пользователь интернета или любая программа.

Возможности внешнего агента

  • Может взаимодействовать только с сущностями у которых уровень видимости соответствует Public

Шифрование

Pepeunit использует шифрование AES256 с 16 байтовым инициирующим вектором и 32 байтовым ключом - схема шифрования CBC

python
def aes_encode(data: str, key: str = settings.encrypt_key) -> str:
    """
    data: any python str
    key: (base64 str) 16, 24, 32 bytes sync encrypt key
    return: (base64 str - iv).(base64 str - encrypted data)
    """
    key = base64.b64decode(key.encode())
    iv = os.urandom(16)

    # set encrypter
    encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
    # encrypted binary to base64 str
    cipher = base64.b64encode(encrypter.feed(data) + encrypter.feed()).decode('utf-8')

    return f"{base64.b64encode(iv).decode('utf-8')}.{cipher}"


def aes_decode(data: str, key: str = settings.encrypt_key) -> str:
    """
    data: (base64 str - iv).(base64 str - encrypted data)
    key: (base64 str) 16, 24, 32 bytes sync encrypt key
    return: decode python str
    """
    key = base64.b64decode(key.encode())
    iv = base64.b64decode(data.split('.')[0].encode())

    # set decrypter
    decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(key, iv))
    # data (iv).(encrypted text) to binary encrypted text
    cipher = base64.b64decode(data.split('.')[1].encode())

    return (decrypter.feed(cipher) + decrypter.feed()).decode('utf-8')

Какие данные шифрует Pepeunit?

Все конфиденциальные данные, а именно:

  1. Динамическая соль, использующаяся для хэширования пароля пользователя
  2. Авторизационные данные, отвестветвенные за доступ до приватных репозиториев
  3. Файлы окружений - env.json от Unit

Федерация