SatelliteStorage

This application monitors a subset of satellites with continuous data collection and is used to track the state of each satellite’s solid-state recorder while its orbital position is propagated from Two-Line Elements (TLEs).

The application contains one SatelliteStorage (Entity) object class and one SatStatePublisher (WallclockTimeIntervalPublisher) object. The application also contains two global methods outside of these classes, which contain standardized calculations sourced from Ch. 5 of Space Mission Analysis and Design by Wertz and Larson.

NOTE: For example code demonstrating how an application is started up and how the Entity and WallclockTimeIntervalPublisher object classes are initialized and added to the simulator, see FireSat+ Constellations.


Methods

main_satelliteStorage.get_elevation_angle(sat, loc)

Returns the elevation angle (degrees) of satellite with respect to the topocentric horizon

Parameters:
  • t (Time) – Time object of skyfield.timelib module

  • sat (EarthSatellite) – Skyview EarthSatellite object from skyfield.sgp4lib module

  • loc (GeographicPosition) – Geographic location on surface specified by latitude-longitude from skyfield.toposlib module

Returns:

alt.degrees

Elevation angle (degrees) of satellite with respect to the topocentric horizon

Return type:

float

main_satelliteStorage.check_in_range(satellite, grounds)

Checks if the satellite is in range of any of the operational ground stations

Parameters:
  • t (Time) – Time object of skyfield.timelib module

  • satellite (EarthSatellite) – Skyview EarthSatellite object from skyfield.sgp4lib module

  • grounds (DataFrame) – Dataframe of ground station locations, minimum elevation angles for communication, and operational status (T/F)

Returns:

isInRange

True/False indicating visibility of satellite to any operational ground station

groundId

groundId of the ground station currently in comm range (NOTE: If in range of two ground stations simultaneously, will return first groundId)

Return type:

bool, int


Classes

While the latter methods are globally defined, the following classes have built-in methods that are unique to each object. The SatelliteStorage class tracks state transitions for the satellites in the constellation, while the SatStatePublisher standardizes the message structure and frequency of published messages updating these states.

SatelliteStorage

class SatelliteStorage(cName, app, id, names, ES=None, tles=None)

Bases: Entity

This object class inherits properties from the Entity object class in the NOS-T tools library

Parameters:
  • cName (str) – A string containing the name for the application that tracks the constituent EarthSatellites for this simulation

  • app (ManagedApplication) – An application containing a test-run namespace, a name and description for the app, client credentials, and simulation timing instructions

  • id (list) – List of unique int ids for each constituent satellite

  • names (list) – List of unique str for each constituent satellite (must be same length as id)

  • ES (list) – Optional list of EarthSatellite objects to be included in the simulation (NOTE: at least one of ES or tles MUST be specified, or an exception will be thrown)

  • tles (list) – Optional list of Two-Line Element str to be converted into EarthSatellite objects and included in the simulation

groundTimes

Dictionary with keys corresponding to unique satellite name and values corresponding to sequential list of ground access opportunities - NOTE: each value is initialized as an empty list and opportunities are appended chronologically

Type:

dict

grounds

Dataframe containing information about ground stations with unique groundId (int), latitude-longitude location (GeographicPosition), min_elevation (float) angle constraints, and operational status (bool) - NOTE: initialized as None

Type:

DataFrame

satellites

List of constituent EarthSatellite objects - NOTE: must be same length as id

Type:

list

positions

List of current latitude-longitude-altitude locations (GeographicPosition) of each constituent satellite - NOTE: must be same length as id

Type:

list

next_positions

List of next latitude-longitude-altitude locations (GeographicPosition) of each constituent satellite - NOTE: must be same length as id

Type:

list

ssr_capacity

List of fixed Solid-State Recorder (SSR) capacities in Gigabits (int) for each constituent satellite - NOTE: must be same length as id

Type:

list

capacity_used

list of values (float) representing current fraction of SSR capacity used for each constituent satellite, continuously updated through simulation - NOTE: must be same length as id

Type:

list

instrument_rates

