Pull to refresh

GPS мониторинг авто или домашнее задание на вечер

Reading time6 min
Views73K
Здравствуйте! Однажды, задумавшись о безопасности своего автомобиля, я прошелестел достаточно много ресурсов с информацией об автомобильных противоугонных системах в том числе и с GPS. Но все было либо не то, что нужно, либо достаточно дорого, да и сопутствующие сервисы мне особым функционалом не нравились, да и признаться есть доля паранойи во мне. В общем, главной отпугивающей причиной для меня стало — делить с кем-то информацию о своем местоположении. В итоге была куплена обычная сигнализация с авто запуском и обратной связью, но речь сейчас немного о другом.

Все же мысли о сохранении информации о положении авто у меня крутились в голове, да и хотелось просто найти интересное занять на досуг. НА этих мыслях я решился на покупку т. н. персонального GPS — трекера. Особо к моделям не присматривался, у все примерно одно и тоже, но очень важной особенностью такой как настройка на собственный сервер обладали не многие из перебранных кандидатов. В итоге мой выбор пал на персональный GPS трекер китайской компании Xexun — Xexun TK102-2. После еще нескольких часов выискивания как все настраивается и кучи различных мануалов я решил, что нужно уже купить и посмотреть что это такое. Кому интересна информация о трекере и о написании собственного «сервера» для трекера, прошу подкат.


На формах разных компаний, предоставляющие услуги GPS мониторинга, писали и предупреждали что гуляет куча подделок и что есть вероятность нарваться на них, что якобы внешне не отличить и т. д., если вы не приоритете товар у них, но я пошел проверенным путем и заказал приблуду на ebay, пришлось правда подождать 4 недели, ну да ладно — пришел.

Кратко о трекере:
Стандарт связи: GSM 850, GSM 900, GSM 1800, GSM 1900
GPS-чипсет: SiRF Star III
Спутниковая система навигации: GPS
Технические характеристики:
Чувствительность отслеживания: -159 dBm
«Горячий» старт 2 секунды
«Холодный» старт 35 секунд
Точность 5 метров
Рабочая температура от -10 до +65 С°

Функции
Удаленное управление SMS
Контроль скорости, начала передвижения
Сигнал «низкий уровень заряда»

Габариты и вес
Длина 64 мм
Ширина 46 мм
Толщина 17 мм
Вес 50 г

Память
Поддержка карт памяти SD
Передача данных GPRS

Горячие клавиши и индикация
Тревожная кнопка: отправка текущих координат, отправка сигнала SOS через SMS
Индикация: зеленый светодиод

Аккумулятор
Тип аккумулятора Li-ion
Емкость аккумулятора 860 мАч
Время работы в обычном режиме до 12 часов
Время работы в режиме ожидания до 80 часов

Пришел девайс в такой коробочке, которая, кстати говоря, была довольно не плохо сделана.



Само же устройство выполнено из приятного на ощупь прорезиненного пластика.



Вид изнутри с уже установленной симкой.


В комплекте так же лежало зарядное для сменного аккумулятора и для самого трекера.


Очень жаль, что в коробке небыло никакого ПО для проверки работоспособности трекера, но благо есть сервисы которые позволяют относительно просто для простого (извиняюсь за тавтологию) человека зарегистрировать и себя и девайс и посмотреть как это все работает, но это не для меня об этом я писал в начале топика.

Итак, пришло время испытаний. Не долго думая я вышел на балкон и запустил трекер, прочитав инструкцию я попытался настроить его, но мне давалось это с переменным т. к. инструкция была написана очень не грамотно, много опечаток, причем опечаток в самих командах для отправки на трекер, поэтому я нашел русский вариант и настройка прошла быстро и без ошибок.

Первым делом я опробовал опросить трекер по смс — получил координаты и мигом проверил в картах — отлично, следующий этап это настройка на свой сервер, но т. к. у меня сервера своего нет, а есть белый IP я недолго думая написал консольное приложение на C# и решил посмотреть, что там приходит с трекера, а с трекера приходила следующая строка:
«130402213013,+79637**3***,GPRMC,173013.000,A,6146.4979,N,03421.2399,E,1.92,21.48,020413,,,A*5B,F,, imei:*************,00,-16.4,F:3.73V,0,139,49646,250,99,1478,68A7\n\r»

Звездочки в полях с номером телефона (2) и в поле imei я написал специально.
Собственно описание этой строки было и в самой инструкции, но не всей полностью, кое с чем пришлось по разбираться например: выяснить что такое за GPRMC, но и это тоже не сложно т.к. информации полно.

Одним из основных непонятных моментов для меня стало то, что координаты приходят не совсем точно несколько десятков километров в сторону, хотя тут же приходит смс с нормальными координатами. Это доставляло не мало раздражения, потому что к тому моменту я уже написал небольшую программку которая все парсит и сохраняет в xml файл (об этом чуть позже). Решение не лежало на поверхности, потому что я просто не понимал как сформулировать запрос в Google чтобы найти нужную информацию в итоге несколько дней в подряд я читал различные технические спецификации о морской и не только навигации и статьи о работе GPS приемников. Оказалось все достаточно просто координаты приходили в формате WGS-84 и их необходимо было перевести в «обычные» т. е. те, которые подойдут например Яндекс Картам. Собственно с приходом «WGS-84» круг сузился и тут же нашлись формулы и все посчиталось.

