Всегда ли вы берете с собой смартфон? Наверное да, ведь это удобно, когда под руками есть все каналы связи.
Но что, если вы собираете автономно работающее устройство с микрокомпьютером, такое как как радиоуправляемый вездеход, робот присутствия, устройство управления шлагбаумом, систему IoT, турникет или что-то подобное?
Было бы неплохо оснастить это устройство чем-то, похожим по функциональности на смартфон. Тогда вы смогли бы определять его координаты GNSS, обмениваться данными через GPRS, Bluetooth или SMS, а также просто позвонить на свое устройство по телефону и поговорить с ним (или с тем, кто стоит рядом).
Еще не так давно все это было реализовать довольно затруднительно, но сейчас доступны недорогие модули на базе SIM868, в которых есть все необходимое.
В этой статье мы расскажем о том, как настроить обмен данными по каналам GPRS мобильных провайдеров между микрокомпьютерам Repka Pi с сервером, размещенном в интернете. Для обмена будем использовать модуль GSM/GPRS/GNSS Bluetooth HAT. Для Raspberry Pi всё будет примерно так же с поправкой на различие между repka-config и rasbi-config, что можно считать однозначным аргументом в пользу того, что Репка является функциональным аналогом с максимальной совместимостью с малиной, в чём Вы сами можете удостовериться.
Но давайте теперь перейдём к существу вопроса!
Все материалы данной статьи представлены в соответствии вот с такой структурой со ссылками на части структуры для Вашего большего удобства:
Итак, погнали в инженерную часть!
Модуль GSM/GPRS/GNSS Bluetooth HAT на базе SIM868
В этой статье мы начнем рассказывать об использовании модуля GSM/GPRS/GNSS/Bluetooth HAT for Raspberry Pi компании Waveshare на базе SIM868 производства компании SIMcom. Для начала мы будем использовать модуль для обмена данными JSON через GPRS с REST-сервисом, созданным с использованием Python и Flask.
Хотя модуль позиционируется для использования с Raspberry Pi, он может работать с отечественным микрокомпьютером Repka-Pi и с любым другим микрокомпьютером или микроконтроллером через интерфейсы GPIO (UART) или USB.
Возможности модуля впечатляют:
прием и передача SMS и MMS;
возможность позвонить и принять телефонный звонок;
передача данных с использованием стандарта GPRS (General Packet Radio Service) и Bluetooth;
использование протоколов HTTP и FTP, работа с E-Mail;
определение географических координат с помощью GNSS
Управляется устройство с помощью AT-команд по стандартам:
3GPP TS 27.007 — работа с SMS;
3GPP TS 27.005 — стандарт описывает протоколы и процедуры для взаимодействия с различными службами и приложениями Unstructured Supplementary Service Data (USSD ), например, проверка баланса на счету, активация услуг и так далее;
SIMCOM enhanced AT Commands — расширение базового набора команд AT.
На сайте компании SIMcom имеется обширная и подробная документация по командам, но для ее загрузки необходимо зарегистрироваться.
Ваше устройство может периодически собирать данные телеметрии (например, температура, влажность, давление, состояние различного рода сенсоров, контактов и кнопок, текущие координаты GPS и так далее). Затем с помощью модуля GSM/GPRS/GNSS Bluetooth HAT эти данные можно передать на созданный вами сервис узла контроля и управления через GPRS.
В том случае, когда GPRS по каким-то причинам использовать не получается, отправляйте самые важные данные телеметрии в виде SMS.
И, наконец, бывают случаи, когда устройство находится вне зоны покрытия мобильных сетей. Тогда для передачи телеметрии можно воспользоваться модулями LoRa, о которых мы уже рассказывали ранее в материале Дальняя радиосвязь с LoRa на одноплатных микрокомпьютерах Repka Pi.
Если нужно выдать какую-либо команду вашему устройству, то это можно сделать через GPRS, SMS или при недоступности сетей через LoRa.
Вы также можете оснастить свое устройство динамиком и микрофоном (соответствующий разъем есть на плате устройства GSM/GPRS/GNSS Bluetooth HAT). Тогда при необходимости оператор, обслуживающий устройство, может позвонить на него как на обычный мобильный телефон и поговорить с теми, кто находится рядом с этим устройством.
При этом на экран, подключенный к микрокомпьютеру, можно выводить соответствующую ситуации картинку или видео.
Добавив видеокамеру, можно реализовать робот присутствия, который с помощью оператора (или ИИ) сможет выполнять, например, обязанности сотрудника ресепшена или аналогичные функции.
Подключаем модуль на базе SIM868 к Raspberry Pi и Repka Pi
Проще всего подключить модуль GSM/GPRS/GNSS Bluetooth HAT к Raspberry Pi, вставив его в разъем GPIO (рис.1).
Обратите внимание, что при таком подключении желтые перемычки нужно установить на пины B (рис.2).
Другие варианты:
A - управление SIM868 через USB TO UART;
B - прямое подключение к Raspberry Pi или Repka Pi;
C - USB TO UART интерфейс будет использоваться для доступа к Raspberry Pi (например, для удаленного управления или обновления программного обеспечения на Raspberry Pi через USB TO UART)
На рис.3 мы показали подключение модуля к микрокомпьютеру российской сборки Repka Pi. Здесь вы также можете вставить модуль в разъем GPIO.
Чтобы можно было обмениваться данными через GPRS, передавать и принимать SMS и звонки, вставьте в модуль SIM-карту.
После подключения модуля и загрузки ОС нажмите примерно на 1 секунду кнопку включения питания, показанную на рис.1. Через некоторое время модуль включится, о чем можно судить по миганию светодиодов.
Программа get-telemetry.py
Предположим, что вам нужно передавать данные телеметрии с ровера (радиоуправляемого вездехода) или аналогичного устройства, оснащенного микрокомпьютером,. Напишем простую программу get-telemetry.py, которая будет периодически запускаться на этом микрокомпьютере, например, с помощью crontab.
При запуске программа (листинг 1) получит и отправит на управляющий сервер данные телеметрии, а затем примет и покажет на консоли ответ сервера. Вы можете изменить или дополнить эту программу в соответствии с вашими задачами.
Листинг 1. Программа get-telemetry.py
import traceback
import pdb
import re
import time
import datetime
import json
from collections import namedtuple
from sim800l import SIM800L
from rover_connect import SmsTz
from rover_connect import RoverConnect
from rover_connect import Telemetry
if __name__ == "__main__":
#pdb.set_trace()
api_url = "http://my-json-server.ru:9000/api/data"
rover = RoverConnect('/dev/ttyS0', 'internet.mts.ru')
telemetry_data = Telemetry(rover)
td = telemetry_data.get_telemetry_data()
print(td)
rover.post_get(td, api_url)
Многие (но не все) операции с модулем выполняются с помощью библиотеки SIM800L.
Сайт библиотеки SIM800L находится по адресу: https://pypi.org/project/sim800l-gsm-module/1.0.0/. Исходные коды и описание процедуры установки вы можете посмотреть здесь: https://github.com/Ircama/raspberry-pi-sim800l-gsm-module.
Установка несложна:
# apt update
# apt install python3-pip
# python3 -m pip install sim800l-gsm-module
В процессе работы над статьей были созданы библиотеки RoverConnect и Telemetry, а также добавлена библиотека SmsTz.
Чтобы скопировать эти библиотеки в рабочий каталог, воспользуйтесь следующей командой:
# git clone git@github.com:AlexandreFrolov/rover_connect2.git
С помощью библиотек RoverConnect и SmsTz в дополнение к возможностям SIM800L реализовано управление питанием модуля GSM/GPRS/GNSS Bluetooth HAT, получение данных GPS с формированием соответствующих строк для отображения координат на картах Google Maps, Open Street Map, а также на Яндекс.Картах.
Также реализовано получение GPS координат по базовым станциям через сайт lbs-simcom.com, получение и отправка SMS в формате PDU (в сообщениях можно использовать кириллицу), контроль баланса от операторов сотовой связи, обмен данными в формате JSON с управляющим сервером.
Для работы с модулем GSM/GPRS/GNSS Bluetooth HAT используются AT-команды, передаваемые через UART.
Библиотека Telemetry получает данные телеметрии от модуля GSM/GPRS/GNSS Bluetooth HAT, текущие координаты GPS, отправляет их на управляющий сервер и получает от него ответ. Вы можете дополнить эту библиотеку функциями, получающими данные телеметрии от различных модулей, подключенных к микрокомпьютеру, например, от погодной станции или различных устройств IoT.
Инициализация
При инициализации программа get-telemetry.py создает объект класса RoverConnect, передавая конструктору интерфейс последовательного порта, а также настройки APN (Access Point Name) провайдера связи (в данном случае это был МТС), необходимые для подключения к сети мобильного оператора:
rover = RoverConnect('/dev/ttyS0', 'internet.mts.ru')
Из всех настроек APN нужно указать имя точки доступа. Для оператора МТС это internet.mts.ru - для других операторов нужно уточнять имена или адреса сервисов.
Конструктор класса RoverConnect вызывает конструктор базового класса SIM800L, который инициализирует последовательный порт и задает для него таймаут, равный 15 секунд:
class RoverConnect(SIM800L):
def __init__(self, serial_port, apn='internet.mts.ru'):
super().__init__(serial_port, timeout=15.0)
self.setup()
self.debug = 0
self.apn=apn
…
Кроме того, из класса SIM800L вызывается метод setup, выполняющий необходимую инициализацию модуля GSM/GPRS/GNSS Bluetooth HAT.
Получение данных телеметрии
На следующем шаге программа get-telemetry.py создает объект класса Telemetry, получает данные телеметрии функцией get_telemetry_data и выводит эти данные на консоль:
telemetry_data = Telemetry(rover)
td = telemetry_data.get_telemetry_data()
print(td)
Конструктору класса Telemetry передается созданный ранее объект класса RoverConnect, необходимый для обмена данными с модулем GSM/GPRS/GNSS Bluetooth HAT:
class Telemetry():
def __init__(self, rover):
self.debug = 0
self.rover = rover
…
Далее вызывается функция get_telemetry_data, которая и возвращает данные телеметрии в виде JSON:
{
"sim868cfg": {
"Flash ID": "Device Name:SERIAL§FLASH§MTKSIP§6261§SF§32§01",
"Hw revision": "Revision:1418B06SIM868M32§BT",
"Date": "2023-11-22 15:31:32",
"Operator": "Mts",
"Service provider": "MTS RUS",
"Signal strength": "56.25%",
"Temperature": "31.00 degrees",
"MSISDN": "Unstored MSISDN",
"Battery Voltage": "3.983 V",
"IMSI": "250016442143869",
"ICCID": "89701010064421438699",
"Unit Name": "SIM868 R14.18",
"Balance": "809,48 rub.",
"SIM is registered": true
},
"gnss": {
"GNSS Position not fixed": 1
},
"gsm_gnss": {
"latitude": "55.641XXX",
"longitude": "37.333XXX",
"msl_altitude": "550"
}
}
При запуске программы модуль находился в помещении и спутники GNSS были недоступны. Поэтому координаты GPS были определены только через базовые станции GSM с использованием сайта lbs-simcom.com, и они не точные. Некоторые цифры координат были заменены символами XXX.
Какие полезные данные мы получили от модуля GSM/GPRS/GNSS Bluetooth HAT?
Например, мы узнали, что на момент запуска программы баланс аккаунта в МТС (поле Balance) был равен 809,48 руб. Если не контролировать баланс и допустить, что он станет отрицательным, то передача данных через GPRS и SMS, а также голосовые звонки будут недоступны.
Также важно, чтобы SIM-карта была зарегистрирована провайдером, о чем можно судить по содержимому поля SIM is registered.
В полях Battery Voltage и Temperature будут переданы величина питающего напряжения в вольтах и температура, измеренная модулем, соответственно. Существенные отклонения от нормы могут повлиять на работоспособность модуля.
Анализируя поле Signal strength, можно определить силу сигнала от базовой станции. Если сигнал очень слабый, связь с модулем может быть потеряна.
Все данные телеметрии были получены от модуля GSM/GPRS/GNSS Bluetooth HAT с помощью соответствующих функций класса RoverConnect.
После получения данные были сформированы функцией get_telemetry_data в строку JSON, пригодную для передачи на сервер управления через GPRS.
Передача данных телеметрии
Для передачи строки JSON с телеметрией в классе RoverConnect определена функция post_get:
api_url = "http://my-json-server.ru:9000/api/data"
rover.post_get(td, api_url)
В качестве первого параметра этой функции нужно передать строку JSON, а в качестве второго — адрес URL управляющего сервера, на который будут передаваться данные.
В данном примере предполагается, что вы зарегистрировали доменное имя my-json-server.ru (у вас будет другое имя) и привязали его через DNS к адресу IP вашего управляющего сервиса, доступному через интернет.
Вначале функция post_get отправляет данные на адрес api_url с помощью функции http, определенной в базовом классе SIM800L:
rc = self.http(api_url, td.encode(), method="PUT", use_ssl=False, apn=self.apn)
Обратите внимание, что здесь используется метод передачи PUT, а использование SSL отключено. К сожалению, модуль GSM/GPRS/GNSS Bluetooth HAT не поддерживает современные протоколы безопасного обмена данными. Поэтому при необходимости вам нужно будет самостоятельно зашифровывать данные перед передачей на сервер и расшифровывать их на сервере после получения. В Python есть соответствующие средства для этого.
После отправки данных функция post_get запрашивает данные с сервера методом GET:
print(self.http(api_url, method="GET", use_ssl=False, apn=self.apn))
Полученные данные выводятся на консоль.
Отключение вывода сообщений Repka Pi на UART0
Если вы запускаете программу get-telemetry.py на микрокомпьютере Repka Pi, то перед запуском нужно отключить вывод сообщений на UART0 с помощью repka-config
.
После запуска этой программы вы увидите текущую максимальную частоту процессора (рис.4).
Щелкните кнопку Ок. Появится меню настраиваемых опций (рис.5).
Выберите здесь строку Включить / отключить вывод сообщений на UART0.
Далее появится возможность отключения или включения вывода сообщений (рис.6).
Выберите здесь строку Отключить вывод сообщений на UART, и после появления приглашения перезагрузите Repka OS.
Запуск программы get-telemetry.py
Программа get-telemetry.py должна запускаться под управлением Python версии 3 с правами пользователя root:
# python3 get-telemetry.py
Но прежде, чем ее запускать, вам нужно запустить и проверить управляющий сервис, к которому эта программа будет обращаться.
Управляющий сервис rest_app.py
Описанная выше программа get-telemetry.py отправляет данные телеметрии через GPRS с помощью модуля GSM/GPRS/GNSS Bluetooth HAT на управляющий сервис. Давайте займемся его запуском и проверкой.
Заказываем виртуальный или облачный сервер или.... поднимаем свой
В качестве сервера для запуска нашего тестового управляющего сервиса может выступать физический, виртуальный или облачный сервер с адресом IP, доступным из интернета. Для экспериментов вы можете арендовать недорогой виртуальный или облачный сервер с ОС Linux в любом дата-центре. Будет достаточно одного ядра процессора, 1 ГБайт оперативной памяти и 10 ГБайт дисковой памяти.
Заметим, что для сервера локальные («серые») адреса IP не подойдут. При передаче данных через GPRS обращение к вашему серверу будет выполняться через интернет с серверов провайдера мобильного интернета. В нашем случае это серверы от мобильного оператора... ну это уже было бы рекламой - выбирайте сами что Вам больше нравится :-).
Если сервер с внешним адресом IP недоступен, то вы можете настроить проброс нужного порта (маскарадинг) с внешнего адреса маршрутизатора на сервер, расположенный в вашей локальной сети. Для этого, однако, потребуется приобрести у вашего провайдера интернета фиксированный адрес IP и научиться настраивать маскарадинг на вашем маршрутизаторе для порта 9000 (можно поискать инструкции в интернете по названию модели маршрутизатора).
Маршруты для записи и получения данных
Исходный код программы тестового управляющего сервиса rest_app.py приведен ниже:
from flask import Flask, request, jsonify
app = Flask(__name__)
data = {
}
@app.route('/api/data', methods=['GET'])
def get_data():
return jsonify(data)
@app.route('/api/data/<string:key>', methods=['GET'])
def get_data_by_key(key):
if key in data:
return jsonify({key: data[key]})
else:
return jsonify({"message": "Key not found"}), 404
@app.route('/api/data', methods=['POST'])
def add_data():
new_data = request.get_json()
print(new_data)
key = str(len(data) + 1)
data[key] = new_data
return jsonify({"message": "Data added", "key": key, "value": data[key]}), 200
if __name__ == '__main__':
app.run(host='xxx.xxx.xxx.xxx', port=9000, debug=True)
Программное обеспечение управляющего сервиса основано на фреймворке Flask. В интернете есть немало статей и руководств, посвященных этому фреймворку.
В самом начале программы rest_app.py мы определили пустой словарь data, в который будем записывать полученные данные телеметрии. В реальных приложениях такие данные лучше хранить в базе данных (MySQL, PostgreSQL), в хранилище типа «ключ-значение», таком как Redis, или в файлах.
Добавление данных выполняется методом POST при помощи функции add_data.
Обратите внимание, что здесь после успешного завершения функция add_data возвращает код 200, а не 201, как полагается для метода POST при добавлении новых данных. Это связано с тем, как этот код обрабатывается библиотекой SIM800L на отправляющей стороне, то есть на микрокомпьютере. Получение кода 201 для метода POST рассматривается этой библиотекой как ошибка.
Функция add_data выводит полученные данные JSON на консоль сервера для контроля. В реальных приложениях такой вывод скорее всего вам не потребуется.
Маршрут для получения всех данных из словаря data использует функцию get_data.
Здесь содержимое словаря преобразуется в JSON и отправляется в ответ на запрос GET вызывающей стороне (на микрокомпьютер) без дополнительной обработки. Ваше приложение может анализировать полученные данные и при необходимости предпринимать какие-либо действия.
Например, если баланс аккаунта приближается к нулю, слишком снизилось напряжение питания модуля или обнаружено, что сигнал от мобильной станции имеет слишком низкий уровень, можно отправлять в службу сопровождения сообщение с соответствующим предупреждением.
И, наконец, с помощью функции get_data_by_key обрабатывается маршрут для выборки из словаря данных по ключу.
Если искомый ключ не найден, возвращается сообщение об ошибке и код 404.
Запускаем все вместе
Мы предполагаем, что к этому моменту вы уже подключили модуль GSM/GPRS/GNSS Bluetooth HAT к порту GPIO микрокомпьютера и включили его, а также записали в каталог /home/pi/rover_connect программу сбора данных телеметрии get-telemetry.py.
Если используется Repka Pi, то вы отключили вывод сообщений на UART0 с помощью программы repka-config из состава Repka OS.
Также предполагаем, что вы арендовали виртуальный или облачный сервер с ОС Linux (например, Debian или Ubuntu), и записали в свой рабочий каталог на этом сервере программу rest_app.py.
Запуск управляющего сервиса
Сервис запускается на виртуальном сервисе с «белым» адресом IP, доступным через интернет, следующим образом:
$ python3 rest_app.py
Перед запуском отредактируйте поле host, указав в нем адрес IP сервера, который вы арендовали в дата-центре:
if __name__ == '__main__':
app.run(host='xxx.xxx.xxx.xxx', port=9000, debug=True)
В этом случае сервис будет доступен на порту 9000 по заданному вами адресу IP. Вы можете прописать доменное имя на сервере DNS дата-центра, указав адрес IP в записи A. Тогда вместо адреса IP можно будет указывать на сервере и в программе сбора телеметрии доменное имя.
Проверка управляющего сервиса
Если вы уже запустили сервис, то перейдите в консоль сервера (любого сервера или микрокомпьютера Linux, подключенного к интернету) и выдайте такую команду:
$ curl http:// xxx.xxx.xxx.xxx:9000/api/data
{}
Вместо xxx.xxx.xxx.xxx укажите адрес IP сервера или привязанное к нему через DNS доменное имя.
Так как мы еще не запускали программу сбора данных, эта команда выведет пустое содержимое хранилища data.
Теперь перейдите в консоль микрокомпьютера и запустите там программу сбора телеметрии get-telemetry.py с правами пользователя root:
# python3 get-telemetry.py
Программа get-telemetry.py получит и выведет на консоль данные телеметрии, передаст эти данные на сервис, а потом получит содержимое хранилища data сервиса и выведет его на консоль (данные GNSS получить не удалось, так как модуль находился в помещении).
Ниже вывод программы get-telemetry.py показан в сокращенном виде:
Ошибка: GNSS Position не зафиксировано
{
"sim868cfg": {
"Flash ID": "Device Name:SERIAL§FLASH§MTKSIP§6261§SF§32§01",
"Hw revision": "Revision:1418B06SIM868M32§BT",
"Date": "2023-11-22 18:50:37",
…
"Balance": "806,48 rub.",
"SIM is registered": true
},
"gnss": {
"GNSS Position not fixed": 1
},
"gsm_gnss": {
"latitude": "55.636XXX",
"longitude": "37.336XXX",
"msl_altitude": "550"
}
}
{
"1": {
"gnss": {
"GNSS Position not fixed": 1
},
"gsm_gnss": {
"latitude": "55.636XXX",
"longitude": "37.336XXX",
"msl_altitude": "550"
},
"sim868cfg": {
"Balance": "806,48 rub.",
"Battery Voltage": "3.983 V",
"Date": "2023-11-22 18:50:37",
…
"Signal strength": "71.875%",
"Temperature": "28.35 degrees",
"Unit Name": "SIM868 R14.18"
}
}
}
Как видите, в хранилище появился элемент с индексом 1, в чем нетрудно убедиться при помощи команды, которую вы вводили раньше:
$ curl http://xxx.xxx.xxx.xxx:9000/api/data
{
"1": {
"gnss": {
"GNSS Position not fixed": 1
},
"gsm_gnss": {
"latitude": "55.636XXX",
"longitude": "37.336XXX",
"msl_altitude": "550"
},
"sim868cfg": {
"Balance": "806,48 rub.",
"Battery Voltage": "3.983 V",
"Date": "2023-11-22 18:50:37",
…
"Signal strength": "71.875%",
"Temperature": "28.35 degrees",
"Unit Name": "SIM868 R14.18"
}
}
}
Запустите программу get-telemetry.py несколько раз. После этого убедитесь, что в хранилище появилось несколько записей с разными ключами.
Теперь выдайте команду с маршрутом, позволяющим извлечь из хранилища запись с ключом, равном трем:
$ curl http://xxx.xxx.xxx.xxx:9000/api/data/3
{
"3": {
"gnss": {
"GNSS Position not fixed": 1
},
"gsm_gnss": {
"latitude": "55.636XXX",
"longitude": "37.336XXX",
"msl_altitude": "550"
},
"sim868cfg": {
"Balance": "806,48 rub.",
"Battery Voltage": "3.983 V",
…
"Temperature": "29.46 degrees",
"Unit Name": "SIM868 R14.18"
}
}
}
В этом случае в программе rest_app.py была вызвана функция get_data_by_key, описанная выше.
Итак, мы собрали систему, позволяющую получать данные телеметрии от модуля GSM/GPRS/GNSS Bluetooth HAT, а после доработки программы get-telemetry.py и от других модулей или оборудования, подключенного к микрокомпьютеру.
Собранные данные передаются через GPRS мобильного провайдера в управляющий REST-сервис, работающий на виртуальном сервере, доступном через интернет.
Полезные ссылки
Перечисленные ниже ресурсы будут вам полезны при изучении модулей, созданных на базе SIM800 и SIM868:
модуль GSM/GPRS/GNSS/Bluetooth HAT for Raspberry Pi компании Waveshare;
документация по командам AT модуля SIM868 (требуется регистрация);
сайт библиотеки SIM800L: https://pypi.org/project/sim800l-gsm-module/1.0.0/;
проект библиотеки SIM800L: https://github.com/Ircama/raspberry-pi-sim800l-gsm-module;
статья Работа со встроенным TCP/IP-стеком модулей GSM/GPRS серии SIM800 компании SIMCom Wireless Solutions
статья Дальняя радиосвязь с LoRa на одноплатных микрокомпьютерах Repka Pi;
Итоги
Из этой статьи вы узнали, как можно обмениваться данными между микрокомпьютерами на примере Российского одноплатника Repka Pi с JSON-сервисом, доступным в интернете.
Вы запустили простой JSON-сервис, написанный на Python с использованием фреймворка Flask, а также программу сбора и передачи на этот сервис телеметрии, полученной от модуля GSM/GPRS/GNSS Bluetooth HAT на базе SIM868.
Вы загрузили в свой рабочий каталог на микрокомпьютере библиотеку RoverConnect, которая помимо передачи данных через GPRS способна принимать и отправлять SMS с символами кириллицы, определять координаты GPS как с помощью оборудования, установленного на модуле, так и получать примерные координаты от базовых станций.
Каждая из этих возможностей заслуживает отдельной статьи, которые готовятся к выпуску. Так что пишите в комментариях, интересно ли Вам увидеть продолжение данной статьи.