list of fixed instrument data collection rates in Gigabits/second (float) for each constituent satellite - NOTE: must be same length as id

Type:

list

cost_mode

list of str representing one of three cost modes used to update cumulative costs: discrete (per downlink), continuous (fixed contract), or both - NOTE: must be same length as id

Type:

list

fixed_rates

list of fixed rates of cost accumulation in dollars/second for continuous cost_mode for each constituent satellite - NOTE: must be same length as id, but ignored if cost_mode for corresponding satellite is discrete

Type:

list

linkCounts

list of cumulative counts of link opportunies (int) for each constituent satellite - NOTE: must be same length as id, initialized as list of zeros

Type:

list

linkStatus

list of states (bool) indicating whether or not each constituent satellite is currently in view of an available ground station - NOTE: must be same length as id, each satellite state initialized as False

Type:

list

cumulativeCostBySat

Dictionary with keys corresponding to unique satellite name and values corresponding to current cumulative costs in dollars (float) accrued by each constituent satellite, continuously updated throughout the simulation - NOTE: must be same length as id, each satellite cost initialized as zero dollars

Type:

dict

cumulativeCosts

Sum of values in cumulativeCostBySat in dollars, continuously updated throughout the simulation

Type:

float

SatelliteStorage.initialize(init_time)

Activates the SatelliteStorage object with all constituent satellites at a specified initial scenario time

Parameters:

init_time (datetime) – Initial scenario time for simulating propagation of satellites

SatelliteStorage.tick(time_step)

Computes the next SatelliteStorage state after the specified scenario duration and the next simulation scenario time

Parameters:

time_step (timedelta) – Duration between current and next simulation scenario time

SatelliteStorage.tock()

Commits the next SatelliteStorage state and advances simulation scenario time

SatelliteStorage.on_ground(ch, method, properties, body)

Callback function appends a dictionary of information for a new ground station to grounds list when message detected on the PREFIX/ground/location topic.

Ground station information is published at beginning of simulation, and the list is converted to a DataFrame when the Constellation is initialized.

Parameters:
  • client (MQTT Client) – Client that connects application to the event broker using the MQTT protocol. Includes user credentials, tls certificates, and host server-port information.

  • userdata – User defined data of any type (not currently used)

  • message (message) – Contains topic the client subscribed to and payload message content as attributes

SatelliteStorage.on_linkStart(ch, method, properties, body)

Callback function when message detected on the PREFIX/ground/linkStart topic.

Parameters:
  • client (MQTT Client) – Client that connects application to the event broker using the MQTT protocol. Includes user credentials, tls certificates, and host server-port information.

  • userdata – User defined data of any type (not currently used)

  • message (message) – Contains topic the client subscribed to and payload message content as attributes

SatelliteStorage.on_linkCharge(ch, method, properties, body)

Callback function when message detected on the PREFIX/ground/linkCharge topic.

Parameters:
  • client (MQTT Client) – Client that connects application to the event broker using the MQTT protocol. Includes user credentials, tls certificates, and host server-port information.

  • userdata – User defined data of any type (not currently used)

  • message (message) – Contains topic the client subscribed to and payload message content as attributes

SatelliteStorage.on_outage(ch, method, properties, body)

Callback function when message detected on the PREFIX/outage/report topic.

Parameters:
  • client (MQTT Client) – Client that connects application to the event broker using the MQTT protocol. Includes user credentials, tls certificates, and host server-port information.

  • userdata – User defined data of any type (not currently used)

  • message (message) – Contains topic the client subscribed to and payload message content as attributes

SatelliteStorage.on_restore(ch, method, properties, body)

Callback function when message detected on the PREFIX/outage/restore topic.

Parameters:
  • client (MQTT Client) – Client that connects application to the event broker using the MQTT protocol. Includes user credentials, tls certificates, and host server-port information.

  • userdata – User defined data of any type (not currently used)

  • message (message) – Contains topic the client subscribed to and payload message content as attributes


SatStatePublisher

class SatStatePublisher(app, constellation, time_status_step=None, time_status_init=None)

