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.
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
- The SDK detects a mismatch after the device connection and command channel are ready.
- The app explains that the device must update its radio settings for the current country.
- The user confirms the change.
- The app shows a blocking progress state while the device updates and restarts.
- 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.
Recommended UI integration
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
| API | Use |
|---|---|
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:
| Outcome | Host behavior |
|---|---|
idle | No check has run. Show nothing. |
updateAvailable | Ask for explicit user confirmation. No write or reboot has happened. |
applying | Show non-dismissible progress and ask the user to keep the device nearby. |
applied | Show success; the device has rebooted and reported the target region. |
skippedUpToDate | No action required. If this follows an apply, it is also a successful result. |
skippedNoLocation | Keep normal UX quiet; guide the user to location settings only from a manual retry flow. |
skippedCountryUnknown | Country resolution or backend config was unavailable. Keep the existing device region. |
skippedDeviceOffline | Wait for a command-capable connection before retrying. |
skippedSafetyActive | Defer the change until SOS, PRE-SOS, DMP, Protection Mode, or OTA work is no longer active. |
skippedFirmwareUnsupported | Do not loop reboots. Explain that the device firmware must be updated or support is required. |
failed | Use canRetry to decide whether to offer retry; keep diagnostic detail out of ordinary user copy. |
Two fields help avoid misleading UI:
applyAttempteddistinguishes a failure after user confirmation from a silent detection-only skip.canRetryis 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
EU868fallback. - An unrecognized byte may appear as
LoraRegionCode.unsetin 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
applyingas non-terminal and wait for the next outcome. - Offer retry only when
canRetryis 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.
Related REST endpoints
- Get device config by country
- Reverse-geocode coordinates to a country is normally consumed internally by the SDK.