Привет! Я занимаюсь разработкой электроники (благо навыки охватывают большую часть этого интереснейшего увлечения). И заказали мне как-то разработку GSM-логгера для ЖКХ.
Кроме наличия требуемых входов/выходов (в том числе 4-20 ма) и источника питания 5-30 в для датчиков, основным условием было минимизация потребления дабы иметь возможность питаться от батарей.После проработки схемотехники и печатной платы во весь рост встал вопрос о используемом протоколе. Хотелось чего-то простого и стандартного.
MQTT. Но MQTT это TCP со всеми достоинствами и недостатками. А у меня аккумулятор и срок работы от 3 месяцов. Для тестов был написан примитивный протокол поверх UDP. Но поскольку не отношу себя к пионэрам, свято уверенным, что вот сейчас за 2 дня напишут что-то удобоваримое — продолжил поиски чего-то общепринятого.
Уж не помню как — попалось мне упоминание о MQTT-SN. Протокол, наследующий семантику MQTT, но приспособленный для передачи по UDP и клиентам с батарейным питанием. Оказалось, есть такой, разработан в недрах IBM и в последующем открыт для сообщества. После прочтения описания стало понятно, что вот оно, счастье, рядом.
Но нужен брокер (так в MQTT называют сервер), привычный Mosquitto (по словам Яна Крагса от 2013) когда-нибудь сможет в MQTT-SN, но не сейчас. Зато есть RSMB, и даже в исходниках на Git-хабе.
Исходники это хорошо, надо собирать. Сборка производиться CygWin-ом в Visual Studio (которую я видел последний раз лет 5 назад). Ставим фришную версию, создаём проект и — никак. На 5-10 раз (вообще в моей жизни большую роль играет случай и упрямство) прописал правильно проект — и о, чудо, собрал таки брокера. Замечу что под Linux это действие прошло гораздо проще.
Торжественно запускаем. Обидно но не работает. Может всё-таки свой протокол это выход? Представив себе объём работы по написанию и отладке сервера и клиентов — решил нет, мой выбор — MQTT-SN. Оказалось всё просто — надо было конфигурацию прописать и указать брокеру.
Минимальная выглядит таким образом:
trace_output off # Диагностика, можно и включить
listener 1883 INADDR_ANY # Порт для обычного MQTT
listener 1883 INADDR_ANY mqtts # Порт для MQTT-SN протокола
И после этого брокер заработал. Вкратце отличия MQTT-SN от классического MQTT.
- Протокол MQTT-SN работает поверх UDP, а не TCP как обычный. Это перекладывает ответственность за контроль доставки сообщений на программиста. Зато позволяет устройству расходовать меньше энергии (а для меня это важно) на поддержание канала связи через GSM.
- Введён новый уровень QoS (Quality of Service, качество сервиса) -1. Означающий отсутствие контроля доставки. Устройство просыпается, делает нужную работу, отсылает результаты и тут-же засыпает не ожидая подтверждения.
- Появились шлюзы, позволяющие агрегировавать данные от множества устройств и пересылать их брокеру.
На git-е eclipsa лежат исходники клиента MQTT-SN с примерами. Собственно надо прописать функции работы с каналом transport_xx под свои нужды. В остальном больших проблем нет (нашёл пару ошибок, надо тестировать).
К сожалению не реализована поддержка спящих клиентов. Стоят заглушки. Кто сможет бросить в авторов протокола камень — исходники доступны, помощь приветствуется.
Что хотел сказать в итоге. Потратив некоторое (небольшое время) я получил готовую инфраструктуру для дальнейшего развития проекта. Протокол позволяет использовать STM32 на 4 МГц. Я могу использовать множество клиентов на разных платформах (что нереально было-бы сделать в одиночку при написании своего протокола). Более того, имея возможность собрать брокера под Linux я разместил его на инстансе Amazon-а и мой заказчик получил решение без необходимости держать и обслуживать сервер. Стандартные решения (не всегда, но в подавляющем количестве случаев) ускоряют исполнение задачи.
Автор: elAlex