Bases: WallclockTimeIntervalPublisher

This object class inherits properties from the WallclockTimeIntervalPublisher object class from the publisher template in the NOS-T tools library

The user can optionally specify the wallclock timedelta between message publications and the scenario datetime when the first of these messages should be published.

Parameters:
  • app (ManagedApplication) – An application containing a test-run namespace, a name and description for the app, client credentials, and simulation timing instructions

  • constellation (SatelliteStorage) – SatelliteStorage Entity object class with all constituent satellites

  • time_status_step (timedelta) – Optional duration between time status ‘heartbeat’ messages

  • time_status_init (datetime) – Optional scenario datetime for publishing the first time status ‘heartbeat’ message

SatStatePublisher.publish_message()

Abstract publish_message method inherited from the WallclockTimeIntervalPublisher object class from the publisher template in the NOS-T tools library

This method sends a message to the PREFIX/constellation/location topic for each constituent satellite (SatelliteStorage), which includes:

Parameters:
  • id (int) – Unique id for satellite in constellation

  • name (str) – Unique str name for satellite in constellation

  • latitude (float) – Latitude in degrees for satellite in constellation at current scenario time

  • longitude (float) – Longitude in degrees for satellite in constellation at current scenario time

  • altitude (float) – Altitude above sea-level in meters for satellite in constellation at current scenario time

  • capacity_used (float) – Fraction of solid-state recorder capacity used for satellite in constellation at current scenario time

  • commRange (bool) – Boolean state variable indicating if satellite in constellaton is in view of a ground station at current scenario time

  • groundId (int) – Optional unique id for ground station in view of satellite in constellation at current scenario time (if commRange = False, the groundId = None)

  • totalLinkCount (int) – Unique count of downlink opportunities for satellite in constellation

  • cumulativeCostBySat (float) – Cumulative costs incurred for downlinks and/or fixed cost contracts for satellite in constellation at current scenario time

  • time (datetime) – Current scenario datetime


Schema

Schema are implemented using the pydantic library. The following schema define consistent message structures between this application and other observer applications:

pydantic settings SatelliteReady

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized initializing message for each satellite in the constellation includes:

Show JSON schema
{
   "title": "SatelliteReady",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized initializing message for each satellite in the constellation includes: ",
   "type": "object",
   "properties": {
      "id": {
         "description": "Unique satellite identifier",
         "title": "Id",
         "type": "integer"
      },
      "name": {
         "description": "Satellite name for labeling",
         "title": "Name",
         "type": "string"
      },
      "ssr_capacity": {
         "description": "Capacity of onboard Solid State Recorder in Gigabytes",
         "title": "Ssr Capacity",
         "type": "number"
      }
   },
   "required": [
      "id",
      "name",
      "ssr_capacity"
   ]
}

Fields:
  • id (int)

  • name (str)

  • ssr_capacity (float)

field id: int [Required]

Unique satellite identifier

field name: str [Required]

Satellite name for labeling

field ssr_capacity: float [Required]

Capacity of onboard Solid State Recorder in Gigabytes


pydantic settings SatelliteAllReady

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized trigger message indicating SatelliteReady messages have been received for all satellites in the constellation:

Show JSON schema
{
   "title": "SatelliteAllReady",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized trigger message indicating :obj:`SatelliteReady` messages have been received for all satellites in the constellation: ",
   "type": "object",
   "properties": {
      "ready": {
         "default": "allReady",
         "description": "Indicates completion of SatelliteReady messages",
         "title": "Ready",
         "type": "string"
      }
   }
}

Fields:
  • ready (str)

field ready: str = 'allReady'

Indicates completion of SatelliteReady messages


pydantic settings SatelliteState

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized satellite status message includes:

