Migration Lambda

Migration Lambda

Overview

The Migration Lambda provides three core operations for managing IoT device metadata between different systems for Sensors and Gateways which are present in the InstalllerAppDeviceDetails table:

  1. enrichMetadataFromLoRaWAN: Backfills missing device metadata from LoRaWAN tables to InstallerAppDeviceDetails

  2. renameIoTCoreNames: Updates IoT Core device/gateway names & description and stores metadata back to InstallerAppDeviceDetails

  3. migrateMetadata: Migrates device metadata from InstallerAppDeviceDetails to LoRaWAN Devices/Gateways tables
    Note: Recommended execution order is enrichMetadataFromLoRaWAN → renameIoTCoreNames → migrateMetadata to ensure all required metadata is available for subsequent operations.

Flow Diagram

image-20250626-185704.png

NOTE – Enrichment Pre-Step

A new, silent pre-step (enrichMetadataFromLoRaWAN) now runs before the two operations shown above.
Its only purpose is to back-fill any missing values for Vendor, Model, Floor, or FullEUI in InstallerAppDeviceDetails.

API Reference

Request Parameters:

{ "enrichMetadataFromLoRaWAN": boolean, // Enable metadata enrichment operation   "renameIoTCoreNames": boolean,  // Enable IoT Core renaming operation   "migrateMetadata": boolean,     // Enable metadata migration operation     "site": string                  // Site filter specification }

Important Constraints:

  • Only one operation can run at a time

  • The Lambda returns an error if multiple flags are set to true.

Site Filtering

The `site` parameter supports flexible filtering options:

Value

Description

Example

Value

Description

Example

All

Process all sites

{"migrateMetadata": true, "site": "All"}

Single site

Process specific site

{"migrateMetadata": true, "site": "TEST"}

Multiple sites

Comma-separated list

{"migrateMetadata": true, "site": "Site0,Site1"}

Features:

  • Case-insensitive matching (e.g., "test" matches "TEST")

  • Whitespace handling (e.g., "Site0, Site1" works correctly)

Operation 0: enrichMetadataFromLoRaWAN

Purpose

Backfills missing device metadata (Vendor, Model, Floor, FullEUI) in InstallerAppDeviceDetails by looking up corresponding records in LoRaWAN Devices/Gateways tables.

When This Operation is Needed

  • Devices were created in InstallerApp before being provisioned in LoRaWAN

  • Frontend didn't populate all required metadata fields

  • Missing attributes prevent rename/migrate operations from succeeding

Decision Logic

The system determines the action for each device based on field completeness and EnrichmentStatus:

Decision

Condition

Action

Decision

Condition

Action

enrich

Any of Vendor/Model/Floor/FullEUI is empty AND EnrichmentStatus is empty/null

Process device for first time

retry

Any of Vendor/Model/Floor/FullEUI is empty AND EnrichmentStatus = "FAILED"

Retry previously failed device

already_enriched

All fields populated OR previous enrichment succeeded

Skip (counted in "previously_enriched")

skip_other

Exception occurred during decision logic

Skip due to error

Processing Flow

  1. Scan InstallerAppDeviceDetails for records with missing metadata

  2. Match by EntityId: Use last 5 characters to find corresponding DevEui/GatewayEui in LoRaWAN tables

  3. Selective Update: Only populate empty fields, preserve existing data

  4. Status Tracking: Update EnrichmentStatus, EnrichmentTimestamp, EnrichmentError

Status Values

Status

Description

Status

Description

ENRICHED

Successfully populated missing fields

ENRICHED_AFTER_FAILED

Retry succeeded after previous failure

FAILED

No matching record found in LoRaWAN tables

Operation 1: renameIoTCoreNames

Purpose

Rename IoT Core devices/gateways based on standardized naming conventions and update InstallerAppDeviceDetails with IoT metadata.

Decision Logic

The system determines the action for each device based on `IotRenameStatus`:

Decision

Condition

Action

Decision

Condition

Action

rename

`IotRenameStatus` is empty/null

Process device for first time

retry

`IotRenameStatus` = "FAILED"

Retry previously failed device

rerename

`IotRenameTimestamp` < `UpdatedAt`

Re-process updated device

already_renamed

Device previously processed successfully

Skip (counted in "previously_renamed" )

Naming Conventions

Sensors

Format: `{Site}-{Model} {last5CharsOfEUI}`

Example:

  • Site: "TEST", Model: "EMS1", EUI: "c01122334455600" → "TEST-EMS1 56000"

Gateways

Format: `{Site}-{last5CharsOfEUI}`

Example:

  • Site: "TEST", EUI: "8153f95c7c1452211" → "TEST-52211"

IoT Core Description

The system generates a JSON description stored in both IoT Core and InstallerAppDeviceDetails:

{   "Location": "Column location",   "Floor": "P1",   "Site": "TEST",    "Vendor": "Elsys",   "Model": "EMS1" }

Status Tracking

Updates InstallerAppDeviceDetails with the following attributes:

Attribute

Description

Values

Attribute

Description

Values

IotRenameStatus

Processing status

IOT_RENAMED, IOT_RENAMED_AFTER_FAILED, IOT_RENAMED_AFTER_SOURCE_UPDATE, FAILED

IotRenameTimestamp

Processing timestamp

ISO 8601 UTC format

IotRenameError

Error details

Error message (cleared on success)

WirelessIotName

Generated device name

As per naming conventions

WirelessIotId

IoT Core device ID

AWS IoT Core identifier

WirelessIoTDesc

JSON description

Structured metadata

Error Conditions

Error Type

Condition

Status

Action

Error Type

Condition

Status

Action

Description too long

JSON description > 2048 characters

FAILED

Log error, store in IotRenameError

Device not found

Device/Gateway not in IoT Core

FAILED

Log error, store in IotRenameError

API Exception

Any other AWS API error

FAILED

Log error, store in IotRenameError

Operation 2: migrateMetadata

Purpose

Copy device metadata from InstallerAppDeviceDetails to LoRaWAN Devices/Gateways tables.

Decision Logic

The system determines the action for each device based on `MigrationStatus`:

Decision

Condition

Action

Decision

Condition

Action

migrate

`MigrationStatus` is empty/null

Process device for first time

retry

`MigrationStatus` = "FAILED"

Retry previously failed device

remigrate

`MigrationTimestamp` < `UpdatedAt`

Re-process updated device

already_migrated

Device previously processed successfully

Skip (counted in "previously_migrated" )

Pulse Counter Processing

Overview

The migration system handles sensors with pulse counters by creating child records in the LoRaWAN Devices table. Each pulse counter creates a separate record with a unique EUI suffix.

Processing Flow

  1. Check HasPulseCounters: If True, process pulse counters

  2. Create Child Records: For each DeviceType{i} that exists:

  • Generate child EUI: {parent_eui}_P{i}

  • Parse PulseScaler{i} into value and unit

  • Create record with all pulse counter attributes

  1. Set Parent DeviceType: Set parent record's DeviceType = "LWM"

  2. Cleanup Orphans: Remove any existing _P{i} records that no longer have corresponding DeviceType{i}

Pulse Counter Child Record Creation

When a sensor has HasPulseCounters = True, the system creates up to 3 child records:

Child Record EUI Format:

  • {parent_eui}_P1 - First pulse counter

  • {parent_eui}_P2 - Second pulse counter

  • {parent_eui}_P3 - Third pulse counter

Example:

  • Parent EUI: 0004a30b012e2891

  • Child EUIs:

  • 0004a30b012e2891_P1

  • 0004a30b012e2891_P2

  • 0004a30b012e2891_P3

Pulse Scaler Parsing Logic

The system parses pulse scaler values from the format "{value} {unit}":

Source Field Examples:

  • PulseScaler1: 10.0 kW

  • PulseScaler2: 1.0 gal

  • PulseScaler3: Empty value

Parsing Results:

  • PulseScaler1: Value = 10.0, Unit = kW

  • PulseScaler2: Value = 1.0, Unit = gal

  • PulseScaler3: Value = null, Unit = null

Attribute

Source Field

Example Value

Attribute

Source Field

Example Value

DevEui

{parent_eui}_P{i}

0004a30b012e2891_P2

DeviceType

DeviceType{i}

Pulse Water Meter

Vendor

Vendor

Synetica

Model

Model

ENL-STS-P

InstallationTimestamp

CreatedAt

2025-08-19T23:45:47Z

MigrationTimestamp

Current timestamp

2025-08-20T07:59:25Z

PulseScalarValue

Parsed from PulseScaler{i}

1.0

PulseScalarUnit

Parsed from PulseScaler{i}

gal

Example Migration Result

Before Migration (InstallerAppDeviceDetails):

{ "EntityId": "0004a30b012e2891", "FullEUI": "0004a30b012e2891", "HasPulseCounters": true, "DeviceType1": "Pulse Electricity Meter", "DeviceType2": "Pulse Water Meter", "PulseScaler1": "10.0 kW", "PulseScaler2": "1.0 gal", "Vendor": "Synetica", "Model": "ENL-STS-P" }

After Migration (LoRaWAN Devices Table):

Parent Record:

{ "DevEui": "0004a30b012e2891", "DeviceType": "LWM", "Site": "TEST", "SensorLocation": "Column test", "InstallationTimestamp": "2025-08-19T23:45:47Z" }

Child Record 1:

{ "DevEui": "0004a30b012e2891_P1", "DeviceType": "Pulse Electricity Meter", "Vendor": "Synetica", "Model": "ENL-STS-P", "PulseScalarValue": "10.0", "PulseScalarUnit": "kW", "InstallationTimestamp": "2025-08-19T23:45:47Z" }

Child Record 2:

{ "DevEui": "0004a30b012e2891_P2", "DeviceType": "Pulse Water Meter", "Vendor": "Synetica", "Model": "ENL-STS-P", "PulseScalarValue": "1.0", "PulseScalarUnit": "gal", "InstallationTimestamp": "2025-08-19T23:45:47Z" }

Pulse Counter Cleanup and Deletion

The migration system includes automatic cleanup functionality to handle pulse counter record lifecycle:

Automatic Cleanup Scenarios

1. DeviceType Removal Cleanup
When a sensor has HasPulseCounters = true but a specific DeviceType{i} is empty/null:

  • System automatically deletes the corresponding {parent_eui}_P{i} record from LoRaWAN Devices table

  • Uses conditional delete to ensure the record existed before deletion

  • Logs cleanup actions for audit purposes

2. HasPulseCounters Toggle Cleanup
When a sensor's HasPulseCounters is changed from true to false:

  • System removes all potential orphaned {parent_eui}_P1, {parent_eui}_P2, {parent_eui}_P3 records

  • Ensures data consistency between InstallerAppDeviceDetails and LoRaWAN Devices table

  • Handles cases where pulse counter configuration is removed

Benefits of Automatic Cleanup

  1. Data Consistency: Prevents orphaned records in LoRaWAN tables

  2. Configuration Changes: Handles device reconfiguration automatically

  3. Audit Trail: All cleanup actions are logged for compliance

  4. Error Resilience: Graceful handling of missing records

Target Tables & Field Mapping

LoRaWAN Devices Table (Sensors)

Source Field

Target Field

Source Field

Target Field

SecondaryId

Site

LocationType + LocationDesc

SensorLocation

PulseScaler1

PulseScalarValue

PulseScaler1

PulseScalarUnit

DirectionalDegrees

DirectionalDegreesScalar

WirelessIotName

WirelessIotName

WirelessIotId

WirelessIotId

WirelessIoTDesc

WirelessIoTDesc

MigrationTimestamp

MigrationTimestamp

DeviceType

DeviceType

CreatedAt

InstallationTimestamp

LoRaWAN Gateways Table (Gateways)

Source Field

Target Field

Source Field

Target Field

SecondaryId

Site

LocationType + LocationDesc

Location

WirelessIotName

WirelessIotName

WirelessIotId

WirelessIotId

WirelessIoTDesc

WirelessIoTDesc

MigrationTimestamp

MigrationTimestamp

CreatedAt

InstallationTimestamp

Status Tracking

Updates InstallerAppDeviceDetails with:

Attribute

Attribute