Pull to refresh

Как GPS трекер стал логером или простой и дешевый способ организовать мониторинг физических параметров удаленных объектов

Reading time 5 min
Views 21K

Задача


Как часто бывает задачи не вписываются в стандартные возможности доступных инструментов. Так случилось и в этот раз. Далее обрисую задачу.

Имеется несколько удаленных объектов на просторах страны (Украина) электрифицированных, но не имеющих простых технических возможностей для подключения интернета. Объекты, как правило, расположены так что про 3G или WiMax заикаться не приходится. Доступен только GPRS. Нужно иметь возможность мониторить температуру в нескольких помещениях этих объектов. Причем желательно если не в реальном времени то с минимальной задержкой. Усложняется все еще тем что объекты хоть и недвижимость, но возможны ситуации что будет переезд. Поэтому капитальные методы установки оборудования отпадают.

То есть хорошо бы иметь такой комплекс который без труда можно перенести на новое место, воткнуть в розетку и развесив датчики забыть про него. Я хорошо отдаю себе отчет в том что сей час рынок переполнен подходящими решениями, но как всегда есть ложка дегтя — это цена в данном случае. Плюс нередко подобные решения идут со своим ПО. И если не дай бог вам надо что-то в нем изменить то дальше я вам рассказывать не буду, многие наверно общались сами на подобные темы с службами поддержки.




Оборудование


Так случилось что в связи с другим проектом у меня на столе лежал GPS трекер, примерно вот такой — habrahabr.ru/post/100747 Их особенность в том что они реализованы с использованием модулей итальянской фирмы Telit. Эта фирма выпускает как GPS-GSM модули так и просто GSM. Особенность этих модулей в том что у них есть внутри Python. То есть они могут выполнять скрипты. И естественно что из Python доступны все устройства и ресурсы модуля. Понимаете к чему все идет?)

Многие трекеры имеют возможность прямого подключения датчиков, но во первых датчики не установишь на значительно расстоянии, а во вторых их количество ограничивается двумя — четырьмя. По этому я пошел другим путем. К счастью у трекера есть еще и COM порт. А вот с его помощью уже можно опрашивать практически любое оборудование для стационарных SCADA систем.

Тут стоит заметить что так как модули Telit почти все имеют Python на борту и скрипты написанные для одного модуля с минимальными изменениями будут работать на другом. Просто если модуль не имеет например GPS то надо проявить недюжинную смекалку и не пытаться его использовать в скрипте.

Писал и тестировал скрипт на трекере, а потом уже был закуплен модем gprs-modem.ru/product/gsm-modem-teleofis-rx108-r-rs485-s-opciej-kreplenie-na-din-rejku на модуле Telit GL868-Dual и все заработало буквально сразу!

Также неподалеку валялся модуль аналогового ввода фирмы «ОВЕН» МВА-8 www.owen.ru/catalog/95286354.



Это простой модуль ввода аналоговых сигналов на 8 датчиков. Поддерживает протоколы Modbus (ASCII, RTU), DCON, ОВЕН. Вот только трекер и Python не знает о таких протоколах. Придется обучать.

Связь между устройствами идет по RS485 и поэтому они могут взаимно располагаться друг от друга на значительном расстоянии. Кроме того сами датчики могут располагаться довольно далеко от МВА-8.

Реализация


С модулями Telit работать довольно просто. Написанный скрипт загружаем в модуль и отмечаем для выполнения. Доки по АТ командам и функциям Python можно найти тут www.telit.com/en/products/gsm-gprs.php?p_id=12&p_ac=show&p=47 GL865-DUAL — модуль в формате SMT и платформа модуля аналогична GE865-QUAD. Просто его немного допилили для наших стран.



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

Хочу отметить что когда вы скачаете документацию обязательно проверьте что она подходит для конкретной версии прошивки вашего модуля. Это серьезные грабли. Можно долго и нудно искать баг, а окажется что просто функция не поддерживается. Поддерживаемые версии прошивок можно найти с самого начала инструкции.

Я не буду пересказывать все что написано в доках. Там все доступно. Если вкратце то мы имеем в распоряжении несколько устройств на борту как-то: MDM, MDM2, SER, SER2, MOD, GPS(если есть). Думаю по названию вы догадались что есть что. И в итоге все сводится к тому что мы через SER опрашиваем МВА8 и пробуем отослать это через MDM (модем) себе на сервер, а если не получилось то складываем данные в файл истории до лучших времен.

MDM и MDM2 это не два модема и просто два интерфейса одного и того же модема. Для чего? Это вы узнаете если захотите реализовать нечто подобное.

Теперь по порядку. Как организовать работу с модемом можно посмотреть выше по ссылке где я приводил пример трекера. Остается опрос МВА8. Им и займемся.

