Инструменты пользователя

Инструменты сайта


sharixopen:knowledge:scenarios:teltonika_gps_tracker

Это старая версия документа!


Приёмник Teltonika open_teltonika_gps_tracker

Область: ShariX Open. Обработчик: open_teltonika_gps_tracker, системный first-party handler без типа/рабочего статуса Ticket. Проверено 29.10.2026: опубликованный Python побайтово совпадает с каноническим first-party Blockly renderer. Сеть, устройства, runtime version и фактические env конкретного сервера отдельно не проверялись.

Назначение и канонический контракт

Handler запускает пример UDP-приёмника AVL-пакетов: получает датаграмму, разбирает её, пишет читаемую диагностику и отвечает устройству. Условно доступна запись GPX и отдельных AVL-файлов. В этом пути нет записи координат в Orders/Provider/Ticket, интеграции с картой или автоматического изменения статуса заказа.

В Blockly зафиксирована typed operation teltonika_udp_receiver. Сгенерированный Python вызывает binding; runtime сверяет точную program tuple с каталогом и загружает first_party_operations/open_teltonika_gps_tracker.py. Бизнес-детали находятся также в catcher/decoder/GPX recorder, поэтому они включены в источники сценария. Совпадение generated wrapper не заменяет анализа вложенной operation.

BPMN описательные, isExecutable=false; исполняется Python из Blockly, а не JSON/XML Wiki. Сценарий описывает текущий пример, не обещает поддержку всех вариантов протокола Teltonika.

Запуск и UDP loop (BPMN)

Схема BPMN

