# `Jido.Sensor.Runtime`
[🔗](https://github.com/agentjido/jido/blob/v2.3.0/lib/jido/sensor/runtime.ex#L1)

GenServer runtime for Jido sensors.

Runtime wraps sensor modules and manages their lifecycle, similar to how
AgentServer wraps agent modules. It handles configuration validation,
event scheduling, and signal delivery.

## Architecture

- Single GenServer per sensor instance
- Configuration validated via sensor module's `schema()` (Zoi.parse)
- Timer-based event scheduling via `{:schedule, interval_ms}` directives
- Signal delivery to agent via pid or `Jido.Signal.Dispatch`

## Public API

- `start/1` - Start unlinked to caller
- `start_link/1` - Start linked to caller
- `child_spec/1` - Returns a proper child spec with stable id
- `event/2` - Inject an external event into the sensor

## Options

- `:sensor` - Sensor module (required)
- `:config` - Configuration map or keyword list for the sensor
- `:context` - Context map including `:agent_ref`
- `:id` - Instance ID (auto-generated if not provided)
- `:owner_pid` - Optional owner process to monitor; runtime stops if owner exits

## Signal Delivery

When the sensor emits a signal:
- If `agent_ref` is a pid, uses `send(agent_ref, {:signal, signal})` (for testing)
- Otherwise uses `Jido.Signal.Dispatch.dispatch/2` with target: agent_ref

## Examples

    {:ok, pid} = Jido.Sensor.Runtime.start_link(
      sensor: MySensor,
      config: %{interval: 1000},
      context: %{agent_ref: self()}
    )

    # Inject an external event
    Jido.Sensor.Runtime.event(pid, :custom_event)

# `server`

```elixir
@type server() :: pid() | atom() | {:via, module(), term()}
```

# `child_spec`

```elixir
@spec child_spec(keyword() | map()) :: Supervisor.child_spec()
```

Returns a child_spec for supervision.

Uses the `:id` option if provided, otherwise defaults to the module name.

# `event`

```elixir
@spec event(server(), term()) :: :ok
```

Injects an external event into the sensor.

The event will be passed to the sensor's `handle_event/2` callback.

## Examples

    :ok = Jido.Sensor.Runtime.event(pid, :my_event)
    :ok = Jido.Sensor.Runtime.event(pid, {:data_received, payload})

# `start`

```elixir
@spec start(keyword() | map()) :: GenServer.on_start()
```

Starts a Sensor.Runtime unlinked to the calling process.

Use this when another runtime will monitor and manage the sensor lifecycle
itself. Use `start_link/1` for direct supervision tree children.

# `start_link`

```elixir
@spec start_link(keyword() | map()) :: GenServer.on_start()
```

Starts a Sensor.Runtime linked to the calling process.

## Options

- `:sensor` - Sensor module (required)
- `:config` - Configuration map or keyword list for the sensor (default: %{})
- `:context` - Context map including `:agent_ref` (default: %{})
- `:id` - Instance ID (auto-generated if not provided)
- `:owner_pid` - Optional owner process to monitor; runtime stops if owner exits

## Examples

    {:ok, pid} = Jido.Sensor.Runtime.start_link(
      sensor: MySensor,
      config: %{interval: 5000},
      context: %{agent_ref: agent_pid}
    )

