Public API
Complete reference for the partner-facing SDK methods. Deprecated and compatibility methods are intentionally omitted — see the full internal docs for those surfaces.
Bootstrap
EixamConnectSdk.bootstrap(...)
Creates the SDK, resolves the selected environment, validates the config, and applies the initial signed session when provided.
Returns: Future<EixamConnectSdk>
Key inputs: appId, environment, initialSession
The partner backend owns the app secret and signs the session. The mobile app receives appId, externalUserId, and userHash. The same identity is reused across HTTP and MQTT.
final sdk = await EixamConnectSdk.bootstrap(
const EixamBootstrapConfig(
appId: 'partner-app',
environment: EixamEnvironment.sandbox,
initialSession: EixamSession.signed(
appId: 'partner-app',
externalUserId: 'partner-user-123',
userHash: 'signed-session-hash',
),
),
);
final session = await sdk.getCurrentSession();
debugPrint('session user=${session?.externalUserId}');
Diagnostics
getOperationalDiagnostics()
Returns the latest operational runtime snapshot for session, transport, bridge, and SOS rehydration state.
Returns: SdkOperationalDiagnostics
final diagnostics = await sdk.getOperationalDiagnostics();
debugPrint('mqtt=${diagnostics.connectionState.name}');
debugPrint('telTopic=${diagnostics.telemetryPublishTopic}');
debugPrint('lastDecision=${diagnostics.bridge.lastDecision}');
debugPrint('pendingSos=${diagnostics.bridge.pendingSos != null}');
watchOperationalDiagnostics()
Streams operational changes after bootstrap, session updates, reconnects, and bridge/runtime changes.
Returns: Stream<SdkOperationalDiagnostics>
final sub = sdk.watchOperationalDiagnostics().listen((diagnostics) {
debugPrint('mqtt=${diagnostics.connectionState.name}');
debugPrint('bridge=${diagnostics.bridge.lastDecision}');
});
Device Lifecycle
connectDevice(...)
Pairs or reconnects the partner-selected device and returns the resulting runtime status.
Returns: DeviceStatus
final status = await sdk.connectDevice(pairingCode: '123456');
debugPrint('device=${status.deviceId}');
debugPrint('lifecycle=${status.lifecycleState.name}');
debugPrint('ready=${status.isReadyForSafety}');
getDeviceStatus()
Reads the latest cached device runtime snapshot without starting a new pairing flow.
Returns: DeviceStatus
final status = await sdk.getDeviceStatus();
debugPrint('connected=${status.connected}');
debugPrint('lastSeen=${status.lastSeen}');
debugPrint('firmware=${status.firmwareVersion}');
deviceStatusStream
Streams lifecycle changes while the device connects, activates, disconnects, or recovers.
Returns: Stream<DeviceStatus>
final sub = sdk.deviceStatusStream.listen((status) {
debugPrint('lifecycle=${status.lifecycleState.name}');
debugPrint('connected=${status.connected}');
debugPrint('battery=${status.approximateBatteryPercentage}');
});
getDeviceSosStatus()
Returns the current device-side SOS state tracked by the SDK runtime.
Returns: DeviceSosStatus
final status = await sdk.getDeviceSosStatus();
debugPrint('state=${status.state.name}');
debugPrint('event=${status.lastEvent}');
debugPrint('countdown=${status.countdownRemainingSeconds}');
SOS
triggerSos(...)
Creates an app-originated SOS incident using the current signed session and operational runtime.
Returns: SosIncident
final incident = await sdk.triggerSos(
const SosTriggerPayload(
message: 'Need assistance',
triggerSource: 'button_ui',
),
);
debugPrint('incident=${incident.id}');
debugPrint('state=${incident.state.name}');
getCurrentSosIncident()
Returns the latest known active or recently settled SOS incident after runtime rehydration.
Returns: Future<SosIncident?>
final incident = await sdk.getCurrentSosIncident();
if (incident != null) {
debugPrint('incident=${incident.id}');
debugPrint('state=${incident.state.name}');
debugPrint('hasPosition=${incident.positionSnapshot != null}');
}
getSosState()
Returns the current SOS lifecycle state.
Returns: Future<SosState>
Values: idle, sent, acknowledged, cancelRequested, cancelled
final state = await sdk.getSosState();
debugPrint('sosState=${state.name}');
Contacts
listEmergencyContacts()
Loads the current backend-synced emergency contacts for the signed user.
Returns: Future<List<EmergencyContact>>
final contacts = await sdk.listEmergencyContacts();
for (final contact in contacts) {
debugPrint('${contact.priority}: ${contact.name} ${contact.phone}');
}
createEmergencyContact(...)
Creates a new emergency contact and returns the saved record.
Returns: EmergencyContact
final contact = await sdk.createEmergencyContact(
name: 'Mountain Rescue Desk',
phone: '+34600000000',
email: 'rescue@example.com',
priority: 1,
);
debugPrint('contact=${contact.id}');
debugPrint('priority=${contact.priority}');
updateEmergencyContact(...)
Updates an existing contact and returns the saved record.
Returns: EmergencyContact
final current = (await sdk.listEmergencyContacts()).first;
final updated = await sdk.updateEmergencyContact(
current.copyWith(name: 'Mountain Rescue 24/7'),
);
debugPrint('contact=${updated.id}');
debugPrint('name=${updated.name}');
debugPrint('updatedAt=${updated.updatedAt}');
Permissions
getPermissionState()
Returns one aggregated snapshot for location, notifications, Bluetooth, and Bluetooth service availability.
Returns: PermissionState
final state = await sdk.getPermissionState();
debugPrint('location=${state.location.name}');
debugPrint('notifications=${state.notifications.name}');
debugPrint('bluetoothReady=${state.canUseBluetooth}');
Protection Mode
Background continuity is significantly stronger on Android when Protection Mode (native foreground service) owns the BLE transport. Plain Flutter-owned BLE provides no guaranteed full background runtime.
getProtectionStatus()
Returns the current runtime status for armed/degraded/off state and native BLE ownership.
Returns: ProtectionStatus
final status = await sdk.getProtectionStatus();
debugPrint('mode=${status.modeState.name}');
debugPrint('runtime=${status.runtimeState.name}');
debugPrint('owner=${status.bleOwner.name}');
debugPrint('protectedDevice=${status.protectedDeviceId}');
getProtectionDiagnostics()
Returns the latest native/runtime diagnostics for reconnects, wake events, queueing, and command routing.
Returns: ProtectionDiagnostics
final diagnostics = await sdk.getProtectionDiagnostics();
debugPrint('wake=${diagnostics.lastWakeReason}');
debugPrint('reconnects=${diagnostics.reconnectAttemptCount}');
debugPrint('lastCommandRoute=${diagnostics.lastCommandRoute}');
Backend Device Registry
listRegisteredDevices()
Returns backend device records associated with the signed user.
Returns: Future<List<BackendRegisteredDevice>>
final devices = await sdk.listRegisteredDevices();
for (final device in devices) {
debugPrint('${device.hardwareId} ${device.firmwareVersion}');
}
:::note Paired-device sync
After a device is paired/connected and the signed-session identity is ready, the SDK may attempt automatic backend sync. Sync uses hardware_id, firmware_version, hardware_model, and paired_at, and is safe only when a canonical backend-compatible hardware ID can be resolved.
:::
Omitted from the partner path
The partner API intentionally omits:
- Deprecated compatibility methods kept only for migration
- Internal validation-first capability groups such as Guided Rescue Phase 1
- Low-level device-control examples outside the recommended onboarding path