Zarządzanie przestrzenią powietrzną

2026-09-22

Opis funkcji

Po włączeniu raportowania danych przestrzeni powietrznej w czasie rzeczywistym możesz uzyskać adres URL Webhook i token szyfrowania od swojego dostawcy usług. Po ich wprowadzeniu i zapisaniu interfejs API FlightHub może przesyłać dane statku powietrznego w czasie rzeczywistym do stron trzecich. Poniżej znajduje się przewodnik po integracji dla dostawców usług stron trzecich.

Przewodnik po integracji

Protokół raportowania danych

1. Nagłówek żądania

Nazwa polaKod polaTyp danychOpisWymagane
Źródło danychsourceInteger1: raportowane bezpośrednio przez statek powietrzny
2: raportowane przez system producenta
3: raportowane przez moduł dodatkowy
4: raportowane przez urządzenie zbierające
Tak
Platforma raportującaplatformStringNazwa platformy (np. DJI Fly)Tak
Wersja programuprogramVersionStringNumer wersji (np. version 1.0)Tak
PodpissignatureStringWygenerowany podpis żądaniaTak
Znacznik czasu żądaniatimestampStringZnacznik czasu Unix żądania (w sekundach)Tak
NoncenonceStringLosowo generowany ciągTak
Proces generowania podpisu

Parametry wejściowe

  • token: klucz aplikacji (dostarczony przez zintegrowanego dostawcę usług i skonfigurowany przez użytkownika w FlightHub 2). Musi mieć od 32 do 64 znaków i składać się z kombinacji co najmniej trzech z następujących typów: litery, cyfry i znaki specjalne.
  • timestamp: znacznik czasu żądania (z nagłówka żądania timestamp)
  • nonce: losowy ciąg (z nagłówka żądania nonce)
  • body: surowe dane bajtowe treści żądania (np. RequestBody zserializowany w JSON)

Zasady podpisu

  1. Połącz timestamp, nonce i body w jeden ciąg w tej kolejności (bez separatorów).
  2. Użyj algorytmu HMAC-SHA256 z token jako kluczem, aby zaszyfrować połączony ciąg.
  3. Przekonwertuj zaszyfrowany wynik na mały ciąg szesnastkowy.

Implementacja kodu Go

import (
    "crypto/hmac"
    "crypto/sha256"
    "crypto/subtle"
    "encoding/hex"
)

func GenerateHMACSignature(appKey, timestamp, nonce string, body []byte) string {
    mac := hmac.New(sha256.New, []byte(appKey))
    mac.Write([]byte(timestamp))
    mac.Write([]byte(nonce))
    mac.Write(body)
    return hex.EncodeToString(mac.Sum(nil))
}
Proces weryfikacji podpisu

Logika weryfikacji

  1. Serwer pobiera następujące elementy z nagłówka żądania:
    • signature: podpis wygenerowany przez klienta
    • timestamp: znacznik czasu żądania
    • nonce: losowy ciąg
  2. Serwer ponownie generuje podpis przy użyciu tych samych parametrów i klucza tajnego appKey.
  3. Użyj porównania w stałym czasie, aby sprawdzić, czy podpis klienta jest zgodny z podpisem wygenerowanym przez serwer.

Implementacja kodu Go

func VerifyHMACSignature(appKey, timestamp, nonce string, body []byte, signature string) bool {
    expected := GenerateHMACSignature(appKey, timestamp, nonce, body)
    return subtle.ConstantTimeCompare([]byte(expected), []byte(signature)) == 1
}

2. Treść żądania

Format JSON

{
  "app_id":"default",
   "flight_hub_organization_id":"xxxx",
  "paths": [
    { /* FlightPath object */ },
    { /* FlightPath object */ }
  ]
}

Opisy pól

PoleTypWymaganeOpis
app_idstringTakUnikalny identyfikator aplikacji. Obecnie domyślnie ustawiony na default.
flight_hub_organization_idstringTakIdentyfikator organizacji FlightHub użytkownika
pathsFlightPath[]TakTablica danych tras lotu (patrz struktura obiektu poniżej)
Opis struktury FlightPathRecord

