

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Reserva contactos con efemérides personalizadas
<a name="reserving-contacts-with-custom-ephemeris"></a>

## Descripción general de
<a name="w2aac28c19b3"></a>

 Al usar efemérides personalizadas (TLE, OEM o elevación de acimut), puedes reservar contactos mediante la API. [ReserveContact](https://docs.aws.amazon.com/ground-station/latest/APIReference/API_ReserveContact.html) En esta sección se describen dos flujos de trabajo comunes para reservar contactos y algunas consideraciones importantes para garantizar una programación de contactos correcta. 

 AWS Ground Station las antenas son recursos compartidos entre varios clientes. Esto significa que, aunque aparezca una ventana de contactos disponible al enumerar los contactos, es posible que otro cliente la reserve antes que tú. Por lo tanto, es fundamental comprobar que tu contacto llegue al `SCHEDULED` estado tras realizar la reserva e implementar un seguimiento adecuado de los cambios de estado del contacto. 

**importante**  
 En el caso de las efemérides de elevación de acimut, es posible que se omita el `satelliteArn` parámetro en la `ReserveContact` solicitud y debes proporcionarnos el identificador de la efeméride. `trackingOverrides` En el caso de las efemérides TLE y OEM, aún debe proporcionar el. `satelliteArn` 

## Flujos de trabajo para reservar contactos
<a name="w2aac28c19b5"></a>

 Existen dos flujos de trabajo principales para reservar contactos con efemérides personalizadas: 

1. *List-then-reserve flujo de trabajo:* primero enumere las ventanas de contactos disponibles y [ListContacts](https://docs.aws.amazon.com/ground-station/latest/APIReference/API_ListContacts.html), a continuación, seleccione y reserve una ventana específica. Este enfoque resulta útil si desea ver todas las oportunidades disponibles antes de realizar una selección.

1. *Flujo de trabajo de reserva directa:* reserve directamente un contacto para un período de tiempo específico sin enumerar primero los contactos disponibles. Este enfoque resulta útil cuando ya sabes la hora de contacto deseada o si trabajas con horarios predeterminados.

 Ambos flujos de trabajo son válidos y la elección depende de sus requisitos operativos. En las siguientes secciones se proporcionan ejemplos de cada enfoque. 

## Flujo de trabajo 1: Listar los contactos disponibles y luego reservar
<a name="w2aac28c19b7"></a>

 Este flujo de trabajo consulta primero las ventanas de contacto disponibles y, a continuación, reserva una ventana específica. Esto resulta útil si desea ver todas las oportunidades disponibles antes de realizar una selección. 

### Ejemplo: Listar y reservar con efemérides de elevación acimutal
<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")
```

### Ejemplo: Listar y reservar con efemérides TLE
<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")
```

## Flujo de trabajo 2: reserva por contacto directo
<a name="w2aac28c19b9"></a>

 Este flujo de trabajo reserva directamente un contacto sin enumerar primero las ventanas disponibles. Este enfoque es útil cuando ya sabe la hora de contacto deseada o si está implementando una programación automatizada. 

### Ejemplo: reserva directa con efemérides de elevación acimutal
<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']}")
```

### Ejemplo: reserva directa con efemérides TLE
<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']}")
```

## Supervisión de los cambios de estado de los contactos
<a name="w2aac28c19c11"></a>

 Tras reservar un contacto, es importante supervisar su estado para garantizar que la transición a un contacto se realice correctamente `SCHEDULED` y se le notifique cualquier problema. AWS Ground Station emite eventos a Amazon EventBridge para todos los cambios de estado de contacto. 

 Los estados de contacto siguen este ciclo de vida: 
+ `SCHEDULING`- El contacto se está procesando para su programación
+ `SCHEDULED`- El contacto se programó correctamente y se ejecutará
+ `FAILED_TO_SCHEDULE`- No se ha podido programar el contacto (estado terminal)

 Para obtener más información sobre los estados y el ciclo de vida de los contactos, consulte[Comprenda el ciclo de vida de](contacts.lifecycle.md). 

### Implementar la supervisión del estado de los contactos con EventBridge
<a name="w2aac28c19c11c11"></a>

 Para monitorizar los cambios de estado de los contactos en tiempo real, puedes configurar una EventBridge regla de Amazon que active una función Lambda cada vez que un contacto de Ground Station cambie de estado. Este enfoque es más eficiente y escalable que sondear el estado del contacto. 

#### Pasos para la implementación
<a name="w2aac28c19c11c11b5"></a>

1. Cree una función Lambda para procesar eventos de cambio de estado de contacto

1. Cree una EventBridge regla que coincida con los eventos de cambio de estado de contacto de Ground Station

1. Agregue la función Lambda como objetivo de la regla

#### Ejemplo de controlador de funciones Lambda
<a name="w2aac28c19c11c11b7"></a>

 Para ver un ejemplo completo de una función Lambda que procesa eventos de cambio de estado de contacto, consulte el `GroundStationCloudWatchEventHandlerLambda` recurso de la `AquaSnppJpssTerraDigIF.yml` CloudFormation plantilla. Esta plantilla está disponible en el bucket de Amazon S3 que se está incorporando AWS Ground Station al cliente. Para obtener instrucciones sobre cómo acceder a esta plantilla, consulte la [Poniéndolo todo junto](examples.pbs-data-dataflow-endpoint.md#examples.pbs-dataflow-endpoint.putting-it-together) sección del ejemplo del punto final del flujo de datos. 

#### EventBridge configuración de reglas
<a name="w2aac28c19c11c11b9"></a>

 La EventBridge regla debe usar el siguiente patrón de eventos para que coincida con todos los cambios de estado de contacto de Ground Station: 

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

 Para filtrar únicamente por estados específicos (por ejemplo, errores), puedes añadir un filtro detallado: 

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

 Para obtener instrucciones detalladas sobre la creación de EventBridge reglas con objetivos Lambda, consulte [Creación de reglas que reaccionen a los eventos](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html) en la Guía EventBridge del usuario de Amazon. 

### Configuración de EventBridge reglas para la automatización
<a name="w2aac28c19c11c13"></a>

 Puede crear EventBridge reglas para responder automáticamente a los cambios de estado de los contactos. Por ejemplo: 
+ Envía notificaciones cuando un contacto no pueda programar una cita
+ Activa funciones Lambda para preparar los recursos cuando entra un contacto `PREPASS`
+ Registre las terminaciones de los contactos con fines de auditoría

 Para obtener información detallada sobre cómo configurar EventBridge las reglas para AWS Ground Station los eventos, consulte[Automatiza AWS Ground Station con eventos](monitoring.automating-events.md). 

## Prácticas recomendadas y consideraciones
<a name="w2aac28c19c13"></a>

### Gestión de conflictos de programación
<a name="w2aac28c19c13b3"></a>

 Como AWS Ground Station las antenas son recursos compartidos, es `ListContacts` posible que otro cliente reserve una ventana de contacto que aparece disponible en antes de que tú puedas reservarla. Para gestionar esto: 

1. Compruebe siempre el estado de contacto después de la reserva

1. Implemente la lógica de reintento con ventanas de tiempo alternativas

1. Considere la posibilidad de reservar los contactos con bastante antelación siempre que sea posible

1. Utilice EventBridge los eventos para monitorear los estados `FAILED_TO_SCHEDULE`

### Tiempo de validación de efemérides
<a name="w2aac28c19c13b5"></a>

 Recuerda que las efemérides deben estar en `ENABLED` estado para poder usarlas para reservar contactos. El proceso de validación suele tardar entre unos segundos y unos minutos, según el tipo y el tamaño de las efemérides. Compruebe siempre el estado de las efemérides antes de intentar reservar los contactos. 

### Consideraciones sobre el tiempo de contacto
<a name="w2aac28c19c13b7"></a>

 Al usar efemérides personalizadas: 
+ Asegúrate de que tus efemérides cubran toda la duración del contacto
+ [En el caso de las efemérides de elevación acimutal, compruebe que los ángulos mantienen la antena por encima de la máscara de sitio durante todo el contacto](https://docs.aws.amazon.com/ground-station/latest/ug/locations.site-masks.html)
+ Tenga en cuenta los tiempos de caducidad de las efemérides al programar futuros contactos

### Diferencias de API por tipo de efemérides
<a name="w2aac28c19c13b9"></a>

 La `ReserveContact` API se comporta de forma diferente según el tipo de efemérides: 


| Tipo de efemérides | Se requiere un ARN satelital | Es obligatorio rastrear las anulaciones | 
| --- | --- | --- | 
| TLE | Sí | No (opcional) | 
| OEM | Sí | No (opcional) | 
| Elevación del acimut | No (opcional) | Sí | 