Show JSON schema
{
   "title": "SatelliteState",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized satellite status message includes: \n    ",
   "type": "object",
   "properties": {
      "id": {
         "description": "Unique satellite identifier",
         "title": "Id",
         "type": "integer"
      },
      "name": {
         "description": "Satellite name for labeling",
         "title": "Name",
         "type": "string"
      },
      "latitude": {
         "description": "Latitude (deg) of satellite subpoint location.",
         "maximum": 90,
         "minimum": -90,
         "title": "Latitude",
         "type": "number"
      },
      "longitude": {
         "description": "Longitude (deg) of satellite subpoint location.",
         "maximum": 180,
         "minimum": -180,
         "title": "Longitude",
         "type": "number"
      },
      "altitude": {
         "description": "Altitude (meters) of satellite above sea level",
         "title": "Altitude",
         "type": "number"
      },
      "capacity_used": {
         "description": "GB of solid state recorder capacity used",
         "title": "Capacity Used",
         "type": "number"
      },
      "commRange": {
         "default": false,
         "description": "Boolean for if satellite is in ground stations view",
         "title": "Commrange",
         "type": "boolean"
      },
      "groundId": {
         "anyOf": [
            {
               "type": "integer"
            },
            {
               "type": "null"
            }
         ],
         "description": "Ground Station id in view (None if not in view)",
         "title": "Groundid"
      },
      "totalLinkCount": {
         "anyOf": [
            {
               "type": "integer"
            },
            {
               "type": "null"
            }
         ],
         "description": "Running count of downlink opportunity per satellite",
         "title": "Totallinkcount"
      },
      "cumulativeCostBySat": {
         "description": "Cumulative cost of downlinks and/or fixed cost contracts per satellite",
         "title": "Cumulativecostbysat",
         "type": "number"
      },
      "time": {
         "description": "Time in satellite reference frame",
         "format": "date-time",
         "title": "Time",
         "type": "string"
      }
   },
   "required": [
      "id",
      "name",
      "latitude",
      "longitude",
      "altitude",
      "capacity_used",
      "groundId",
      "totalLinkCount",
      "cumulativeCostBySat",
      "time"
   ]
}

Fields:
  • id (int)

  • name (str)

  • latitude (float)

  • longitude (float)

  • altitude (float)

  • capacity_used (float)

  • commRange (bool)

  • groundId (int | None)

  • totalLinkCount (int | None)

  • cumulativeCostBySat (float)

  • time (datetime.datetime)

field id: int [Required]

Unique satellite identifier

field name: str [Required]

Satellite name for labeling

field latitude: float [Required]

Latitude (deg) of satellite subpoint location.

Constraints:
  • ge = -90

  • le = 90

field longitude: float [Required]

Longitude (deg) of satellite subpoint location.

Constraints:
  • ge = -180

  • le = 180

field altitude: float [Required]

Altitude (meters) of satellite above sea level

field capacity_used: float [Required]

GB of solid state recorder capacity used

field commRange: bool = False

Boolean for if satellite is in ground stations view

field groundId: int | None [Required]

Ground Station id in view (None if not in view)

field totalLinkCount: int | None [Required]

Running count of downlink opportunity per satellite

field cumulativeCostBySat: float [Required]

Cumulative cost of downlinks and/or fixed cost contracts per satellite

field time: datetime [Required]

Time in satellite reference frame


pydantic settings GroundLocation

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message for ground station information includes:

Show JSON schema
{
   "title": "GroundLocation",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message for ground station information includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier",
         "title": "Groundid",
         "type": "integer"
      },
      "latitude": {
         "description": "Latitude (deg) of ground station.",
         "maximum": 90,
         "minimum": -90,
         "title": "Latitude",
         "type": "number"
      },
      "longitude": {
         "description": "Longitude (deg) of ground station.",
         "maximum": 180,
         "minimum": -180,
         "title": "Longitude",
         "type": "number"
      },
      "elevAngle": {
         "description": "Minimum elevation angle (deg) for satellite-ground communications",
         "title": "Elevangle",
         "type": "number"
      },
      "operational": {
         "default": true,
         "description": "True, if this ground station is operational",
         "title": "Operational",
         "type": "boolean"
      },
      "downlinkRate": {
         "description": "Downlink rate for this ground station in Megabytes per second",
         "title": "Downlinkrate",
         "type": "number"
      },
      "costPerSecond": {
         "description": "Cost in $ per second for downlinks",
         "title": "Costpersecond",
         "type": "number"
      },
      "costMode": {
         "default": "discrete",
         "description": "Could be a boolean, options are discrete or fixed, default to discrete",
         "title": "Costmode",
         "type": "string"
      }
   },
   "required": [
      "groundId",
      "latitude",
      "longitude",
      "elevAngle",
      "downlinkRate",
      "costPerSecond"
   ]
}

Fields:
  • groundId (int)

  • latitude (float)

  • longitude (float)

  • elevAngle (float)

  • operational (bool)

  • downlinkRate (float)

  • costPerSecond (float)

  • costMode (str)

field groundId: int [Required]

Unique ground station identifier

field latitude: float [Required]

Latitude (deg) of ground station.

Constraints:
  • ge = -90

  • le = 90

field longitude: float [Required]

Longitude (deg) of ground station.

Constraints:
  • ge = -180

  • le = 180

field elevAngle: float [Required]

Minimum elevation angle (deg) for satellite-ground communications

field operational: bool = True

True, if this ground station is operational

field downlinkRate: float [Required]

Downlink rate for this ground station in Megabytes per second

field costPerSecond: float [Required]

Cost in $ per second for downlinks

field costMode: str = 'discrete'

Could be a boolean, options are discrete or fixed, default to discrete


pydantic settings LinkStart

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message indicating the beginning of a downlink opportunity includes:

Show JSON schema
{
   "title": "LinkStart",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message indicating the beginning of a downlink opportunity includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier",
         "title": "Groundid",
         "type": "integer"
      },
      "satId": {
         "description": "Unique satellite identifier that performed the downlink",
         "title": "Satid",
         "type": "integer"
      },
      "satName": {
         "description": "Name of satellite that performed the downlink",
         "title": "Satname",
         "type": "string"
      },
      "linkId": {
         "description": "Unique downlink counter for the specific spacecraft that downlinked",
         "title": "Linkid",
         "type": "integer"
      },
      "start": {
         "description": "Start time in ground network reference frame",
         "format": "date-time",
         "title": "Start",
         "type": "string"
      },
      "data": {
         "description": "Current amount of data on-board the satellite that needs to be offloaded",
         "title": "Data",
         "type": "number"
      }
   },
   "required": [
      "groundId",
      "satId",
      "satName",
      "linkId",
      "start",
      "data"
   ]
}

Fields:
  • groundId (int)

  • satId (int)

  • satName (str)

  • linkId (int)

  • start (datetime.datetime)

  • data (float)

field groundId: int [Required]

Unique ground station identifier

field satId: int [Required]

Unique satellite identifier that performed the downlink

field satName: str [Required]

Name of satellite that performed the downlink

field linkId: int [Required]

Unique downlink counter for the specific spacecraft that downlinked

field start: datetime [Required]

Start time in ground network reference frame

field data: float [Required]

Current amount of data on-board the satellite that needs to be offloaded


pydantic settings LinkCharge

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message indicating the end of a downlink opportunity and updating cost ledgers includes:

Show JSON schema
{
   "title": "LinkCharge",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message indicating the end of a downlink opportunity and updating cost ledgers includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier",
         "title": "Groundid",
         "type": "integer"
      },
      "satId": {
         "description": "Unique satellite identifier that performed the downlink",
         "title": "Satid",
         "type": "integer"
      },
      "satName": {
         "description": "Name of satellite that performed the downlink",
         "title": "Satname",
         "type": "string"
      },
      "linkId": {
         "description": "Unique downlink counter for the specific spacecraft that downlinked",
         "title": "Linkid",
         "type": "integer"
      },
      "end": {
         "description": "Time stamp for end of downlink when charge is sent",
         "format": "date-time",
         "title": "End",
         "type": "string"
      },
      "duration": {
         "description": "Time duration of satellite in view for this downlink (s)",
         "title": "Duration",
         "type": "number"
      },
      "dataOffload": {
         "description": "Amount of data offloaded based on linear downlink rates unique to each ground station (GB)",
         "title": "Dataoffload",
         "type": "number"
      },
      "downlinkCost": {
         "description": "Cost of data downlink based on per-second cost rates unique to each ground station",
         "title": "Downlinkcost",
         "type": "number"
      },
      "cumulativeCostBySat": {
         "description": "Dictionary of running totals for downlink costs per satellite",
         "title": "Cumulativecostbysat",
         "type": "number"
      },
      "cumulativeCosts": {
         "description": "Running total of ALL downlink costs for the entirety of the Test Case",
         "title": "Cumulativecosts",
         "type": "number"
      }
   },
   "required": [
      "groundId",
      "satId",
      "satName",
      "linkId",
      "end",
      "duration",
      "dataOffload",
      "downlinkCost",
      "cumulativeCostBySat",
      "cumulativeCosts"
   ]
}

Fields:
  • groundId (int)

  • satId (int)

  • satName (str)

  • linkId (int)

  • end (datetime.datetime)

  • duration (float)

  • dataOffload (float)

  • downlinkCost (float)

  • cumulativeCostBySat (float)

  • cumulativeCosts (float)

field groundId: int [Required]

Unique ground station identifier

field satId: int [Required]

Unique satellite identifier that performed the downlink

field satName: str [Required]

Name of satellite that performed the downlink

field linkId: int [Required]

Unique downlink counter for the specific spacecraft that downlinked

field end: datetime [Required]

Time stamp for end of downlink when charge is sent

field duration: float [Required]

Time duration of satellite in view for this downlink (s)

field dataOffload: float [Required]

Amount of data offloaded based on linear downlink rates unique to each ground station (GB)

field downlinkCost: float [Required]

Cost of data downlink based on per-second cost rates unique to each ground station

field cumulativeCostBySat: float [Required]

Dictionary of running totals for downlink costs per satellite

field cumulativeCosts: float [Required]

Running total of ALL downlink costs for the entirety of the Test Case


pydantic settings OutageReport

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message indicating the beginning of an outage at a ground station includes:

Show JSON schema
{
   "title": "OutageReport",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message indicating the beginning of an outage at a ground station includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier experiencing outage",
         "title": "Groundid",
         "type": "integer"
      },
      "outageStart": {
         "description": "Initial time of outage report",
         "format": "date-time",
         "title": "Outagestart",
         "type": "string"
      },
      "outageDuration": {
         "description": "Duration of the reported outage",
         "format": "duration",
         "title": "Outageduration",
         "type": "string"
      },
      "outageEnd": {
         "description": "outageStart + outageDuration",
         "format": "date-time",
         "title": "Outageend",
         "type": "string"
      }
   },
   "required": [
      "groundId",
      "outageStart",
      "outageDuration",
      "outageEnd"
   ]
}

Fields:
  • groundId (int)

  • outageStart (datetime.datetime)

  • outageDuration (datetime.timedelta)

  • outageEnd (datetime.datetime)

field groundId: int [Required]

Unique ground station identifier experiencing outage

field outageStart: datetime [Required]

Initial time of outage report

field outageDuration: timedelta [Required]

Duration of the reported outage

field outageEnd: datetime [Required]

outageStart + outageDuration


pydantic settings OutageRestore

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message indicating the end of an outage with restored service at a ground station includes:

Show JSON schema
{
   "title": "OutageRestore",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message indicating the end of an outage with restored service at a ground station includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier",
         "title": "Groundid",
         "type": "integer"
      },
      "outageEnd": {
         "description": "outageStart + outageDuration",
         "format": "date-time",
         "title": "Outageend",
         "type": "string"
      }
   },
   "required": [
      "groundId",
      "outageEnd"
   ]
}

Fields:
  • groundId (int)

  • outageEnd (datetime.datetime)

field groundId: int [Required]

Unique ground station identifier

field outageEnd: datetime [Required]

outageStart + outageDuration