Skip to content

Commit

Permalink
Refactor gateway metadata processing to handle multiple gateways in T…
Browse files Browse the repository at this point in the history
…TN v3 payload
  • Loading branch information
mateuscardosodeveloper committed Jan 17, 2025
1 parent 551b04b commit d0f9d9b
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 44 deletions.
64 changes: 48 additions & 16 deletions decoders/network/lorawan-ttittn-v3/v1.0.0/payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,29 +216,61 @@ if (ttn_payload_v3) {
}

if (ttn_payload_v3.rx_metadata && ttn_payload_v3.rx_metadata.length) {
const processGatewayMetadata = (metadata, prefix = '') => {
const result = {
[`gateway_eui${prefix}`]: metadata.gateway_ids.eui,
[`rssi${prefix}`]: metadata.rssi,
[`snr${prefix}`]: metadata.snr,
};
const [first_gateway, ...other_gateways] = ttn_payload_v3.rx_metadata;

if (metadata.location?.latitude && metadata.location?.longitude) {
const { latitude: lat, longitude: lng } = metadata.location;
result[`gateway_location${prefix}`] = {
value: `${lat},${lng}`,
location: { lat, lng },
const getLocationInfo = (gateway) => {
if (gateway?.location && gateway.location?.latitude && gateway.location?.longitude) {
return {
lat: gateway.location.latitude,
lng: gateway.location.longitude
};
}
return null;
};

// Create metadata objects for additional values
const gateway_eui_metadata = {};
const rssi_metadata = {};
const snr_metadata = {};
const gateway_location = {};

// Loop through all other gateways and add metadata
for (let index = 0; index < other_gateways.length; index++) {
const gateway = other_gateways[index];

gateway_eui_metadata[`gateway_eui_${index + 1}`] = gateway.gateway_ids.eui;
rssi_metadata[`rssi_${index + 1}`] = gateway.rssi;
snr_metadata[`snr_${index + 1}`] = gateway.snr;

const locationInfo = getLocationInfo(gateway);
if (locationInfo) {
gateway_location[`gateway_location_${index + 1}`] = { lat: locationInfo.lat, lng: locationInfo.lng };
}
}

// Add metadata to respective variables
to_tago.rssi = {
value: first_gateway.rssi,
metadata: rssi_metadata
};

return result;
to_tago.snr = {
value: first_gateway.snr,
metadata: snr_metadata
};

const [firstGateway, ...otherGateways] = ttn_payload_v3.rx_metadata;
Object.assign(to_tago, processGatewayMetadata(firstGateway));
to_tago.gateway_eui = {
value: first_gateway.gateway_ids.eui,
metadata: gateway_eui_metadata
};

for (let i = 0; i < otherGateways.length; i++) {
Object.assign(to_tago, processGatewayMetadata(otherGateways[i], `_${i + 1}`));
const firstLocation = getLocationInfo(first_gateway);
if (firstLocation) {
to_tago.gateway_location = {
value: `${firstLocation.lat},${firstLocation.lng}`,
location: firstLocation,
metadata: gateway_location
};
}

delete ttn_payload_v3.rx_metadata;
Expand Down
69 changes: 41 additions & 28 deletions decoders/network/lorawan-ttittn-v3/v1.0.0/payload.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ describe("Test Suite for 1", () => {
payload = [];
});

test("Parsing TTN v3 payload with one gateways", () => {
payload = [{ variable:"ttn_payload_v3", value: "{\"end_device_ids\":{\"dev_eui\":\"A84041787659637D\",\"device_id\":\"gps-tracker-ifsc-1\",\"application_ids\":{\"application_id\":\"lora-trackers-ifsc\"},\"join_eui\":\"A840410000000102\",\"dev_addr\":\"260C050A\"},\"uplink_message\":{\"frm_payload\":\"/mUhcP0ZNSwPoiACjwEw\",\"f_port\":2,\"f_cnt\":123,\"session_key_id\":\"AZQ+K9zD8uA3z9egjhu4oA==\",\"decoded_payload\":{\"ALARM_status\":\"FALSE\",\"BatV\":4.002,\"Bg\":0,\"Date\":0,\"Hum\":65.5,\"MD\":0,\"Tem\":30.4,\"Time\":0,\"Transport\":\"STILL\",\"location_tago\":{\"latitude\":-26.926736,\"longitude\":-48.679636}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"gw1-outdoor-campus-itajai-ifsc\",\"eui\":\"F8033202462F0000\"},\"timestamp\":4106052491,\"rssi\":-107,\"channel_rssi\":-107,\"snr\":5.8,\"location\":{\"latitude\":-26.9311154775541,\"longitude\":-48.6848670244217,\"altitude\":14,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"CiwKKgoeZ3cxLW91dGRvb3ItY2FtcHVzLWl0YWphaS1pZnNjEgj4AzICRi8AABCLx/WlDxoLCNC0+7sGEOyWwQkg+K2znsDWggM=\",\"channel_index\":4,\"received_at\":\"2025-01-08T20:04:32.019942252Z\"}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":7,\"coding_rate\":\"4/5\"}},\"frequency\":\"917600000\",\"timestamp\":4106052491},\"received_at\":\"2025-01-08T20:04:32.024084580Z\",\"consumed_airtime\":\"0.066816s\",\"locations\":{\"frm-payload\":{\"latitude\":-26.931472,\"longitude\":-48.68494,\"source\":\"SOURCE_GPS\"}},\"network_ids\":{\"net_id\":\"000013\",\"ns_id\":\"EC656E0000000182\",\"tenant_id\":\"ttn\",\"cluster_id\":\"nam1\",\"cluster_address\":\"nam1.cloud.thethings.network\"}},\"correlation_ids\":[\"gs:uplink:01JH3R9J4Q1TX6NQFZT1W4RFDF\"],\"received_at\":\"2025-01-08T20:04:32.229870322Z\"}"}];

const result = decoderRun(file_path, { payload });
console.log(result);

expect(result).toEqual(
expect.arrayContaining([
expect.objectContaining({ variable: "gateway_eui", value: "F8033202462F0000", metadata: {} }),
expect.objectContaining({ variable: "rssi", value: -107, metadata: {} }),
expect.objectContaining({ variable: "snr", value: 5.8, metadata: {} }),
expect.objectContaining({
variable: "gateway_location",
value: "-26.9311154775541,-48.6848670244217",
location: { lat: -26.9311154775541, lng: -48.6848670244217 },
metadata: {},
}),
])
);
});

test("Parsing TTN v3 payload with two gateways", () => {
payload = [{ variable:"ttn_payload_v3", value:"{\"end_device_ids\":{\"dev_eui\":\"A84041787659637D\",\"device_id\":\"gps-tracker-ifsc-1\",\"application_ids\":{\"application_id\":\"lora-trackers-ifsc\"},\"join_eui\":\"A840410000000102\",\"dev_addr\":\"260C050A\"},\"uplink_message\":{\"frm_payload\":\"/mUhcP0ZNSwPoiACjwEw\",\"f_port\":2,\"f_cnt\":123,\"session_key_id\":\"AZQ+K9zD8uA3z9egjhu4oA==\",\"decoded_payload\":{\"ALARM_status\":\"FALSE\",\"BatV\":4.002,\"Bg\":0,\"Date\":0,\"Hum\":65.5,\"MD\":0,\"Tem\":30.4,\"Time\":0,\"Transport\":\"STILL\",\"location_tago\":{\"latitude\":-26.926736,\"longitude\":-48.679636}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"gw1-outdoor-campus-itajai-ifsc\",\"eui\":\"F8033202462F0000\"},\"timestamp\":4106052491,\"rssi\":-107,\"channel_rssi\":-107,\"snr\":5.8,\"location\":{\"latitude\":-26.9311154775541,\"longitude\":-48.6848670244217,\"altitude\":14,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"CiwKKgoeZ3cxLW91dGRvb3ItY2FtcHVzLWl0YWphaS1pZnNjEgj4AzICRi8AABCLx/WlDxoLCNC0+7sGEOyWwQkg+K2znsDWggM=\",\"channel_index\":4,\"received_at\":\"2025-01-08T20:04:32.019942252Z\"},{\"gateway_ids\":{\"gateway_id\":\"eui-0000f8033201cf2b\",\"eui\":\"0000F8033201CF2B\"},\"timestamp\":1389112315,\"rssi\":-50,\"channel_rssi\":-50,\"snr\":9.2,\"location\":{\"latitude\":-26.9263939015043,\"longitude\":-48.6796842068482,\"altitude\":10,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"CiIKIAoUZXVpLTAwMDBmODAzMzIwMWNmMmISCAAA+AMyAc8rEPvXsJYFGgsI0LT7uwYQ6KGrCSD4mK/stqUB\",\"channel_index\":4,\"received_at\":\"2025-01-08T20:04:32.019583208Z\"}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":7,\"coding_rate\":\"4/5\"}},\"frequency\":\"917600000\",\"timestamp\":4106052491},\"received_at\":\"2025-01-08T20:04:32.024084580Z\",\"consumed_airtime\":\"0.066816s\",\"locations\":{\"frm-payload\":{\"latitude\":-26.931472,\"longitude\":-48.68494,\"source\":\"SOURCE_GPS\"}},\"network_ids\":{\"net_id\":\"000013\",\"ns_id\":\"EC656E0000000182\",\"tenant_id\":\"ttn\",\"cluster_id\":\"nam1\",\"cluster_address\":\"nam1.cloud.thethings.network\"}},\"correlation_ids\":[\"gs:uplink:01JH3R9J4Q1TX6NQFZT1W4RFDF\"],\"received_at\":\"2025-01-08T20:04:32.229870322Z\"}" }];

Expand All @@ -37,14 +58,17 @@ describe("Test Suite for 1", () => {
expect.objectContaining({ variable: "application_id", value: "lora-trackers-ifsc" }),
expect.objectContaining({ variable: "fport", value: 2 }),
expect.objectContaining({ variable: "fcnt", value: 123 }),
expect.objectContaining({ variable: "gateway_eui", value: "F8033202462F0000" }),
expect.objectContaining({ variable: "gateway_eui_1", value: "0000F8033201CF2B" }),
expect.objectContaining({ variable: "rssi", value: -107 }),
expect.objectContaining({ variable: "rssi_1", value: -50 }),
expect.objectContaining({ variable: "snr", value: 5.8 }),
expect.objectContaining({ variable: "snr_1", value: 9.2 }),
expect.objectContaining({ variable: "gateway_location", value: "-26.9311154775541,-48.6848670244217", location: { lat: -26.9311154775541, lng: -48.6848670244217 } }),
expect.objectContaining({ variable: "gateway_location_1", value: "-26.9263939015043,-48.6796842068482", location: { lat: -26.9263939015043, lng: -48.6796842068482 } }),
expect.objectContaining({ variable: "gateway_eui", value: "F8033202462F0000", metadata: { gateway_eui_1: "0000F8033201CF2B" } }),
expect.objectContaining({ variable: "rssi", value: -107, metadata: { rssi_1: -50 } }),
expect.objectContaining({ variable: "snr", value: 5.8, metadata: { snr_1: 9.2 } }),
expect.objectContaining({
variable: "gateway_location",
value: "-26.9311154775541,-48.6848670244217",
location: { lat: -26.9311154775541, lng: -48.6848670244217 },
metadata: {
gateway_location_1: { lat: -26.9263939015043, lng: -48.6796842068482 },
},
}),
expect.objectContaining({ variable: "frm_payload", value: "fe652170fd19352c0fa220028f0130" }),
])
);
Expand All @@ -54,33 +78,22 @@ describe("Test Suite for 1", () => {
payload = [{ variable:"ttn_payload_v3", value: "{\"end_device_ids\":{\"dev_eui\":\"A84041787659637D\",\"device_id\":\"gps-tracker-ifsc-1\",\"application_ids\":{\"application_id\":\"lora-trackers-ifsc\"},\"join_eui\":\"A840410000000102\",\"dev_addr\":\"260C050A\"},\"uplink_message\":{\"frm_payload\":\"/mUhcP0ZNSwPoiACjwEw\",\"f_port\":2,\"f_cnt\":123,\"session_key_id\":\"AZQ+K9zD8uA3z9egjhu4oA==\",\"decoded_payload\":{\"ALARM_status\":\"FALSE\",\"BatV\":4.002,\"Bg\":0,\"Date\":0,\"Hum\":65.5,\"MD\":0,\"Tem\":30.4,\"Time\":0,\"Transport\":\"STILL\",\"location_tago\":{\"latitude\":-26.926736,\"longitude\":-48.679636}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"gw1-outdoor-campus-itajai-ifsc\",\"eui\":\"F8033202462F0000\"},\"timestamp\":4106052491,\"rssi\":-107,\"channel_rssi\":-107,\"snr\":5.8,\"location\":{\"latitude\":-26.9311154775541,\"longitude\":-48.6848670244217,\"altitude\":14,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"CiwKKgoeZ3cxLW91dGRvb3ItY2FtcHVzLWl0YWphaS1pZnNjEgj4AzICRi8AABCLx/WlDxoLCNC0+7sGEOyWwQkg+K2znsDWggM=\",\"channel_index\":4,\"received_at\":\"2025-01-08T20:04:32.019942252Z\"},{\"gateway_ids\":{\"gateway_id\":\"eui-0000f8033201cf2b\",\"eui\":\"0000F8033201CF2B\"},\"timestamp\":1389112315,\"rssi\":-50,\"channel_rssi\":-50,\"snr\":9.2,\"location\":{\"latitude\":-26.9263939015043,\"longitude\":-48.6796842068482,\"altitude\":10,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"CiIKIAoUZXVpLTAwMDBmODAzMzIwMWNmMmISCAAA+AMyAc8rEPvXsJYFGgsI0LT7uwYQ6KGrCSD4mK/stqUB\",\"channel_index\":4,\"received_at\":\"2025-01-08T20:04:32.019583208Z\"},{\"gateway_ids\":{\"eui\":\"0000F8033201CF3C\"},\"rssi\":-75,\"snr\":7.5,\"location\":{\"latitude\":-26.9278123456789,\"longitude\":-48.6812345678912}}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":7,\"coding_rate\":\"4/5\"}},\"frequency\":\"917600000\",\"timestamp\":4106052491},\"received_at\":\"2025-01-08T20:04:32.024084580Z\",\"consumed_airtime\":\"0.066816s\",\"locations\":{\"frm-payload\":{\"latitude\":-26.931472,\"longitude\":-48.68494,\"source\":\"SOURCE_GPS\"}},\"network_ids\":{\"net_id\":\"000013\",\"ns_id\":\"EC656E0000000182\",\"tenant_id\":\"ttn\",\"cluster_id\":\"nam1\",\"cluster_address\":\"nam1.cloud.thethings.network\"}},\"correlation_ids\":[\"gs:uplink:01JH3R9J4Q1TX6NQFZT1W4RFDF\"],\"received_at\":\"2025-01-08T20:04:32.229870322Z\"}"}];

const result = decoderRun(file_path, { payload });
console.log(result);

expect(result).toEqual(
expect.arrayContaining([
expect.objectContaining({ variable: "gateway_eui", value: "F8033202462F0000" }),
expect.objectContaining({ variable: "gateway_eui_1", value: "0000F8033201CF2B" }),
expect.objectContaining({ variable: "gateway_eui_2", value: "0000F8033201CF3C" }),
expect.objectContaining({ variable: "rssi", value: -107 }),
expect.objectContaining({ variable: "rssi_1", value: -50 }),
expect.objectContaining({ variable: "rssi_2", value: -75 }),
expect.objectContaining({ variable: "snr", value: 5.8 }),
expect.objectContaining({ variable: "snr_1", value: 9.2 }),
expect.objectContaining({ variable: "snr_2", value: 7.5 }),
expect.objectContaining({ variable: "gateway_eui", value: "F8033202462F0000", metadata: { gateway_eui_1: "0000F8033201CF2B", gateway_eui_2: "0000F8033201CF3C" } }),
expect.objectContaining({ variable: "rssi", value: -107, metadata: { rssi_1: -50, rssi_2: -75 } }),
expect.objectContaining({ variable: "snr", value: 5.8, metadata: { snr_1: 9.2, snr_2: 7.5 } }),
expect.objectContaining({
variable: "gateway_location",
value: "-26.9311154775541,-48.6848670244217",
location: { lat: -26.9311154775541, lng: -48.6848670244217 }
location: { lat: -26.9311154775541, lng: -48.6848670244217 },
metadata: {
gateway_location_1: { lat: -26.9263939015043, lng: -48.6796842068482 },
gateway_location_2: { lat: -26.9278123456789, lng: -48.6812345678912 },
},
}),
expect.objectContaining({
variable: "gateway_location_1",
value: "-26.9263939015043,-48.6796842068482",
location: { lat: -26.9263939015043, lng: -48.6796842068482 }
}),
expect.objectContaining({
variable: "gateway_location_2",
value: "-26.9278123456789,-48.6812345678912",
location: { lat: -26.9278123456789, lng: -48.6812345678912 }
})
])
);
});
Expand Down

0 comments on commit d0f9d9b

Please sign in to comment.