Ta struktura służy do opisywania danych punktów trasy lotu. Poniżej znajdują się szczegółowe opisy pól:

NrNazwa polaKod polaTyp danychOpisWymagane
1Flight Record IDorder_idStringFormat: Numer seryjny producenta (sn)-8-cyfrowa data startu (YYYYMMDD)-8-cyfrowy kod losowy.
Przykład: 1581F5FHD25G100C1SDN-20240320-owvGyLqe.
Ten sam identyfikator jest używany przez cały lot.
Tak
2Numer seryjny statku powietrznegosnStringNumer seryjny produkcyjny statku powietrznego producentaTak
3Status lotuflight_statusStringTakeOff: punkt startu, Inflight: w locie, Land: punkt lądowaniaTak
4Ujednolicony kod kredytu społecznegomanufacturer_idStringUjednolicony kod kredytu społecznego producenta.Tak
5Numer rejestracji na nazwisko CAACuas_idStringJeśli nie ma numeru rejestracyjnego, użyj wartości domyślnej UAS-DEFAULT.Tak
6Bieżący znacznik czasutime_stampStringCzas UTC+8, format: yyyyMMddHHmmss. Przykład: 20240124095001Tak
7Model produktuuas_modelStringKombinacja liter, cyfr i/lub symboli.Tak
8Typ układu współrzędnychcoordinateInteger1: WGS-84
2: CGCS2000
3: GLONASS-PZ90
Tak
9Długość geograficznalongitudeLongJednostka: stopnie (°). Wartość rzeczywista = wartość pola / 10⁷.Tak
10Szerokość geograficznalatitudeLongJednostka: stopnie (°). Wartość rzeczywista = wartość pola / 10⁷.Tak
11Typ wysokości rzeczywistejheight_typeInteger1: wysokość względem punktu startu (ALT)
2: wysokość względem bieżącej pozycji (AGL)
Tak
12Wysokość rzeczywistaheightIntegerJednostka: metry (m). Wartość rzeczywista = wartość pola / 10.Tak
13WysokośćaltitudeIntegerJednostka: metry (m). Wartość rzeczywista = wartość pola / 10.Tak
14Prędkość pionowavsIntegerJednostka: m/s. Wartość rzeczywista = wartość pola / 10.Tak
15Prędkość lotu poziomegogsIntegerJednostka: m/s. Wartość rzeczywista = wartość pola / 10.Tak
16KurscourseIntegerKąt zgodnie z ruchem wskazówek zegara od północy rzeczywistej (0°-360°). Wartość rzeczywista = wartość pola / 10. Wpisz -999, gdy dane nie są dostępne.Tak
17Status transmisji RIDremote_id_statusInteger0: wyłączone
1: włączone
Tak

Przykład treści:

{
	"app_id": "default",
	"flight_hub_organization_id": "105ddf05-54ce-4626-a872-cb32b8c98864",
	"paths": [{
		"order_id": "1529F6QAD23CB00A42DP-20251028-89W2aK2W",
		"sn": "1529F6QAD23CB00A42DP",
		"flight_status": "Land",
		"manufacturer_id": "925413007954257495",
		"uas_id": "UAS-DEFAULT",
		"time_stamp": "20251028115000",
		"uas_model": "M3D",
		"coordinate": 1,
		"longitude": 1243579943,
		"latitude": 217931488,
		"height_type": 1,
		"height": 0,
		"altitude": 187,
		"vs": 0,
		"gs": 0,
		"course": 1229,
		"remote_id_status": 1
	}]
}

3. Treść odpowiedzi

Nazwa polaKod polaTyp danychOpis
Kod stanucodeString0 = sukces, 400 = niepowodzenie
Opis wynikuresultStringSzczegółowy opis (np. success)

Przykład odpowiedzi:

{
  "code": "0",
  "result": "success"
}
Last Updated: