

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用自訂 ephemeris 預留聯絡人
<a name="reserving-contacts-with-custom-ephemeris"></a>

## 概觀
<a name="w2aac28c19b3"></a>

 使用自訂 ephemeris (TLE、OEM 或方位提升） 時，您可以使用 [ReserveContact](https://docs.aws.amazon.com/ground-station/latest/APIReference/API_ReserveContact.html) API 保留聯絡人。本節說明兩種保留聯絡人的常見工作流程，以及確保成功安排聯絡人的重要考量事項。

 AWS Ground Station 天線是多個客戶的共用資源。這表示即使聯絡人時段在您列出聯絡人時出現，其他客戶仍可能會在您之前保留該時段。因此，請務必確認您的聯絡人在保留後達到 `SCHEDULED` 狀態，並針對聯絡狀態變更實作適當的監控。

**重要**  
 對於方位提升暫時性，可能會從`ReserveContact`請求中省略 `satelliteArn` 參數，而且您必須`trackingOverrides`提供暫時性 ID。對於 TLE 和 OEM ephemeris，您仍然需要提供 `satelliteArn`。

## 聯絡預留工作流程
<a name="w2aac28c19b5"></a>

 使用自訂 ephemeris 預留聯絡人有兩個主要工作流程：

1. *List-then-reserve 工作流程：*先使用 [ListContacts](https://docs.aws.amazon.com/ground-station/latest/APIReference/API_ListContacts.html) 列出可用的聯絡時段，然後選取並預留特定時段。當您想要在選擇之前查看所有可用的機會時，此方法非常有用。

1. *直接保留工作流程：*直接保留特定時段的聯絡人，而不先列出可用的聯絡人。當您已經知道所需的聯絡時間或正在使用預先決定的排程時，此方法很有用。

 這兩個工作流程都是有效的，選擇取決於您的操作需求。下列各節提供每種方法的範例。

## 工作流程 1：列出可用的聯絡人，然後保留
<a name="w2aac28c19b7"></a>

 此工作流程會先查詢可用的聯絡時段，然後保留特定的時段。當您想要在選擇之前查看所有可用的機會時，此功能非常有用。

### 範例：列出並預留方位角海拔高度
<a name="w2aac28c19b7b5"></a>

```
import boto3
from datetime import datetime, timezone
import time

# Create AWS Ground Station client
ground_station_client = boto3.client("groundstation")

# Create azimuth elevation ephemeris
print("Creating azimuth elevation ephemeris...")
ephemeris_response = ground_station_client.create_ephemeris(
    name="AzEl Ephemeris for Contact",
    ephemeris={
        "azEl": {
            "groundStation": "Ohio 1",
            "data": {
                "azElData": {
                    "angleUnit": "DEGREE_ANGLE",
                    "azElSegmentList": [
                        {
                            "referenceEpoch": "2024-03-15T10:00:00Z",
                            "validTimeRange": {
                                "startTime": "2024-03-15T10:00:00Z",
                                "endTime": "2024-03-15T10:15:00Z",
                            },
                            "azElList": [
                                {"dt": 0.0, "az": 45.0, "el": 10.0},
                                {"dt": 180.0, "az": 50.0, "el": 15.0},
                                {"dt": 360.0, "az": 55.0, "el": 20.0},
                                {"dt": 540.0, "az": 60.0, "el": 25.0},
                                {"dt": 720.0, "az": 65.0, "el": 30.0},
                                {"dt": 900.0, "az": 70.0, "el": 35.0},
                            ],
                        }
                    ],
                }
            },
        }
    },
)

ephemeris_id = ephemeris_response["ephemerisId"]
print(f"Created ephemeris: {ephemeris_id}")

# Wait for ephemeris to become ENABLED
while True:
    status = ground_station_client.describe_ephemeris(ephemerisId=ephemeris_id)[
        "status"
    ]
    if status == "ENABLED":
        print("Ephemeris is ENABLED")
        break
    elif status in ["INVALID", "ERROR"]:
        raise RuntimeError(f"Ephemeris failed: {status}")
    time.sleep(5)

# List available contacts
print("Listing available contacts...")
contacts = ground_station_client.list_contacts(
    # Note: satelliteArn is omitted for azimuth elevation ephemeris
    groundStation="Ohio 1",
    missionProfileArn="arn:aws:groundstation:us-east-2:111122223333:mission-profile/example-profile",
    startTime=datetime(2024, 3, 15, 10, 0, 0, tzinfo=timezone.utc),
    endTime=datetime(2024, 3, 15, 10, 15, 0, tzinfo=timezone.utc),
    statusList=["AVAILABLE"],
    ephemeris={"azEl": {"id": ephemeris_id}},
)

if contacts["contactList"]:
    # Reserve the first available contact
    contact = contacts["contactList"][0]
    print(f"Reserving contact from {contact['startTime']} to {contact['endTime']}...")

    reservation = ground_station_client.reserve_contact(
        # Note: satelliteArn is omitted when using azimuth elevation ephemeris
        missionProfileArn="arn:aws:groundstation:us-east-2:111122223333:mission-profile/example-profile",
        groundStation="Ohio 1",
        startTime=contact["startTime"],
        endTime=contact["endTime"],
        trackingOverrides={
            "programTrackSettings": {"azEl": {"ephemerisId": ephemeris_id}}
        },
    )

    print(f"Reserved contact: {reservation['contactId']}")
else:
    print("No available contacts found")
```

### 範例：使用 TLE ephemeris 列出和保留
<a name="w2aac28c19b7b7"></a>

```
import boto3
from datetime import datetime, timedelta, timezone
import time

# Create AWS Ground Station client
ground_station_client = boto3.client("groundstation")

satellite_id = "12345678-1234-1234-1234-123456789012"
satellite_arn = f"arn:aws:groundstation::111122223333:satellite/{satellite_id}"

# Create TLE ephemeris
print("Creating TLE ephemeris...")
ephemeris_response = ground_station_client.create_ephemeris(
    name="TLE Ephemeris for Contact",
    satelliteId=satellite_id,
    enabled=True,
    expirationTime=datetime.now(timezone.utc) + timedelta(days=7),
    priority=1,  # Higher priority than default ephemeris
    ephemeris={
        "tle": {
            "tleData": [
                {
                    "tleLine1": "1 25994U 99068A   24075.54719794  .00000075  00000-0  26688-4 0  9997",
                    "tleLine2": "2 25994  98.2007  30.6589 0001234  89.2782  18.9934 14.57114995111906",
                    "validTimeRange": {
                        "startTime": datetime.now(timezone.utc),
                        "endTime": datetime.now(timezone.utc) + timedelta(days=7),
                    },
                }
            ]
        }
    },
)

ephemeris_id = ephemeris_response["ephemerisId"]
print(f"Created ephemeris: {ephemeris_id}")

# Wait for ephemeris to become ENABLED
while True:
    status = ground_station_client.describe_ephemeris(ephemerisId=ephemeris_id)[
        "status"
    ]
    if status == "ENABLED":
        print("Ephemeris is ENABLED")
        break
    elif status in ["INVALID", "ERROR"]:
        raise RuntimeError(f"Ephemeris failed: {status}")
    time.sleep(5)

# List available contacts
print("Listing available contacts...")
start_time = datetime.now(timezone.utc) + timedelta(hours=1)
end_time = start_time + timedelta(days=1)

contacts = ground_station_client.list_contacts(
    satelliteArn=satellite_arn,  # Required for TLE/OEM ephemeris
    groundStation="Hawaii 1",
    missionProfileArn="arn:aws:groundstation:us-west-2:111122223333:mission-profile/example-profile",
    startTime=start_time,
    endTime=end_time,
    statusList=["AVAILABLE"],
)

if contacts["contactList"]:
    # Reserve the first available contact
    contact = contacts["contactList"][0]
    print(f"Reserving contact from {contact['startTime']} to {contact['endTime']}...")

    reservation = ground_station_client.reserve_contact(
        satelliteArn=satellite_arn,  # Required for TLE/OEM ephemeris
        missionProfileArn="arn:aws:groundstation:us-west-2:111122223333:mission-profile/example-profile",
        groundStation="Hawaii 1",
        startTime=contact["startTime"],
        endTime=contact["endTime"],
        # Note: trackingOverrides is optional for TLE/OEM
        # The system will use the highest priority ephemeris automatically
    )

    print(f"Reserved contact: {reservation['contactId']}")
else:
    print("No available contacts found")
```

## 工作流程 2：直接聯絡預留
<a name="w2aac28c19b9"></a>

 此工作流程會直接保留聯絡人，而不會先列出可用的時段。當您已經知道所需的聯絡時間或正在實作自動化排程時，此方法很有用。

### 範例：使用方位角海拔凹凸直接保留
<a name="w2aac28c19b9b5"></a>

```
import boto3
from datetime import datetime, timezone
import time

# Create AWS Ground Station client
ground_station_client = boto3.client("groundstation")

# Define contact window
contact_start = datetime(2024, 3, 20, 14, 0, 0, tzinfo=timezone.utc)
contact_end = datetime(2024, 3, 20, 14, 15, 0, tzinfo=timezone.utc)

# Create azimuth elevation ephemeris for the specific contact time
print("Creating azimuth elevation ephemeris...")
ephemeris_response = ground_station_client.create_ephemeris(
    name="Direct Contact AzEl Ephemeris",
    ephemeris={
        "azEl": {
            "groundStation": "Ohio 1",
            "data": {
                "azElData": {
                    "angleUnit": "DEGREE_ANGLE",
                    "azElSegmentList": [
                        {
                            "referenceEpoch": contact_start.isoformat(),
                            "validTimeRange": {
                                "startTime": contact_start.isoformat(),
                                "endTime": contact_end.isoformat(),
                            },
                            "azElList": [
                                {"dt": 0.0, "az": 45.0, "el": 10.0},
                                {"dt": 180.0, "az": 50.0, "el": 15.0},
                                {"dt": 360.0, "az": 55.0, "el": 20.0},
                                {"dt": 540.0, "az": 60.0, "el": 25.0},
                                {"dt": 720.0, "az": 65.0, "el": 30.0},
                                {"dt": 900.0, "az": 70.0, "el": 35.0},
                            ],
                        }
                    ],
                }
            },
        }
    },
)

ephemeris_id = ephemeris_response["ephemerisId"]
print(f"Created ephemeris: {ephemeris_id}")

# Wait for ephemeris to become ENABLED
while True:
    status = ground_station_client.describe_ephemeris(ephemerisId=ephemeris_id)[
        "status"
    ]
    if status == "ENABLED":
        print("Ephemeris is ENABLED")
        break
    elif status in ["INVALID", "ERROR"]:
        raise RuntimeError(f"Ephemeris failed: {status}")
    time.sleep(5)

# Directly reserve the contact
print(f"Reserving contact from {contact_start} to {contact_end}...")

reservation = ground_station_client.reserve_contact(
    # Note: satelliteArn is omitted for azimuth elevation
    missionProfileArn="arn:aws:groundstation:us-east-2:111122223333:mission-profile/example-profile",
    groundStation="Ohio 1",
    startTime=contact_start,
    endTime=contact_end,
    trackingOverrides={"programTrackSettings": {"azEl": {"ephemerisId": ephemeris_id}}},
)

print(f"Reserved contact: {reservation['contactId']}")
```

### 範例：使用 TLE ephemeris 直接保留
<a name="w2aac28c19b9b7"></a>

```
import boto3
from datetime import datetime, timedelta, timezone
import time

# Create AWS Ground Station client
ground_station_client = boto3.client("groundstation")

satellite_id = "12345678-1234-1234-1234-123456789012"
satellite_arn = f"arn:aws:groundstation::111122223333:satellite/{satellite_id}"

# Define contact window (based on predicted pass)
contact_start = datetime(2024, 3, 21, 10, 30, 0, tzinfo=timezone.utc)
contact_end = datetime(2024, 3, 21, 10, 42, 0, tzinfo=timezone.utc)

# Create TLE ephemeris
print("Creating TLE ephemeris...")
ephemeris_response = ground_station_client.create_ephemeris(
    name="Direct Contact TLE Ephemeris",
    satelliteId=satellite_id,
    enabled=True,
    expirationTime=contact_end + timedelta(days=1),
    priority=1,
    ephemeris={
        "tle": {
            "tleData": [
                {
                    "tleLine1": "1 25994U 99068A   24080.50000000  .00000075  00000-0  26688-4 0  9999",
                    "tleLine2": "2 25994  98.2007  35.6589 0001234  89.2782  18.9934 14.57114995112000",
                    "validTimeRange": {
                        "startTime": (contact_start - timedelta(hours=1)).isoformat(),
                        "endTime": (contact_end + timedelta(hours=1)).isoformat(),
                    },
                }
            ]
        }
    },
)

ephemeris_id = ephemeris_response["ephemerisId"]
print(f"Created ephemeris: {ephemeris_id}")

# Wait for ephemeris to become ENABLED
while True:
    status = ground_station_client.describe_ephemeris(ephemerisId=ephemeris_id)[
        "status"
    ]
    if status == "ENABLED":
        print("Ephemeris is ENABLED")
        break
    elif status in ["INVALID", "ERROR"]:
        raise RuntimeError(f"Ephemeris failed: {status}")
    time.sleep(5)

# Directly reserve the contact
print(f"Reserving contact from {contact_start} to {contact_end}...")

reservation = ground_station_client.reserve_contact(
    satelliteArn=satellite_arn,  # Required for TLE ephemeris
    missionProfileArn="arn:aws:groundstation:us-west-2:111122223333:mission-profile/example-profile",
    groundStation="Hawaii 1",
    startTime=contact_start,
    endTime=contact_end,
    # Note: trackingOverrides is optional for TLE
    # The system will use the highest priority ephemeris automatically
)

print(f"Reserved contact: {reservation['contactId']}")
```

## 監控聯絡狀態變更
<a name="w2aac28c19c11"></a>

 保留聯絡人之後，請務必監控其狀態，以確保其成功轉換為 ，`SCHEDULED`並在發生任何問題時收到通知。 會向 Amazon EventBridge AWS Ground Station 發出所有聯絡人狀態變更的事件。

 聯絡狀態遵循此生命週期：
+ `SCHEDULING` - 正在處理聯絡人以進行排程
+ `SCHEDULED` - 已成功排程聯絡人並將執行
+ `FAILED_TO_SCHEDULE` - 無法排程聯絡人 （終端狀態）

 如需聯絡狀態和生命週期的詳細資訊，請參閱 [了解聯絡生命週期](contacts.lifecycle.md)。

### 使用 EventBridge 實作聯絡狀態監控
<a name="w2aac28c19c11c11"></a>

 若要即時監控聯絡狀態變更，您可以設定每當 Ground Station 聯絡狀態變更時觸發 Lambda 函數的 Amazon EventBridge 規則。相較於輪詢聯絡狀態，此方法更有效率且可擴展。

#### 實作步驟
<a name="w2aac28c19c11c11b5"></a>

1. 建立 Lambda 函數來處理聯絡狀態變更事件

1. 建立符合 Ground Station 聯絡狀態變更事件的 EventBridge 規則

1. 新增 Lambda 函數做為規則的目標

#### Lambda 函數處理常式範例
<a name="w2aac28c19c11c11b7"></a>

 如需處理聯絡狀態變更事件的 Lambda 函數完整範例，請參閱 `AquaSnppJpssTerraDigIF.yml` CloudFormation 範本中的 `GroundStationCloudWatchEventHandlerLambda` 資源。此範本可在 AWS Ground Station 客戶加入 Amazon S3 儲存貯體中取得。如需存取此範本的指示，請參閱資料流程端點範例的 [將它放在一起](examples.pbs-data-dataflow-endpoint.md#examples.pbs-dataflow-endpoint.putting-it-together)一節。

#### EventBridge 規則組態
<a name="w2aac28c19c11c11b9"></a>

 EventBridge 規則應使用下列事件模式，以符合所有 Ground Station 聯絡狀態變更：

```
{
  "source": ["aws.groundstation"],
  "detail-type": ["Ground Station Contact State Change"]
}
```

 若要篩選特定狀態 （例如失敗），您可以新增詳細資訊篩選條件：

```
{
  "source": ["aws.groundstation"],
  "detail-type": ["Ground Station Contact State Change"],
  "detail": {
    "contactStatus": [
      "FAILED_TO_SCHEDULE",
      "FAILED",
      "AWS_FAILED",
      "AWS_CANCELLED"
    ]
  }
}
```

 如需使用 Lambda 目標建立 EventBridge 規則的詳細說明，請參閱《Amazon EventBridge 使用者指南》中的[建立對事件做出反應的規則](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html)。

### 設定用於自動化的 EventBridge 規則
<a name="w2aac28c19c11c13"></a>

 您可以建立 EventBridge 規則，以自動回應聯絡狀態變更。例如：
+ 當聯絡人無法排程時傳送通知
+ 觸發 Lambda 函數，以在聯絡進入時準備資源 `PREPASS`
+ 記錄聯絡完成以進行稽核

 如需設定 AWS Ground Station 事件的 EventBridge 規則的詳細資訊，請參閱 [AWS Ground Station 使用 事件自動化](monitoring.automating-events.md)。

## 最佳實務和考量
<a name="w2aac28c19c13"></a>

### 處理排程衝突
<a name="w2aac28c19c13b3"></a>

 由於 AWS Ground Station 天線是共用資源，因此在 中出現的聯絡時段`ListContacts`可能由其他客戶保留，然後才能進行保留。若要處理此問題：

1. 保留後一律檢查聯絡狀態

1. 使用替代時段實作重試邏輯

1. 可能的話，請考慮提前預留聯絡人

1. 使用 EventBridge 事件來監控`FAILED_TO_SCHEDULE`狀態

### Ephemeris 驗證時間
<a name="w2aac28c19c13b5"></a>

 請記住，ephemeris 必須處於 `ENABLED` 狀態，才能使用它來保留聯絡人。根據暫時性的類型和大小，驗證程序通常需要幾秒鐘到幾分鐘的時間。在嘗試保留聯絡人之前，請務必驗證暫時性狀態。

### 聯絡時間考量事項
<a name="w2aac28c19c13b7"></a>

 使用自訂 ephemeris 時：
+ 確保您的暫時性接觸涵蓋整個聯絡持續時間
+ 對於方位角升高暫時性，請確認在整個接觸過程中，角度將天線保持在[站點遮罩](https://docs.aws.amazon.com/ground-station/latest/ug/locations.site-masks.html)上方
+ 安排未來聯絡時，請考慮暫時性過期時間

### 依暫時性差異類型的 API 差異
<a name="w2aac28c19c13b9"></a>

 `ReserveContact` API 的行為會因 ephemeris 類型而有所不同：


| Ephemeris 類型 | satelliteArn 必要 | trackingOverrides 必要 | 
| --- | --- | --- | 
| TLE | 是 | 否 （選用） | 
| OEM | 是 | 否 （選用） | 
| 方位上升 | 否 （選用） | 是 | 