Загрузка схемы…

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_teltonika_startup" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="udp_Process_udp" name="open_teltonika_gps_tracker: XMPP bootstrap и UDP loop" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false; typed operation teltonika_udp_receiver из Blockly, Python сверён канонически.", "Штатный binding requires_xmpp=True: UDP запускается после XMPP connection preflight.", "GPX и отдельные AVL файлы по умолчанию выключены в этом binding; интерактивный catcher main не вызывается.", "ACK из raw byte slices не доказывает успешное сохранение всех точек."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker.py", "repository": "sharix-open-handlers-examples", "sha256": "176dc8e04c8370481da568124f7e5a27a5418592a3947f718986b042b4a5e083"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_teltonika_gps_tracker.json", "repository": "sharix-open-handlers-examples", "sha256": "a44f034cf10fe311ba6775c8c3579bd14448dc95c9c8ef08fa699c5c2b13ef2d"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "first_party_operations/open_teltonika_gps_tracker.py", "repository": "sharix-open-handlers-examples", "sha256": "d8c766ceecb6eabdd24bccc0d0f6e9ddcab1fc3b8dab7432b1cf6a0dbda27e86"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "config.py", "repository": "sharix-open-handlers-examples", "sha256": "7b23db9ed283d3bbc3cf2cfbd5d41c629f6be507c3ca38c611572d08a75743a4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "first_party_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "7f4dc6607ad62f3150c58de6341b758ebe97f81bd936c9ec033b7d86fed44640"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/first_party_handler_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "fb5ee98561b029de9291e73c2a08205cc9fc2b7b239abffe4a4bb24f56093bdb"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "main.py", "repository": "sharix-open-handlers-backend", "sha256": "66b7df94fedbec931ed4cb2d4e1afd9cf0386e14ed0932e22b15eb301cd792d7"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "runtime_provider.py", "repository": "sharix-open-handlers-backend", "sha256": "c311d3b0721d18d8eccc9cd7fba155108bf285df3002507ee915ee73b797a2f4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/JabberBot.py", "repository": "sharix-open-handlers-backend", "sha256": "7fbd4d1f41bc867109b73dbb632efcfae920269a1aaf6da0e577cc70838820f1"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "teltonika_config.py", "repository": "sharix-open-handlers-examples", "sha256": "37b1abca5f520f89812e0c0f02c0386511a69553ace5e9cf29243d0ad3d7fb0d"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/catcher.py", "repository": "sharix-open-handlers-examples", "sha256": "f99e418651e38d15bf198e5cd8fb547d97fc084a7bd330e88f9bb9a8e0cdf6dd"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/decoder.py", "repository": "sharix-open-handlers-examples", "sha256": "e5420416a997acfabf29ae0942d8fa95b52890cec71d036f39d9164c210942d3"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/gpx_recorder.py", "repository": "sharix-open-handlers-examples", "sha256": "fa7cbabbfe354fade58e2d9b16195df911755dc49489c405fad389a38abb1b38"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/config_importer.py", "repository": "sharix-open-handlers-examples", "sha256": "3b2ca95e371bdf92dad65a7a9bd4befd0682f0c8ea03212c94b1c2678376c5df"}]}</bpmn:documentation>
    <bpmn:laneSet id="udp_Lanes_udp">
      <bpmn:lane id="udp_Lane_worker" name="Выбранный Python binding, не отдельный запуск catcher.main">
        <bpmn:flowNodeRef>udp_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_xmpp</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_socket</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_stop</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_close</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_receive</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_result</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_repeat</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>udp_error</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="udp_start" name="Штатный launcher, typed binding">
      <bpmn:outgoing>udp_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:serviceTask id="udp_xmpp" name="XMPP connect preflight; callback и supervisor">
      <bpmn:incoming>udp_Flow_0</bpmn:incoming>
      <bpmn:outgoing>udp_Flow_1</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="udp_socket" name="AF_INET/SOCK_DGRAM, reuseaddr, timeout=1s, bind env host/port">
      <bpmn:incoming>udp_Flow_1</bpmn:incoming>
      <bpmn:outgoing>udp_Flow_2</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="udp_stop" name="exit_event установлен?">
      <bpmn:incoming>udp_Flow_2</bpmn:incoming>
      <bpmn:outgoing>udp_Flow_3</bpmn:outgoing>
      <bpmn:outgoing>udp_Flow_4</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="udp_close" name="Да: finally закрывает socket, затем XMPP">
      <bpmn:incoming>udp_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="udp_receive" name="receive_and_print: recvfrom(1024), parse, optional write, ACK">
      <bpmn:incoming>udp_Flow_4</bpmn:incoming>
      <bpmn:outgoing>udp_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="udp_result" name="Чем закончился вызов?">
      <bpmn:incoming>udp_Flow_5</bpmn:incoming>
      <bpmn:outgoing>udp_Flow_6</bpmn:outgoing>
      <bpmn:outgoing>udp_Flow_7</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="udp_repeat" name="Успех/обычный timeout: следующий проход loop">
      <bpmn:incoming>udp_Flow_6</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:endEvent id="udp_error" name="Иное исключение: socket finally close; общий restart policy">
      <bpmn:incoming>udp_Flow_7</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="udp_Flow_0" sourceRef="udp_start" targetRef="udp_xmpp" name="" />
    <bpmn:sequenceFlow id="udp_Flow_1" sourceRef="udp_xmpp" targetRef="udp_socket" name="" />
    <bpmn:sequenceFlow id="udp_Flow_2" sourceRef="udp_socket" targetRef="udp_stop" name="" />
    <bpmn:sequenceFlow id="udp_Flow_3" sourceRef="udp_stop" targetRef="udp_close" name="Да" />
    <bpmn:sequenceFlow id="udp_Flow_4" sourceRef="udp_stop" targetRef="udp_receive" name="Нет" />
    <bpmn:sequenceFlow id="udp_Flow_5" sourceRef="udp_receive" targetRef="udp_result" name="" />
    <bpmn:sequenceFlow id="udp_Flow_6" sourceRef="udp_result" targetRef="udp_repeat" name="Возврат / timeout" />
    <bpmn:sequenceFlow id="udp_Flow_7" sourceRef="udp_result" targetRef="udp_error" name="Иное исключение" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_teltonika_startup">
    <bpmn:participant id="udp_Pool_udp" name="open_teltonika_gps_tracker: XMPP bootstrap и UDP loop" processRef="udp_Process_udp" />
    <bpmn:participant id="device_Participant" name="GPS-устройство: UDP датаграммы к настроенному endpoint" />
    <bpmn:messageFlow id="Message_teltonika_startup_0" sourceRef="device_Participant" targetRef="udp_receive" name="UDP трафик отделён от XMPP; готовность XMPP не доказывает приход UDP" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_teltonika_startup">
    <bpmndi:BPMNPlane id="Plane_teltonika_startup" bpmnElement="Collaboration_teltonika_startup">
      <bpmndi:BPMNShape id="udp_DI_Pool_udp" bpmnElement="udp_Pool_udp" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="2150" height="440" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_Lane_worker" bpmnElement="udp_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="2120" height="440" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_start" bpmnElement="udp_start">
        <dc:Bounds x="132.0" y="82.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_xmpp" bpmnElement="udp_xmpp">
        <dc:Bounds x="365.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_socket" bpmnElement="udp_socket">
        <dc:Bounds x="675.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_stop" bpmnElement="udp_stop">
        <dc:Bounds x="1035.0" y="75.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_close" bpmnElement="udp_close">
        <dc:Bounds x="1042.0" y="322.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_receive" bpmnElement="udp_receive">
        <dc:Bounds x="1295.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_result" bpmnElement="udp_result">
        <dc:Bounds x="1655.0" y="75.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_repeat" bpmnElement="udp_repeat">
        <dc:Bounds x="1972.0" y="82.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="udp_DI_error" bpmnElement="udp_error">
        <dc:Bounds x="1662.0" y="322.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="udp_DI_Flow_0" bpmnElement="udp_Flow_0">
        <di:waypoint x="168.0" y="100.0" />
        <di:waypoint x="365.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_1" bpmnElement="udp_Flow_1">
        <di:waypoint x="515.0" y="100.0" />
        <di:waypoint x="675.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_2" bpmnElement="udp_Flow_2">
        <di:waypoint x="825.0" y="100.0" />
        <di:waypoint x="1035.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_3" bpmnElement="udp_Flow_3">
        <di:waypoint x="1060.0" y="125.0" />
        <di:waypoint x="1060.0" y="322.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_4" bpmnElement="udp_Flow_4">
        <di:waypoint x="1085.0" y="100.0" />
        <di:waypoint x="1295.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_5" bpmnElement="udp_Flow_5">
        <di:waypoint x="1445.0" y="100.0" />
        <di:waypoint x="1655.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_6" bpmnElement="udp_Flow_6">
        <di:waypoint x="1705.0" y="100.0" />
        <di:waypoint x="1972.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="udp_DI_Flow_7" bpmnElement="udp_Flow_7">
        <di:waypoint x="1680.0" y="125.0" />
        <di:waypoint x="1680.0" y="322.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="DI_device_Participant" bpmnElement="device_Participant" isHorizontal="true">
        <dc:Bounds x="0" y="650" width="2150" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="DI_Message_teltonika_startup_0" bpmnElement="Message_teltonika_startup_0">
        <di:waypoint x="1800" y="650" />
        <di:waypoint x="2080" y="650" />
        <di:waypoint x="2080" y="30" />
        <di:waypoint x="1370" y="30" />
        <di:waypoint x="1370" y="65" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1550" y="530" width="260" height="42" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Несмотря на UDP-полезную работу, текущий binding имеет requires_xmpp=true и создаёт JabberBot. Общий launcher сначала подключает XMPP, регистрирует callback/supervisor и ждёт connection preflight. При неуспехе UDP loop не начинается. Успешный XMPP connect, напротив, ещё не доказывает доступность UDP endpoint устройству.

Operation создаёт IPv4 UDP socket, включает SO_REUSEADDR, timeout=1.0 секунды и bind на TELTONIKA_HOSTNAME/TELTONIKA_PORT. Пока exit_event не установлен, вызывается receive_and_print. Обычный TimeoutError/socket.timeout продолжает цикл. Иное исключение выходит через finally с закрытием socket и передаётся общей политике рестартов launcher. При штатной остановке loop замечает exit_event между вызовами; затем socket и XMPP закрываются.

В operation нет отдельного TCP listener или IMEI handshake. Закомментированный TCP-код в catcher не является активным путём запуска.

Одна датаграмма: разбор, файлы и ACK (BPMN)

Схема BPMN

Загрузка схемы…

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_teltonika_packet" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="packet_Process_packet" name="Одна датаграмма: decoder, условные файлы и ответ устройству" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false; typed operation teltonika_udp_receiver из Blockly, Python сверён канонически.", "Штатный binding requires_xmpp=True: UDP запускается после XMPP connection preflight.", "GPX и отдельные AVL файлы по умолчанию выключены в этом binding; интерактивный catcher main не вызывается.", "ACK из raw byte slices не доказывает успешное сохранение всех точек."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker.py", "repository": "sharix-open-handlers-examples", "sha256": "176dc8e04c8370481da568124f7e5a27a5418592a3947f718986b042b4a5e083"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_teltonika_gps_tracker.json", "repository": "sharix-open-handlers-examples", "sha256": "a44f034cf10fe311ba6775c8c3579bd14448dc95c9c8ef08fa699c5c2b13ef2d"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "first_party_operations/open_teltonika_gps_tracker.py", "repository": "sharix-open-handlers-examples", "sha256": "d8c766ceecb6eabdd24bccc0d0f6e9ddcab1fc3b8dab7432b1cf6a0dbda27e86"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "config.py", "repository": "sharix-open-handlers-examples", "sha256": "7b23db9ed283d3bbc3cf2cfbd5d41c629f6be507c3ca38c611572d08a75743a4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "first_party_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "7f4dc6607ad62f3150c58de6341b758ebe97f81bd936c9ec033b7d86fed44640"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/first_party_handler_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "fb5ee98561b029de9291e73c2a08205cc9fc2b7b239abffe4a4bb24f56093bdb"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "main.py", "repository": "sharix-open-handlers-backend", "sha256": "66b7df94fedbec931ed4cb2d4e1afd9cf0386e14ed0932e22b15eb301cd792d7"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "runtime_provider.py", "repository": "sharix-open-handlers-backend", "sha256": "c311d3b0721d18d8eccc9cd7fba155108bf285df3002507ee915ee73b797a2f4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/JabberBot.py", "repository": "sharix-open-handlers-backend", "sha256": "7fbd4d1f41bc867109b73dbb632efcfae920269a1aaf6da0e577cc70838820f1"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "teltonika_config.py", "repository": "sharix-open-handlers-examples", "sha256": "37b1abca5f520f89812e0c0f02c0386511a69553ace5e9cf29243d0ad3d7fb0d"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/catcher.py", "repository": "sharix-open-handlers-examples", "sha256": "f99e418651e38d15bf198e5cd8fb547d97fc084a7bd330e88f9bb9a8e0cdf6dd"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/decoder.py", "repository": "sharix-open-handlers-examples", "sha256": "e5420416a997acfabf29ae0942d8fa95b52890cec71d036f39d9164c210942d3"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/gpx_recorder.py", "repository": "sharix-open-handlers-examples", "sha256": "fa7cbabbfe354fade58e2d9b16195df911755dc49489c405fad389a38abb1b38"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_teltonika_gps_tracker_dir/config_importer.py", "repository": "sharix-open-handlers-examples", "sha256": "3b2ca95e371bdf92dad65a7a9bd4befd0682f0c8ea03212c94b1c2678376c5df"}]}</bpmn:documentation>
    <bpmn:laneSet id="packet_Lanes_packet">
      <bpmn:lane id="packet_Lane_worker" name="Без Ticket/Orders/Provider CRUD в этом пути">
        <bpmn:flowNodeRef>packet_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_parse</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_parsed</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_log</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_record</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_gpx</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_ack</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_broken</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_abort</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_gpx_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>packet_ack_error</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="packet_start" name="recvfrom: raw data + sender addr">
      <bpmn:outgoing>packet_Flow_0</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="packet_parse" name="update_data; parse length/header/IMEI/records/IO">
      <bpmn:incoming>packet_Flow_0</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_1</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="packet_parsed" name="parse вернул структуру?">
      <bpmn:incoming>packet_Flow_1</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_2</bpmn:outgoing>
      <bpmn:outgoing>packet_Flow_8</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="packet_log" name="Читаемый logging; отдельный AVL log лишь при write_logs">
      <bpmn:incoming>packet_Flow_2</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="packet_record" name="GPX recorder включён?">
      <bpmn:incoming>packet_Flow_3</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_4</bpmn:outgoing>
      <bpmn:outgoing>packet_Flow_6</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="packet_gpx" name="Добавить точки по IMEI, пропустить (0,0)">
      <bpmn:incoming>packet_Flow_4</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sendTask id="packet_ack" name="answer_to_device из raw slices; sendto(sender addr)">
      <bpmn:incoming>packet_Flow_5</bpmn:incoming>
      <bpmn:incoming>packet_Flow_6</bpmn:incoming>
      <bpmn:incoming>packet_Flow_9</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_7</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:endEvent id="packet_end" name="Следующая датаграмма; бизнес-объект не обновлён">
      <bpmn:incoming>packet_Flow_7</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="packet_broken" name="BROKEN DATA / parse None; GPX не пишется">
      <bpmn:incoming>packet_Flow_8</bpmn:incoming>
      <bpmn:outgoing>packet_Flow_9</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:boundaryEvent id="packet_error" name="Parse / AVL file исключение" attachedToRef="packet_parse" cancelActivity="true">
      <bpmn:outgoing>packet_Flow_10</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:endEvent id="packet_abort" name="Нет нормального ACK; внешний loop завершится с ошибкой">
      <bpmn:incoming>packet_Flow_10</bpmn:incoming>
      <bpmn:incoming>packet_Flow_11</bpmn:incoming>
      <bpmn:incoming>packet_Flow_12</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:boundaryEvent id="packet_gpx_error" name="GPX file исключение" attachedToRef="packet_gpx" cancelActivity="true">
      <bpmn:outgoing>packet_Flow_11</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="packet_ack_error" name="sendto исключение" attachedToRef="packet_ack" cancelActivity="true">
      <bpmn:outgoing>packet_Flow_12</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:sequenceFlow id="packet_Flow_0" sourceRef="packet_start" targetRef="packet_parse" name="" />
    <bpmn:sequenceFlow id="packet_Flow_1" sourceRef="packet_parse" targetRef="packet_parsed" name="" />
    <bpmn:sequenceFlow id="packet_Flow_2" sourceRef="packet_parsed" targetRef="packet_log" name="Да" />
    <bpmn:sequenceFlow id="packet_Flow_3" sourceRef="packet_log" targetRef="packet_record" name="" />
    <bpmn:sequenceFlow id="packet_Flow_4" sourceRef="packet_record" targetRef="packet_gpx" name="Да" />
    <bpmn:sequenceFlow id="packet_Flow_5" sourceRef="packet_gpx" targetRef="packet_ack" name="" />
    <bpmn:sequenceFlow id="packet_Flow_6" sourceRef="packet_record" targetRef="packet_ack" name="Нет" />
    <bpmn:sequenceFlow id="packet_Flow_7" sourceRef="packet_ack" targetRef="packet_end" name="" />
    <bpmn:sequenceFlow id="packet_Flow_8" sourceRef="packet_parsed" targetRef="packet_broken" name="Нет" />
    <bpmn:sequenceFlow id="packet_Flow_9" sourceRef="packet_broken" targetRef="packet_ack" name="" />
    <bpmn:sequenceFlow id="packet_Flow_10" sourceRef="packet_error" targetRef="packet_abort" name="" />
    <bpmn:sequenceFlow id="packet_Flow_11" sourceRef="packet_gpx_error" targetRef="packet_abort" name="" />
    <bpmn:sequenceFlow id="packet_Flow_12" sourceRef="packet_ack_error" targetRef="packet_abort" name="" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_teltonika_packet">
    <bpmn:participant id="packet_Pool_packet" name="Одна датаграмма: decoder, условные файлы и ответ устройству" processRef="packet_Process_packet" />
    <bpmn:participant id="device_Participant" name="UDP-устройство: ACK транспортного примера, не receipt БД/GPX" />
    <bpmn:messageFlow id="Message_teltonika_packet_0" sourceRef="packet_ack" targetRef="device_Participant" name="packet ids и count извлечены из raw bytes, не из фактически сохранённых точек" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_teltonika_packet">
    <bpmndi:BPMNPlane id="Plane_teltonika_packet" bpmnElement="Collaboration_teltonika_packet">
      <bpmndi:BPMNShape id="packet_DI_Pool_packet" bpmnElement="packet_Pool_packet" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="2150" height="680" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_Lane_worker" bpmnElement="packet_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="2120" height="680" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_start" bpmnElement="packet_start">
        <dc:Bounds x="132.0" y="82.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_parse" bpmnElement="packet_parse">
        <dc:Bounds x="365.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_parsed" bpmnElement="packet_parsed">
        <dc:Bounds x="725.0" y="75.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_log" bpmnElement="packet_log">
        <dc:Bounds x="985.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_record" bpmnElement="packet_record">
        <dc:Bounds x="1345.0" y="75.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_gpx" bpmnElement="packet_gpx">
        <dc:Bounds x="1605.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_ack" bpmnElement="packet_ack">
        <dc:Bounds x="1605.0" y="305.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_end" bpmnElement="packet_end">
        <dc:Bounds x="1972.0" y="322.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_broken" bpmnElement="packet_broken">
        <dc:Bounds x="675.0" y="545.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_error" bpmnElement="packet_error">
        <dc:Bounds x="472.0" y="117.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_abort" bpmnElement="packet_abort">
        <dc:Bounds x="422.0" y="562.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_gpx_error" bpmnElement="packet_gpx_error">
        <dc:Bounds x="1712.0" y="117.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="packet_DI_ack_error" bpmnElement="packet_ack_error">
        <dc:Bounds x="1712.0" y="357.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="packet_DI_Flow_0" bpmnElement="packet_Flow_0">
        <di:waypoint x="168.0" y="100.0" />
        <di:waypoint x="365.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_1" bpmnElement="packet_Flow_1">
        <di:waypoint x="515.0" y="100.0" />
        <di:waypoint x="725.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_2" bpmnElement="packet_Flow_2">
        <di:waypoint x="775.0" y="100.0" />
        <di:waypoint x="985.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_3" bpmnElement="packet_Flow_3">
        <di:waypoint x="1135.0" y="100.0" />
        <di:waypoint x="1345.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_4" bpmnElement="packet_Flow_4">
        <di:waypoint x="1395.0" y="100.0" />
        <di:waypoint x="1605.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_5" bpmnElement="packet_Flow_5">
        <di:waypoint x="1680.0" y="135.0" />
        <di:waypoint x="1680.0" y="305.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_6" bpmnElement="packet_Flow_6">
        <di:waypoint x="1395.0" y="100.0" />
        <di:waypoint x="1490.0" y="100.0" />
        <di:waypoint x="1550.0" y="100.0" />
        <di:waypoint x="1550.0" y="270.0" />
        <di:waypoint x="1680.0" y="270.0" />
        <di:waypoint x="1680.0" y="305.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_7" bpmnElement="packet_Flow_7">
        <di:waypoint x="1755.0" y="340.0" />
        <di:waypoint x="1972.0" y="340.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_8" bpmnElement="packet_Flow_8">
        <di:waypoint x="750.0" y="125.0" />
        <di:waypoint x="750.0" y="545.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_9" bpmnElement="packet_Flow_9">
        <di:waypoint x="825.0" y="580.0" />
        <di:waypoint x="870.0" y="580.0" />
        <di:waypoint x="1100.0" y="580.0" />
        <di:waypoint x="1100.0" y="270.0" />
        <di:waypoint x="1680.0" y="270.0" />
        <di:waypoint x="1680.0" y="305.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_10" bpmnElement="packet_Flow_10">
        <di:waypoint x="508.0" y="135.0" />
        <di:waypoint x="550.0" y="135.0" />
        <di:waypoint x="600.0" y="135.0" />
        <di:waypoint x="600.0" y="510.0" />
        <di:waypoint x="440.0" y="510.0" />
        <di:waypoint x="440.0" y="562.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_11" bpmnElement="packet_Flow_11">
        <di:waypoint x="1748.0" y="135.0" />
        <di:waypoint x="1790.0" y="135.0" />
        <di:waypoint x="1830.0" y="135.0" />
        <di:waypoint x="1830.0" y="630.0" />
        <di:waypoint x="440.0" y="630.0" />
        <di:waypoint x="440.0" y="562.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="packet_DI_Flow_12" bpmnElement="packet_Flow_12">
        <di:waypoint x="1748.0" y="375.0" />
        <di:waypoint x="1790.0" y="375.0" />
        <di:waypoint x="1830.0" y="375.0" />
        <di:waypoint x="1830.0" y="630.0" />
        <di:waypoint x="440.0" y="630.0" />
        <di:waypoint x="440.0" y="562.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="DI_device_Participant" bpmnElement="device_Participant" isHorizontal="true">
        <dc:Bounds x="0" y="900" width="2150" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="DI_Message_teltonika_packet_0" bpmnElement="Message_teltonika_packet_0">
        <di:waypoint x="1680" y="375" />
        <di:waypoint x="1680" y="800" />
        <di:waypoint x="1100" y="800" />
        <di:waypoint x="1100" y="900" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1160" y="755" width="260" height="42" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

