CloudGate Device Support - Egypt Project Implementation Plan

CloudGate Device Support - Egypt Project Implementation Plan

Background

Problem: Deploying LoRaWAN gateways in Egypt requires Milvian to become a licensed network operator — not feasible.

Solution: Support CloudGate Mini — a cellular device (by Option) that that acts as a standalone pulse counter (up to 3 inputs, just like a Synetica pulse counter). It uses cellular connectivity (not LoRaWAN) and connects to AWS IoT Core over MQTT.

Proven approach: Gabe already implemented CloudGate in the Aqueduct project for MWAA.


Key Technical Insight: No Decoder Needed

Unlike LoRaWAN devices, CloudGate does NOT send raw binary/hex payloads.

LoRaWAN devices send encoded binary data (e.g., `AQEMLDgVBQAAAAA=`) that must be decoded by vendor-specific decoders in our platform. CloudGate is fundamentally different:

  • CloudGate runs LuvitRED (a Node-RED-based visual programming environment) on the device itself

  • LuvitRED reads the pulse counter inputs, formats the data as clean JSON, and publishes it to AWS IoT Core via MQTT

  • By the time data reaches our platform, it is already decoded

Actual CloudGate payload (From Aqueduct’s LuvitRED debug output):

json {   "pulse_count_1": 12438188804,   "pulse_count_2": 3052867502,   "pulse_count_3": 4137847942,   "timestamp": "2026-02-02T21:07:35.025",   "topic": "mwaa/cloudgate/pulse_telemetry" }

What we need: Only enrichment — look up the device in DynamoDB using their serial number and add Site, Floor, SensorLocation, DeviceType, then map field names to our platform standard (`pulse_count_1` -> `PulseCount1`) and publish to the existing Timestream pipeline.

Architecture — How CloudGate Fits In

image-20260304-220212.png

What is LuvitRED? (For PO/PM context)

LuvitRED is a visual programming tool built into the CloudGate hardware (based on Node-RED). It is NOT part of our platform — it runs on the CloudGate device at the edge.

Needed on CloudGate device to:

  1. Read pulse counter inputs (Pulse Input 1, 2, 3)

  2. Format the data as JSON

  3. Set timestamps

  4. Load AWS IoT Core certificates

  5. Publish to our MQTT topic

This is a device-side configuration task, not a platform code change. Aqueduct’s LuvitRED flow can be exported and reused as a template.

Consideration

We will use the Serial Number of the CloudGate device as the DevEui in our platform. DevEUI are ONLY for LoRaWAN devices. CloudGate does not have a DevEUI, but it does have a serial number (e.g., `KNS831100`) available in the `device_info` payload under `sys_info.serial_number` that can be used for identification and assetId. This keeps the platform consistent — all devices (LoRaWAN, Sidewalk, CloudGate) are identified by `DevEui` in DynamoDB, Timestream, and the Device Data API.

Changes Required — Summary

What we do need to build(Platform side)

#

Change

Description

#

Change

Description

1

IoT Core Certificates + Policy

Create certs so CloudGate can authenticate with AWS IoT Core. Create an IoT policy allowing Connect + Publish to `{pipeline}/cloudgate/pulse_telemetry`

2

IoT Rule (CDK)

New rule on topic `{pipeline}/cloudgate/pulse_telemetry` that invokes the existing Decoder Lambda with the CloudGate JSON payload

3

Decoder Lambda — CloudGate enrichment

Add a CloudGate code path in the existing decoder Lambda: skip binary decoding, map JSON fields (`pulse_count_1` → `PulseCount1`), enrich with Site/Floor from DDB, reuse existing pulse-to-reading conversion, publish to `{pipeline}/dt/master/`

4

CRD API — '/cloudgate_devices'

New endpoint to register/delete CloudGate devices (single + bulk). On create: generate IoT Core cert + key, store device in DDB with `Protocol=CloudGate`. Return cert/key to caller for device configuration

5

Bulk Provisioning

Add CloudGate CSV path in bulk provisioning Lambda for registering multiple devices at once

6

CDK Stack wiring

Wire the IoT policy, IoT Rule, and API Gateway resource for '/cloudgate_devices'

What Configuration needs to be handled on the CloudGate devices

