Files
my-vault/04_Archive/Projects/Airport/Guangzhou/New Telegram.md
T

12 KiB
Raw Blame History

技术选型

串口数据接收

  1. 串口模拟器
    1. socat
      1. Create Virtual Serial Port Pair Use socat to create two linked virtual serial ports. This example creates two virtual serial ports: /dev/ttyV0 and /dev/ttyV1.

socat -d -d PTY,link=./dev/ttyV0,raw,echo=0 PTY,link=./dev/ttyV1,raw,echo=0 **Explanation:** - `-d -d`: Enables debug output to see the details of the operations. - `PTY,link=/dev/ttyV0,raw,echo=0`: Creates a pseudo-terminal (PTY) with a symbolic link `/dev/ttyV0`, in raw mode with no echo. - `PTY,link=/dev/ttyV1,raw,echo=0`: Creates another PTY with a symbolic link `/dev/ttyV1`, in raw mode with no echo. - bash screen ./dev/ttyV0 9600

	  echo "hello" > ./dev/ttyV1
```

消息队列

nats-server

架构设计

micrioprofile openliberty

micronaut

  1. 串口读取
  2. 报文拆分
  3. 动态解析
  4. 计划解析
  5. 总线消息生成
  6. 动态信息转发
  7. 计划转发

串口 => 消息流原始 => 已分离电报消息 => 待发送 => 消息总线

系统总线适配

日计划处理
季度计划处理
航班主要信息同步
动态消息转发

串口转消息队列

命令行工具 1. 串口参数 2. 消息队列参数

电报存储

postgresql pocketbase

nats nui pocketbase meilisearch

compose.yml

services:
  nats:
    container_name: nats
    image: nats
    ports:
      - "4222:4222"
      - "6222:6222"
      - "8222:8222"
    restart: unless-stopped

  nui:
    container_name: nui
    image: ghcr.io/nats-nui/nui
    volumes:
      - ./db:/db
      - ./creds:/nats-creds:ro
    ports:
      - "31311:31311"
    restart: unless-stopped

  pocketbase:
    image: ghcr.io/muchobien/pocketbase:latest
    container_name: pocketbase
    restart: unless-stopped
    command:
      #- --encryptionEnv #optional
      #- ENCRYPTION #optional
    environment:
      ENCRYPTION: example #optional
    ports:
      - "8090:8090"
    volumes:
      - ./data:/pb_data
      - ./public:/pb_public #optional
      - ./hooks:/pb_hooks #optional

    healthcheck: #optional (recommended) since v0.10.0
      test: wget --no-verbose --tries=1 --spider http://localhost:8090/api/health || exit 1
      interval: 30s
      timeout: 5s
      retries: 5
  meilisearch:
    container_name: meilisearch
    image: getmeili/meilisearch:v1.8
    environment:
      - http_proxy
      - https_proxy
      - MEILI_MASTER_KEY=${MEILI_MASTER_KEY:-masterKey}
      - MEILI_NO_ANALYTICS=${MEILI_NO_ANALYTICS:-true}
      - MEILI_ENV=${MEILI_ENV:-development}
    ports:
      - ${MEILI_PORT:-7700}:7700
    volumes:
      - ./meili_data:/meili_data
    restart: unless-stopped

nat with monitor:

networks:
  monitor-net:
    driver: bridge

services:
  nats:
    image: nats
    container_name: nats
    restart: always
    command: -c /etc/nats/nats.conf
    ports:
      - "4222:4222" # client port
      - "6222:6222" # cluster port
      - "8222:8222" # monitoring port
    volumes:
      - ./nats.conf:/etc/nats/nats.conf
      - $JETSTREAM_STORAGE:/data
    networks:
      - monitor-net

  exporter:
    image: natsio/prometheus-nats-exporter
    container_name: nats-exporter
    restart: always
    command: 
      # see https://github.com/nats-io/prometheus-nats-exporter/blob/main/main.go#L87
      # "-connz",               # connection metrics
      - -connz_detailed         # advanced connection metrics
      - -jsz
      - all                # jetstream metrics
      - -routez                 # route metrics
      - -subz                   # subscription metrics
      - -varz                   # general metrics
      - -prefix=nats            # prefix for all metrics
      - -use_internal_server_id # using serverID from /varz
      - http://nats:8222/
    networks:
      - monitor-net
    labels:
      org.label-schema.group: "nats-monitoring"
    depends_on:
      - nats

    # ports:
    #   - "7777:7777"
    
  surveyor:
    image: natsio/nats-surveyor
    container_name: nats-surveyor
    restart: always
    volumes:
      - ./observations:/observations
      - $JETSTREAM_STORAGE:/data
    command: |
      -s "${NATS_SURVEYOR_SERVERS}" --accounts --observe /observations --jetstream /data
    networks:
      - monitor-net
    labels:
      org.label-schema.group: "nats-monitoring"
    depends_on:
      - nats

  prometheus:
    image: prom/prometheus
    container_name: prometheus
    restart: always
    volumes:
      - ./prometheus/:/etc/prometheus/
      - $PROMETHEUS_STORAGE:/usr/local/share/prometheus
    command: --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/usr/local/share/prometheus
    networks:
      - monitor-net
    labels:
      org.label-schema.group: "nats-monitoring"
    ports:
      - "9090:9090"
    depends_on:
      - surveyor
      - exporter

  grafana:
    image: grafana/grafana
    container_name: grafana
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - ./grafana/dashboards:/var/lib/grafana/dashboards
      - ./grafana/provisioning:/etc/grafana/provisioning
    networks:
      - monitor-net
    labels:
      org.label-schema.group: "nats-monitoring"
    depends_on:
      - prometheus

电报解析,电报存储,电报转发

管理界面接口

管理界面

电报界面 日计划界面 全文检索 typesense meli

nextjs shadcn svelte shadcn melt-ui: https://melt-ui.com flowbite: Flowbite Svelte

htmx: go: chi htmx tailwindcss echo htmx tailwindcss python:

deno: fresh

Telegram Message Body Expression:

FPL:


\((?P<category>[A-Z]{3})-(?P<number>[A-Z]+\d+)-(?P<indicator>[A-Z]{2})\n-(?P<aircraft>[A-Z]+\d+\/?[A-Z]?)\n?-(?P<surve>.*)\n?-(?P<departure>[A-Z]{4})(?P<departure_time>\d{4})\n?-(?P<speed>[A-Z]+\d+)(?P<level>[A-Z0-9]+)\s+(?P<route>(.|\n)+)\n-(?P<destination>[A-Z]{4})(?P<estt>\d{4})\s+(?P<alter>[A-Z]{4})\n?-([A-Z]{3}\/(?:[A-Z]{4}\d{4}\s?)+)?(?P<other>(?m)[A-Z]{3}\/(.|\n)*)\)$

ARR:


\\((?P<type>[A-Z]{3})\\-(?P<number>([A-Z]+\\d+))\\/?(?P<ssr>[A-Z]+\\d+)\\-(?P<departure>[A-Z]{4})\\-(?P<arrival>[A-Z]{4})(?P<time>\\d{4})\\)

DEP:


^\\((?P<type>[A-Z]{3})\\-(?P<number>([A-Z]+\\d+))\\/?(?P<ssr>[A-Z]+\\d+)\\-(?P<departure>[A-Z]{4})(?P<departure_time>\\d{4})\\-(?P<destination>[A-Z]{4})(?P<destination_time>\\d{4})?\\-?(?P<alter>[A-Z]{4})?\\-?(?P<other>.*)?\\)$

NEW FPL:

\((?P<category>[A-Z]{3})-(?P<number>[A-Z]+\d+)-(?P<indicator>[A-Z]{2})\n-(?P<aircraft>[A-Z]+\d+\/?[A-Z]?)\n?-(?P<surve>.*)\n?-(?P<departure>[A-Z]{4})(?P<departure_time>\d{4})\n?-(?P<speed>[A-Z]+\d+)(?P<level>[A-Z0-9]+)\s+(?P<route>(.|\n)+)\n-(?P<destination>[A-Z]{4})(?P<estt>\d{4})\s?(?P<alter>(\s[A-Z]{4})+)\n?-([A-Z]{3}\/(?:[A-Z]{4}\d{4}\s?)+)?(?P<other>(?m)[A-Z]{3}\/(.|\n)*)\)$

CNL:

^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<departure>[A-Z]{4})?-?(?<destination>[A-Z]{4})\)$

DLA:

^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<departure>[A-Z]{4})(?P<departure_time>\d{4})?-?(?<destination>[A-Z]{4})(?<destination_time>\d{4})?\)$
ZCZC TMQ1067 150518     


QU TSNZPCA

.     

QU SZXZPCA TAOZPCA WNZZPCA SHATZCR PEKZPCA WUHZPCA TSNZPCA

.TNAUOSC 150519

PLN 16MAY

01)  SC4731/4732/4667/4668 B2968/B733 ILS I (7) TAO/2340 WNZ/0225

 SZX/

    0500 WNZ/0725 TAO/1000 SHA/1210

      SI:AWY/TAO WNZ SZX WNZ TAO SHA TAO

02)  SC4617/4618/4655/4656/4087/4088/4669/4670 B2996/B733 ILS I (8)

 TA

    O/0030 WUH/0255 TAO/0520 PEK/0730 TAO/0945 ICN/1155 TAO/1350

 SHA/1550

      SI:AWY/TAO WUH TAO PEK TAO ICN TAO SHA TAO

03)  SC4621/4622/4733/4734 B3005/CRJ2 ILS I (5) TAO/0005 DLC/0130

 TAO/

    0300 XIY/0545 KWE/0745 XIY/0950

      SI:AWY/TAO DLC TAO XIY KWE XIY TAO

04)  SC4607/4608/4623/4880/4879/4624 B3007/CRJ2 ILS I (5) TAO/2355

 TY

    N/0150 ZGC/0350 TYN/0545 TAO/0745 DLC/0900 YNT/1015 HGH/1225

 YNT/1435 DLC

    /1550

      SI:AWY/TAO TYN ZGC TYN TAO DLC YNT HGH YNT DLC TAO

05)  SC4679/4680/4711/4712 B3079/CRJ7 ILS I (5) TAO/0001 HGH/0210

 FOC/

    0350 HGH/0530 TAO/0735 HGH/0940 NNG/1255 HGH/1525

      SI:AWY/TAO HGH FOC HGH TAO HGH NNG HGH TAO

06)  SC4717/4817/4818/4718 B3080/CRJ7 ILS I (5) TAO/0005 TSN/0135

 HET/

    0320 TGO/0535 HET/0750 TSN/0930

      SI:AWY/TAO TSN HET TGO HET TSN TAO

07)  SC4709/4981/4982 B5065/B733 ILS I (7) TAO/2355 NGB/0155

 XMN/0430 

    TNA/0725 HET/0950 TNA/1200

      SI:AWY/TAO NGB XMN TNA HET TNA XMN

08)  SC4651/1152/1155/1156/1165/1166/1167/1168 B5205/B737 ILS I (7)

 TA

    O/2340 PEK/0140 TNA/0320 PEK/0510 TNA/0715 SHA/0925 TNA/1135

 SHA/1340

      SI:AWY/TAO PEK TNA PEK TNA SHA TNA SHA TNA

09)  SC4695/4696/4657/4658 B5331/B738 ILS I (8) TAO/2350 NKG/0145

 KMG/

    0505 NKG/0830 TAO/1045 PEK/1300

      SI:AWY/TAO NKG KMG NKG TAO PEK TAO

10)  SC4601/4602/4675/4672 B5348/B738 ILS I (10) TAO/2330 TNA/0055

 CTU

    /0405 TNA/0645 TAO/0830 CAN/1225 LYI/1515

      SI:AWY/TAO TNA CTU TNA TAO CAN LYI TAO

11)  SC4705/4706/4751/4752 B5349/B738 ILS I (8) TAO/2340 HFE/0135

 HHA/

    0335 HFE/0530 TAO/0720 CGO/0930 KWL/1210 CGO/1440

      SI:AWY/TAO HFE HHA HFE TAO CGO KWL CGO TAO

12)  SC4671/4676/4665/4666/4659/4660 B5350/B738 ILS I (8) TAO/2350

 LYI

    /0105 CAN/0415 TAO/0745 SHA/0950 TAO/1155 PEK/1400

      SI:AWY/TAO LYI CAN TAO SHA TAO 

PART ONE  CONTINUED

=




NNNN

ZCZC TMQ2544 141652


FF ZBTJZXZX


141652 ZBTJZPZX


(FPL-JAE7433-IS


-B744/H-SXIRPZJWY/S


-ZBTJ1755


-K0926S0920
 

-EDDF0948 EDDK


-EET/ZMUB0100 UNKL0236 UNWW0332 UNNT0332 USRR0447 USHH0507


 USSS0535 UUYY0602 ULKK0634 ULWW0653 ULLL0720 EETT0748 EVRR0815


 ESAA0821 EPWW0848 EDUU0900


 REG/B2422 SEL/JLAD OPR/JADE CARGO DAT/S RVR/200


 NAV/RNAV1 RNAV5 RNP4


 RMK/AGCS EQUIPPED


 ACARS EQUIPPED/TCAS EQUIPPED/FOREIGN PILOT


 E/1148 P/TBN R/UV S/M J/LF D/1 15 C YELLOW


 A/WHITE GREEN)

NNNN

计划:

airway

(?P<arr_time>\d{4}(\(\d{2}\w{3}\))?)(?P<airport>\w{3})\/?(?P<dep_time>\d{4}(\(\d{2}\w{3}\))?)

Store

nats: serial to nats

services:
  nats:
    container_name: nats
    image: nats
    ports:
      - "4222:4222"
      - "6222:6222"
      - "8222:8222"
    restart: unless-stopped

  nui:
    container_name: nui
    image: ghcr.io/nats-nui/nui
    volumes:
      - ./db:/db
      - ./creds:/nats-creds:ro
    ports:
      - "31311:31311"
    restart: unless-stopped

python:


f:\D\DEV\lang\python3.13\python.exe -m site

nats browser websocket client

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>NATS WebSocket Example</title>
  </head>
  <body>
    <h1>NATS WebSocket Example</h1>

    <!-- A button to send a message -->
    <button id="sendMessageBtn">Send Message</button>

    <!-- An area to display received messages -->
    <pre id="messages"></pre>

    <!-- Use a JavaScript module to import the NATS WebSocket client -->
    <script type="module">
      // Import the NATS WebSocket client from a CDN (Skypack is used as an example)
      import { connect, StringCodec } from "https://cdn.skypack.dev/nats.ws";

      // A simple string codec for encoding/decoding message data
      const sc = StringCodec();

      async function runNATS() {
        try {
          // Connect to the NATS WebSocket server (adjust URL as needed)
          const nc = await connect({ servers: "ws://fzq-pc:7070" });

          // Subscribe to a subject (e.g., "mySubject") to receive messages
          const sub = nc.subscribe("Telegram.Serial");
          (async () => {
            for await (const msg of sub) {
              const messageText = sc.decode(msg.data);
              document.getElementById("messages").textContent +=
                `\nReceived: ${messageText}`;
            }
          })().then(() => {
            console.log("Subscription closed");
          });

          // Bind our "Send Message" button to publish messages
          document
            .getElementById("sendMessageBtn")
            .addEventListener("click", () => {
              const payload = "Hello from the browser!";
              nc.publish("mySubject", sc.encode(payload));
              document.getElementById("messages").textContent +=
                `\nSent: ${payload}`;
            });
        } catch (err) {
          console.error("Error connecting to NATS:", err);
        }
      }

      // Start the NATS connection on page load
      runNATS();
    </script>
  </body>
</html>