# `XMAVLink.Heartbeat`
[🔗](https://github.com/fancydrones/xmavlink/blob/main/lib/mavlink/heartbeat.ex#L1)

Emits MAVLink HEARTBEAT messages on a configurable interval.

Most MAVLink nodes (cameras, GCSes, companion computers, autopilots)
must emit a HEARTBEAT roughly once per second so peers know they're
alive. Without it, dynamic / peer-learning routers like the
reference `mavlink-router` don't forward traffic to them. xmavlink
itself does not emit HEARTBEATs by default; consumers traditionally
built and sent their own. This module standardises that pattern.

## Configuration

Set `:heartbeat` in the application environment for `:xmavlink`. If
the key is unset or `nil`, no HEARTBEATs are emitted (backwards
compatible with versions ≤ 0.6.0).

### Static message

    config :xmavlink,
      heartbeat: [
        interval_ms: 1000,
        source_system: 245,
        source_component: 191,
        message: %Common.Message.Heartbeat{
          type: :mav_type_gcs,
          autopilot: :mav_autopilot_invalid,
          base_mode: MapSet.new(),
          custom_mode: 0,
          system_status: :mav_state_active,
          mavlink_version: 3
        }
      ]

Suitable for nodes whose HEARTBEAT contents don't change at runtime
(e.g. a stateless GCS).

### Dynamic builder

    config :xmavlink,
      heartbeat: [
        interval_ms: 1000,
        source_system: 1,
        source_component: 100,
        builder: {MyApp.Mavlink, :build_heartbeat, []}
      ]

The `{module, function, args}` tuple is invoked on every tick to
produce a fresh struct. Use this when `system_status`, `base_mode`,
or `custom_mode` should reflect application state.

Either `:message` or `:builder` is required (not both). `:interval_ms`
is required. Pass `:router` when heartbeats should be emitted through a
named or pid router other than the default `XMAVLink.Router`.

## First heartbeat

The first HEARTBEAT is dispatched immediately after init, so a
peer-learning router admits the node within milliseconds rather than
waiting up to a full interval.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
