@tak-ps/etl
    Preparing search index...

    Class default

    Index
    • Create a new TaskBase instance - Usually not called directly but instead inherited via an extends TaskBase call

      Currently settings are configured based on the environment that will be provided by the ETL server. As such the following environment variables must be set. ETL_API - The URL of the API to use ETL_LAYER - The Integer Layer ID to get config information and post results to ETL_TOKEN - The access token specific to the Layer

      Parameters

      • Optionalcurrent: string
      • Optionalopts: { logging?: { event?: boolean; webhooks?: boolean } }

      Returns default

    layer?: {
        alarm_evals: number;
        alarm_period: number;
        alarm_points: number;
        connection: number | null;
        created: string;
        description: string;
        enabled: boolean;
        id: number;
        incoming?: {
            config: { timezone?: { timezone: string } };
            created: string;
            cron: string | null;
            data: number | null;
            enabled_styles: boolean;
            environment: any;
            ephemeral: { [key: string]: unknown };
            layer: number;
            styles: unknown;
            updated: string;
            webhooks: boolean;
        };
        logging: boolean;
        memory: number;
        name: string;
        outgoing?: {
            created: string;
            environment: any;
            ephemeral: { [key: string]: unknown };
            filters: { queries?: { name?: string; query: string }[] };
            layer: number;
            subscriptions: string[];
            updated: string;
        };
        parent?: { enabled: boolean; id: number; name: string };
        priority: "high" | "low" | "off";
        status?: string;
        task: string;
        timeout: number;
        updated: string;
        username: string | null;
        uuid: string;
    }
    logging: TaskLogging
    flow: DataFlowType[] = ...
    invocation: InvocationType[] = ...
    invocationDefaults: {
        schedule?: { cron: string; enabled: boolean };
        webhook?: { enabled: boolean };
    } = {}
    name: string = 'default'
    webhooks?: (schema: Schemas, context: default) => Promise<void>
    • Post an Alert to the Layer Alert API

      Parameters

      Returns Promise<object>

      The Response from the Layer Alert API

    • Returns Promise<
          {
              incoming?: {
                  invocation: InvocationType[];
                  invocationDefaults: {
                      schedule?: { cron: string; enabled: boolean };
                      webhook?: { enabled: boolean };
                  };
                  schema: {
                      input: unknown;
                      inputError?: { message: string; status: number };
                      output: unknown;
                      outputError?: { message: string; status: number };
                  };
              };
              name: string;
              outgoing?: {
                  schema: {
                      input: unknown;
                      inputError?: { message: string; status: number };
                      output: unknown;
                      outputError?: { message: string; status: number };
                  };
              };
              version: string;
          },
      >

    • Returns Promise<void>

    • Returns Promise<Application>

    • Validate and return a typed Environment object

      Type Parameters

      • T extends TSchema = TUnknown

      Parameters

      Returns Promise<(T & { params: [] })["static"]>

    • Validate and return a typed Ephemeral object If the object fails validation, the store will be reset and an empty store returned

      Type Parameters

      • T extends TSchema = TUnknown

      Parameters

      Returns Promise<(T & { params: [] })["static"]>

    • Provides a Fetch class with preset Authentication and JSON parsing For making calls to CloudTAK APIs

      Parameters

      • url: string | URL
      • Optionalopts: FetchInit

      Returns Promise<object>

      The parsed response body

    • Get all information about the layer being processed most importantly the user-defined environment object

      Returns Promise<
          {
              alarm_evals: number;
              alarm_period: number;
              alarm_points: number;
              connection: number
              | null;
              created: string;
              description: string;
              enabled: boolean;
              id: number;
              incoming?: {
                  config: { timezone?: { timezone: string } };
                  created: string;
                  cron: string | null;
                  data: number | null;
                  enabled_styles: boolean;
                  environment: any;
                  ephemeral: { [key: string]: unknown };
                  layer: number;
                  styles: unknown;
                  updated: string;
                  webhooks: boolean;
              };
              logging: boolean;
              memory: number;
              name: string;
              outgoing?: {
                  created: string;
                  environment: any;
                  ephemeral: { [key: string]: unknown };
                  filters: { queries?: { name?: string; query: string }[] };
                  layer: number;
                  subscriptions: string[];
                  updated: string;
              };
              parent?: { enabled: boolean; id: number; name: string };
              priority: "high" | "low" | "off";
              status?: string;
              task: string;
              timeout: number;
              updated: string;
              username: string | null;
              uuid: string;
          },
      >

      A Layer Config Object

    • Parameters

      • event: SQSEvent

      Returns Promise<boolean>

    • The extended class should override this function if it needs additional user-defined config values or wants to provide a Schema

      Input: By default it simply adds a DEBUG boolean which will conditionally print CoT GeoJSON in the logs if true.

      Output: Does not provide a defined schema. Providing a schema allow the User to perform mapping and styling operations

      Tasks that submit multiple record shapes via submit({ schema, items }) can instead return an array of named Output schemas - one { id, schema } entry per shape, with the id referenced by the submission's schema field

      Parameters

      Returns Promise<TSchema | NamedSchema[]>

      A JSON Schema Object or an array of named JSON Schema Objects

    • Set ephemeral key/values Overwrites existing values, if any

      Parameters

      • ephem: Record<string, unknown>
      • flow: DataFlowType = DataFlowType.Incoming

      Returns Promise<void>

      A Layer Config Object

    • Submit a GeoJSON Feature Collection to be submitted to the TAK Server as CoTs or a { schema, items } record submission to be mapped to CoT Features, Core Events or Core Devices by the Layer's configured Maps

      A Feature Collection is posted to the /layer/:layer/cot API while a record submission is posted to the /layer/:layer/submit API. The submission's schema names which of the task's Output schemas the items conform to. opts.archive only applies to Feature Collection submissions

      Parameters

      • input:
            | SubmitRecords
            | {
                features: {
                    geometry: | { coordinates: number[]; type: "Point" }
                    | { coordinates: number[][]; type: "LineString" }
                    | { coordinates: number[][][]; type: "Polygon" };
                    id?: string;
                    path?: string;
                    properties: {
                        ackrequest?: { ackrequested: boolean; tag: string; uid: string };
                        archived?: boolean;
                        attachments?: string[];
                        bearing?: number;
                        biosensordetail?: {
                            measurement?: {
                                bioClass?: (...) | (...);
                                channel?: (...) | (...);
                                concentration?: (...) | (...);
                                confidence?: (...) | (...);
                                confirmationLevel?: (...) | (...);
                                dose: number;
                                doseTime?: (...) | (...);
                                harmful?: (...) | (...) | (...);
                                level?: (...) | (...);
                                persistency?: (...) | (...);
                                sampleId?: (...) | (...);
                                time: string;
                                type?: (...) | (...);
                            }[];
                            sensor_data: {
                                attachedUid?: string;
                                batterylevel?: number;
                                callsign?: string;
                                manufacturer: string;
                                model: string;
                                ordinal?: number;
                                revision?: number;
                                serialnumber: string;
                                simulated?: boolean;
                                status?: string;
                            };
                        };
                        callsign?: string;
                        center?: number[];
                        chat?: {
                            chatgrp: any;
                            chatroom: string;
                            groupOwner?: string;
                            id?: string;
                            messageId?: string;
                            parent?: string;
                            senderCallsign: string;
                        };
                        chemsensordetail?: {
                            detection?: {
                                agent: string;
                                alarm: number;
                                class?: (...)
                                | (...);
                                concentration?: (...) | (...);
                                confidence?: (...) | (...);
                                id?: (...) | (...);
                                massfraction?: (...) | (...);
                                percent?: (...) | (...);
                                quantity: number;
                                quantityunits: string;
                                time: string;
                            }[];
                            sensor_data: {
                                attachedUid?: string;
                                batterylevel?: number;
                                callsign?: string;
                                manufacturer: string;
                                model: string;
                                ordinal?: number;
                                revision?: number;
                                serialnumber: string;
                                simulated?: boolean;
                                status?: string;
                            };
                        };
                        contact?: {
                            callsign?: string;
                            endpoint?: string;
                            name?: string;
                            phone?: string;
                        };
                        course?: number;
                        creator?: {
                            callsign?: string;
                            time?: string;
                            type: string;
                            uid: string;
                        };
                        dest?: | {
                            after?: string;
                            callsign?: string;
                            group?: string;
                            mission?: string;
                            "mission-guid"?: string;
                            path?: string;
                            uid?: string;
                        }
                        | {
                            after?: string;
                            callsign?: string;
                            group?: string;
                            mission?: string;
                            "mission-guid"?: string;
                            path?: string;
                            uid?: string;
                        }[];
                        droid?: string;
                        fileshare?: {
                            filename: string;
                            name: string;
                            senderCallsign: string;
                            senderUid: string;
                            senderUrl: string;
                            sha256: string;
                            sizeInBytes: number;
                        };
                        fill?: string;
                        "fill-opacity"?: number;
                        flow?: { [key: string]: string };
                        forcedelete?: boolean;
                        geofence?: {
                            boundingSphere?: number;
                            elevationMonitored?: boolean;
                            maxElevation?: string;
                            minElevation?: string;
                            monitor?: string;
                            tracking?: boolean;
                            trigger?: string;
                        };
                        group?: { name: string; role: string };
                        how?: string;
                        icon?: string;
                        labels?: boolean;
                        links?: {
                            callsign?: string;
                            event?: string;
                            mime?: string;
                            mission?: string;
                            parent_callsign?: string;
                            point?: string;
                            production_time?: string;
                            relation?: string;
                            remarks?: string;
                            type?: string;
                            uid?: string;
                            url?: string;
                        }[];
                        "marker-color"?: string;
                        "marker-opacity"?: number;
                        marti_archive?: boolean;
                        maxzoom?: number;
                        metadata?: { [key: string]: unknown };
                        milicon?: { id: string };
                        milsym?: { id: string };
                        minzoom?: number;
                        mission?: {
                            authorUid?: string;
                            guid?: string;
                            missionChanges?: {
                                contentResource?: (...) | (...);
                                contentUid?: (...) | (...);
                                creatorUid: string;
                                details?: (...) | (...);
                                isFederatedChange: boolean;
                                missionName: string;
                                timestamp: string;
                                type: string;
                            }[];
                            missionLayer?: {
                                name?: string;
                                parentUid?: string;
                                type?: string;
                                uid?: string;
                            };
                            name?: string;
                            tool?: string;
                            type?: string;
                        };
                        precisionlocation?: { altsrc?: string; geopointsrc?: string };
                        radsensordetail?: {
                            command_permissions?: { all: boolean; contact_list: string };
                            data_permissions?: { all: boolean; contact_list: string };
                            isotope?: { confidence: number; name: string; type: string }[];
                            physical_module?: {
                                gamma_alarm: number;
                                gamma_cps: number;
                                gamma_dose_rate: number;
                                location: (...) | (...) | (...) | (...) | (...);
                            }[];
                            radmeasurement?: {
                                alarm: number;
                                measurement: number;
                                nalarmstddev: number;
                                name: (...)
                                | (...)
                                | (...)
                                | (...)
                                | (...);
                            }[];
                            search_algorithm?: {
                                gamma_loc: number;
                                gamma_loc_alarm: number;
                                gamma_loc_alarm_value: number;
                                neutron_loc: number;
                                neutron_loc_alarm: number;
                                neutron_loc_alarm_value: number;
                            };
                            sensor_data: {
                                alarm_algorithm?: string;
                                attachedUid?: string;
                                batterylevel?: number;
                                callsign?: string;
                                detector_number?: number;
                                gammastatus: string;
                                heading?: number;
                                id_algorithm?: string;
                                manufacturer: string;
                                master_sensor_manufacturer?: string;
                                master_sensor_serial?: string;
                                measurement_ref?: number;
                                mission_acquired_uR?: number;
                                mission_stay_time_sec?: number;
                                mission_total_mR?: number;
                                model: string;
                                module_location?: string;
                                neutronstatus: string;
                                ordinal?: number;
                                relay_type?: string;
                                search_algorithm?: string;
                                sensor_temp_deg_c?: number;
                                serialnumber: string;
                                simulated?: boolean;
                                source_bearing?: number;
                                source_distance?: | "MOVE_MUCH_CLOSER"
                                | "MOVE_CLOSER"
                                | "OPTIMAL"
                                | "MOVE_AWAY"
                                | "MOVE_FAR_AWAY";
                                source_strength?: number;
                                subchannel?: string;
                                time: string;
                            };
                            spectrum?: {
                                channeldata: string;
                                crystal_id?: (...)
                                | (...);
                                livetime_ms: string;
                                realtime_ms: string;
                                type: string;
                                zerocompression: number;
                            }[];
                        };
                        range?: number;
                        remarks?: string;
                        rotate?: boolean;
                        sensor?: {
                            azimuth?: number;
                            displayMagneticReference?: number;
                            elevation?: number;
                            fov?: number;
                            fovAlpha?: number;
                            fovBlue?: number;
                            fovGreen?: number;
                            fovRed?: number;
                            hideFov?: boolean;
                            model?: string;
                            north?: number;
                            range?: number;
                            rangeLines?: number;
                            rangeLineStrokeColor?: number;
                            rangeLineStrokeWeight?: number;
                            roll?: number;
                            strokeColor?: number;
                            strokeWeight?: number;
                            type?: string;
                            version?: string;
                            vfov?: number;
                        };
                        shape?: {
                            ellipse?: {
                                angle: number;
                                major: number;
                                minor: number;
                                swapAxis?: boolean;
                            };
                        };
                        slope?: number;
                        spatial?: {
                            attitude: {
                                ePitch?: number;
                                eRoll?: number;
                                eYaw?: number;
                                pitch: number;
                                roll: number;
                                yaw?: number;
                            };
                            spin: {
                                ePitch?: number;
                                eRoll?: number;
                                eYaw?: number;
                                pitch: number;
                                roll: number;
                                yaw?: number;
                            };
                            version?: number;
                        };
                        speed?: number;
                        stale?: string
                        | number;
                        start?: string;
                        status?: { battery?: string; readiness?: string };
                        stroke?: string;
                        "stroke-opacity"?: number;
                        "stroke-style"?: string;
                        "stroke-width"?: number;
                        takv?: {
                            device?: string;
                            os?: string;
                            platform?: string;
                            version?: string;
                        };
                        time?: string;
                        track?: {
                            course?: string;
                            eCourse?: string;
                            eSlope?: string;
                            eSpeed?: string;
                            slope?: string;
                            speed?: string;
                        };
                        type?: string;
                        video?: {
                            connection?: {
                                address: string;
                                alias?: string;
                                bufferTime?: number;
                                ignoreEmbeddedKLV?: boolean;
                                networkTimeout?: number;
                                path?: string;
                                port?: number;
                                protocol?: string;
                                roverPort?: number;
                                rtspReliable?: number;
                                uid: string;
                            };
                            sensor?: string;
                            spi?: string;
                            uid?: string;
                            url?: string;
                        };
                    };
                    type: "Feature";
                }[];
                type: "FeatureCollection";
            }
      • Optionalopts: { archive?: boolean; verbose?: boolean }

      Returns Promise<boolean>

      A boolean representing the success state

    • Submit a { schema, items } record submission to the /layer/:layer/submit API where the items are mapped to CoT Features, Core Events or Core Devices by the Layer's configured Maps - usually called via submit()

      Submissions over submit_size are split into multiple posts, each carrying the same schema

      Parameters

      Returns Promise<boolean>

      A boolean representing the success state

    • Arbitrary JSON objects occasionally need to get typed as part of an ETL This function provides the ability to strictly type unknown objects at runtime

      Type Parameters

      • T extends TSchema = TUnknown

      Parameters

      • type: T
      • body: unknown

      Returns (T & { params: [] })["static"]

    • Called by CloudTAK when a significant Config Change takes place

      Parameters

      Returns Promise<void>

    • Parameters

      • Optionalcurrent: string
      • Optionalopts: { logging?: { event?: boolean; webhooks?: boolean } }

      Returns Promise<default>

    • Parse the SQS records of an Outgoing invocation into typed messages. Records predating the type field are treated as feature messages

      Parameters

      • event: SQSEvent

      Returns (
          | {
              geojson: {
                  geometry: | { coordinates: number[]; type: "Point" }
                  | { coordinates: number[][]; type: "LineString" }
                  | { coordinates: number[][][]; type: "Polygon" };
                  id: string;
                  path?: string;
                  properties: {
                      ackrequest?: { ackrequested: boolean; tag: string; uid: string };
                      archived?: boolean;
                      attachments?: string[];
                      bearing?: number;
                      biosensordetail?: {
                          measurement?: {
                              bioClass?: (...) | (...);
                              channel?: (...) | (...);
                              concentration?: (...) | (...);
                              confidence?: (...) | (...);
                              confirmationLevel?: (...) | (...);
                              dose: number;
                              doseTime?: (...) | (...);
                              harmful?: (...) | (...) | (...);
                              level?: (...) | (...);
                              persistency?: (...) | (...);
                              sampleId?: (...) | (...);
                              time: string;
                              type?: (...) | (...);
                          }[];
                          sensor_data: {
                              attachedUid?: string;
                              batterylevel?: number;
                              callsign?: string;
                              manufacturer: string;
                              model: string;
                              ordinal?: number;
                              revision?: number;
                              serialnumber: string;
                              simulated?: boolean;
                              status?: string;
                          };
                      };
                      callsign: string;
                      center: number[];
                      chat?: {
                          chatgrp: any;
                          chatroom: string;
                          groupOwner?: string;
                          id?: string;
                          messageId?: string;
                          parent?: string;
                          senderCallsign: string;
                      };
                      chemsensordetail?: {
                          detection?: {
                              agent: string;
                              alarm: number;
                              class?: (...)
                              | (...);
                              concentration?: (...) | (...);
                              confidence?: (...) | (...);
                              id?: (...) | (...);
                              massfraction?: (...) | (...);
                              percent?: (...) | (...);
                              quantity: number;
                              quantityunits: string;
                              time: string;
                          }[];
                          sensor_data: {
                              attachedUid?: string;
                              batterylevel?: number;
                              callsign?: string;
                              manufacturer: string;
                              model: string;
                              ordinal?: number;
                              revision?: number;
                              serialnumber: string;
                              simulated?: boolean;
                              status?: string;
                          };
                      };
                      contact?: {
                          callsign?: string;
                          endpoint?: string;
                          name?: string;
                          phone?: string;
                      };
                      course?: number;
                      creator?: {
                          callsign?: string;
                          time?: string;
                          type: string;
                          uid: string;
                      };
                      dest?: | {
                          after?: string;
                          callsign?: string;
                          group?: string;
                          mission?: string;
                          "mission-guid"?: string;
                          path?: string;
                          uid?: string;
                      }
                      | {
                          after?: string;
                          callsign?: string;
                          group?: string;
                          mission?: string;
                          "mission-guid"?: string;
                          path?: string;
                          uid?: string;
                      }[];
                      droid?: string;
                      fileshare?: {
                          filename: string;
                          name: string;
                          senderCallsign: string;
                          senderUid: string;
                          senderUrl: string;
                          sha256: string;
                          sizeInBytes: number;
                      };
                      fill?: string;
                      "fill-opacity"?: number;
                      flow?: { [key: string]: string };
                      forcedelete?: boolean;
                      geofence?: {
                          boundingSphere?: number;
                          elevationMonitored?: boolean;
                          maxElevation?: string;
                          minElevation?: string;
                          monitor?: string;
                          tracking?: boolean;
                          trigger?: string;
                      };
                      group?: { name: string; role: string };
                      how: string;
                      icon?: string;
                      labels?: boolean;
                      links?: {
                          callsign?: string;
                          event?: string;
                          mime?: string;
                          mission?: string;
                          parent_callsign?: string;
                          point?: string;
                          production_time?: string;
                          relation?: string;
                          remarks?: string;
                          type?: string;
                          uid?: string;
                          url?: string;
                      }[];
                      "marker-color"?: string;
                      "marker-opacity"?: number;
                      marti_archive?: boolean;
                      maxzoom?: number;
                      metadata?: { [key: string]: unknown };
                      milicon?: { id: string };
                      milsym?: { id: string };
                      minzoom?: number;
                      mission?: {
                          authorUid?: string;
                          guid?: string;
                          missionChanges?: {
                              contentResource?: (...) | (...);
                              contentUid?: (...) | (...);
                              creatorUid: string;
                              details?: (...) | (...);
                              isFederatedChange: boolean;
                              missionName: string;
                              timestamp: string;
                              type: string;
                          }[];
                          missionLayer?: {
                              name?: string;
                              parentUid?: string;
                              type?: string;
                              uid?: string;
                          };
                          name?: string;
                          tool?: string;
                          type?: string;
                      };
                      precisionlocation?: { altsrc?: string; geopointsrc?: string };
                      radsensordetail?: {
                          command_permissions?: { all: boolean; contact_list: string };
                          data_permissions?: { all: boolean; contact_list: string };
                          isotope?: { confidence: number; name: string; type: string }[];
                          physical_module?: {
                              gamma_alarm: number;
                              gamma_cps: number;
                              gamma_dose_rate: number;
                              location: (...) | (...) | (...) | (...) | (...);
                          }[];
                          radmeasurement?: {
                              alarm: number;
                              measurement: number;
                              nalarmstddev: number;
                              name: (...)
                              | (...)
                              | (...)
                              | (...)
                              | (...);
                          }[];
                          search_algorithm?: {
                              gamma_loc: number;
                              gamma_loc_alarm: number;
                              gamma_loc_alarm_value: number;
                              neutron_loc: number;
                              neutron_loc_alarm: number;
                              neutron_loc_alarm_value: number;
                          };
                          sensor_data: {
                              alarm_algorithm?: string;
                              attachedUid?: string;
                              batterylevel?: number;
                              callsign?: string;
                              detector_number?: number;
                              gammastatus: string;
                              heading?: number;
                              id_algorithm?: string;
                              manufacturer: string;
                              master_sensor_manufacturer?: string;
                              master_sensor_serial?: string;
                              measurement_ref?: number;
                              mission_acquired_uR?: number;
                              mission_stay_time_sec?: number;
                              mission_total_mR?: number;
                              model: string;
                              module_location?: string;
                              neutronstatus: string;
                              ordinal?: number;
                              relay_type?: string;
                              search_algorithm?: string;
                              sensor_temp_deg_c?: number;
                              serialnumber: string;
                              simulated?: boolean;
                              source_bearing?: number;
                              source_distance?: | "MOVE_MUCH_CLOSER"
                              | "MOVE_CLOSER"
                              | "OPTIMAL"
                              | "MOVE_AWAY"
                              | "MOVE_FAR_AWAY";
                              source_strength?: number;
                              subchannel?: string;
                              time: string;
                          };
                          spectrum?: {
                              channeldata: string;
                              crystal_id?: (...)
                              | (...);
                              livetime_ms: string;
                              realtime_ms: string;
                              type: string;
                              zerocompression: number;
                          }[];
                      };
                      range?: number;
                      remarks?: string;
                      rotate?: boolean;
                      sensor?: {
                          azimuth?: number;
                          displayMagneticReference?: number;
                          elevation?: number;
                          fov?: number;
                          fovAlpha?: number;
                          fovBlue?: number;
                          fovGreen?: number;
                          fovRed?: number;
                          hideFov?: boolean;
                          model?: string;
                          north?: number;
                          range?: number;
                          rangeLines?: number;
                          rangeLineStrokeColor?: number;
                          rangeLineStrokeWeight?: number;
                          roll?: number;
                          strokeColor?: number;
                          strokeWeight?: number;
                          type?: string;
                          version?: string;
                          vfov?: number;
                      };
                      shape?: {
                          ellipse?: {
                              angle: number;
                              major: number;
                              minor: number;
                              swapAxis?: boolean;
                          };
                      };
                      slope?: number;
                      spatial?: {
                          attitude: {
                              ePitch?: number;
                              eRoll?: number;
                              eYaw?: number;
                              pitch: number;
                              roll: number;
                              yaw?: number;
                          };
                          spin: {
                              ePitch?: number;
                              eRoll?: number;
                              eYaw?: number;
                              pitch: number;
                              roll: number;
                              yaw?: number;
                          };
                          version?: number;
                      };
                      speed?: number;
                      stale: string;
                      start: string;
                      status?: { battery?: string; readiness?: string };
                      stroke?: string;
                      "stroke-opacity"?: number;
                      "stroke-style"?: string;
                      "stroke-width"?: number;
                      takv?: {
                          device?: string;
                          os?: string;
                          platform?: string;
                          version?: string;
                      };
                      time: string;
                      track?: {
                          course?: string;
                          eCourse?: string;
                          eSlope?: string;
                          eSpeed?: string;
                          slope?: string;
                          speed?: string;
                      };
                      type: string;
                      video?: {
                          connection?: {
                              address: string;
                              alias?: string;
                              bufferTime?: number;
                              ignoreEmbeddedKLV?: boolean;
                              networkTimeout?: number;
                              path?: string;
                              port?: number;
                              protocol?: string;
                              roverPort?: number;
                              rtspReliable?: number;
                              uid: string;
                          };
                          sensor?: string;
                          spi?: string;
                          uid?: string;
                          url?: string;
                      };
                  };
                  type: "Feature";
              };
              type: Feature;
              xml: string;
          }
          | {
              action: OutgoingAction;
              channels: number[];
              data: { [key: string]: unknown };
              type: Event;
          }
          | {
              action: OutgoingAction;
              channels: number[];
              data: { [key: string]: unknown };
              type: Device;
          }
      )[]