четверг, 1 июля 2010 г.

СМС оповещения из QUIK

Дошли наконец-то руки сделать эту полезную, на мой взгляд, фичу для работы с терминалом QUIK. Итак, что для этого нам понадобится:
  1. Сервер рассылки СМС сообщений
  2. GSM модем или мобильный телефон с возможностью подключения к компьютеру. Желательно чтобы телефон умел работать с сообщениями в PDU-формате. Скорее всего другого телефона уже просто не найти, если только не задаться целью использовать очень старую модель.
  3. Небольшой скрипт на QPILE для демонстрации работы.
Сервер рассылки СМС сообщений
С огромным удовольствием обнаружил что мой любимый SMS Server замечательно портируется на платформу Windows с помощью пакета Cygwin. Скачиваем этот пакет, устанавливаем. В процессе установки добавляем следующие пакеты:
  • gcc 
  • make 
  • gcc-g++
  • cygrunsrv
Подробную инструкцию по установке, настройке и запуску можно найти здесь
Если все получилось, и сервер заработал как сервис в системе то можно попробовать отправить сообщение. Для этого нужно создать текстовый файл содержащий примерно следующее:

To: 79131234567

SMS text

Первая строчка - номер телефона без '+', затем идет текст сообщения.
При запущенном сервисе надо скопировать этот файл в каталог
"C:\cygwin\var\spool\sms\outgoing\"
Сервис проверит сообщение и отправит СМС с текстом "SMS text". Все просто.
Теперь пример простого скрипта на QPILE, который будет сообщать нам о потери связи с сервером QUIK.

PORTFOLIO_EX sms;
DESCRIPTION sms;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST FIRM_ID;
USE_CASE_SENSITIVE_CONSTANTS
PROGRAM
 
file_path="C:\cygwin\var\spool\sms\outgoing\"
 
uids=create_map()

FUNC gen_file_name(time)
    result=""
    if(len(get_value(time, "HOUR")) <2 )
        result = result & "0" & get_value(time, "HOUR")
    else 
        result = result & get_value(time, "HOUR")
    end if
    if(len(get_value(time, "MIN")) <2 )
        result = result & "0" & get_value(time, "MIN")
    else 
        result = result & get_value(time, "MIN")
    end if
    if(len(get_value(time, "SEC")) <2 )
        result = result & "0" & get_value(time, "SEC")
    else 
        result = result & get_value(time, "SEC")
    end if
    result = result & get_value(time, "MILLISEC")
    result = result & ".msg"
end func
 
FUNC send_sms(phone_number, text, prefix)
    result=""
    error=0
    file_name=file_path & prefix & "_"  & gen_file_name(get_datetime())
    writeln(file_name, "To: " & phone_number)
    writeln(file_name, "")
    writeln(file_name, text)
END FUNC
 
    new_global("count", 1)
    new_global("state", 1)
    new_global("line", 1)
 
    phone1="79131234567"
    phone1="79131234568"

    string=""
    info_param=""
    info_param=get_info_param("USERID")
    new_state=0
    new_state = is_connected()
    if (state != new_state)
        str_state=""
        if(new_state == 0)
            str_state = "disconnected. "
        else
            str_state = "is connected. "
        end if
        str_state = str_state & & "USERID:" & info_param
        
        sms_text = "QUIK " & str_state
 
        send_sms(phone1, sms_text, phone1)
        send_sms(phone2, sms_text, phone2)
        state = new_state
        string=set_value(string, "SMS", "SMS: " & sms_text & " sent" )
        add_item(line, string)
        line = line + 1
    end if

END_PROGRAM
 
PARAMETER SMS;
PARAMETER_TITLE SMS;
PARAMETER_DESCRIPTION SMS;
PARAMETER_TYPE STRING(255);
END

END_PORTFOLIO_EX



В скрипте имя файла для сообщения генерируется из системного времени машины с точностью до миллисекунд, этим должно гарантироваться уникальное имя файла. Но если идет одновременная отправка на несколько номеров, то такой фокус не проходит. Скрипт на QPILE выполняется очень быстро :) В результате несколько сообщений пишутся в один файл. Чтобы этого избежать, в функцию send_sms() добавлен префикс имени файла в виде номера телефона.
В результате работы скрипта смс-ки будут отправляться на два номера при любом смене состояния подключения - при разрыве и при восстановлении связи.
Ну и напоследок еще немного вкусного. Сервер не только отправляет смс-ки, но и читает входящие сообщения. Для себя я написал нехитрый парсер сообщений, и теперь могу получать необходимые данные из QUIK на мобильный телефон по запросу. Например могу посмотреть текущее состояние денежных средств или позиций.
Описание тут конечно очень краткое, но в целом понятно, что дальнейшее развитие темы ограничено только фантазией разработчика. Например можно папку для исходящих сообщений сделать доступной по сети и использовать сервер рассылки сообщений из терминалов работающих на разных машинах.
Have fun, что называется :)