{
  "$id": "/1-4-1/application.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "YAML Application Description",
  "description": "An AICA application graph description using YAML syntax.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "on_start": {
      "title": "On Start",
      "description": "A special keyword that triggers events when the application is launched",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "load": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Load",
          "description": "Load a component, hardware interface or controller",
          "oneOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "$ref": "#/properties/on_start/properties/load/oneOf/1"
              }
            },
            {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Load / Unload Target",
              "description": "Identifier for a component, hardware interface or controller to load or unload",
              "oneOf": [
                {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "component": {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
                    }
                  },
                  "required": [
                    "component"
                  ]
                },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "hardware": {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
                    }
                  },
                  "required": [
                    "hardware"
                  ]
                },
                {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "title": "Controller Identifier",
                  "description": "A controller associated with a particular hardware interface",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "hardware": {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
                    },
                    "controller": {
                      "title": "Controller Name",
                      "description": "The name of a controller",
                      "type": "string",
                      "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
                    }
                  },
                  "required": [
                    "hardware",
                    "controller"
                  ]
                }
              ]
            }
          ]
        },
        "lifecycle": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Lifecycle Transition",
          "description": "Transition the lifecycle state on a component",
          "oneOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "oneOf": [
                  {
                    "$ref": "#/properties/on_start/properties/lifecycle/$defs/lifecycle_object"
                  },
                  {
                    "$ref": "#/properties/on_start/properties/lifecycle/$defs/transition"
                  }
                ]
              }
            },
            {
              "$ref": "#/properties/on_start/properties/lifecycle/$defs/lifecycle_object"
            },
            {
              "$ref": "#/properties/on_start/properties/lifecycle/$defs/transition"
            }
          ],
          "$defs": {
            "transition": {
              "title": "Lifecycle Transition Label",
              "description": "A lifecycle transition",
              "type": "string",
              "enum": [
                "create",
                "configure",
                "cleanup",
                "activate",
                "deactivate",
                "unconfigured_shutdown",
                "inactive_shutdown",
                "active_shutdown",
                "destroy"
              ]
            },
            "lifecycle_object": {
              "title": "Lifecycle Object",
              "description": "A lifecycle identifier containing a transition label and target component",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "transition": {
                  "$ref": "#/properties/on_start/properties/lifecycle/$defs/transition"
                },
                "component": {
                  "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
                }
              },
              "required": [
                "transition"
              ]
            }
          }
        },
        "call_service": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Call Service",
          "description": "Call a service",
          "oneOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "$ref": "#/properties/on_start/properties/call_service/$defs/service_object"
              }
            },
            {
              "$ref": "#/properties/on_start/properties/call_service/$defs/service_object"
            },
            {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Service Name",
              "description": "The name of a service",
              "type": "string",
              "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
            }
          ],
          "$defs": {
            "payload": {
              "title": "Service Payload",
              "description": "The payload of the service call, formatted according to the service description",
              "type": [
                "string",
                "object"
              ]
            },
            "service_object": {
              "title": "Call Service Object",
              "oneOf": [
                {
                  "title": "Call Component Service Object",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "service": {
                      "$ref": "#/properties/on_start/properties/call_service/oneOf/2"
                    },
                    "payload": {
                      "$ref": "#/properties/on_start/properties/call_service/$defs/payload"
                    },
                    "component": {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
                    }
                  },
                  "required": [
                    "service"
                  ]
                },
                {
                  "title": "Call Controller Service Object",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "service": {
                      "$ref": "#/properties/on_start/properties/call_service/oneOf/2"
                    },
                    "hardware": {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
                    },
                    "controller": {
                      "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
                    },
                    "payload": {
                      "$ref": "#/properties/on_start/properties/call_service/$defs/payload"
                    }
                  },
                  "required": [
                    "service",
                    "hardware",
                    "controller"
                  ]
                }
              ]
            }
          }
        },
        "switch_controllers": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Switch Controllers",
          "description": "Activate or deactivate controllers on a hardware interface",
          "oneOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "$ref": "#/properties/on_start/properties/switch_controllers/$defs/switch_controllers_object"
              }
            },
            {
              "$ref": "#/properties/on_start/properties/switch_controllers/$defs/switch_controllers_object"
            }
          ],
          "$defs": {
            "switch_controllers_object": {
              "title": "Switch Controllers Object",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "hardware": {
                  "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
                },
                "activate": {
                  "$ref": "#/properties/on_start/properties/switch_controllers/$defs/switch_controllers_target"
                },
                "deactivate": {
                  "$ref": "#/properties/on_start/properties/switch_controllers/$defs/switch_controllers_target"
                }
              },
              "required": [
                "hardware"
              ]
            },
            "switch_controllers_target": {
              "title": "Target Controller",
              "Description": "A controller or list of controllers",
              "additionalProperties": false,
              "oneOf": [
                {
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
                  }
                },
                {
                  "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
                }
              ]
            }
          }
        },
        "sequence": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Manage a sequence",
          "description": "Start, restart or abort a sequence",
          "oneOf": [
            {
              "type": "array",
              "minItems": 1,
              "items": {
                "$ref": "#/properties/on_start/properties/sequence/$defs/sequence_object"
              }
            },
            {
              "$ref": "#/properties/on_start/properties/sequence/$defs/sequence_object"
            }
          ],
          "$defs": {
            "sequence_object": {
              "title": "Sequence event",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "start": {
                  "description": "Name of the sequence to start",
                  "type": "string"
                },
                "restart": {
                  "description": "Name of the sequence to restart",
                  "type": "string"
                },
                "abort": {
                  "description": "Name of the sequence to abort",
                  "type": "string"
                }
              },
              "oneOf": [
                {
                  "required": [
                    "start"
                  ]
                },
                {
                  "required": [
                    "restart"
                  ]
                },
                {
                  "required": [
                    "abort"
                  ]
                }
              ]
            }
          }
        },
        "position": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Position",
          "description": "The position of the element on the graph",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "x": {
              "title": "X Position",
              "description": "The X position of the element on the graph",
              "type": "number"
            },
            "y": {
              "title": "Y Position",
              "description": "The Y position of the element on the graph",
              "type": "number"
            }
          },
          "required": [
            "x",
            "y"
          ]
        }
      }
    },
    "hardware": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Hardware Interfaces",
      "description": "A description of hardware interfaces used in the application",
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
          "title": "Hardware",
          "description": "A named hardware configuration",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "urdf": {
              "title": "URDF",
              "description": "The path to the URDF file of the hardware",
              "type": "string"
            },
            "rate": {
              "title": "Rate",
              "description": "The rate in Hz at which to run the hardware interface",
              "type": "number"
            },
            "parameters": {
              "title": "Hardware Parameters",
              "type": "object",
              "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                  "title": "Hardware Parameter",
                  "description": "A hardware parameter in the URDF to be overridden with a new value",
                  "type": [
                    "string"
                  ]
                }
              }
            },
            "display_name": {
              "title": "Hardware Display Name",
              "description": "The human-readable name to display on the hardware interface",
              "type": "string"
            },
            "position": {
              "$ref": "#/properties/on_start/properties/position"
            },
            "controllers": {
              "title": "Controllers",
              "description": "The controllers attached to the hardware interface",
              "additionalProperties": false,
              "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                  "title": "Controller",
                  "description": "A named controller configuration",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "log_level": {
                      "$ref": "#/properties/components/patternProperties/(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)/properties/log_level"
                    },
                    "plugin": {
                      "title": "Controller Plugin",
                      "description": "The name of the controller plugin",
                      "type": "string"
                    },
                    "parameters": {
                      "$ref": "#/properties/components/patternProperties/(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)/properties/parameters"
                    },
                    "inputs": {
                      "$ref": "#/properties/components/patternProperties/(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)/properties/inputs"
                    },
                    "outputs": {
                      "$ref": "#/properties/components/patternProperties/(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)/properties/outputs"
                    },
                    "events": {
                      "title": "Controller Event Predicates",
                      "description": "Controller predicates that trigger events",
                      "type": "object",
                      "additionalProperties": false,
                      "patternProperties": {
                        "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                          "title": "Controller Predicate",
                          "description": "A controller-specific predicate",
                          "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                        }
                      }
                    }
                  },
                  "required": [
                    "plugin"
                  ]
                }
              }
            }
          },
          "required": [
            "urdf",
            "rate"
          ]
        }
      }
    },
    "components": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Components",
      "description": "A description of components used in the application",
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
          "title": "Component",
          "description": "A named component configuration",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "log_level": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Log Level",
              "description": "The log severity level for the component",
              "type": "string",
              "enum": [
                "debug",
                "info",
                "warn",
                "error",
                "fatal"
              ]
            },
            "display_name": {
              "title": "Component Display Name",
              "description": "The human-readable name to display on the component",
              "type": "string"
            },
            "component": {
              "title": "Component Registration",
              "description": "The fully qualified class name used to register the component",
              "type": "string"
            },
            "mapping": {
              "title": "Component Mapping",
              "description": "The remapping rules for the component name and namespace",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "name": {
                  "title": "Name Mapping",
                  "description": "The remapping rules for the component name",
                  "type": "string",
                  "pattern": "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$"
                },
                "namespace": {
                  "title": "Namespace Mapping",
                  "description": "The remapping rules for the component namespace",
                  "type": "string",
                  "pattern": "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$"
                }
              }
            },
            "parameters": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Parameters",
              "description": "A collection of named parameters with assigned values",
              "type": "object",
              "additionalProperties": false,
              "patternProperties": {
                "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
                  "title": "Parameter Value",
                  "description": "The value assigned to the named parameter",
                  "type": [
                    "boolean",
                    "number",
                    "string",
                    "array"
                  ],
                  "items": {
                    "type": [
                      "boolean",
                      "number",
                      "string"
                    ]
                  }
                }
              }
            },
            "inputs": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Inputs",
              "description": "Input signals",
              "type": "object",
              "additionalProperties": false,
              "patternProperties": {
                "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
                  "title": "Input topic",
                  "description": "The corresponding topic of the input signal",
                  "type": "string"
                }
              }
            },
            "outputs": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Outputs",
              "description": "Output signals",
              "type": "object",
              "additionalProperties": false,
              "patternProperties": {
                "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
                  "title": "Output topic",
                  "description": "The corresponding topic of the output signal",
                  "type": "string"
                }
              }
            },
            "input_collections": {
              "title": "Input collections",
              "description": "Collections of input signals of the component",
              "type": "object",
              "additionalProperties": false,
              "patternProperties": {
                "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
                  "title": "Input topics",
                  "description": "The array of topics that are included in the signal collection",
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            },
            "events": {
              "title": "Component Event Predicates",
              "description": "Component predicates that trigger events",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "on_load": {
                  "title": "On Load",
                  "description": "An internal predicate that triggers events when the component is loaded",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "on_unload": {
                  "title": "On Unload",
                  "description": "An internal predicate that triggers events when the component is unloaded",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "is_unconfigured": {
                  "title": "Is Unconfigured (lifecycle)",
                  "description": "A lifecycle predicate that triggers events when the component enters the unconfigured state",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "is_inactive": {
                  "title": "Is Inactive (lifecycle)",
                  "description": "A lifecycle predicate that triggers events when the component enters the inactive state",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "is_active": {
                  "title": "Is Active (lifecycle)",
                  "description": "A lifecycle predicate that triggers events when the component enters the active state",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "is_finalized": {
                  "title": "Is Finalized (lifecycle)",
                  "description": "A lifecycle predicate that triggers events when the component enters the finalized state",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "is_finished": {
                  "title": "Is Finished",
                  "description": "A standard predicate that triggers events when the component finishes executing a post-construction function",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                },
                "in_error_state": {
                  "title": "In Error State",
                  "description": "A predicate that triggers events when the component encounters an error",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                }
              },
              "patternProperties": {
                "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$": {
                  "title": "Component Predicate",
                  "description": "A component-specific predicate",
                  "$ref": "#/properties/sequences/$defs/timeout/properties/events"
                }
              }
            },
            "position": {
              "$ref": "#/properties/on_start/properties/position"
            }
          }
        }
      }
    },
    "buttons": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Buttons",
      "description": "A description of interactive buttons in the application graph",
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
          "title": "Button",
          "description": "A named interactive button",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "display_name": {
              "title": "Button Display Name",
              "description": "The human-readable name to display on the button",
              "type": "string"
            },
            "on_click": {
              "title": "On Click",
              "description": "Events that are triggered when the button is pressed",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "load": {
                  "$ref": "#/properties/on_start/properties/load"
                },
                "unload": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "title": "Unload",
                  "description": "Unload a component, hardware interface or controller",
                  "oneOf": [
                    {
                      "type": "array",
                      "minItems": 1,
                      "uniqueItems": true,
                      "items": {
                        "$ref": "#/properties/on_start/properties/load/oneOf/1"
                      }
                    },
                    {
                      "$ref": "#/properties/on_start/properties/load/oneOf/1"
                    }
                  ]
                },
                "call_service": {
                  "$ref": "#/properties/on_start/properties/call_service"
                },
                "lifecycle": {
                  "$ref": "#/properties/on_start/properties/lifecycle"
                },
                "switch_controllers": {
                  "$ref": "#/properties/on_start/properties/switch_controllers"
                }
              }
            },
            "position": {
              "$ref": "#/properties/on_start/properties/position"
            }
          }
        }
      }
    },
    "conditions": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Conditions",
      "description": "A description of logical conditions used to trigger events in the application",
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
          "title": "Condition Name",
          "description": "The name of the condition",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "events": {
              "title": "Conditional Events",
              "description": "Events triggered by the condition",
              "$ref": "#/properties/sequences/$defs/timeout/properties/events"
            },
            "all": {
              "title": "All",
              "description": "True only when every listed item is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "any": {
              "title": "Any",
              "description": "True if at least one of the listed items is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "one_of": {
              "title": "One Of",
              "description": "True only when exactly one of the listed items is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "not": {
              "title": "Not",
              "description": "True only when the sub-item is false",
              "oneOf": [
                {
                  "$ref": "#/properties/conditions/$defs/condition_object"
                },
                {
                  "$ref": "#/properties/conditions/$defs/predicate_object"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "component": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
            },
            "controller": {
              "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
            },
            "hardware": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
            },
            "predicate": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/predicate"
            }
          },
          "oneOf": [
            {
              "required": [
                "all"
              ]
            },
            {
              "required": [
                "any"
              ]
            },
            {
              "required": [
                "one_of"
              ]
            },
            {
              "required": [
                "not"
              ]
            },
            {
              "required": [
                "component",
                "predicate"
              ]
            },
            {
              "required": [
                "controller",
                "hardware",
                "predicate"
              ]
            }
          ]
        }
      },
      "$defs": {
        "condition_object": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "all": {
              "title": "All",
              "description": "True only when every listed item is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "any": {
              "title": "Any",
              "description": "True if at least one of the listed items is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "one_of": {
              "title": "One Of",
              "description": "True only when exactly one of the listed items is true",
              "$ref": "#/properties/conditions/$defs/condition_array"
            },
            "not": {
              "title": "Not",
              "description": "True only when the sub-item is false",
              "oneOf": [
                {
                  "$ref": "#/properties/conditions/$defs/condition_object"
                },
                {
                  "$ref": "#/properties/conditions/$defs/predicate_object"
                },
                {
                  "type": "boolean"
                }
              ]
            }
          },
          "oneOf": [
            {
              "required": [
                "all"
              ]
            },
            {
              "required": [
                "any"
              ]
            },
            {
              "required": [
                "one_of"
              ]
            },
            {
              "required": [
                "not"
              ]
            }
          ]
        },
        "condition_array": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "oneOf": [
              {
                "$ref": "#/properties/conditions/$defs/condition_object"
              },
              {
                "$ref": "#/properties/conditions/$defs/predicate_object"
              },
              {
                "type": "boolean"
              }
            ]
          }
        },
        "predicate_object": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "component": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
            },
            "controller": {
              "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
            },
            "hardware": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
            },
            "predicate": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/predicate"
            }
          },
          "oneOf": [
            {
              "required": [
                "component",
                "predicate"
              ]
            },
            {
              "required": [
                "controller",
                "hardware",
                "predicate"
              ]
            }
          ]
        }
      }
    },
    "sequences": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "title": "Sequences",
      "description": "A description of sequences used to trigger events events in a specific order",
      "type": "object",
      "additionalProperties": false,
      "patternProperties": {
        "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)": {
          "title": "Sequence",
          "description": "A named event sequence",
          "type": "array",
          "items": {
            "oneOf": [
              {
                "$ref": "#/properties/sequences/$defs/timeout/properties/events"
              },
              {
                "title": "Wait",
                "additionalProperties": false,
                "properties": {
                  "wait": {
                    "oneOf": [
                      {
                        "$ref": "#/properties/sequences/$defs/wait_for_condition"
                      },
                      {
                        "$ref": "#/properties/sequences/$defs/wait_for_predicate"
                      },
                      {
                        "$ref": "#/properties/sequences/$defs/wait_for_time"
                      }
                    ]
                  }
                },
                "required": [
                  "wait"
                ]
              },
              {
                "title": "Assert",
                "additionalProperties": false,
                "properties": {
                  "assert": {
                    "oneOf": [
                      {
                        "$ref": "#/properties/sequences/$defs/assert_condition"
                      },
                      {
                        "$ref": "#/properties/sequences/$defs/assert_predicate"
                      }
                    ]
                  }
                },
                "required": [
                  "assert"
                ]
              }
            ]
          }
        }
      },
      "$defs": {
        "seconds": {
          "title": "Seconds to wait",
          "description": "The duration to wait in seconds",
          "type": "number"
        },
        "timeout": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "seconds": {
              "$ref": "#/properties/sequences/$defs/seconds"
            },
            "events": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Events",
              "description": "A description of application events to be triggered",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "load": {
                  "$ref": "#/properties/on_start/properties/load"
                },
                "unload": {
                  "$ref": "#/properties/buttons/patternProperties/(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)/properties/on_click/properties/unload"
                },
                "transition": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "title": "Transition Components",
                  "description": "Unload the current component and load another one",
                  "oneOf": [
                    {
                      "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
                    }
                  ]
                },
                "set": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "title": "Set Parameter",
                  "description": "Set a parameter on a component",
                  "oneOf": [
                    {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/set_parameter_object"
                      }
                    },
                    {
                      "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/set_parameter_object"
                    }
                  ],
                  "$defs": {
                    "parameter": {
                      "title": "Parameter Name",
                      "description": "The name of a parameter to set",
                      "type": "string",
                      "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
                    },
                    "value": {
                      "title": "New Parameter Value",
                      "description": "The value of the parameter to set",
                      "type": [
                        "boolean",
                        "number",
                        "string",
                        "array"
                      ],
                      "items": {
                        "type": [
                          "boolean",
                          "number",
                          "string"
                        ]
                      }
                    },
                    "set_parameter_object": {
                      "title": "Set Parameter Object",
                      "oneOf": [
                        {
                          "title": "Set Component Parameter Object",
                          "type": "object",
                          "additionalProperties": false,
                          "properties": {
                            "parameter": {
                              "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/parameter"
                            },
                            "value": {
                              "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/value"
                            },
                            "component": {
                              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
                            }
                          },
                          "required": [
                            "parameter",
                            "value"
                          ]
                        },
                        {
                          "title": "Set Controller Parameter Object",
                          "type": "object",
                          "additionalProperties": false,
                          "properties": {
                            "parameter": {
                              "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/parameter"
                            },
                            "value": {
                              "$ref": "#/properties/sequences/$defs/timeout/properties/events/properties/set/$defs/value"
                            },
                            "hardware": {
                              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
                            },
                            "controller": {
                              "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
                            }
                          },
                          "required": [
                            "parameter",
                            "value",
                            "hardware",
                            "controller"
                          ]
                        }
                      ]
                    }
                  }
                },
                "call_service": {
                  "$ref": "#/properties/on_start/properties/call_service"
                },
                "lifecycle": {
                  "$ref": "#/properties/on_start/properties/lifecycle"
                },
                "switch_controllers": {
                  "$ref": "#/properties/on_start/properties/switch_controllers"
                },
                "sequence": {
                  "$ref": "#/properties/on_start/properties/sequence"
                }
              }
            }
          },
          "required": [
            "seconds",
            "events"
          ]
        },
        "wait_for_condition": {
          "title": "Wait for Condition",
          "description": "Wait until a condition is true with an optional timeout to abort the sequence and handle breakout events",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "condition": {
              "$ref": "#/properties/sequences/$defs/assert_condition/properties/condition"
            },
            "timeout": {
              "$ref": "#/properties/sequences/$defs/timeout"
            }
          },
          "required": [
            "condition"
          ]
        },
        "wait_for_predicate": {
          "title": "Wait for Predicate",
          "description": "Wait until a predicate is true with an optional timeout to abort the sequence and handle breakout events",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "component": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/component"
            },
            "controller": {
              "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
            },
            "hardware": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/hardware"
            },
            "predicate": {
              "$ref": "#/properties/sequences/$defs/assert_predicate/properties/predicate"
            },
            "timeout": {
              "$ref": "#/properties/sequences/$defs/timeout"
            }
          },
          "oneOf": [
            {
              "required": [
                "component",
                "predicate"
              ]
            },
            {
              "required": [
                "controller",
                "hardware",
                "predicate"
              ]
            }
          ]
        },
        "wait_for_time": {
          "title": "Wait",
          "description": "Wait for a defined time",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "seconds": {
              "$ref": "#/properties/sequences/$defs/seconds"
            }
          },
          "required": [
            "seconds"
          ]
        },
        "assert_condition": {
          "title": "Assert Condition",
          "description": "Assert that a condition is true or else abort the sequence and handle breakout events",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "condition": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Condition Name",
              "description": "The name of a condition",
              "type": "string",
              "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
            },
            "else": {
              "description": "A description of application events to be triggered if the assertion fails",
              "$ref": "#/properties/sequences/$defs/timeout/properties/events"
            }
          },
          "required": [
            "condition"
          ]
        },
        "assert_predicate": {
          "title": "Assert Predicate",
          "description": "Assert that a predicate is true or else abort the sequence and handle breakout events",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "component": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Component Name",
              "description": "The name of a component",
              "type": "string",
              "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
            },
            "controller": {
              "$ref": "#/properties/on_start/properties/load/oneOf/1/oneOf/2/properties/controller"
            },
            "hardware": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Hardware Name",
              "description": "The name of a hardware interface",
              "type": "string",
              "pattern": "(^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$)|(^[a-zA-Z]$)"
            },
            "predicate": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "title": "Predicate Name",
              "description": "The name of a predicate",
              "type": "string",
              "pattern": "^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$"
            },
            "else": {
              "description": "A description of application events to be triggered if the assertion fails",
              "$ref": "#/properties/sequences/$defs/timeout/properties/events"
            }
          },
          "oneOf": [
            {
              "required": [
                "component",
                "predicate"
              ]
            },
            {
              "required": [
                "controller",
                "hardware",
                "predicate"
              ]
            }
          ]
        }
      }
    }
  }
}