Aller au contenu principal

LoRa Radio Region

Eixam devices must use the radio region configured for their physical country. The SDK resolves the device's country from an authoritative location, fetches the backend configuration, compares it with the connected device, and reports whether a change is required.

A check never changes or reboots the device. The host app must show the user a confirmation and call the apply API explicitly. The SDK then rechecks safety and device identity, writes the region, reboots the device, reconnects, and verifies the reported value.

Explicit confirmation required

Do not apply a region silently. A region change reboots the device and temporarily interrupts its connection. Keep the device nearby and do not start the change during SOS, PRE-SOS, DMP, Protection Mode activity, or an OTA firmware update.

What the user experiences

  1. The SDK detects a mismatch after the device connection and command channel are ready.
  2. The app explains that the device must update its radio settings for the current country.
  3. The user confirms the change.
  4. The app shows a blocking progress state while the device updates and restarts.
  5. The app shows success, a retry action when safe, or an error with support guidance.

Detection-only outcomes such as no location, no connection, or already up to date should remain silent in ordinary end-user UX.

Technical flow

The SDK also performs best-effort, detection-only checks at device lifecycle seams such as a new command-capable connection. Foreground/resume checks are throttled. You can request a manual recheck, but repeated polling is unnecessary.

Prerequisites

  • A bootstrapped SDK with an active signed session.
  • Location permission and an authoritative, valid current location.
  • A connected device with a ready BLE command channel.
  • Backend country resolution and device configuration available for the current environment.
  • Firmware that supports the region command and reports runtime status.
  • No active safety flow or firmware update that would make a reboot unsafe.

The host app owns the permission explanation and prompt timing. See the Permissions Checklist.

The optional eixam_connect_ui package provides DeviceCountryConfigModalHost, which already handles confirmation, applying, success, error, and retry states.

Add it from the same immutable SDK release ref used by eixam_connect_flutter:

dependencies:
eixam_connect_flutter:
git:
url: https://github.com/eixam-tech/eixam-sdk-flutter.git
ref: YOUR_EIXAM_SDK_RELEASE_REF # Replace with the supplied tag or commit.
path: packages/eixam_connect_flutter
eixam_connect_ui:
git:
url: https://github.com/eixam-tech/eixam-sdk-flutter.git
ref: YOUR_EIXAM_SDK_RELEASE_REF # Use exactly the same ref as above.
path: packages/eixam_connect_ui

Create the status stream once, then wrap the authenticated app shell:

import 'package:eixam_connect_flutter/eixam_connect_flutter.dart';
import 'package:eixam_connect_ui/eixam_connect_ui.dart';
import 'package:flutter/material.dart';

late final Stream<DeviceCountryConfigStatus> regionStatusStream =
sdk.watchDeviceCountryConfigStatus();

Widget buildAppShell(BuildContext context, Widget child) {
return EixamUiScope(
localeCode: Localizations.localeOf(context).languageCode,
child: DeviceCountryConfigModalHost(
statusStream: regionStatusStream,
onConfirm: () => sdk.applyPendingDeviceCountryConfig(
reason: 'user_confirmed_modal',
),
child: child,
),
);
}

The UI package includes English, Spanish, Catalan, and French copy. Use EixamUiTexts when your product needs approved custom wording.

Public APIs

APIUse
getDeviceCountryConfigStatus()Read the most recent typed status.
watchDeviceCountryConfigStatus()Observe detection, apply, and terminal outcomes. The stream begins with the current status.
checkDeviceCountryConfig({reason, countryIsoOverride})Run a detection-only check. countryIsoOverride is for controlled development tools only.
applyPendingDeviceCountryConfig({reason})Apply the last detected mismatch after explicit confirmation.
ensureDeviceCountryConfig(...)Deprecated detection-only alias. Use checkDeviceCountryConfig(...).

Do not call the reverse-geocoding or device-config REST routes from host UI. They are SDK-owned integration details documented in the REST reference for backend and support visibility.

Status handling

Use DeviceCountryConfigStatus.outcome for control flow:

OutcomeHost behavior
idleNo check has run. Show nothing.
updateAvailableAsk for explicit user confirmation. No write or reboot has happened.
applyingShow non-dismissible progress and ask the user to keep the device nearby.
appliedShow success; the device has rebooted and reported the target region.
skippedUpToDateNo action required. If this follows an apply, it is also a successful result.
skippedNoLocationKeep normal UX quiet; guide the user to location settings only from a manual retry flow.
skippedCountryUnknownCountry resolution or backend config was unavailable. Keep the existing device region.
skippedDeviceOfflineWait for a command-capable connection before retrying.
skippedSafetyActiveDefer the change until SOS, PRE-SOS, DMP, Protection Mode, or OTA work is no longer active.
skippedFirmwareUnsupportedDo not loop reboots. Explain that the device firmware must be updated or support is required.
failedUse canRetry to decide whether to offer retry; keep diagnostic detail out of ordinary user copy.

Two fields help avoid misleading UI:

  • applyAttempted distinguishes a failure after user confirmation from a silent detection-only skip.
  • canRetry is true only when the current pending plan can be retried safely without a new detection check.

Backend and fallback rules

The backend is the source of truth for the raw region byte. The SDK does not maintain a country-to-frequency mapping in host code.

  • If a country has no configuration and no backend default, the SDK skips the change. It does not assume a region.
  • If the backend returns a configuration but omits or zeroes its region byte, the SDK uses its defined EU868 fallback.
  • An unrecognized byte may appear as LoraRegionCode.unset in typed diagnostics. Apply/idempotency logic still compares the raw backend and device bytes.
  • A verified apply is stored per device to avoid unnecessary reboots.
  • If firmware does not adopt a requested region, the SDK stores that outcome and suppresses repeated reboot attempts during a cooldown.

Custom UI

If you do not use DeviceCountryConfigModalHost, your UI must still:

  • Subscribe before the first command-capable device connection can produce updateAvailable.
  • Require explicit confirmation before applyPendingDeviceCountryConfig(...).
  • Keep the confirmation tied to the latest status; dismiss it if a new detection-only status invalidates the plan.
  • Treat applying as non-terminal and wait for the next outcome.
  • Offer retry only when canRetry is true.
  • Avoid showing internal country codes, raw region bytes, BLE command ids, or diagnostic messages as end-user copy.

Interaction with OTA

Radio-region apply and OTA both need exclusive access to a connected device and may reboot it. The SDK blocks a region apply while a firmware session is active and applies the same SOS, PRE-SOS, DMP, and Protection Mode safety gates used by OTA.

After an OTA update finishes, let the SDK reconnect and verify the installed firmware before responding to a pending region change. See Firmware Updates / OTA.