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
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:
Read pulse counter inputs (Pulse Input 1, 2, 3)
Format the data as JSON
Set timestamps
Load AWS IoT Core certificates
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 |
|---|---|---|
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 |
|---|---|---|
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 |
|---|---|---|---|
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 |
|---|---|
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 |
|---|---|
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 |
|---|---|
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) |
|---|---|---|
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 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 |
|---|---|
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?