Each CloudGate device takes approximately 1-2 hours to provision (based on Gabe's Aqueduct experience). This involves provisioning on the CloudGateUniverse web console and then loading the LuvitRED flow with proper certificates.

#

Task

Description

#

Task

Description

1

CloudGateUniverse provisioning

Provision each CloudGate device on the CloudGateUniverse web console

2

LuvitRED flow configuration

Configure pulse counter inputs, JSON formatting, timestamps on each CloudGate device. Can reuse Aqueduct’s flow as template

3

Certificate loading

Load the IoT Core certificates (generated by our CRD API) into each CloudGate device via LuvitRED Certificate Storage

4

MQTT broker configuration

Point CloudGate to our AWS IoT Core endpoint, set topic to '{pipeline}/cloudgate/pulse_telemetry'

5

Device testing

Verify each CloudGate device publishes data and it appears in the platform

Files to Modify

#

File

Action

What changes

#

File

Action

What changes

1

data_ingest/data_ingest/data_ingest_stack.py

MODIFY

Add CloudGate IoT Rule + Lambda permission (mirror LoRaWan rule pattern)

2

device_management/device_management/device_management_stack.py

MODIFY

CloudGate IoT policy, `/cloudgate_devices` API resource, env vars

3

device_management/lambda/crd_api/main.py

MODIFY

`cloudgate_devices_create/delete`, function_mapping, lambda_handler routing, device defaults

4

data_ingest/lambda/decoder/main.py`

MODIFY

Add CloudGate enrichment path: detect `source=cloudgate`, skip base64 decode, map JSON fields, reuse pulse-to-reading + enrichment logic

5

device_management/lambda/bulk_provisioning/main.py

MODIFY

Add `cloudgate_devices` CSV path for bulk registration

No new files needed. All changes are modifications to existing files.

Detailed Timeline

Phase 1: Platform Development + Deployment (4 days)

Task

Details

Task

Details

IoT Rule + IoT Policy (CDK) + Decoder Lambda enrichment path

Add CloudGateDecoderRule in `data_ingest_stack.py` (mirror Sidewalk pattern). Add CloudGate IoT policy in `device_management_stack.py`. In decoder `main.py`: detect `source == 'cloudgate'`, skip base64 decoding, map `pulse_count_1/2/3` → `PulseCount1/2/3`, skip f_port/frame_count validation, reuse existing enrichment (Site, Floor, SensorLocation from DDB) and pulse-to-reading conversion. Publish to `dt/master/`.

CRD API — `/cloudgate_devices`

Add `cloudgate_devices_create()`: creates IoT Core cert (`create_keys_and_certificate`), attaches policy, stores device in Devices table with `Protocol=CloudGate`, returns cert+key. Add `cloudgate_devices_delete()`: revokes cert, deletes from DDB. Add function_mapping + lambda_handler routing. Wire `/cloudgate_devices` API Gateway resource in CDK.

Bulk provisioning + CDK deploy

Add CloudGate CSV path in bulk provisioning Lambda. CDK deploy to dev. Fix any deployment issues.

Unit tests + buffer

Unit tests for enrichment path, CRD routes, and bulk provisioning. Buffer for any issues from deploy.

Phase 2: Integration Testing (3 days)

Task

Details

Task

Details

Register test device + MQTT simulation

Register CloudGate device via CRD API. Use MQTT test client (with generated cert) to publish sample CloudGate JSON to `{pipeline}/cloudgate/pulse_telemetry`. Verify decoder Lambda invoked, data appears in Timestream.

End-to-end validation

Verify: DDB device entry correct, Timestream dimensions correct (DevEui, Site, Floor, SensorLocation), pulse-to-reading conversion works, Device Data API returns CloudGate data, no impact on existing LoRaWAN/Sidewalk devices.

Bug fixes + edge cases

Handle: missing fields in payload, duplicate messages, device not found in DDB, cert errors. Buffer day.

Unit tests + buffer

Unit tests for enrichment path, CRD routes, and bulk provisioning. Buffer for any issues from deploy.

Phase 3: Device Configuration + Validation (3 days)

Note: If Gabe is available, Phase 3 can start in parallel with Phase 2 — Gabe can begin LuvitRED setup while developer runs integration tests. This could save 1-2 days on the overall timeline.

Each CloudGate device takes ~1-2 hours to provision on CloudGateUniverse + load the LuvitRED flow with certs (based on Gabe's Aqueduct experience).

Task

Details

Task

Details

LuvitRED flow setup

Configure CloudGate devices: provision on CloudGateUniverse web console, load LuvitRED flow (reuse/adapt from Aqueduct), load IoT Core certificates, set MQTT endpoint + topic.

Device-to-cloud validation

Connect actual CloudGate hardware, verify real pulse data flows through entire pipeline. Confirm data in Timestream and Device Data API.

Comparison: LoRaWAN vs CloudGate in Our Platform

Aspect

LoRaWAN

CloudGate (Egypt)

Aspect

LoRaWAN

CloudGate (Egypt)

Connectivity

LoRaWAN radio → Gateway → AWS IoT Wireless

Cellular → AWS IoT Core MQTT

Data format from device

Binary/hex (needs decoding)

JSON (already decoded by LuvitRED on device)

Platform processing

Full decoder (hex→JSON) + enrichment

Enrichment only (field mapping + DDB lookup)

Device registration

AWS IoT Wireless (`create_wireless_device`)

AWS IoT Core certs (`create_keys_and_certificate`)

Device identifier

DevEui (from LoRaWAN chip)

Serial Number (from CloudGate `sys_info.serial_number`, stored as DevEui)

Operator license needed

Yes (problem in Egypt)

No

Pulse counter inputs

Varies by model

Up to 3 inputs (same as Synetica)

Meeting Discussion Summary

What changes in our platform?

  • Small — no new decoder, no new database, no new infrastructure

  • We add an enrichment path in our existing decoder Lambda (map JSON fields, add Site/Floor from DDB)

  • We add a new API endpoint to register CloudGate devices and generate IoT Core certificates

  • Everything downstream (Timestream, Device Data API) works unchanged

Timeline

Phase

What

Days

Who

Phase

What

Days

Who

Phase 1

Platform development + deploy

4

Developer

Phase 2

Integration testing

3

Developer

Phase 3

Device configuration + validation

3

Gabe + Developer

Total (parallel): If Gabe starts Phase 3 during Phase 2: 8 days

Total (sequential): If Gabe starts after Phase 2: 10 days

Key advantage

Gabe built this for Aqueduct already — the device-side setup is a known, proven process. The platform changes are straightforward modifications to existing code. Low risk.

Gabe's Answers (From Aqueduct Experience)

Question

Answer

Question

Answer

How long per CloudGate device?

1-2 hours each; provision on CloudGateUniverse web console, then load LuvitRED flow with proper certs

Which CloudGate model?

CloudGate Mini

Standalone pulse counter?

Yes; up to 3 inputs, just like a Synetica pulse counter

LuvitRED flow export?

Gabe will share the Aqueduct LuvitRED flow (pending)

DevEui or other identifier?

DevEUI are ONLY for LoRaWAN devices. CloudGate has a serial number that it can publish — use that for identification and assetId

Questions to Resolve Before Starting

  • When will the CloudGate project start? Kristie / Mitra - Issue with certifications in Egypt.

Development for LoRaWAN platform(SW-Vishakha) - 15th April

Configuration and Integration testing(HW- Gabe) - 15th April

  • Is there a target timeline or deadline for Egypt deployment? 15th April

  • Will we order the CloudGate devices for testing? Gabe will ship one CloudGate device to Vishakha

  • Will Gabe be available to support device configuration and testing? - Yes

  • Can Gabe export and share the LuvitRED flow file? - Done

  • Is the physical installation of CloudGate different than LoRaWAN installation devices? - Gabe confirmed that we just need cable

  • Are we planning to use Atria app to save installation details? - Gabe will confirm this

  • How many number of CloudGate devices for Egypt? - 8 sites and 10 CloudGate devices will be ordered as there are 10 meters

  • Egypt SIM/carrier details; Cellular connectivity for CloudGate - Jessica will confirm

  • Do we have common/shared email address to create an account for Melvin group for CloudGate device configuration?

  • Where will these devices be installed—which type of meter: water, gas, or electricity?