Мне не повезло у меня оказался старый МВА8 и он поддерживал только собственный протокол ОВЕН. Это протокол вызвал у меня сильное удивление. Зачем так мудрить мне осталось не понятно, но реализовать опрос на нем у меня получилось. Вам не придется уходить с головой в протокол. Приведу тут уже готовые функции опроса и подсчета контрольной суммы. Прошу не бить ногами, это первое что я писал на Python. Кстати Python там хоть и 1.5.2 но сильно урезанный. Например в нем отсутствуют как явление числа с плавающей запятой. Поэтому обязательно читайте доки.

Функция для подсчета контрольной суммы:

def Crc16Owen(buffer):
    CRC = 0x0000    
    for j in range(0,len(buffer)):
        byte = ord(buffer[j])       
        for i in range(0,8):       
            if ((byte^(CRC>>8))&0x80):
                CRC = (CRC & 0x7FFF) << 1
                CRC = CRC ^ 0x8F57
            else :
                CRC= (CRC & 0x7FFF) << 1
            byte = (byte&0x7F) << 1
    return CRC


Функция для перевода строк ОВЕН в нормальный вид:

def OwenToHex(S):
    Sr=''
    for i in range(1,len(S)-1,2):
        a = ((ord(S[i])+0x09) << 4) & 0xF0
        b =  (ord(S[i+1])+0x09)&0x0F
        Sr = Sr + chr(a+b)
    return Sr


Функция опроса МВА8 имеющего адрес №8:

ToMva8Request = ['#GOHGONOKHTVU\r',
                 '#GPHGONOKINGG\r',
                 '#GQHGONOKMOGI\r',
                 '#GRHGONOKLIVS\r',
                 '#GSHGONOKVMGM\r',
                 '#GTHGONOKSSVO\r',
                 '#GUHGONOKOJVQ\r',
                 '#GVHGONOKRPGK\r']

def GetMva8Data():
    Mva8Data = ''
    
    SER.receive(5) #Выгребаем мусор из буфера чтения
    
    for i in range(0,len(ToMva8Request)):
        
        ValCurSensor = FFFFFFh + chr(0xf1) #Сообщение что получен фарш
        SER.send(ToMva8Request[i])
        MOD.sleep(20)
        SRcv = SER.receive(10)
        if len(SRcv)==0:
            ValCurSensor = FFFFFFh + chr(0xf3) #Нет ответа от MVA8
        else:
            if len(SRcv) > 13:
                SRcv = OwenToHex(SRcv) 
                if (ord(SRcv[-2])*0x100+ord(SRcv[-1])) == Crc16Owen(SRcv[:-2]):
                    if (len(SRcv)==7):
                        ValCurSensor = FFFFFFh + SRcv[4]
                    if (len(SRcv)==12):
                        ValCurSensor = SRcv[4:8]
                else:
                    ValCurSensor = FFFFFFh + chr(0xf2) #Ошибка CRC пакета OWEN
        Mva8Data = Mva8Data + ValCurSensor

    Mva8Data = ShortImei + Mva8Data
    Mva8Data = Ascii2Bin("%08x"%MOD.secCounter()) + Mva8Data
    Mva8Data = Mva8Data + Ascii2Bin("%04x"%Crc16Owen(Mva8Data))
        
    return Mva8Data


Хочу еще раз напомнить что прежде чем орать на меня благим матом стоит разобраться в тонкостях встроенного питона, там много заморочек.

Есть несколько ограничений. Например места под скрипты и прочие файлы всего 2 Мb. Но для файла истории хватает. Также работа с файлами очень медленна и холодный старт такого логера длится около 1,5 минуты. Организовать опрос чаще чем раз в 30 секунд конечно можно, но придется этим заниматься. Так как меня устраивает опрос раз в 5 минут меня эта проблема не коснулась. И еще не стоит забывать про то что мы используем память которая имеет ограниченное количество перезаписей. Если ваш логер будет лупить данные постоянно в одну и туже ячейку то вам памяти хватит аж на два месяца, после чего будут сбои. Но реализовать файл истории таким образом чтоб запись велась все время в разные ячейки возможно, что и было реализовано. Расчетное время использования памяти в таком режиме получилось около 500 лет., если опираться на данные от производителей памяти.

У модема есть один минус — он сбрасывает часы при отключении питания, пришлось организовывать получение времени с сервера.

И кстати я знаю что существуют такие же умные модемы Siemens, но Telit мне нравится больше. И есть другие причины но не будем они них тут.

Ну, а теперь о главном — цене.

Модем — 2 950 руб.
МВА8 — 4 189,00 руб.
Датчики + провода сами приплюсуйте.

По моему довольно дешево получилось. И не стоит забывать что все это можно легко перенести и установить в другом месте.

P.S. Основная идея в том что модем выполняет не только функции модема, но и функции мастера который опрашивает оборудование и функции хранилища. И не нужно использовать отдельный, даже минимальный, буферный сервер.
Tags:
Hubs:
+9
Comments 21
Comments Comments 21

Articles