Отдельно, хочу написать о программке, которой я занимался по вечерам, для того чтобы принимать данные с трекера. Я выбрал язык c# как наиболее удобный для себя, в универе лабы предпочитал делать на нем в силу его кажущейся простоты, однако. Однако, все чему учили в универе и чему я учился сам — не пригодилось в данном проекте. Например о многопоточности я не слышал ни разу в курсе о C#. Да да. Работы с сетью не было тоже. В общем пришлось разбираться и читать все самому.

Обо всем по порядку.
Для начала стартует метод ServerStart, который заставляет слушать входище соедения, за одно запускает метод, который порождает новый поток который ожидает «клиентов». При подключении клиента порождается еще один поток, который принимает данные с трекера. Все достаточно просто.
        public void ServerStart()
        {
            isServerRunning = true;
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // Определяем конечную точку, IPAddress.Any означает что наш сервер будет принимать входящие соединения с любых адресов
            Point = new IPEndPoint(IPAddress.Any, port);
            // Связываем сокет с конечной точкой
            listener.Bind(Point);
            // Начинаем слушать входящие соединения
            listener.Listen(10);

            socketAccepter();
        }

public void socketAccepter()
        {
            // Запускаем цикл в отдельном потоке, чтобы приложение не зависло
            Thread th = new Thread(delegate()
            {
                while (isServerRunning)
                {
                    // Создаем новый сокет, по которому мы сможем обращаться клиенту
                    // Этот цикл остановится, пока какой-нибудь клиент не попытается присоединиться к серверу
                    Socket client = listener.Accept();

                    //client.ReceiveTimeout = 20000;
                    // Теперь, обратившись к объекту client, мы сможем отсылать и принимать пакеты от последнего подключившегося пользователя.
                    // Добавляем подключенного клиента в список всех клиентов, для дальнейшей массовой рассылки пакетов
                    clients.Add(client);

                    // Начинаем принимать входящие пакеты
                    Thread thh = new Thread(delegate()
                    {
                        messageReciever(client);
                    });

                    thh.Name = "Recieving bags " + DateTime.Now.ToString();
                    thh.Start();
                    threads.Add(thh);
                }
            });
            th.Name = "Accepting Connecton " + threads.Count;
            th.Start();
            threads.Add(th);
        }


Метод который, принимает сообщения. Много раз слышал «За бесконечные циклы нужно сжигать на костре», в виду своей не опытности или правильней сказать не грамотности в данном вопросе, решил пока что использовать так, потом после прочтения нужной литературы попробую написать так как это было бы правильно. Хотя на самом деле я не заметил, чтобы у меня начиналось пожирание процессора, были моменты когда одно ядро полностью загружалось процессом ввиду этого цикла, но после я отладил и стал использовать метод Recieve который останавливает выполнение потока до тех пор пока не придет сообщение от трекера, в общем используется та же самая логика что и с listener.Accept().

        public void messageReciever(Socket client)
        {
            int i = 0, av = 0;
            double t = 0;
            string[] data;
            string[] messages;
            char[] spliter = { '\n', '\r' };
            string message = "";
            
            while (isServerRunning && client.Connected == true)
            {
                try
                {
                    // Сюда будем записывать принятые байты
                    byte[] bytes = new byte[2048];
                    // Принимаем
                    av = client.Receive(bytes);
                    if (av != 0)
                    {

                        message = Encoding.UTF8.GetString(bytes).Remove(av);
                        messages = message.Split(spliter, System.StringSplitOptions.RemoveEmptyEntries);
                        for (i = 0; i < messages.Length; i++)
                        {
                            data = messages[i].Split(',');
                            if (double.TryParse(data[0], out t))
                                saver.parseData(data);
                            //else
                                //MessageBox.Show(messages[i].ToString());

                        }
                    }
                    else
                    {
                        continue;
                    }

                }
                catch //(Exception e)
                {
                    //MessageBox.Show(e.Message + " " + e.StackTrace, "Метод Message Reciever");
                }
            }
            threads.Remove(Thread.CurrentThread);
            Thread.CurrentThread.Abort();
        }


На это в общем то и хочу закончить, единственное что я хочу дополнить, так это, что от сохранения данных в xml файл я решил отказаться, т. к. толком не разобрался как синхронизировать потоки между собой и часто получалось, что файл был открыл одним потоком, а к нему пытается достучаться уже другой поток. Проблему блокировок возложил на СУБД — MySQL. Ах да, парсинг данных разделенных запятой я думаю тоже не нужен в особом представлении, а подключение C# к MySQL достаточно просто и дружелюбно происходит, тем более что MySQL предоставляет все коннекторы.

На данный момент, я планирую расширить функционал этого приложения и накидать веб морду для того чтобы начать все-таки визуализировать перемещения. С веб мордой тоже есть определенные трудности, а именно: определился какие карты использовать, ну собственно изучение API карт. Опыта работы с API каких либо карт нет, но думаю в неспешном порядке так же вечерами все и будет изучаться.

Спасибо тем кто прочел, и отдельное спасибо НЛО.

Приложение
Tags:
Hubs:
Total votes 39: ↑33 and ↓6+27
Comments41

Articles