receive_and_print делает recvfrom(1024), сохраняет raw bytes и sender addr в decoder, затем вызывает parse_data. Decoder сопоставляет заявленную длину с фактической, извлекает заголовки, IMEI, codec id, records и IO. При успешной структуре формируется читаемый logging-output; отдельный AVL-файл пишется только при write_logs=true.

Если структура возвращена и GPX recorder включён, по IMEI добавляются точки с координатами, высотой и timestamp. Точка (0,0) пропускается. Далее answer_to_device формирует ACK и sendto отправляет его на адрес источника датаграммы.

ACK не равен сохранённой телеметрии

ACK собирается из raw byte slices: UDP packet id, AVL packet id и count по фиксированному смещению. Count не вычисляется по фактически разобранным/сохранённым GPX-точкам. Даже если parse_data вернул None и GPX не выполнялся, catcher продолжает к answer_to_device и sendto, если не было исключения.

Поэтому ACK не доказывает корректность всех координат, запись файла или обновление бизнес-объекта. Исключение декодирования, файловой операции или sendto — другой исход: оно не обрабатывается как обычный socket timeout и может завершить текущий запуск с последующим restart. Разбор не содержит полноценного fail-closed валидатора всех возможных форматов/codec; IMEI извлекается как данные, а не сопоставляется здесь с разрешённым устройством в БД.

Лимит recvfrom — 1024 байта. Для диагностики длинных/повреждённых пакетов учитывайте этот предел и реальный формат входа, а не только факт получения UDP. Сценарий не объявляет универсальную совместимость по одному удачно разобранному пакету.

Что действительно включено при штатном запуске

GPX_Recorder создаётся с is_recording=false, AVL_DATA — с write_logs=false и show_broken_data=false. Штатный first-party binding вызывает receive_and_print напрямую; он не вызывает catcher.main, control_thread и переключатели записи. Поэтому команды stdin g/l/b/q из самостоятельного примера не являются интерфейсом управления этим handler через XMPP или launcher.

Обычный читаемый logging при удачном parse выполняется, но отдельные AVL-файлы и GPX в этом binding автоматически не включаются. Директории могут создаваться при импорте recorder/decoder ещё до открытия socket; наличие каталога не доказывает активную запись. Если запись включена другим разрешённым способом, GPX хранится по IMEI и времени первой точки, AVL logs — по IMEI в своих output dirs. Это файлы примера, а не проекция в БД сервиса.

Настройки и диагностика

Назначение Настройка / значение источника
UDP host TELTONIKA_HOSTNAME; default 0.0.0.0
UDP port TELTONIKA_PORT; default 350, допустимо 1..65535
Часовой пояс timestamp TELTONIKA_TIMEZONE; default UTC, проверяется ZoneInfo
Каталог отдельного AVL-log TELTONIKA_AVL_OUTPUT_DIR
Каталог GPX TELTONIKA_GPX_OUTPUT_DIR
Период проверки остановки socket loop Socket timeout 1.0 секунды, в operation
Подключение и общие restart limits Штатные настройки общего handler runtime

Относительные output paths разрешаются от корня проекта; реальные значения и managed permissions определяет установка. Не следует считать default внутри каталога примера доказательством фактического пути production. Проверяйте штатную env/permission-подготовку, не создавая параллельный неуправляемый конфиг для handler.

Диагностируйте последовательно выбранную Python version/binding, XMPP preflight, импорт/права output dirs, bind UDP, приход датаграммы, parse result, режимы записи и ACK. Не путайте XMPP callback с UDP decoder: callback только логирует допустимые chat/normal от технического allowlist, не переключает GPX и не обновляет трекер в БД.

Проверенные источники

Git SHA/SHA-256 и модели закреплены в metadata/BPMN; упаковка повторно сверяет файлы. Handler, socket, устройства и тестовые сообщения при анализе не запускались, секретные runtime env не читались. Общий автоматический hook Wiki пока не завершён.

Связанные материалы

sharixopen/knowledge/scenarios/teltonika_gps_tracker.1793223565.txt.gz · Последнее изменение: — sx_knowledge_api_open

© 2022 ShariX