From bb6d0b8b01b512611eabec2c86878e4971ee9bc1 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Tue, 26 Nov 2024 15:05:40 -0500 Subject: [PATCH 1/7] Update external events guide for attributes & schemas --- .../external_events_tutorial_upload_step3.png | 4 +- .../external_events_tutorial_upload_step4.png | 4 +- .../assets/external_source_manager.png | 3 + .../assets/external_type_manager.png | 3 + .../external_type_manager_file_parsed.png | 3 + ...xternal_type_manager_successful_upload.png | 3 + .../creating-an-external-source.mdx | 86 ++++++++++++++++--- .../external-events/introduction.mdx | 2 +- .../uploading-an-external-source.mdx | 33 ++++++- 9 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 docs/tutorials/external-events/assets/external_source_manager.png create mode 100644 docs/tutorials/external-events/assets/external_type_manager.png create mode 100644 docs/tutorials/external-events/assets/external_type_manager_file_parsed.png create mode 100644 docs/tutorials/external-events/assets/external_type_manager_successful_upload.png diff --git a/docs/tutorials/external-events/assets/external_events_tutorial_upload_step3.png b/docs/tutorials/external-events/assets/external_events_tutorial_upload_step3.png index ffa0f8d..1053c66 100644 --- a/docs/tutorials/external-events/assets/external_events_tutorial_upload_step3.png +++ b/docs/tutorials/external-events/assets/external_events_tutorial_upload_step3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:115672a75c4777bf76692decd10bfc7b7dd2b166df26109cf48931fd4eb345dc -size 331700 +oid sha256:b221faaa2050fb3a9e9a4f51dcf30543aa90d4bdc17cd60c4d9713042153b256 +size 387941 diff --git a/docs/tutorials/external-events/assets/external_events_tutorial_upload_step4.png b/docs/tutorials/external-events/assets/external_events_tutorial_upload_step4.png index 87a878d..bf9bab2 100644 --- a/docs/tutorials/external-events/assets/external_events_tutorial_upload_step4.png +++ b/docs/tutorials/external-events/assets/external_events_tutorial_upload_step4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d9496806831fd734e2392a8e28e6e2c9a31fc3a7c88904ec91992cc7179b9a5 -size 348269 +oid sha256:84202eb63dbe87e25d50498b3e1efb0fbb49973ceb53f0e55547560a5d52fa1b +size 370174 diff --git a/docs/tutorials/external-events/assets/external_source_manager.png b/docs/tutorials/external-events/assets/external_source_manager.png new file mode 100644 index 0000000..5c8d6ba --- /dev/null +++ b/docs/tutorials/external-events/assets/external_source_manager.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d59232132a31cb486322be8115755ba589ef948dc315e9a815a93966a2866b5 +size 212378 diff --git a/docs/tutorials/external-events/assets/external_type_manager.png b/docs/tutorials/external-events/assets/external_type_manager.png new file mode 100644 index 0000000..d672797 --- /dev/null +++ b/docs/tutorials/external-events/assets/external_type_manager.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7523bcfb81914bad624bdcb9de997e66072d215ae95c66d212ca371b2ba891ab +size 204004 diff --git a/docs/tutorials/external-events/assets/external_type_manager_file_parsed.png b/docs/tutorials/external-events/assets/external_type_manager_file_parsed.png new file mode 100644 index 0000000..968c197 --- /dev/null +++ b/docs/tutorials/external-events/assets/external_type_manager_file_parsed.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0196fa1c1300924f05c7a87fc8d7637beb12b708a5a6a39ad87f9f6dc7a82be +size 79520 diff --git a/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png b/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png new file mode 100644 index 0000000..1753cc2 --- /dev/null +++ b/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0106a3d228d79ebedbe0200f62bd6eb1b47d8731da9db23904ae68b58e552587 +size 204115 diff --git a/docs/tutorials/external-events/creating-an-external-source.mdx b/docs/tutorials/external-events/creating-an-external-source.mdx index 4a150da..3861fee 100644 --- a/docs/tutorials/external-events/creating-an-external-source.mdx +++ b/docs/tutorials/external-events/creating-an-external-source.mdx @@ -1,5 +1,47 @@ import externalEventsOverlappingSources from './assets/external_events_overlapping_sources.png'; +# Creating External Source & Event Types +Before creating an External Source, we must define the Source & Event types that our External Source will use. The files we create will define 1) the name of the type and 2) the schema for the type's `attributes`. These files make use of the [JSON Schema](https://json-schema.org/) format and are additionally constrained by a meta-schema. + +Create the following `JSON` file in an editor: + +`External_Types_Schema.json`: +```json +{ + "event_types": { + "SampleTypeA": { + "properties": { + "EventExampleAttribute": { + "type": "number" + } + }, + "required": ["EventExampleAttribute"], + "type": "object" + }, + "SampleTypeB": { + "properties": { + "DifferentExampleAttribute": { + "type": "boolean" + } + }, + "required": ["DifferentExampleAttribute"], + "type": "object" + } + }, + "source_types": { + "DemoType": { + "properties": { + "SourceExampleAttribute": { + "type": "string" + } + }, + "required": ["SourceExampleAttribute"], + "type": "object" + } + } +} +``` + # Creating an External Source We are going to manually create two External Sources and upload them to Aerie. They will be slightly staggered in the times they cover to help us later in illustrating how derivation works. @@ -8,10 +50,10 @@ We are going to manually create two External Sources and upload them to Aerie. T
Diagram of the two source's overlapping time ranges
-Create the following JSON files in an editor: +Create the following `JSON` files in an editor: `External_Events_Demo_00.json`: -``` +```json { "source": { "key": "External_Events_Demo_00.json", @@ -20,6 +62,9 @@ Create the following JSON files in an editor: "period": { "start_time": "2026-001T00:00:00Z", "end_time": "2026-007T00:00:00Z" + }, + "attributes": { + "SourceExampleAttribute": "this is an example attribute" } }, "events": [ @@ -27,28 +72,37 @@ Create the following JSON files in an editor: "key": "DemoType/SampleTypeA/1", "event_type": "SampleTypeA", "start_time": "2026-001T12:00:00Z", - "duration": "02:00:00" + "duration": "02:00:00", + "attributes": { + "EventExampleAttribute": 1 + } }, { "key": "DemoType/SampleTypeA/2", "event_type": "SampleTypeA", "start_time": "2026-002T00:00:00Z", - "duration": "01:00:00" + "duration": "01:00:00", + "attributes": { + "EventExampleAttribute": 2 + } }, { "key": "DemoType/SampleTypeA/3", "event_type": "SampleTypeA", "start_time": "2026-003T12:00:00Z", - "duration": "03:00:00" + "duration": "03:00:00", + "attributes": { + "EventExampleAttribute": 1 + } } ] } ``` `External_Events_Demo_01.json`: -``` +```json { "source": { "key": "External_Events_Demo_01.json", @@ -57,6 +111,9 @@ Create the following JSON files in an editor: "period": { "start_time": "2026-003T00:00:00Z", "end_time": "2026-010T00:00:00Z" + }, + "attributes": { + "SourceExampleAttribute": "this is an example attribute" } }, "events": [ @@ -64,21 +121,28 @@ Create the following JSON files in an editor: "key": "DemoType/SampleTypeA/1", "event_type": "SampleTypeA", "start_time": "2026-003T20:00:00Z", - "duration": "02:00:00" + "duration": "02:00:00", + "attributes": { + "EventExampleAttribute": 3 + } }, - { "key": "DemoType/SampleTypeA/3", "event_type": "SampleTypeB", "start_time": "2026-004T12:00:00Z", - "duration": "01:00:00" + "duration": "01:00:00", + "attributes": { + "DifferentExampleAttribute": true + } }, - { "key": "DemoType/SampleTypeA/4", "event_type": "SampleTypeB", "start_time": "2026-009T20:00:00Z", - "duration": "03:00:00" + "duration": "03:00:00", + "attributes": { + "DifferentExampleAttribute": true + } } ] } diff --git a/docs/tutorials/external-events/introduction.mdx b/docs/tutorials/external-events/introduction.mdx index 133f351..5706e89 100644 --- a/docs/tutorials/external-events/introduction.mdx +++ b/docs/tutorials/external-events/introduction.mdx @@ -4,7 +4,7 @@ In this tutorial, we will provide a brief overview of External Events in Aerie i ## Prerequisites -External events are a component similar to Activities and Resources within Aerie, and as such requires a deployment of Aerie. Additionally, to interact with the external events in a plan's context, a mission model must be created (though as of now, there is no connection between anything related to external events and mission models, so any mission model should be fine). +External events are a component similar to Activities and Resources within Aerie, and as such require a deployment of Aerie. Additionally, to interact with the external events in a plan's context, a mission model must be created (though as of now, there is no connection between anything related to external events and mission models, so any mission model should be fine). You can deploy Aerie locally on your machine by following the simple steps outlined in our [Fast Track](../../../introduction/#fast-track) instructions. diff --git a/docs/tutorials/external-events/uploading-an-external-source.mdx b/docs/tutorials/external-events/uploading-an-external-source.mdx index e43bf84..87101a6 100644 --- a/docs/tutorials/external-events/uploading-an-external-source.mdx +++ b/docs/tutorials/external-events/uploading-an-external-source.mdx @@ -4,14 +4,43 @@ import externalEventsTutorialUploadStep3 from './assets/external_events_tutorial import externalEventsTutorialUploadStep4 from './assets/external_events_tutorial_upload_step4.png'; import externalEventsTutorialUploadStep5Timeline from './assets/external_events_tutorial_upload_step5_timeline.png'; import externalEventsTutorialUploadStep5Table from './assets/external_events_tutorial_upload_step5_table.png'; +import externalTypeManager from './assets/external_type_manager.png'; +import externalTypeManagerFileParsed from './assets/external_type_manager_file_parsed.png'; +import externalTypeManagerSuccessfulUpload from './assets/external_type_manager_successful_upload.png'; +import externalSourceManager from './assets/external_source_manager.png'; -# Uploading the External Source -Having created our sources, we are now able to upload them. Assuming you have deployed an instance of Aerie, navigate to the External Sources page: +# Upload the External Source & Event Type Schema +First, we must upload the schema we created for the External Source Type & the two External Event Types. Assuming you have deployed an instance of Aerie, navigate to the External Sources page:
Click 'External Sources' button
+Next, click the 'Types' button in the top-right to switch to the sub-page used for creating & managing External Source & Event Types. + +
+ External Type Manager +
+ +Click 'Choose File' and select the `External_Types_Schema.json` file we previously created. The new Source Type & the two Event Types should have their names shown on the left-panel. + +
+ Results from successfully parsing the file +
+ +Clicking 'Upload' will create the listed types! + +
+ External Source type created +
+ +# Uploading the External Source +Having created our types, we are now able to upload the External Source. Navigate to the External Sources page: + +
+ External Source Manager +
+ Once here, we can now upload our new External Sources. Click the **'Browse...'** button, and select the first file, `External_Events_Demo_00.json`. The upload section should autofill as follows:
From 1c412383eced2a7f3dd41838d8593bbb38f9104e Mon Sep 17 00:00:00 2001 From: psubram3 Date: Tue, 26 Nov 2024 14:35:12 -0800 Subject: [PATCH 2/7] introduce attribute explanation --- .../assets/external_source_manager_intro.png | 3 - .../assets/create_derivation_group.png | 0 .../assets/create_external_event_type.png | 0 .../assets/create_external_source_type.png | 0 .../assets/create_groups_and_types_button.png | 0 .../assets/derivation_example_full.png | 0 .../assets/derivation_group_motivation.png | 0 .../assets/derivation_group_motivation_ii.png | 0 .../assets/derivation_motivation.png | 0 .../assets/external_event_options.png | 0 .../assets/external_event_table.png | 0 .../assets/external_events_before.png | 0 ...ernal_events_derivation_group_disabled.png | 0 ...ternal_events_derivation_group_enabled.png | 0 .../external_events_group_by_event_type.png | 0 .../external_events_group_by_source.png | 0 .../assets/external_events_on_timeline.png | 0 .../assets/external_events_options.png | 0 .../assets/external_events_table.png | 0 .../assets/external_source_manager_intro.png | 3 + ...external_source_manager_types_expanded.png | 3 + .../external_source_manager_types_page.png | 3 + .../assets/external_source_manager_upload.png | 0 .../assets/external_sources_table.png | 0 .../assets/inspected_source.png | 0 .../assets/manage_derivation_group_modal.png | 0 .../assets/ordering_external_sources.png | 0 .../assets/plan_external_source_full_view.png | 0 .../assets/plan_external_sources_panel.png | 0 .../assets/plan_selected_external_event.png | 0 .../assets/timeline_and_editor_full.png | 0 .../external-events-attributes.md | 164 +++++++++++ .../introduction.mdx} | 255 ++++++++++++------ sidebars.js | 10 +- 34 files changed, 356 insertions(+), 85 deletions(-) delete mode 100644 docs/planning/assets/external_source_manager_intro.png rename docs/planning/{ => external-events}/assets/create_derivation_group.png (100%) rename docs/planning/{ => external-events}/assets/create_external_event_type.png (100%) rename docs/planning/{ => external-events}/assets/create_external_source_type.png (100%) rename docs/planning/{ => external-events}/assets/create_groups_and_types_button.png (100%) rename docs/planning/{ => external-events}/assets/derivation_example_full.png (100%) rename docs/planning/{ => external-events}/assets/derivation_group_motivation.png (100%) rename docs/planning/{ => external-events}/assets/derivation_group_motivation_ii.png (100%) rename docs/planning/{ => external-events}/assets/derivation_motivation.png (100%) rename docs/planning/{ => external-events}/assets/external_event_options.png (100%) rename docs/planning/{ => external-events}/assets/external_event_table.png (100%) rename docs/planning/{ => external-events}/assets/external_events_before.png (100%) rename docs/planning/{ => external-events}/assets/external_events_derivation_group_disabled.png (100%) rename docs/planning/{ => external-events}/assets/external_events_derivation_group_enabled.png (100%) rename docs/planning/{ => external-events}/assets/external_events_group_by_event_type.png (100%) rename docs/planning/{ => external-events}/assets/external_events_group_by_source.png (100%) rename docs/planning/{ => external-events}/assets/external_events_on_timeline.png (100%) rename docs/planning/{ => external-events}/assets/external_events_options.png (100%) rename docs/planning/{ => external-events}/assets/external_events_table.png (100%) create mode 100644 docs/planning/external-events/assets/external_source_manager_intro.png create mode 100644 docs/planning/external-events/assets/external_source_manager_types_expanded.png create mode 100644 docs/planning/external-events/assets/external_source_manager_types_page.png rename docs/planning/{ => external-events}/assets/external_source_manager_upload.png (100%) rename docs/planning/{ => external-events}/assets/external_sources_table.png (100%) rename docs/planning/{ => external-events}/assets/inspected_source.png (100%) rename docs/planning/{ => external-events}/assets/manage_derivation_group_modal.png (100%) rename docs/planning/{ => external-events}/assets/ordering_external_sources.png (100%) rename docs/planning/{ => external-events}/assets/plan_external_source_full_view.png (100%) rename docs/planning/{ => external-events}/assets/plan_external_sources_panel.png (100%) rename docs/planning/{ => external-events}/assets/plan_selected_external_event.png (100%) rename docs/planning/{ => external-events}/assets/timeline_and_editor_full.png (100%) create mode 100644 docs/planning/external-events/external-events-attributes.md rename docs/planning/{external-events.mdx => external-events/introduction.mdx} (78%) diff --git a/docs/planning/assets/external_source_manager_intro.png b/docs/planning/assets/external_source_manager_intro.png deleted file mode 100644 index 8cb9cdb..0000000 --- a/docs/planning/assets/external_source_manager_intro.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4ba57a4db965b33f777e53c27a184d751ced0969c2f3502f0f823b188b9a081 -size 419048 diff --git a/docs/planning/assets/create_derivation_group.png b/docs/planning/external-events/assets/create_derivation_group.png similarity index 100% rename from docs/planning/assets/create_derivation_group.png rename to docs/planning/external-events/assets/create_derivation_group.png diff --git a/docs/planning/assets/create_external_event_type.png b/docs/planning/external-events/assets/create_external_event_type.png similarity index 100% rename from docs/planning/assets/create_external_event_type.png rename to docs/planning/external-events/assets/create_external_event_type.png diff --git a/docs/planning/assets/create_external_source_type.png b/docs/planning/external-events/assets/create_external_source_type.png similarity index 100% rename from docs/planning/assets/create_external_source_type.png rename to docs/planning/external-events/assets/create_external_source_type.png diff --git a/docs/planning/assets/create_groups_and_types_button.png b/docs/planning/external-events/assets/create_groups_and_types_button.png similarity index 100% rename from docs/planning/assets/create_groups_and_types_button.png rename to docs/planning/external-events/assets/create_groups_and_types_button.png diff --git a/docs/planning/assets/derivation_example_full.png b/docs/planning/external-events/assets/derivation_example_full.png similarity index 100% rename from docs/planning/assets/derivation_example_full.png rename to docs/planning/external-events/assets/derivation_example_full.png diff --git a/docs/planning/assets/derivation_group_motivation.png b/docs/planning/external-events/assets/derivation_group_motivation.png similarity index 100% rename from docs/planning/assets/derivation_group_motivation.png rename to docs/planning/external-events/assets/derivation_group_motivation.png diff --git a/docs/planning/assets/derivation_group_motivation_ii.png b/docs/planning/external-events/assets/derivation_group_motivation_ii.png similarity index 100% rename from docs/planning/assets/derivation_group_motivation_ii.png rename to docs/planning/external-events/assets/derivation_group_motivation_ii.png diff --git a/docs/planning/assets/derivation_motivation.png b/docs/planning/external-events/assets/derivation_motivation.png similarity index 100% rename from docs/planning/assets/derivation_motivation.png rename to docs/planning/external-events/assets/derivation_motivation.png diff --git a/docs/planning/assets/external_event_options.png b/docs/planning/external-events/assets/external_event_options.png similarity index 100% rename from docs/planning/assets/external_event_options.png rename to docs/planning/external-events/assets/external_event_options.png diff --git a/docs/planning/assets/external_event_table.png b/docs/planning/external-events/assets/external_event_table.png similarity index 100% rename from docs/planning/assets/external_event_table.png rename to docs/planning/external-events/assets/external_event_table.png diff --git a/docs/planning/assets/external_events_before.png b/docs/planning/external-events/assets/external_events_before.png similarity index 100% rename from docs/planning/assets/external_events_before.png rename to docs/planning/external-events/assets/external_events_before.png diff --git a/docs/planning/assets/external_events_derivation_group_disabled.png b/docs/planning/external-events/assets/external_events_derivation_group_disabled.png similarity index 100% rename from docs/planning/assets/external_events_derivation_group_disabled.png rename to docs/planning/external-events/assets/external_events_derivation_group_disabled.png diff --git a/docs/planning/assets/external_events_derivation_group_enabled.png b/docs/planning/external-events/assets/external_events_derivation_group_enabled.png similarity index 100% rename from docs/planning/assets/external_events_derivation_group_enabled.png rename to docs/planning/external-events/assets/external_events_derivation_group_enabled.png diff --git a/docs/planning/assets/external_events_group_by_event_type.png b/docs/planning/external-events/assets/external_events_group_by_event_type.png similarity index 100% rename from docs/planning/assets/external_events_group_by_event_type.png rename to docs/planning/external-events/assets/external_events_group_by_event_type.png diff --git a/docs/planning/assets/external_events_group_by_source.png b/docs/planning/external-events/assets/external_events_group_by_source.png similarity index 100% rename from docs/planning/assets/external_events_group_by_source.png rename to docs/planning/external-events/assets/external_events_group_by_source.png diff --git a/docs/planning/assets/external_events_on_timeline.png b/docs/planning/external-events/assets/external_events_on_timeline.png similarity index 100% rename from docs/planning/assets/external_events_on_timeline.png rename to docs/planning/external-events/assets/external_events_on_timeline.png diff --git a/docs/planning/assets/external_events_options.png b/docs/planning/external-events/assets/external_events_options.png similarity index 100% rename from docs/planning/assets/external_events_options.png rename to docs/planning/external-events/assets/external_events_options.png diff --git a/docs/planning/assets/external_events_table.png b/docs/planning/external-events/assets/external_events_table.png similarity index 100% rename from docs/planning/assets/external_events_table.png rename to docs/planning/external-events/assets/external_events_table.png diff --git a/docs/planning/external-events/assets/external_source_manager_intro.png b/docs/planning/external-events/assets/external_source_manager_intro.png new file mode 100644 index 0000000..1323b7c --- /dev/null +++ b/docs/planning/external-events/assets/external_source_manager_intro.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:409f16965dd7a275b1308e6bdc60d6472f8223cad65ee6996adbfcaf67968360 +size 552123 diff --git a/docs/planning/external-events/assets/external_source_manager_types_expanded.png b/docs/planning/external-events/assets/external_source_manager_types_expanded.png new file mode 100644 index 0000000..0cb4b10 --- /dev/null +++ b/docs/planning/external-events/assets/external_source_manager_types_expanded.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6647c3710b3a72223ebb568989dab262693d56c4e34ef49a39279f526f102b1 +size 213950 diff --git a/docs/planning/external-events/assets/external_source_manager_types_page.png b/docs/planning/external-events/assets/external_source_manager_types_page.png new file mode 100644 index 0000000..d8f4dfe --- /dev/null +++ b/docs/planning/external-events/assets/external_source_manager_types_page.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9df7b97e66f3d4f49e62eb41539cdbf4e5e63b24e72cde0e3c0857974fbe90fb +size 153724 diff --git a/docs/planning/assets/external_source_manager_upload.png b/docs/planning/external-events/assets/external_source_manager_upload.png similarity index 100% rename from docs/planning/assets/external_source_manager_upload.png rename to docs/planning/external-events/assets/external_source_manager_upload.png diff --git a/docs/planning/assets/external_sources_table.png b/docs/planning/external-events/assets/external_sources_table.png similarity index 100% rename from docs/planning/assets/external_sources_table.png rename to docs/planning/external-events/assets/external_sources_table.png diff --git a/docs/planning/assets/inspected_source.png b/docs/planning/external-events/assets/inspected_source.png similarity index 100% rename from docs/planning/assets/inspected_source.png rename to docs/planning/external-events/assets/inspected_source.png diff --git a/docs/planning/assets/manage_derivation_group_modal.png b/docs/planning/external-events/assets/manage_derivation_group_modal.png similarity index 100% rename from docs/planning/assets/manage_derivation_group_modal.png rename to docs/planning/external-events/assets/manage_derivation_group_modal.png diff --git a/docs/planning/assets/ordering_external_sources.png b/docs/planning/external-events/assets/ordering_external_sources.png similarity index 100% rename from docs/planning/assets/ordering_external_sources.png rename to docs/planning/external-events/assets/ordering_external_sources.png diff --git a/docs/planning/assets/plan_external_source_full_view.png b/docs/planning/external-events/assets/plan_external_source_full_view.png similarity index 100% rename from docs/planning/assets/plan_external_source_full_view.png rename to docs/planning/external-events/assets/plan_external_source_full_view.png diff --git a/docs/planning/assets/plan_external_sources_panel.png b/docs/planning/external-events/assets/plan_external_sources_panel.png similarity index 100% rename from docs/planning/assets/plan_external_sources_panel.png rename to docs/planning/external-events/assets/plan_external_sources_panel.png diff --git a/docs/planning/assets/plan_selected_external_event.png b/docs/planning/external-events/assets/plan_selected_external_event.png similarity index 100% rename from docs/planning/assets/plan_selected_external_event.png rename to docs/planning/external-events/assets/plan_selected_external_event.png diff --git a/docs/planning/assets/timeline_and_editor_full.png b/docs/planning/external-events/assets/timeline_and_editor_full.png similarity index 100% rename from docs/planning/assets/timeline_and_editor_full.png rename to docs/planning/external-events/assets/timeline_and_editor_full.png diff --git a/docs/planning/external-events/external-events-attributes.md b/docs/planning/external-events/external-events-attributes.md new file mode 100644 index 0000000..200b888 --- /dev/null +++ b/docs/planning/external-events/external-events-attributes.md @@ -0,0 +1,164 @@ +# External Event and Source Attributes + +This page describes the format for files describing External Source Types and External Event Types. These files detail the allowed attributes that each of these components are required and allowed to have (i.e. the attributes defined in a file, and only those, are eligible to be included in a definition). + +Both External Source Types and External Event Types can be detailed in the same file, which has the following general outline: + +```json +{ + "event_types": { + "EventTypeName": { + ... + }, + "SecondEventTypeName": { + ... + }, + ... + }, + "source_types": { + "SourceTypeName": { + ... + }, + "AdditionalSourceTypeName": { + ... + }, + ... + } +} +``` + +Any number of source and event types can be provided in a given file. **At present, there is no explicit tying of external event and source types. That is, a given source type doesn't specify what event types are legal to be included yet.** + +We will now elaborate on the details of the actual event and source types, to make it clear how to define allowable/required attributes. In any case, a review of [JSON Schema](https://json-schema.org/learn/getting-started-step-by-step) would be instrumental in making sense of the following sections. + +## External Types + +An external source type definition might look like the following: + +```json +... +"Weather": { + "type": "object", + "required": [ + "location", + "version", + "changelog" + ], + "properties": { + "location": { + "type": "string" + }, + "version": { + "type": "number" + }, + "changelog": { + "type": "string" + } + } +} +``` + +This is an example of an object nested within `source_types`, and describes the attributes allowed for a `Weather` source. In this file, following JSON Schema syntax, the attributes of a `Weather` object are described - we desire an object, with 3 required fields: `location` (a string), `version` (a number), and `changelog` (a string). Additional JSON Schema functionality can be added to these properties as well, like a `pattern` specification, which restricts strings for a give field to follow a regex. These objects also bear an implied `additionalProperties: false`, meaning only these properties can be provided; any extras will be rejected. + +Event type attribute specifications function similarly: + +```json +"WeatherReport": { + "type": "object", + "required": ["daily_high", "daily_low", "precipitation_lik"], + "properties": { + "daily_high": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "daily_low": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "precipitation_lik": { + "type": "number" + } + } +} +``` + +For completeness, we can show that a complete file then looks like the following: + +```json +{ + "event_types": { + "WeatherReport": { + "type": "object", + "required": ["daily_high", "daily_low", "precipitation_lik"], + "properties": { + "daily_high": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "daily_low": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "precipitation_lik": { + "type": "number" + } + } + } + }, + "source_types": { + "Weather": { + "type": "object", + "required": [ + "location", + "version", + "changelog" + ], + "properties": { + "location": { + "type": "string" + }, + "version": { + "type": "number" + }, + "changelog": { + "type": "string" + } + } + } + } +} +``` + +As can be seen, nested objects are very much fair play in these attribute definitions. The primary requirement is an adherence to JSON Schema syntax. Should a planner fail to do so in creating one of these files, they will be met with a rejection from AERIE as well as a specification of where their attribute specification was wrong. \ No newline at end of file diff --git a/docs/planning/external-events.mdx b/docs/planning/external-events/introduction.mdx similarity index 78% rename from docs/planning/external-events.mdx rename to docs/planning/external-events/introduction.mdx index 52b3df9..105403c 100644 --- a/docs/planning/external-events.mdx +++ b/docs/planning/external-events/introduction.mdx @@ -8,10 +8,8 @@ import externalEventsWithResourcesAndActivities from './assets/external_events_b import externalEventLayerOptions from './assets/external_event_options.png'; import externalSourceOrdering from './assets/ordering_external_sources.png'; import externalSourceManager from './assets/external_source_manager_intro.png'; -import externalSourceManagerCreateDerivationGroup from './assets/create_derivation_group.png'; -import externalSourceManagerCreateExternalEventType from './assets/create_external_event_type.png'; -import externalSourceManagerCreateExternalSourceType from './assets/create_external_source_type.png'; -import externalSourceManagerCreateGroupsAndTypesButton from './assets/create_groups_and_types_button.png'; +import externalSourceManagerTypesPage from './assets/external_source_manager_types_page.png'; +import externalSourceManagerTypesExpanded from './assets/external_source_manager_types_expanded.png'; import externalSourceManagerUpload from './assets/external_source_manager_upload.png'; import externalSourceTable from './assets/external_sources_table.png'; import externalSourceInspected from './assets/inspected_source.png'; @@ -45,10 +43,10 @@ External Events represent temporal occurrences outside of the locus of control o External Sources are containers for External Events and the primary way that users interact with External Events. To get External Events into Aerie, an External Source must be uploaded that contains the event definitions inside. See [External Sources](#external-sources-1) below for more information. #### External Event Types -External Event Types define the *typing* of each External Event. This typing groups External Events on the basis of the data they represent. For example, an External Event may be of the type `Ground Station Contact`, `Solar Flare`, or `Weather Forecast`. +External Event Types define the *typing* of each External Event. This typing groups External Events on the basis of the data they represent, and details the allowed attributes that a given External Event is allowed to have. For example, an External Event may be of the type `Ground Station Contact`, `Solar Flare`, or `Weather Forecast`. Each of these types may entail a set of allowed/defined attributes, like `station`, `flux level`, or `precipitation`. #### External Source Types -External Source Types define the *typing* of each External Source. This typing groups External Sources on the basis of the data they contain. For example, you may have an External Source Type of `Weather Report` to represent all your weather reports, and inside each of the `Weather Report`-typed sources you can expect to find External Events that share a common External Event Type that appears in all `Weather Report`-typed sources (ex: Temperature). +External Source Types define the *typing* of each External Source. This typing groups External Sources on the basis of the data they contain, and details the allowed attributes that a given External Source can have to describe the data contained within it. For example, you may have an External Source Type of `Weather Report` to represent all your weather reports, and inside each of the `Weather Report`-typed sources you can expect to find External Events that share a common External Event Type that appears in all `Weather Report`-typed sources (ex: Temperature). The attributes related to such a source may include details about the people and data involved in creating the forecast. #### Derivation Groups Derivation Groups are collections of External Sources that can be associated with plans. Within a Derivation Group, the collective External Events from its member External Sources are used to create a *derived* set of events for the Derivation Group. See [Derivation](#derivation) below for more information. @@ -135,6 +133,20 @@ The `source` field includes the following fields: ... ``` +* `attributes` + * An object that includes additional data relevant to the External Source in question. + * For a Weather Forecast file, this may include details about the location, which version this file is, and notes about what changed between this version and the last. + * ***Example*** + ```json + ..., + "attributes": { + "location": "Greenbelt, MD", + "version": 2, + "changelog": "Updated precipitation likelihood for 2024-007T00:00:00 from 20% to 35%." + }, + ... + ``` + ##### Events Events are represented as a set of objects contained in a list, and each event has the following fields: @@ -142,7 +154,7 @@ Events are represented as a set of objects contained in a list, and each event h * `key` * Unique identifier for the External Event * Uniqueness is required within the External Source, but **not** across different External Sources. For more information, see [derivation](#derivation) - * Currently has no restrictions or requirements, though those can be optionally imposed by users - see [Formal JSON Schema](#formal-json-schema) for more information + * Currently has no restrictions or requirements * **Example**: `ExampleEvent:1/sc/sc1:1:X/1` * `event_type` @@ -158,6 +170,19 @@ Events are represented as a set of objects contained in a list, and each event h * This value may be 0 to represent an instantaneous event (ex: time of sunrise/sunset) * **Example**: `00:30:00` +* `attributes` + * Similar to attributes for External Sources, this property lists various characteristics of a given event not directly implied by the above fields' values. + * For a Weather Forecast file, a given event may require properties detailing the likelihood of precipitation, or the wind speed. + * **Example:** + ```json + ..., + "attributes": { + "precipitation_lik": 0.35, + "wind_speed (mph)": 3 + }, + ... + ``` + ##### Full External Source Example The following is a full example of a valid, `JSON` representation of an External Source that can be ingested by Aerie. @@ -167,63 +192,157 @@ The example represents a week-long weather forecast where each event is the repo ```json { "source": { - "key": "WeatherForecast2024001_2024008.json", - "source_type": "WeatherForecast", - "valid_at": "2024-01-00T00:00:00Z", + "key": "WEATHER_2024001_2024008_IDEAL.V00.json", + "source_type": "Weather", + "valid_at": "2024-001T00:00:00Z", "period": { "start_time": "2024-001T00:00:00Z", "end_time": "2024-008T00:00:00Z" + }, + "attributes": { + "location": "Greenbelt, MD", + "version": 2, + "changelog": "Updated precipitation_lik for 2024-007T00:00:00 from 20% to 35%." } }, "events": [ { - "key": "Weather/Day/001", + "key": "W/Day/001", "event_type": "WeatherReport", "start_time": "2024-001T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 43.2, + "units": "F" + }, + "daily_low": { + "value": 32.9, + "units": "F" + }, + "precipitation_lik": 0.7 + } }, + + { - "key": "Weather/Day/002", + "key": "W/Day/002", "event_type": "WeatherReport", "start_time": "2024-002T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 40.5, + "units": "F" + }, + "daily_low": { + "value": 29.2, + "units": "F" + }, + "precipitation_lik": 0.6 + } }, + + { - "key": "Weather/Day/003", + "key": "W/Day/003", "event_type": "WeatherReport", "start_time": "2024-003T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 42.1, + "units": "F" + }, + "daily_low": { + "value": 28.4, + "units": "F" + }, + "precipitation_lik": 0.5 + } }, + + { - "key": "Weather/Day/004", + "key": "W/Day/004", "event_type": "WeatherReport", "start_time": "2024-004T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 50.0, + "units": "F" + }, + "daily_low": { + "value": 32.1, + "units": "F" + }, + "precipitation_lik": 0.4 + } }, + + { - "key": "Weather/Day/005", + "key": "W/Day/005", "event_type": "WeatherReport", "start_time": "2024-005T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 46.3, + "units": "F" + }, + "daily_low": { + "value": 21.0, + "units": "F" + }, + "precipitation_lik": 0.3 + } }, + + { - "key": "Weather/Day/006", + "key": "W/Day/006", "event_type": "WeatherReport", "start_time": "2024-006T00:00:00Z", - "duration": "24:00:00" + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 34.3, + "units": "F" + }, + "daily_low": { + "value": 22.5, + "units": "F" + }, + "precipitation_lik": 0.2 + } }, + + { - "key": "Weather/Day/007", + "key": "W/Day/007", "event_type": "WeatherReport", "start_time": "2024-007T00:00:00Z", - "duration": "24:00:00" - }, + "duration": "24:00:00", + "attributes": { + "daily_high": { + "value": 39.0, + "units": "F" + }, + "daily_low": { + "value": 35.3, + "units": "F" + }, + "precipitation_lik": 0.35 + } + } ] } ``` :::info Note -Currently, External Sources only accept a `start_time` and an `end_time`, whereas External Events accept only a `start_time` and a `duration`. This may change in the future (i.e. External Events may accept a start time and an end time as well, for example). This is largely due to simplicity in implementation. +Currently, External Sources only accept a `start_time` and an `end_time`, whereas External Events accept only a `start_time` and a `duration`. This is largely due to simplicity in implementation. ::: @@ -398,56 +517,39 @@ The External Source Manager page handles the uploading & inspection of External
Figure 8: External Source Manager
-#### Creating External Source Types, External Event Types, and Derivation Groups -Within the External Source Manager, the user is able to create new External Source Types, External Event Types, and Derivation Groups. While this is currently **not required** (and these structures will be automatically created if they don't exist on source upload), it is planned to be the main way of creating these types in the future as each will require a strict schema to generate. +#### Creating External Source Types and External Event Types +While derivation groups are automatically created when a user uploads a source file (detailed below), External Source and Event Types require special handling, as they specify allowable attributes as well. -To create one of these types, click the `Create New Groups or Types` button in the top-right: +To create these types, navigate to the `Types` tab in the External Source Manager.
- Figure 8: Create Groups and Types button -
Figure 8: Create Groups and Types button
+ Figure 9: External Source and Event Types Page +
Figure 9: External Source and Event Types Page
-Once the modal has been opened there is a set of tabs - select the tab for the data type you'd like to create: - -##### Creating a Derivation Group -Creating a Derivation Group requires both a name for the group, and a source type to link it with. +Here, the existing types can be inspected for their contents. Most interestingly, we can discern what attributes are available for a given type. Here, we see the `Weather` source type has 3 attributes: `version` (a number), `location` (a string), and `changelog` (a string).
- Figure 8: Create a Derivation Group -
Figure 8: Create a Derivation Group
+ Figure 10: Detail on a given External Source Type +
Figure 10: Detail on a given External Source Type
-##### Creating an External Source Type -Creating an External Source Type just requires a name for the type. - -
- Figure 8: Create an External Source Type -
Figure 8: Create an External Source Type
-
- -##### Creating an External Event Type -Creating an External Event Type just requires a name for the type. - -
- Figure 8: Create an External Event Type -
Figure 8: Create an External Event Type
-
+To create any of these sources, a user must upload a [JSON Schema](https://json-schema.org/learn/getting-started-step-by-step) to AERIE. We go in depth on how to write these schemas [here](../external-events-attributes). #### Uploading an External Source The main view allows users to upload External Sources. Most of these fields autofill and are immutable once parsed - except the Derivation Group which will be autofilled in the style of `external_source_type Default`, but can be edited by the user before upload.
- Figure 9: Uploading an External Source -
Figure 9: Uploading an External Source
+ Figure 11: Uploading an External Source +
Figure 11: Uploading an External Source
#### Inspecting an External Source After uploading an External Source, it will show up in the table on the upper-right pane. This table can be filtered by External Source Type as well as sorted by each of the columns - note the default multi-sorting on the columns `Source Type`, `Derivation Group`, and `Valid At`, which is meant to present the sources in the easiest-to-read manner (grouping by their common types & Derivation Groups, then ordering by their `Valid At` times).
- Figure 10: External Source Table -
Figure 10: External Source Table
+ Figure 12: External Source Table +
Figure 12: External Source Table
Selecting a source allows for the inspection of the source, which is essentially an in-Aerie rendering of what's included under `source` in the uploaded `JSON` (as discussed earlier). It is here, as well as in the table, that deletion can be performed. Note that for deletion to work, an External Source must not be associated with any existing plan (that is the Derivation Group it is a part of must be dissociated from all plans before deletions become legal). Aside from that, there is currently no system of ownership, meaning admins and users alike, as long as External Sources satisfy the aforementioned condition, can delete at will. Viewers, however, cannot. @@ -455,23 +557,23 @@ Selecting a source allows for the inspection of the source, which is essentially It should also be noted that all this inspection takes place outside the context of a plan, so that External Sources & their events can be viewed without having to open and associate the External Source(s) to a plan.
- Figure 11: Inspected External Source -
Figure 11: Inspected External Source
+ Figure 13: Inspected External Source +
Figure 13: Inspected External Source
Finally, it is also possible to inspect each source's contained events as a table. This is useful, as Derivation Groups on plan timelines only show what has been derived, meaning anything that has been selected against won't appear. This page is therefore the absolute truth to see everything that is included, derived-out or not, with a given External Source.
- Figure 12: External Events Table -
Figure 12: External Events Table
+ Figure 14: External Events Table +
Figure 14: External Events Table
### Plan Once an External Source has been uploaded, it can be viewed and interacted with in the context of a plan.
- Figure 13: Overview of the plan view containing External Event information -
Figure 13: Overview of the plan view containing External Event information
+ Figure 15: Overview of the plan view containing External Event information +
Figure 15: Overview of the plan view containing External Event information
To begin working with external sources in the plan, the left side panel should be set to the "External Sources" option. This panel is where users (administrators or plan collaborators) can associate different Derivation Groups with the plan. @@ -481,8 +583,8 @@ To begin working with external sources in the plan, the left side panel should b There are currently two levels to linking a Derivation Group to a plan: **association** and **enabling**. Association is handled here, via the _Manage Derivation Groups_ button. This presents a modal where users can expand different Derivation Groups to view the associated sources and select whether or not they would like to associate said Derivation Group with their plan.
- Figure 14: Derivation Group Modal -
Figure 14: Derivation Group Modal
+ Figure 16: Derivation Group Modal +
Figure 16: Derivation Group Modal
**Association** simply means that the plan is *aware* of the existence of the Derivation Group, and is the gatekeeper for whether it is visible in the External Sources panel. In this panel lies the second level to linking, which is enabling. **Enabling** simply dictates whether a Derivation Group (even if the filters in the *Timeline Editor* select for it) is *visible* on the timeline. Disabling hides all events associated with the group completely, whereas enabling does the opposite. It does not, however, dissociate the plan and Derivation Group. This is simply a visibility attribute and is actually persisted as part of the view (and even persists after Derivation Group dissociation/reassociation, meaning if a Derivation Group is dissociated and then re-associated, its "enabled" setting stays the same). @@ -494,16 +596,16 @@ Enabled|Disabled ![Enabled.](./assets/external_events_derivation_group_enabled.png) | ![Disabled.](./assets/external_events_derivation_group_disabled.png)
- Figure 15: External Sources Panel -
Figure 15: External Sources Panel
+ Figure 17: External Sources Panel +
Figure 17: External Sources Panel
#### Timeline The timeline shows any events from Derivation Groups that are associated with the plan, enabled in the current view, and are filtered for in the timeline editor. Having covered the first two, we can now discuss the editor and its effects on the timeline.
- Figure 16: Timeline & Layer Editor -
Figure 16: Timeline & Layer Editor
+ Figure 18: Timeline & Layer Editor +
Figure 18: Timeline & Layer Editor
The layer of the timeline is modelled after the activity layer, as it provides an easily readable representation of discrete-time occurrences. Layers share the layer options also provided to activity layers, as well as implementing a 'Group By' option specifically for external events. The 'Group By' mechanic allows the user to have external events either grouped by their external source (within the derivation group), or their event types. @@ -513,16 +615,16 @@ The layer of the timeline is modelled after the activity layer, as it provides a ![External Source](./assets/external_events_group_by_source.png) | ![External Event Type](./assets/external_events_group_by_event_type.png)
- Figure 17: External Event Layer Options -
Figure 17: External Event Layer Options
+ Figure 19: External Event Layer Options +
Figure 19: External Event Layer Options
#### Tables and Inspection The screenshot below shows a brief overview of the remaining panels that have been added to plans. It is possible to either mouse over External Events for additional detail or to select them in the timeline, which selects them in a table view beneath the timeline as well as details them in the right pane. This looks as follows:
- Figure 18: The selected External Event view and a table of External Events, working in tandem -
Figure 18: The selected External Event view and a table of External Events, working in tandem
+ Figure 20: The selected External Event view and a table of External Events, working in tandem +
Figure 20: The selected External Event view and a table of External Events, working in tandem
#### A Note on Views @@ -541,15 +643,6 @@ Currently, external events are **not accessible from the [Declarative Scheduling ## What Remains Here, we discuss briefly everything that is not currently implemented but that we do plan to in the future. -### Formal JSON Schema -We currently lack a formal schema uploaded External Sources and their contained External Events. The extent of our schema is just that we ask users to include the fields described in [External Sources](#external-sources), and that any additionally defined fields will be ignored. - -Prior to starting work in the UI, some work on a schema was done. However, it was ultimately ruled that making something restrictive like a schema might be smarter after having done some work on External Events, as it is entirely possible to spend a lot of time on a schema beforehand only to discard or rework a fair amount of it as we progress with development. At this point, we are a lot more confident in what fields should definitely be present in a [JSON Schema](https://json-schema.org/learn/getting-started-step-by-step), which means that creating a definition should be a lot more feasible in a future batch of work. - -These Schemae would likely be a part of the mission model themselves; seeing as defining what activities and resources are allowable for a mission plan are part of a mission model, so too would be definitions of allowable External Source Types and External Event Types. - -This raises the question of how External Source Types and External Event Types should be handled in a Schema. The idea we are currently floating is a multilayered Schema - one that is common to all sources (and events), which essentially details the fields listed in [External Sources](#external-sources), as those show in any External Source regardless of type. The second layer would constrain for an External Source's `metadata` field (to be included in a future update) and for an External Event's `metadata` field (to be included in a future update). Different External Source Types and External Event Types should have different allowable `metadata`, and as such defining a subschema for these fields becomes necessary to restrict and add uniformity to what should be included in that field given the type. It is these subschemae that we suggest should be part of a mission model. Exactly how this definition is to be created, how these layers are to be reconciled, and how to integrate them with the concept of a mission model is yet to be decided. - ### Ownership/Roles Our current solution to a lack of clear ownership/roles around External Sources is as follows: diff --git a/sidebars.js b/sidebars.js index 3492de2..658e72c 100644 --- a/sidebars.js +++ b/sidebars.js @@ -155,7 +155,15 @@ const sidebars = { 'planning/create-plan-and-simulate', 'planning/external-datasets', 'planning/activity-directive-metadata', - 'planning/external-events', + { + type: 'category', + label: 'External Events', + link: { + id: 'planning/external-events/introduction', + type: 'doc' + }, + items: ['planning/external-events/external-events-attributes'] + }, { type: 'category', label: 'Collaboration', From c6e9a7923b88351cea3ad27cfb9ac5b4b1360d72 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Mon, 9 Dec 2024 14:22:48 -0500 Subject: [PATCH 3/7] Update tutorial for event/source attributes --- .../planning/external-events/introduction.mdx | 32 ++-- .../assets/external_type_manager.png | 4 +- ...xternal_type_manager_successful_upload.png | 4 +- .../associating-derivation-groups.mdx | 39 +++-- .../creating-an-external-source.mdx | 157 ++++++++---------- .../uploading-an-external-source.mdx | 16 +- 6 files changed, 131 insertions(+), 121 deletions(-) diff --git a/docs/planning/external-events/introduction.mdx b/docs/planning/external-events/introduction.mdx index 105403c..9aaab56 100644 --- a/docs/planning/external-events/introduction.mdx +++ b/docs/planning/external-events/introduction.mdx @@ -70,22 +70,11 @@ The need for these became apparent after an exploration of External Events imple
Figure 2: External Events - External Events with resources and activities
-:::info Note - -Currently, External Events are *not* accessible to the automated scheduler for purposes of generating activities based on events, satisfying constraints, or other interactions with other data in Aerie. However, this is in the planned scope for External Events, and future releases will add these capabilities - -::: - ### External Sources **External Sources** represent a collection of External Events. When we upload External Events, we can only do so by uploading them in an External Source. -These sources are to be defined in `JSON`, following a general format that will be discussed below. Any data a user wishes to turn into an External Source/External Events should be converted to the `JSON` format to allow ingest within Aerie. - -:::info Note +These sources are defined using [JSON Schema](https://json-schema.org/) format with a [meta-schema](https://github.com/NASA-AMMOS/aerie-gateway/blob/develop/src/schemas/external-event-validation-schemata.ts) enforced to ensure certain fields such as `key` and `start_time` are present and in the correct format. Additionally, the -There is currently no well-defined, official `JSON` schema for External Source input, however there are required fields which will be mentioned below, and any non-known fields included will be ignored during ingest. Additionally, no tool currently exists to provide the generic translation to the `JSON` format, however this is a feature planned for a future release. - -::: #### Schema There are two parts to each External Source: 1) a `source` header and 2) a collection of `events`: @@ -102,7 +91,7 @@ There are two parts to each External Source: 1) a `source` header and 2) a colle ##### Source -The `source` field includes the following fields: +The `source` field includes the following fields, where **all** are required: * `key` * Unique identifier for the External Source @@ -147,6 +136,21 @@ The `source` field includes the following fields: ... ``` +* `attributes` + * Defines the *values* for the attributes of the External Source - these attributes are *defined* or *schematized* by the External Source Type. + * **Example** + ```json + "attributes": { + "version": "1.2.3", + "week": 2, + "isTestFile": true, + "relatedPeriod": { + "startTime": "2024-001T00:00:00Z", + "endTime": "2024-008T00:00:00Z" + } + } + ``` + ##### Events Events are represented as a set of objects contained in a list, and each event has the following fields: @@ -518,7 +522,7 @@ The External Source Manager page handles the uploading & inspection of External #### Creating External Source Types and External Event Types -While derivation groups are automatically created when a user uploads a source file (detailed below), External Source and Event Types require special handling, as they specify allowable attributes as well. +While derivation groups are automatically created when a user uploads a source file (detailed below), External Source and Event Types require special handling, as they specify allowable attributes as well. To create these types, navigate to the `Types` tab in the External Source Manager. diff --git a/docs/tutorials/external-events/assets/external_type_manager.png b/docs/tutorials/external-events/assets/external_type_manager.png index d672797..9d2debf 100644 --- a/docs/tutorials/external-events/assets/external_type_manager.png +++ b/docs/tutorials/external-events/assets/external_type_manager.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7523bcfb81914bad624bdcb9de997e66072d215ae95c66d212ca371b2ba891ab -size 204004 +oid sha256:9b75573d2e40ffed01e17ab71ea8eef25699e4b3dd1fe055572305a9b8e09b42 +size 266574 diff --git a/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png b/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png index 1753cc2..5bcf429 100644 --- a/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png +++ b/docs/tutorials/external-events/assets/external_type_manager_successful_upload.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0106a3d228d79ebedbe0200f62bd6eb1b47d8731da9db23904ae68b58e552587 -size 204115 +oid sha256:2e9805064d586aa1099ee91b60f81efc7d0fe6c19b853d7d8038a58d1e944910 +size 300032 diff --git a/docs/tutorials/external-events/associating-derivation-groups.mdx b/docs/tutorials/external-events/associating-derivation-groups.mdx index 5a70c2d..207e7bf 100644 --- a/docs/tutorials/external-events/associating-derivation-groups.mdx +++ b/docs/tutorials/external-events/associating-derivation-groups.mdx @@ -13,7 +13,13 @@ import externalEventsTutorialTimelineEditor from './assets/external_events_tutor import externalEventsTutorialFilterShown from './assets/external_events_tutorial_filter_shown.png'; # Associating the Derivation Group with a Plan -Now that we have some External Sources uploaded, we can utilize them within a plan to see them on a timeline (and in the future, use them to power constraints, dictate scheduling goals, etc.). +Now that we have some External Sources uploaded, we can utilize them within a plan to see them on a timeline! + +:::caution Note + +Prior to creating a plan, a mission model must exist - currently, the mission model is not tied directly to any external event/source features, so any mission model can be used with any external sources/events. + +::: ## Creating a Plan Start by going to the Aerie **Plan** page: @@ -26,18 +32,21 @@ Once there, create a new plan with the following parameters:
The example plan's parameters -
Note: The start and end times are important here, as they are bounds that contain all the external events in the sources we uploaded!
-To create this plan, make sure that there exists _some_ mission model that can be associated with the plan. The exact model is, at present, entirely unimportant as it has no bearing on External Events functionality. The mission model used here, arbitrarily, is that of Aerie's mission model template. +:::info Note + + The `start` and `end` times are important here, as they are the bounds that contain all the external events in the source we uploaded! + +::: -After the plan has been created, select the plan on the table to the right, and then select **Open plan** in the pane on the left. You should be presented with a plan view that resembles the image below: +After the plan has been created, select the plan on the table to the right, and then select `Open plan` in the pane on the left. You should be presented with a plan view that resembles the image below:
The plans page showing an empty timeline
-Select the `External Sources` tab on the left, and you should see the following: +Click the drop-down menu in the top-right (currently on `Activity, Resource, External Event Types`) and select the `External Sources` tab. You should see the following:
External Sources pane with no associations @@ -46,13 +55,19 @@ Select the `External Sources` tab on the left, and you should see the following: This panel tells us that there are no derivation groups currently linked to our plan, meaning the external events we uploaded before are not yet associated with it. ## Associating the Derivation Group -There are currently no Derivation Groups associated with this plan! While we should have one created, there aren't any that this plan is aware of. To change this, we need to click `Manage Derivation Groups`, to open the Derivation Group management modal. +Previously we created and uploaded an External Source, however our plan is currently unaware of the source's events. To change this, we need to click `Manage Derivation Groups`, to open the Derivation Group management modal. -Once here, we can now look at all of our available (currently only one) Derivation Groups and select which ones to associate with our plan. Association implies that the plan or at least the plan page is in some way aware of the fact that this Derivation Group exists (details on what exactly association entails can be found [here](../../../planning/external-events/#derivation-group-management-modal) under 'Derivation Group Management Modal'). +Once here we can now look at all of our available (currently only one) Derivation Groups and select which ones to associate with our plan. Association means that the plan is aware of the fact this Derivation Group exists and is able to use it's events. -In the `Manage Derivation Groups` modal, check the check-box for our Derivation Group (`DemoType Default`). The check-box itself does not do anything yet, it requires the `Update` button at the bottom of the modal to be clicked to 'save' the linked/un-linked derivation groups. +:::info Note -Click the `Update` button to link the derivation group. +Details on what exactly association entails can be found [here](../../../planning/external-events/) under `Derivation Group Management Modal`. + +::: + +In the `Manage Derivation Groups` modal, check the check-box for our Derivation Group (`DemoType Default`). + +Click the `Update` button to save the current Derivation Group associations. The modal should now appear as below, with a success toast in the bottom-right corner of the screen: @@ -71,8 +86,6 @@ On the left-pane, we can see the breakdown of External Event Counts - where the ## Creating an External Event timeline row Now that we have a derivation group associated with our plan, we can put those external events on the timeline to visualize them. -By default, a dedicated 'External Events Row' is **not** created *unless* the user loads a plan that already existed and has at least one derivation group previously linked. In our case, because this is a new plan we must create our own row to see the events. Alternatively, a filter for the event types can also be added to a pre-existing row. - First, switch to the `Activity, Resource, & Event Types` tab.
@@ -124,6 +137,4 @@ External events appear in the same layer type as activities, and as such share o [//]: # (Examples of the two different `Group By` modes, as well as visibility enable/disable can be seen in the [Plan](../../../planning/external-events/#plan) section of the main External Events documentation.) -## Additional Resources - -More detail on the topics discussed in this tutorial can be found under [External Events](../../../planning/external-events) +With a Derivation Group associated to our plan, we can now run scheduling goals that incorporate External Events! diff --git a/docs/tutorials/external-events/creating-an-external-source.mdx b/docs/tutorials/external-events/creating-an-external-source.mdx index 3861fee..c4d4032 100644 --- a/docs/tutorials/external-events/creating-an-external-source.mdx +++ b/docs/tutorials/external-events/creating-an-external-source.mdx @@ -1,7 +1,7 @@ import externalEventsOverlappingSources from './assets/external_events_overlapping_sources.png'; # Creating External Source & Event Types -Before creating an External Source, we must define the Source & Event types that our External Source will use. The files we create will define 1) the name of the type and 2) the schema for the type's `attributes`. These files make use of the [JSON Schema](https://json-schema.org/) format and are additionally constrained by a meta-schema. +Before creating an External Source, we must define the Source & Event types that our External Source will use. The files we create will define 1) the name of the type and 2) the schema for the type's `attributes`. These files make use of the [JSON Schema](https://json-schema.org/) format and are additionally constrained by a [meta-schema](https://github.com/NASA-AMMOS/aerie-gateway/blob/develop/src/schemas/external-event-validation-schemata.ts). Create the following `JSON` file in an editor: @@ -55,96 +55,85 @@ Create the following `JSON` files in an editor: `External_Events_Demo_00.json`: ```json { - "source": { - "key": "External_Events_Demo_00.json", - "source_type": "DemoType", - "valid_at": "2024-01-01T00:00:00Z", - "period": { - "start_time": "2026-001T00:00:00Z", - "end_time": "2026-007T00:00:00Z" - }, - "attributes": { - "SourceExampleAttribute": "this is an example attribute" - } + "source": { + "key": "External_Events_Demo_00.json", + "source_type": "DemoType", + "valid_at": "2026-001T00:00:00Z", + "period": { + "start_time": "2026-001T00:00:00Z", + "end_time": "2026-007T00:00:00Z" }, - "events": [ - { - "key": "DemoType/SampleTypeA/1", - "event_type": "SampleTypeA", - "start_time": "2026-001T12:00:00Z", - "duration": "02:00:00", - "attributes": { - "EventExampleAttribute": 1 - } - }, - - { - "key": "DemoType/SampleTypeA/2", - "event_type": "SampleTypeA", - "start_time": "2026-002T00:00:00Z", - "duration": "01:00:00", - "attributes": { - "EventExampleAttribute": 2 - } - }, - - { - "key": "DemoType/SampleTypeA/3", - "event_type": "SampleTypeA", - "start_time": "2026-003T12:00:00Z", - "duration": "03:00:00", - "attributes": { - "EventExampleAttribute": 1 - } - } - ] + "attributes": { + "SourceExampleAttribute": "this is an example attribute" + } + }, + "events": [ + { + "key": "DemoType/SampleTypeA/1", + "event_type": "SampleTypeA", + "start_time": "2026-001T12:00:00Z", + "duration": "02:00:00", + "attributes": { + "EventExampleAttribute": 1 + } + }, + { + "key": "DemoType/SampleTypeA/2", + "event_type": "SampleTypeA", + "start_time": "2026-002T00:00:00Z", + "duration": "01:00:00", + "attributes": { + "EventExampleAttribute": 2 + } + }, + { + "key": "DemoType/SampleTypeA/3", + "event_type": "SampleTypeA", + "start_time": "2026-003T12:00:00Z", + "duration": "03:00:00", + "attributes": { + "EventExampleAttribute": 1 + } + } + ] } ``` `External_Events_Demo_01.json`: ```json { - "source": { - "key": "External_Events_Demo_01.json", - "source_type": "DemoType", - "valid_at": "2024-01-02T00:00:00Z", - "period": { - "start_time": "2026-003T00:00:00Z", - "end_time": "2026-010T00:00:00Z" - }, - "attributes": { - "SourceExampleAttribute": "this is an example attribute" - } + "source": { + "key": "External_Events_Demo_01.json", + "source_type": "DemoType", + "valid_at": "2026-004T11:00:00Z", + "period": { + "start_time": "2026-004T11:00:00Z", + "end_time": "2026-010T00:00:00Z" }, - "events": [ - { - "key": "DemoType/SampleTypeA/1", - "event_type": "SampleTypeA", - "start_time": "2026-003T20:00:00Z", - "duration": "02:00:00", - "attributes": { - "EventExampleAttribute": 3 - } - }, - { - "key": "DemoType/SampleTypeA/3", - "event_type": "SampleTypeB", - "start_time": "2026-004T12:00:00Z", - "duration": "01:00:00", - "attributes": { - "DifferentExampleAttribute": true - } - }, - { - "key": "DemoType/SampleTypeA/4", - "event_type": "SampleTypeB", - "start_time": "2026-009T20:00:00Z", - "duration": "03:00:00", - "attributes": { - "DifferentExampleAttribute": true - } - } - ] + "attributes": { + "SourceExampleAttribute": "this is an example attribute" + } + }, + "events": [ + { + "key": "DemoType/SampleTypeB/1", + "event_type": "SampleTypeB", + "start_time": "2026-004T12:00:00Z", + "duration": "01:00:00", + "attributes": { + "DifferentExampleAttribute": true + } + }, + { + "key": "DemoType/SampleTypeB/2", + "event_type": "SampleTypeB", + "start_time": "2026-009T20:00:00Z", + "duration": "03:00:00", + "attributes": { + "DifferentExampleAttribute": true + } + } + ] } ``` @@ -152,7 +141,7 @@ We are now ready to upload our test External Source files to Aerie! :::info Note -In each of these files, the exact formatting of event keys is currently not important. +In each of these files, the exact formatting of the `key` field is currently not important. ::: diff --git a/docs/tutorials/external-events/uploading-an-external-source.mdx b/docs/tutorials/external-events/uploading-an-external-source.mdx index 87101a6..c8df89e 100644 --- a/docs/tutorials/external-events/uploading-an-external-source.mdx +++ b/docs/tutorials/external-events/uploading-an-external-source.mdx @@ -16,19 +16,19 @@ First, we must upload the schema we created for the External Source Type & the t Click 'External Sources' button
-Next, click the 'Types' button in the top-right to switch to the sub-page used for creating & managing External Source & Event Types. +Next, click the `Types` button in the top-right to switch to the sub-page used for creating & managing External Source & Event Types.
External Type Manager
-Click 'Choose File' and select the `External_Types_Schema.json` file we previously created. The new Source Type & the two Event Types should have their names shown on the left-panel. +Click `Choose File` and select the `External_Types_Schema.json` file we previously created. The new Source Type & the two Event Types should have their names shown on the left-panel.
Results from successfully parsing the file
-Clicking 'Upload' will create the listed types! +Clicking `Upload` will create the listed types!
External Source type created @@ -48,7 +48,13 @@ Once here, we can now upload our new External Sources. Click the **'Browse...'**
Uploaded file form should become populated
-Go ahead and leave the `Derivation Group` as `DemoType Default`. +The `Derivation Group` field allows you to change the Derivation Group that the source will associate with, for this tutorial we will leave it as `DemoType Default`. + +:::info Note + +For more information on Derivation Groups, refer to the [External Events](../../../planning/external-events) documentation underneath the `Derivation` section! + +::: Finally, click upload. The new External Source should show in the table on the right: @@ -56,7 +62,7 @@ Finally, click upload. The new External Source should show in the table on the r External Sources table is populated
-Click the 'x' next to 'Selected External Source' to deselect it, then repeat these steps with the second file. The table should now look as follows: +Click the `X` next to `Selected External Source` to deselect it, then repeat these steps with the second file. The table should now look as follows:
External Sources table is populated with both test files From 499be56bde3813b67331bd101207d586499e8343 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Mon, 9 Dec 2024 14:28:55 -0500 Subject: [PATCH 4/7] Add tutorial for creating external event scheduling goal --- .../assets/scheduling_goal_modal.png | 3 + .../assets/scheduling_goal_result.png | 3 + .../assets/scheduling_goal_upload.png | 3 + ...a-scheduling-goal-with-external-events.mdx | 202 ++++++++++++++++++ sidebars.js | 45 ++-- 5 files changed, 233 insertions(+), 23 deletions(-) create mode 100644 docs/tutorials/external-events/assets/scheduling_goal_modal.png create mode 100644 docs/tutorials/external-events/assets/scheduling_goal_result.png create mode 100644 docs/tutorials/external-events/assets/scheduling_goal_upload.png create mode 100644 docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx diff --git a/docs/tutorials/external-events/assets/scheduling_goal_modal.png b/docs/tutorials/external-events/assets/scheduling_goal_modal.png new file mode 100644 index 0000000..9ea85c4 --- /dev/null +++ b/docs/tutorials/external-events/assets/scheduling_goal_modal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:505b4650358075c644204480f1a588b065173f18e11edb5fdf6b0629f154250f +size 197355 diff --git a/docs/tutorials/external-events/assets/scheduling_goal_result.png b/docs/tutorials/external-events/assets/scheduling_goal_result.png new file mode 100644 index 0000000..62dc858 --- /dev/null +++ b/docs/tutorials/external-events/assets/scheduling_goal_result.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e42bd6d892b4dd4f180dedf1fd775ca7d289f2a1ca8de34717d7784c63cfc90a +size 62938 diff --git a/docs/tutorials/external-events/assets/scheduling_goal_upload.png b/docs/tutorials/external-events/assets/scheduling_goal_upload.png new file mode 100644 index 0000000..a7529b0 --- /dev/null +++ b/docs/tutorials/external-events/assets/scheduling_goal_upload.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c01d7e7da06cb7cf9eefb485cbe7a3a9b1faf8276a83f64612080695e9a8f215 +size 281773 diff --git a/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx b/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx new file mode 100644 index 0000000..302f610 --- /dev/null +++ b/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx @@ -0,0 +1,202 @@ +import schedulingGoalUpload from './assets/scheduling_goal_upload.png'; +import schedulingGoalModal from './assets/scheduling_goal_modal.png'; +import schedulingGoalResult from './assets/scheduling_goal_result.png'; + +# Creating a Scheduling Goal with External Events +Now that we have a plan with a Derivation Group associated to it, we can create & run procedural scheduling goals that make use of External Events! + +:::info Note + +This tutorial page will talk specifically about using **External Events** in procedural scheduling. A more in-depth guide to procedural scheduling can be found [here](../../../scheduling-and-constraints/procedural/introduction/). + +::: + +:::info Note + +The following sections is a partial walk-through of creating a procedural goal with some of the general goal setup removed. For reference, the full goal as it should be written is included in the [Full Example Goal](#full-example-goal) section. + +::: + +## Creating a Scheduling Goal + +As a pre-requesite to creating a scheduling goal, follow the `Create a project from the template` steps found in the [procedural scheduling documentation](../../../scheduling-and-constraints/procedural/introduction/). + +### Example: Scheduling an activity for `SampleTypeA` +One simple use case for External Events in scheduling goals is tie-ing an activity instance to whenever an External Event occurs. In this example we'll create a goal that creates a new activity for each occurrence of a `SampleTypeA`-typed External Event in the plan. + +With the project initialized, create a new file within `scheduling/src/main/java/scheduling/procedures/` called `DemoSchedulingGoal.java`. + +External Events can be collected within the scheduling goal by creating `EventQuery`s, and using `plan.events(yourQueryHere).collect()`. To grab all the External Events of type `SampleTypeA`, we can write the following `EventQuery`: + +```java +EventQuery sampleTypeAEvents = new EventQuery(null, List.of("Sample Type A"), null); +``` + +:::info Note on nulls + +The previous `EventQuery` only includes a value for the middle argument, `eventTypes`. A query can also be constructed by passing `Derivation Group(s)` to the first argument of the `EventQuery`, or by passing a list of `Sources` gathered by a `SourceQuery` to the last argument of the `EventQuery`. + +::: + +To retrieve the External Events associated with this `EventQuery`, we can use the following line: + +```java +var exampleEvents = plan.events(sampleTypeAEvents).collect(); +``` + +Prior to planning our new activity instances, we can simulate the plan and take note of all the existing activity instances: + +```java +final var simResults = plan.simulate(); +final var existingSpans = simResults.instances(); +``` + +Next, we can iterate over all of our collected events and plan activities for them: + +```java +for (var currentEvent : exampleEvents) { + if (!areThereSpansForType(existingSpans, currentEvent.getInterval().start, newActivityType)) { + final var newActivityName = currentEvent.key + " Activity"; + final var currentEventExampleAttribute = currentEvent.attributes.get("EventExampleAttribute").asInt().get(); + plan.create( + new NewDirective( + new AnyDirective(Map.of( + "temperature", SerializedValue.of(123.1), + "tbSugar", SerializedValue.of(currentEventExampleAttribute), + "glutenFree", SerializedValue.of(false) + )), + newActivityName, + newActivityType, + new DirectiveStart.Absolute(currentEvent.getInterval().start) + ) + ); + } +} +``` + +And finally, add a `plan.commit();` after the loop to finalize your goal! + +If we compile & upload this goal, we can associate it with the plan we previously created and once scheduling is run a `BakeBananaBread` activity will be planned at the start of each `SampleTypeA` External Event! + +### Example: Scheduling an activity for `SampleTypeA` using attributes + +Building on the above example, you may want to constrain your goal to only plan activity instances on the `SampleTypeA` External Events that have their `EventExampleAttribute` attribute set to `1`. The previous example gathers the `EventExampleAttribute` for use with the `tbSugar` arugment on the `BakeBananaBread` activity but instead we could use it in the `for` loop to filter the External Events we're using for planning: + +```java +for (var currentEvent : exampleEvents) { + if (!areThereSpansForType(existingSpans, currentEvent.getInterval().start, newActivityType)) { + final var currentEventExampleAttribute = currentEvent.attributes.get("EventExampleAttribute").asInt().get(); + if (currentEventExampleAttribute == 1) { + final var newActivityName = currentEvent.key + " Activity"; + plan.create( + new NewDirective( + new AnyDirective(Map.of( + "temperature", SerializedValue.of(123.1), + "tbSugar", SerializedValue.of(currentEventExampleAttribute), + "glutenFree", SerializedValue.of(false) + )), + newActivityName, + newActivityType, + new DirectiveStart.Absolute(currentEvent.getInterval().start) + ) + ); + } + } +} +``` + +### Full Example Goal + +```java +package scheduling.procedures; + +import gov.nasa.ammos.aerie.procedural.scheduling.Goal; +import gov.nasa.ammos.aerie.procedural.scheduling.annotations.SchedulingProcedure; +import gov.nasa.ammos.aerie.procedural.scheduling.plan.EditablePlan; +import gov.nasa.ammos.aerie.procedural.scheduling.plan.NewDirective; +import gov.nasa.ammos.aerie.procedural.timeline.collections.Instances; +import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.AnyDirective; +import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.AnyInstance; +import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.DirectiveStart; +import gov.nasa.ammos.aerie.procedural.timeline.plan.EventQuery; +import gov.nasa.jpl.aerie.merlin.protocol.types.Duration; +import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue; + +import java.util.List; +import java.util.Map; + +@SchedulingProcedure +public record DemoSchedulingGoal() implements Goal { + + boolean areThereSpansForType(Instances spans, Duration startTime, String activityType) { + final var filteredByType = spans.filter(false, it -> it.getType().equals(activityType)); + final var filteredByTime = filteredByType.filter(false, it -> it.getStartTime().equals(startTime)); + return !filteredByTime.collect().isEmpty(); + } + + @Override + public void run(EditablePlan plan) { + final var newActivityType = "BakeBananaBread"; // This can be any activity type in your model! + EventQuery sampleTypeAEvents = new EventQuery(null, List.of("SampleTypeA"), null); + var exampleEvents = plan.events(sampleTypeAEvents).collect(); + + final var simResults = plan.simulate(); + final var existingSpans = simResults.instances(); + + for (var currentEvent : exampleEvents) { + if (!areThereSpansForType(existingSpans, currentEvent.getInterval().start, newActivityType)) { + var currentEventExampleAttribute = currentEvent.attributes.get("EventExampleAttribute").asInt().get(); + if (currentEventExampleAttribute == 1) { + final var newActivityName = currentEvent.key + " Activity"; + plan.create( + new NewDirective( + new AnyDirective(Map.of( + "temperature", SerializedValue.of(123.1), + "tbSugar", SerializedValue.of(currentEventExampleAttribute), + "glutenFree", SerializedValue.of(false) + )), + newActivityName, + newActivityType, + new DirectiveStart.Absolute(currentEvent.getInterval().start) + ) + ); + } + } + } + plan.commit(); + } +} +``` + +## Uploading the Scheduling Goal +After the goal has been created and saved, it must be compiled following the steps in [Getting Started](../../../scheduling-and-constraints/procedural/getting-started/). The following commands should be run from the root of the project directory: + +```bash +./gradlew :scheduling:compileJava +./gradlew :scheduling:buildAllProceduralSchedulingJars +``` + +Afterwards, a `DemoSchedulingGoal.jar` should be created in `$project/scheduling/build/libs/`! + +In the Aerie UI, navigate back to the plan view for our previously created plan and swap the top-left drop-down menu to the `Scheduling Goals` tab. From there, click `Manage Goals` and then the `New` button to be directed to creating/uploading a new scheduling goal. + +
+ Opening the scheduling goal management modal +
+ +In the creation form, enter a name (for example, `DemoSchedulingGoal`), swap the `EDSL/Jar File` button to `Jar File`, and then click `Choose File` and select the previously created `.jar` file. Your screen should show the following: + +
+ Successful scheduling goal upload +
+ +Back in the plan view, the goal can now be associated and run + +
+ Result from running scheduling goal +
Two new activities should be created to satisfy the scheduling goal!
+
+ +## Additional Resources + +More detail on the topics discussed in this tutorial can be found under [External Events](../../../planning/external-events) diff --git a/sidebars.js b/sidebars.js index 658e72c..fd84d7b 100644 --- a/sidebars.js +++ b/sidebars.js @@ -82,6 +82,7 @@ const sidebars = { 'tutorials/external-events/creating-an-external-source', 'tutorials/external-events/uploading-an-external-source', 'tutorials/external-events/associating-derivation-groups', + 'tutorials/external-events/creating-a-scheduling-goal-with-external-events', ], }, ], @@ -160,9 +161,9 @@ const sidebars = { label: 'External Events', link: { id: 'planning/external-events/introduction', - type: 'doc' + type: 'doc', }, - items: ['planning/external-events/external-events-attributes'] + items: ['planning/external-events/external-events-attributes'], }, { type: 'category', @@ -197,7 +198,7 @@ const sidebars = { label: 'Scheduling & Constraints', link: { id: 'scheduling-and-constraints/introduction', - type: 'doc' + type: 'doc', }, items: [ 'scheduling-and-constraints/management', @@ -206,7 +207,7 @@ const sidebars = { label: 'Procedural', link: { id: 'scheduling-and-constraints/procedural/introduction', - type: 'doc' + type: 'doc', }, items: [ 'scheduling-and-constraints/procedural/getting-started', @@ -215,15 +216,15 @@ const sidebars = { label: 'Timelines', link: { id: 'scheduling-and-constraints/procedural/timelines/introduction', - type: 'doc' + type: 'doc', }, items: [ { type: 'category', - label: "Basics", + label: 'Basics', link: { id: 'scheduling-and-constraints/procedural/timelines/basics/introduction', - type: 'doc' + type: 'doc', }, items: [ 'scheduling-and-constraints/procedural/timelines/basics/profiles', @@ -231,23 +232,23 @@ const sidebars = { 'scheduling-and-constraints/procedural/timelines/basics/activities', 'scheduling-and-constraints/procedural/timelines/basics/external-events', 'scheduling-and-constraints/procedural/timelines/basics/windows', - 'scheduling-and-constraints/procedural/timelines/basics/common-operations' - ] + 'scheduling-and-constraints/procedural/timelines/basics/common-operations', + ], }, { type: 'category', - label: "Advanced", + label: 'Advanced', link: { id: 'scheduling-and-constraints/procedural/timelines/advanced/introduction', - type: 'doc' + type: 'doc', }, items: [ // 'scheduling-and-constraints/procedural/timelines/advanced/parallel-profiles', // 'scheduling-and-constraints/procedural/timelines/advanced/custom-operations', // 'scheduling-and-constraints/procedural/timelines/advanced/custom-timelines' - ] - } - ] + ], + }, + ], }, 'scheduling-and-constraints/procedural/plan-and-sim-results', 'scheduling-and-constraints/procedural/constraints', @@ -256,22 +257,20 @@ const sidebars = { label: 'Scheduling', link: { id: 'scheduling-and-constraints/procedural/scheduling/introduction', - type: 'doc' + type: 'doc', }, - items: [ - 'scheduling-and-constraints/procedural/scheduling/examples' - ] + items: ['scheduling-and-constraints/procedural/scheduling/examples'], }, 'scheduling-and-constraints/procedural/parameters-and-invocations', // 'scheduling-and-constraints/procedural/running-externally' - ] + ], }, { type: 'category', label: 'Declarative', link: { id: 'scheduling-and-constraints/declarative/introduction', - type: 'doc' + type: 'doc', }, items: [ { @@ -310,10 +309,10 @@ const sidebars = { }, ], }, - ] + ], }, - 'scheduling-and-constraints/execution' - ] + 'scheduling-and-constraints/execution', + ], }, { type: 'category', From a82c7e041cfad3e965c062d2aea942279776e973 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Mon, 9 Dec 2024 15:11:16 -0500 Subject: [PATCH 5/7] Add full type definition to external event introduction --- .../planning/external-events/introduction.mdx | 106 +++++++++++++----- 1 file changed, 77 insertions(+), 29 deletions(-) diff --git a/docs/planning/external-events/introduction.mdx b/docs/planning/external-events/introduction.mdx index 9aaab56..eccf3df 100644 --- a/docs/planning/external-events/introduction.mdx +++ b/docs/planning/external-events/introduction.mdx @@ -43,10 +43,10 @@ External Events represent temporal occurrences outside of the locus of control o External Sources are containers for External Events and the primary way that users interact with External Events. To get External Events into Aerie, an External Source must be uploaded that contains the event definitions inside. See [External Sources](#external-sources-1) below for more information. #### External Event Types -External Event Types define the *typing* of each External Event. This typing groups External Events on the basis of the data they represent, and details the allowed attributes that a given External Event is allowed to have. For example, an External Event may be of the type `Ground Station Contact`, `Solar Flare`, or `Weather Forecast`. Each of these types may entail a set of allowed/defined attributes, like `station`, `flux level`, or `precipitation`. +External Event Types define the *typing* of each External Event. This typing groups External Events on the basis of the data they represent, and details the allowed attributes that a given External Event is allowed to have. For example, an External Event may be of the type `Ground Station Contact`, `Solar Flare`, or `Weather Forecast`. Each of these types contains a schema for a set of allowed/defined attributes which are then implemented by the events using this External Event Type to display additional data, such as `station`, `flux level`, or `precipitation`. #### External Source Types -External Source Types define the *typing* of each External Source. This typing groups External Sources on the basis of the data they contain, and details the allowed attributes that a given External Source can have to describe the data contained within it. For example, you may have an External Source Type of `Weather Report` to represent all your weather reports, and inside each of the `Weather Report`-typed sources you can expect to find External Events that share a common External Event Type that appears in all `Weather Report`-typed sources (ex: Temperature). The attributes related to such a source may include details about the people and data involved in creating the forecast. +External Source Types define the *typing* of each External Source. This typing groups External Sources on the basis of the data they contain, and details the allowed attributes that a given External Source can have to describe the data contained within it. For example, you may have an External Source Type of `Weather Report` to represent all your weather reports, and inside each of the `Weather Report`-typed sources you can expect to find External Events that share a common External Event Type that appears in all `Weather Report`-typed sources (ex: Temperature). Identical to [External Event Types](#external-event-types), External Source Types also contain attribute schemas that are then implemented by the External Sources using the External Source Type. #### Derivation Groups Derivation Groups are collections of External Sources that can be associated with plans. Within a Derivation Group, the collective External Events from its member External Sources are used to create a *derived* set of events for the Derivation Group. See [Derivation](#derivation) below for more information. @@ -124,6 +124,7 @@ The `source` field includes the following fields, where **all** are required: * `attributes` * An object that includes additional data relevant to the External Source in question. + * Must follow the schema as defined by the External Source Type * For a Weather Forecast file, this may include details about the location, which version this file is, and notes about what changed between this version and the last. * ***Example*** ```json @@ -136,21 +137,6 @@ The `source` field includes the following fields, where **all** are required: ... ``` -* `attributes` - * Defines the *values* for the attributes of the External Source - these attributes are *defined* or *schematized* by the External Source Type. - * **Example** - ```json - "attributes": { - "version": "1.2.3", - "week": 2, - "isTestFile": true, - "relatedPeriod": { - "startTime": "2024-001T00:00:00Z", - "endTime": "2024-008T00:00:00Z" - } - } - ``` - ##### Events Events are represented as a set of objects contained in a list, and each event has the following fields: @@ -176,6 +162,7 @@ Events are represented as a set of objects contained in a list, and each event h * `attributes` * Similar to attributes for External Sources, this property lists various characteristics of a given event not directly implied by the above fields' values. + * Must follow the schema as defined by the External Event Type * For a Weather Forecast file, a given event may require properties detailing the likelihood of precipitation, or the wind speed. * **Example:** ```json @@ -187,6 +174,79 @@ Events are represented as a set of objects contained in a list, and each event h ... ``` +##### Full External Source & Event Types Example + +The following is a full example of a valid, `JSON` representation of an External Source Type and External Event Type. The type definitions **must** be uploaded to Aerie *prior* to attempting to use them in an External Source and/or External Event(s)! + +The example represents the definitions for a weather forecast source & event. + +```json +{ + "event_types": { + "WeatherReport": { + "type": "object", + "required": ["daily_high", "daily_low", "precipitation_lik"], + "properties": { + "daily_high": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "daily_low": { + "type": "object", + "properties": { + "value": { + "type": "number" + }, + "units": { + "type": "string" + } + }, + "required": ["units", "value"] + }, + "precipitation_lik": { + "type": "number" + } + } + } + }, + "source_types": { + "Weather": { + "type": "object", + "required": [ + "location", + "version", + "changelog" + ], + "properties": { + "location": { + "type": "string" + }, + "version": { + "type": "number" + }, + "changelog": { + "type": "string" + } + } + } + } +} +``` + +:::info Note + +For more information on External Source & Type definitions & attribute schemas, see [External Events and Source Attributes](../external-events-attributes) + +::: + ##### Full External Source Example The following is a full example of a valid, `JSON` representation of an External Source that can be ingested by Aerie. @@ -227,8 +287,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.7 } }, - - { "key": "W/Day/002", "event_type": "WeatherReport", @@ -246,8 +304,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.6 } }, - - { "key": "W/Day/003", "event_type": "WeatherReport", @@ -265,8 +321,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.5 } }, - - { "key": "W/Day/004", "event_type": "WeatherReport", @@ -284,8 +338,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.4 } }, - - { "key": "W/Day/005", "event_type": "WeatherReport", @@ -303,8 +355,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.3 } }, - - { "key": "W/Day/006", "event_type": "WeatherReport", @@ -322,8 +372,6 @@ The example represents a week-long weather forecast where each event is the repo "precipitation_lik": 0.2 } }, - - { "key": "W/Day/007", "event_type": "WeatherReport", From 90e75ddbc9e8e0e8231b3465e32f128f14fc1d27 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Mon, 9 Dec 2024 15:36:28 -0500 Subject: [PATCH 6/7] Fix broken links --- docs/planning/collaboration/merging-plans.mdx | 2 +- docs/planning/external-events/introduction.mdx | 6 +++--- .../external-events/associating-derivation-groups.mdx | 6 +++--- .../creating-a-scheduling-goal-with-external-events.mdx | 2 +- .../external-events/creating-an-external-source.mdx | 2 +- docs/tutorials/external-events/introduction.mdx | 2 +- .../external-events/uploading-an-external-source.mdx | 2 +- docs/upgrade-guides/2-21-0-to-3-0-0.md | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/planning/collaboration/merging-plans.mdx b/docs/planning/collaboration/merging-plans.mdx index 9d7330e..e143fc6 100644 --- a/docs/planning/collaboration/merging-plans.mdx +++ b/docs/planning/collaboration/merging-plans.mdx @@ -136,6 +136,6 @@ import approveMerge from './assets/approve-merge.png'; :::info External Events and Plan Merge -External Events (specifically, derivation groups) are not included in plan snapshots and merges. This will be addressed in a future release. See [External Events](../../external-events) for more information. +External Events (specifically, derivation groups) are not included in plan snapshots and merges. This will be addressed in a future release. See [External Events](../../external-events/introduction) for more information. ::: diff --git a/docs/planning/external-events/introduction.mdx b/docs/planning/external-events/introduction.mdx index eccf3df..8250816 100644 --- a/docs/planning/external-events/introduction.mdx +++ b/docs/planning/external-events/introduction.mdx @@ -557,7 +557,7 @@ External Events show up in the UI in two main places - an External Source Manage :::info Note -There is also a [tutorial section](../../tutorials/external-events/introduction) that walks through the content of this section in a step-by-step fashion, albeit with less detail. +There is also a [tutorial section](../../../tutorials/external-events/introduction) that walks through the content of this section in a step-by-step fashion, albeit with less detail. ::: @@ -686,9 +686,9 @@ As a final note on the frontend, it is worth briefly detailing what parts of the - _External Event options_ - the options in the timeline editor filter. ## Scheduling Activities from Events -External events associated with a plan are accessible from the [Procedural Scheduling](../../scheduling-and-constraints/procedural/introduction/) API, just like resources and activities. This allows users to write scheduling goals which create activities based on the presence (or absence) of external events - for example, "create a downlink activity 5 minutes after the start of every 'DSN Contact' type event". +External events associated with a plan are accessible from the [Procedural Scheduling](../../../scheduling-and-constraints/procedural/introduction/) API, just like resources and activities. This allows users to write scheduling goals which create activities based on the presence (or absence) of external events - for example, "create a downlink activity 5 minutes after the start of every 'DSN Contact' type event". -To access events in a procedural goal, you must create an External Events timeline object - see [Timelines: External Events](../../scheduling-and-constraints/procedural/timelines/basics/external-events/). A full example of a scheduling goal using events can be found on the [Procedural Scheduling Examples](../../scheduling-and-constraints/procedural/scheduling/examples/#scheduling-based-off-of-external-events) page. +To access events in a procedural goal, you must create an External Events timeline object - see [Timelines: External Events](../../../scheduling-and-constraints/procedural/timelines/basics/external-events/). A full example of a scheduling goal using events can be found on the [Procedural Scheduling Examples](../../../scheduling-and-constraints/procedural/scheduling/examples/#scheduling-based-off-of-external-events) page. Currently, external events are **not accessible from the [Declarative Scheduling EDSL](http://localhost:3000/aerie-docs/scheduling-and-constraints/declarative/scheduling/introduction/)** - but we may implement support for this in the future. diff --git a/docs/tutorials/external-events/associating-derivation-groups.mdx b/docs/tutorials/external-events/associating-derivation-groups.mdx index 207e7bf..0b4f52c 100644 --- a/docs/tutorials/external-events/associating-derivation-groups.mdx +++ b/docs/tutorials/external-events/associating-derivation-groups.mdx @@ -61,7 +61,7 @@ Once here we can now look at all of our available (currently only one) Derivatio :::info Note -Details on what exactly association entails can be found [here](../../../planning/external-events/) under `Derivation Group Management Modal`. +Details on what exactly association entails can be found [here](../../../planning/external-events/introduction) under `Derivation Group Management Modal`. ::: @@ -133,8 +133,8 @@ External events appear in the same layer type as activities, and as such share o [//]: # (There is a single option that is specific to external events: `Group By`. This allows the user to display the external events either as being grouped underneath the their respective external sources, or grouped underneath their respective external event types.) -[//]: # (Additionally, there is an option for external events on the timeline that doesn't appear underneath the timeline editor: enabling/disabling visibility. This allows the user to hide (or un-hide) derivation groups from being drawn on the timeline irrespective of what row or layer they appear on. More information can be found under the [Plan](../../../planning/external-events/#plan) section of the main External Events documentation.) +[//]: # (Additionally, there is an option for external events on the timeline that doesn't appear underneath the timeline editor: enabling/disabling visibility. This allows the user to hide (or un-hide) derivation groups from being drawn on the timeline irrespective of what row or layer they appear on. More information can be found under the [Plan](../../../planning/external-events/introduction/#plan) section of the main External Events documentation.) -[//]: # (Examples of the two different `Group By` modes, as well as visibility enable/disable can be seen in the [Plan](../../../planning/external-events/#plan) section of the main External Events documentation.) +[//]: # (Examples of the two different `Group By` modes, as well as visibility enable/disable can be seen in the [Plan](../../../planning/external-events/introduction/#plan) section of the main External Events documentation.) With a Derivation Group associated to our plan, we can now run scheduling goals that incorporate External Events! diff --git a/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx b/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx index 302f610..5efe3f8 100644 --- a/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx +++ b/docs/tutorials/external-events/creating-a-scheduling-goal-with-external-events.mdx @@ -199,4 +199,4 @@ Back in the plan view, the goal can now be associated and run ## Additional Resources -More detail on the topics discussed in this tutorial can be found under [External Events](../../../planning/external-events) +More detail on the topics discussed in this tutorial can be found under [External Events](../../../planning/external-events/introduction) diff --git a/docs/tutorials/external-events/creating-an-external-source.mdx b/docs/tutorials/external-events/creating-an-external-source.mdx index c4d4032..c3911da 100644 --- a/docs/tutorials/external-events/creating-an-external-source.mdx +++ b/docs/tutorials/external-events/creating-an-external-source.mdx @@ -145,4 +145,4 @@ In each of these files, the exact formatting of the `key` field is currently not ::: -More details can be found in the [External Events](../../../planning/external-events/) section. +More details can be found in the [External Events](../../../planning/external-events/introduction) section. diff --git a/docs/tutorials/external-events/introduction.mdx b/docs/tutorials/external-events/introduction.mdx index 5706e89..f03a537 100644 --- a/docs/tutorials/external-events/introduction.mdx +++ b/docs/tutorials/external-events/introduction.mdx @@ -1,6 +1,6 @@ # External Events Tutorial -In this tutorial, we will provide a brief overview of External Events in Aerie in a walkthrough format. Extensive details on what External Events, External Sources, and Derivation Groups are can be found under at [External Events planning](../../../planning/external-events) section. +In this tutorial, we will provide a brief overview of External Events in Aerie in a walkthrough format. Extensive details on what External Events, External Sources, and Derivation Groups are can be found under at [External Events planning](../../../planning/external-events/introduction) section. ## Prerequisites diff --git a/docs/tutorials/external-events/uploading-an-external-source.mdx b/docs/tutorials/external-events/uploading-an-external-source.mdx index c8df89e..614e77a 100644 --- a/docs/tutorials/external-events/uploading-an-external-source.mdx +++ b/docs/tutorials/external-events/uploading-an-external-source.mdx @@ -52,7 +52,7 @@ The `Derivation Group` field allows you to change the Derivation Group that the :::info Note -For more information on Derivation Groups, refer to the [External Events](../../../planning/external-events) documentation underneath the `Derivation` section! +For more information on Derivation Groups, refer to the [External Events](../../../planning/external-events/introduction) documentation underneath the `Derivation` section! ::: diff --git a/docs/upgrade-guides/2-21-0-to-3-0-0.md b/docs/upgrade-guides/2-21-0-to-3-0-0.md index a1db2b5..dfd40b0 100644 --- a/docs/upgrade-guides/2-21-0-to-3-0-0.md +++ b/docs/upgrade-guides/2-21-0-to-3-0-0.md @@ -2,5 +2,5 @@ No special instructions are necessary to upgrade to `v3.0.0`. -Aerie `v3.0.0` includes a new feature to support uploading and visualizing External Events, see the [External Events](https://nasa-ammos.github.io/aerie-docs/planning/external-events/) docs page for more information. +Aerie `v3.0.0` includes a new feature to support uploading and visualizing External Events, see the [External Events](https://nasa-ammos.github.io/aerie-docs/planning/external-events/introduction) docs page for more information. From 80d2ab6cceb40c02c927a4072a340d6368f526e5 Mon Sep 17 00:00:00 2001 From: JosephVolosin Date: Fri, 13 Dec 2024 13:44:10 -0500 Subject: [PATCH 7/7] Add API documents for External Events --- .../external-events-uploadExternalSource.png | 3 + ...-events-uploadExternalSourceEventTypes.png | 3 + docs/api/examples/external-events.mdx | 297 ++++++++++++++++++ sidebars.js | 1 + 4 files changed, 304 insertions(+) create mode 100644 docs/api/assets/external-events-uploadExternalSource.png create mode 100644 docs/api/assets/external-events-uploadExternalSourceEventTypes.png create mode 100644 docs/api/examples/external-events.mdx diff --git a/docs/api/assets/external-events-uploadExternalSource.png b/docs/api/assets/external-events-uploadExternalSource.png new file mode 100644 index 0000000..909cbb3 --- /dev/null +++ b/docs/api/assets/external-events-uploadExternalSource.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb5d9bcd51549911df2398f52b3c6da86379c8c48f19589803a80e329cd736d +size 165198 diff --git a/docs/api/assets/external-events-uploadExternalSourceEventTypes.png b/docs/api/assets/external-events-uploadExternalSourceEventTypes.png new file mode 100644 index 0000000..4923e91 --- /dev/null +++ b/docs/api/assets/external-events-uploadExternalSourceEventTypes.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53a867f7ee954b92706e79b427e3772798a254b26829f06afee18abce925138f +size 188012 diff --git a/docs/api/examples/external-events.mdx b/docs/api/examples/external-events.mdx new file mode 100644 index 0000000..59e3bc9 --- /dev/null +++ b/docs/api/examples/external-events.mdx @@ -0,0 +1,297 @@ +import uploadExternalSourceEventTypes from '../assets/external-events-uploadExternalSourceEventTypes.png'; +import uploadExternalSource from '../assets/external-events-uploadExternalSource.png'; + +# External Events + +Refer to [External Events](../../../planning/external-events/introduction) for more information on External Events & Sources. + +## API Gateway +External Events & their respective External Sources utilize routes located on [`aerie-gateway`](https://github.com/NASA-AMMOS/aerie-gateway) to perform data validation and upon success, an upload through Hasura/GQL. + + +### Creating External Source & Event Types +Users should use the following `aerie-gateway` route to upload their "types" file: +
+ Request headers & body for the 'uploadExternalSourceEventTypes' route +
Request headers & body for the 'uploadExternalSourceEventTypes' route
+
+ +When uploading through Aerie's UI, External Source & Event types are packaged together in a single `JSON` file which adheres to the meta-schema defined [here](https://github.com/NASA-AMMOS/aerie-gateway/blob/develop/src/schemas/external-event-validation-schemata.ts). **However**, the Gateway route accepts the content of the two top-level fields (`event_types` and `source_types`) separately as the request body. + +Uploading a simple definition of a single External Source Type (`ExampleSource`) and a single External Event Type (`ExampleEvent`) should yield the following response: + +**Example Input** + +`event_types` +```json +{ + "ExampleEvent": { + "type": "object", + "properties": { + "example": { + "type": "string" + } + }, + "required": [ "example" ] + } +} +``` + +`source_types` +```json +{ + "ExampleSource": { + "type": "object", + "properties": { + "example": { + "type": "string" + } + }, + "required": [ "example" ] + } +} +``` + +**Example Output** +```json +{ + "createExternalEventTypes": { + "returning": [ + { + "name": "ExampleEvent" + } + ] + }, + "createExternalSourceTypes": { + "returning": [ + { + "name": "ExampleSource" + } + ] + } +} +``` + +### Creating an External Source +Users should use the following `aerie-gateway` route to upload their External Sources file: +
+ Request headers & body for the 'uploadExternalSource' route +
Request headers & body for the 'uploadExternalSource' route
+
+ +When uploading through Aerie's UI, the External Source & it's contained External Events are packaged together in a single `JSON` file which adheres to the meta-schema defined [here](https://github.com/NASA-AMMOS/aerie-gateway/blob/develop/src/schemas/external-event-validation-schemata.ts). **However**, the Gateway route accepts the content of the two top-level fields (`source` and `events`) separately as the request body. + +:::info Note + +In order to upload an External Source, the **External Source Type** and **External Event Type** **must** exist. For uploading types, see [above](#creating-external-source--event-types). + +::: + +Uploading a simple definition of an External Source with a single External Event should yield the following result: + +**Example Input** + +`source` +```json +{ + "attributes": { "example": "Example attribute" }, + "derivation_group_name": "ExampleSource Default", + "key": "ExampleSource:1", + "period": { + "end_time": "2024-008T00:00:00Z", + "start_time": "2024-001T00:00:00Z" + }, + "source_type_name": "ExampleSource", + "valid_at": "2024-001T00:00:00Z" +} +``` + +`events` +```json +[ + { + "attributes": { "example": "Example attribute" }, + "duration": "00:00:01", + "event_type_name": "ExampleEvent", + "key": "ExampleEvent:1", + "start_time": "2024-002T00:00:00Z" + } +] +``` + +**Example Output** +```json +{ + "upsertDerivationGroup": { + "name": "ExampleSource Default" + }, + "createExternalSource": { + "attributes": { + "example": "Example attribute" + }, + "derivation_group_name": "ExampleSource Default", + "end_time": "2024-01-08T00:00:00+00:00", + "key": "ExampleSource:1", + "source_type_name": "ExampleSource", + "start_time": "2024-01-01T00:00:00+00:00", + "valid_at": "2024-01-01T00:00:00+00:00" + } +} +``` + +## GQL +The following operations can be performed directly through GQL/Hasura and do not need to interact with Gateway like the above section. + +### Associating a Derivation Group to a Plan +If a plan and a derivation group exist, they can be associated using the following GraphQL mutation: + +```graphql +mutation CreatePlanDerivationGroup($source: plan_derivation_group_insert_input!) { + planExternalSourceLink: insert_plan_derivation_group_one( + object: $source, + on_conflict: { + constraint: plan_derivation_group_pkey + } + ) { + derivation_group_name + } +} +``` + +This mutation requires a an argument, `$source`, which includes: 1) the name of the derivation group to link, and 2) the ID of the plan to link it to. See below for an example input: + +```json +{ + "source": { + "derivation_group_name": "ExampleSource Default", + "plan_id": 1 + } +} +``` + +This request will yield the following response: + +```json +{ + "data": { + "planExternalSourceLink": { + "derivation_group_name": "ExampleSource Default" + } + } +} +``` + +### Disassociating a Derivation Group from a Plan +To disassociate a derivation group from a plan, the following GraphQL mutation can be used: + +```graphql +mutation DeletePlanExternalSource($where: plan_derivation_group_bool_exp!) { + planDerivationGroupLink: delete_plan_derivation_group(where: $where) { + returning { + derivation_group_name + } + } +} +``` + +This mutations requires an argument which is an expression returning a boolean such as: + +```json +{ + "where": { + "_and": { + "derivation_group_name": { "_eq": "ExampleSource Default" }, + "plan_id": { "_eq": 1} + } + } +} +``` + +This request will yield the following response: + +```json +{ + "data": { + "planDerivationGroupLink": { + "returning": [ + { + "derivation_group_name": "ExampleSource Default" + } + ] + } + } +} +``` + +### Get External Events +```graphql +query GetExternalEvents { + external_event { + attributes + event_type_name + key + duration + start_time + source_key + } +} +``` + +### Get External Events from an External Source +```graphql +query GetExternalEventsFromExternalSource($sourceKey: String!, $derivationGroupName: String!) { + external_event(where: {source_key: {_eq: $sourceKey}, derivation_group_name: {_eq: $derivationGroupName}}) { + attributes + event_type_name + key + duration + start_time + source_key + } +} +``` + +### Get External Sources +```graphql +query GetExternalSources { + external_source { + attributes + created_at + derivation_group_name + end_time + key + owner + start_time + source_type_name + valid_at + } +} +``` + +### Get External Sources from a Derivation Group +```graphql +query GetExternalSourcesFromDerivationGroup($derivationGroupName: String!) { + external_source(where: {derivation_group_name: {_eq: $derivationGroupName}}) { + attributes + created_at + derivation_group_name + end_time + key + owner + start_time + source_type_name + valid_at + } +} +``` + +### Get Derivation Groups +```graphql +query GetDerivationGroup { + derivation_group { + name + owner + source_type_name + } +} +``` diff --git a/sidebars.js b/sidebars.js index fd84d7b..46b0216 100644 --- a/sidebars.js +++ b/sidebars.js @@ -31,6 +31,7 @@ const sidebars = { 'api/examples/activity-presets', 'api/examples/advanced-extensions', 'api/examples/tags', + 'api/examples/external-events', ], }, ],