Принципы работы
Какие задачи решают принципы?
Принципы обеспечивают целостность работы системы и определяют, то как Pepeunit взаимодействует с сущностями, которые его составляют, а также определяют стандартное поведение пользователя и Unit
Зависимости
Для чего нужны зависимости приложению Pepeunit?
Зависимости - дополнительные приложения требующиеся для корректной работы Pepeunit
MQTT Broker EMQX
MQTT Broker - обеспечивает прямое взаимодействие через 1883 и 8883 порты между Unit и Backend. Его можно назвать рельсой данных, на которую завязано основное взаимодействие.
Ключевые моменты
Backend выполняет функцию регулятора, а именно:
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 обновляться только при появлении нового Тега
Механизм работы обновлений
- Происходит автоматическая или ручная инициализация обновления Repo
- Pepeunit проверяет schema_example.json и env_example.json в выбранной версии на корректность
- Pepeunit последовательно проходит по каждому отстыкованному Unit и актуализирует следующую информацию:
- schema_example.json в выбранной версии Repo проверяется на наличие нужных категорий топиков. Если топиков нет, то создаётся сущность UnitNode. Если сущность UnitNode существует, но её нет в schema_example.json она будет удалена.
- env_example.json в версии Repo сверяется с зашифрованным env.json на наличие нужных для работы переменных.
- Pepeunit последовательно отправляет каждому подходящему Unit требование об обновлении по OTA, через топик MQTT
- Unit видят требование о обновлении, сравнивают версию своей текущей микропрограммы и новой версии от Pepeunit. При не совпадении версий - обновляют свою микропрограмму по OTA. При совпадении версий - игнорируют. Данный этап может быть модифицирован разработчиками так как проходит на стороне 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
- Пользователь первично видит только те переменные, которые Pepeunit не может заполнить сам, обычно это данные о подключении к
WiFi
. - Пользователь заполняет значения переменных и отправляет их в Pepeunit
- Pepeunit присылает полностью заполненный env.json
- Пользователь может внести изменения по своему желанию если это требуется
- 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
Private
- предоставляет доступ до сущности только создателю и указанным доверенным пользователям Узла или отдельным Unit у которых есть доступ
Роли
Какую функцию несут роли пользователей в системе?
Роль пользователя влияет на его возможности при использовании Узла Pepeunit.
Admin
Aдминистратор - владелец, выполняющий функции модератора, имеет полномочия полного управления Узлом Pepeunit.
Возможности Администратора
- блокирование пользователей, при нарушении условий использования Узла
- блокирование работы отдельных Unit, при нарушении условий использования Узла
- блокирование взаимодействия Узел-Узел, если это нарушает работу текущего Узла Pepeunit
- имеет доступ к настройке лимитов для создания Unit
- имеет доступ ко всем сущностям, но не может получить информацию о зашифрованных данных напрямую через Pepeunit
Очень важно!!!!
Стоит понимать что имея досутп до .env
файла Pepeunit, Администратор может расшифровать ваши env.json файлы. Поэтому используйте только Pepeunit Узлы, которым вы можете доверить информацию из своих env.json файлов.
User
Пользователь - человек, зарегистрированный на Узле Pepeunit.
Возможности обычного пользователя
Bot
Внешний агент - обычный пользователь интернета или любая программа.
Возможности внешнего агента
- Может взаимодействовать только с сущностями у которых уровень видимости соответствует Public
Шифрование
Pepeunit использует шифрование AES256
с 16 байтовым
инициирующим вектором и 32 байтовым
ключом - схема шифрования CBC
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?
Все конфиденциальные данные, а именно: