Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/connectors-custom-decoders #42

Merged
merged 5 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions decoders/connector/actility/custom-actility/connector.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../../../schema/connector.json",
"name": "Custom Actility",
"images": {
"logo": "./assets/logo.png"
},
"versions": {
"v1.0.0": {
"src": "./v1.0.0/payload.js",
"manifest": "./v1.0.0/payload-config.jsonc"
}
}
}
1 change: 1 addition & 0 deletions decoders/connector/actility/custom-actility/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use this custom connector if your device using Actility doesn’t show up in the list. No parser is added.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../../../schema/connector_details.json",
"description": "../description.md",
"install_text": "Use this quick setup to create an integration between Actility and TagoIO if you didn't find your specific device in the list.\n##\nBy default, it will not add a payload parser, as there is no specific information about this device.\n\nYou can build your own payload parser for this device. Check out the 'Payload Parser' tab inside the device information later.",
"install_end_text": "",
"device_annotation": "",
"device_parameters": [],
"networks": [
"../../../../network/lorawan-actility/v1.0.0/payload.js"
]
}
127 changes: 127 additions & 0 deletions decoders/connector/actility/custom-actility/v1.0.0/payload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* This is an example code for TTN Parser.
** TTN send several parameters to TagoIO. The job of this parse is to convert all these parameters into a TagoIO format.
** One of these parameters is the payload of your device. We find it too and apply the appropriate sensor parse.
**
** IMPORTANT: In most case, you will only need to edit the parsePayload function.
**
** Testing:
** You can do manual tests to this parse by using the Device Emulator. Copy and Paste the following code:
** [{ "variable": "ttn_payload", "value": "{ \"payload_raw\": \"0109611395\" }" }]
**
** The ignore_vars variable in this code should be used to ignore variables
** from the device that you don't want.
*/
// Add ignorable variables in this array.
const ignore_vars = ['rf_chain', 'channel', 'modulation', 'app_id', 'time', 'gtw_trusted'];

/**
* Convert an object to TagoIO object format.
* Can be used in two ways:
* toTagoFormat({ myvariable: myvalue , anothervariable: anothervalue... })
* toTagoFormat({ myvariable: { value: myvalue, unit: 'C', metadata: { color: 'green' }} , anothervariable: anothervalue... })
*
* @param {Object} object_item Object containing key and value.
* @param {String} serie Serie for the variables
* @param {String} prefix Add a prefix to the variables name
*/
function toTagoFormat(object_item, serie, prefix = '') {
const result = [];
for (const key in object_item) {
if (ignore_vars.includes(key) || object_item[key] === null) continue;

if (typeof object_item[key] === 'object') {
result.push({
variable: object_item[key].variable || `${prefix}${key}`,
value: object_item[key].value,
serie: object_item[key].serie || serie,
metadata: object_item[key].metadata,
location: object_item[key].location,
unit: object_item[key].unit,
});
} else {
result.push({
variable: `${prefix}${key}`.toLowerCase(),
value: object_item[key],
serie,
});
}
}

return result;
}

// Just convert lat and lng, or latitude and longitude to TagoIO format.
function transformLatLngToLocation(fields, serie, prefix = '') {
if ((fields.latitude && fields.longitude) || (fields.lat && fields.lng)) {
const lat = fields.lat || fields.latitude;
const lng = fields.lng || fields.longitude;

// Change to TagoIO format.
// Using variable "location".
const variable = {
variable: `${prefix}location`,
value: `${lat}, ${lng}`,
location: { lat, lng },
serie,
};

delete fields.latitude; // remove latitude so it's not parsed later
delete fields.longitude; // remove latitude so it's not parsed later
delete fields.lat; // remove latitude so it's not parsed later
delete fields.lng; // remove latitude so it's not parsed later

return variable;
}
}

function inspectFormat(object_item, serie, old_key) {
let result = [];
for (const key in object_item) {
if (key === 'lng'.toLowerCase() || key.toLowerCase() === 'longitude') continue;
else if (key === 'lat'.toLowerCase() || key.toLowerCase() === 'latitude') {
const lng = object_item.lng || object_item.longitude || object_item.Longitude;
result.push({
variable: old_key ? `${old_key}_location` : 'location',
value: `${object_item[key]}, ${lng}`,
location: { lat: Number(object_item[key]), lng: Number(lng) },
serie,
});
} else if (typeof object_item[key] === 'object') {
result = result.concat(inspectFormat(object_item[key], serie, key));
} else {
result.push({
variable: old_key ? `${old_key}_${key}` :`${key}`,
value: object_item[key],
serie,
});
}
}

return result;
}

// Check if what is being stored is the ttn_payload.
// Payload is an environment variable. Is where what is being inserted to your device comes in.
// Payload always is an array of objects. [ { variable, value...}, {variable, value...} ...]
let ttn_payload = payload.find(x => x.variable === 'actility_payload');
if (ttn_payload) {
// Get a unique serie for the incoming data.
const serie = ttn_payload.serie || new Date().getTime();

// Parse the ttn_payload to JSON format (it comes in a String format)
ttn_payload = JSON.parse(ttn_payload.value);

if (ttn_payload.payload_hex) {
ttn_payload.payload = ttn_payload.payload_hex;
delete ttn_payload.payload_hex;
}
delete ttn_payload.CustomerData;
delete ttn_payload.CustomerID;
delete ttn_payload.Lrrs;
delete ttn_payload.DevAddr;
delete ttn_payload.AppSKey;
delete ttn_payload.DynamicClass;
delete ttn_payload.InstantPER;
delete ttn_payload.MeanPER;
payload = toTagoFormat(ttn_payload, serie);
}
17 changes: 17 additions & 0 deletions decoders/connector/actility/custom-actility/v1.0.0/payload.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, test, expect } from "vitest";

import { decoderRun } from "../../../../../src/functions/decoder-run";

const file_path = "decoders/connector/actility/custom-actility/v1.0.0/payload.js" as const;

describe("Shall not be parsed", () => {
let payload = [{ variable: "shallnotpass", value: "04096113950292" }];
payload = decoderRun(file_path, { payload });
test("Output Result", () => {
expect(Array.isArray(payload)).toBe(true);
});

test("Not parsed Result", () => {
expect(payload).toEqual([{ variable: "shallnotpass", value: "04096113950292" }]);
});
});
73 changes: 73 additions & 0 deletions decoders/connector/aws-iot/custom-aws-iot/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions decoders/connector/aws-iot/custom-aws-iot/connector.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../../../schema/connector.json",
"name": "Custom AWS IoT",
"images": {
"logo": "./assets/logo.svg"
},
"versions": {
"v1.0.0": {
"src": "./v1.0.0/payload.js",
"manifest": "./v1.0.0/payload-config.jsonc"
}
}
}
1 change: 1 addition & 0 deletions decoders/connector/aws-iot/custom-aws-iot/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use this custom connector if your device using AWS IoT doesn't show up in the list. No parser is added
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../../../schema/connector_details.json",
"description": "../description.md",
"install_text": "Use this quick setup to create an integration between AWS IoT and TagoIO if your specific device isn't listed. \n\nBy default, it won't include a payload parser because there's no device-specific information available. You have the liberty to design your own custom payload parser for this device",
"install_end_text": "",
"device_annotation": "",
"device_parameters": [],
"networks": [
"../../../../network/aws-iot/v1.0.0/payload.js"
]
}
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions decoders/connector/brdot/custom-brdot/connector.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../../../schema/connector.json",
"name": "Custom Brdot ",
"images": {
"logo": "./assets/logo.png"
},
"versions": {
"v1.0.0": {
"src": "./v1.0.0/payload.js",
"manifest": "./v1.0.0/payload-config.jsonc"
}
}
}
1 change: 1 addition & 0 deletions decoders/connector/brdot/custom-brdot/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Give a name for this device and learn about this network here. Define the type of bucket to be used to store data for this device.
11 changes: 11 additions & 0 deletions decoders/connector/brdot/custom-brdot/v1.0.0/payload-config.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../../../schema/connector_details.json",
"description": "../description.md",
"install_text": "If your specific device is not listed, you can use this quick configuration to integrate BrDot with TagoIO. \n## \nPlease note that by default, it won't include a payload parser as there is no device-specific information available. However, you have the freedom to create a custom payload parser for your device. Take some time later to explore the 'Payload Parser' section within the device information. \n## \nAlso, don't forget to contact [sales@brdot.co](sales@brdot.co) to set up your dedicated tenant on BrDot's LNS.",
"install_end_text": "Congratulations!\nYou have succesfully created a new device using Custom Brdot ;)",
"device_annotation": "",
"device_parameters": [],
"networks": [
"../../../../network/lorawan-brdot/v1.0.0/payload.js"
]
}
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions decoders/connector/chirpstack/custom-chirpstack/connector.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../../../schema/connector.json",
"name": "Custom Chirpstack",
"images": {
"logo": "./assets/logo.png"
},
"versions": {
"v1.0.0": {
"src": "./v1.0.0/payload.js",
"manifest": "./v1.0.0/payload-config.jsonc"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use this custom connector if your device using Chirpstack doesn’t show up in the list. No parser is added.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../../../schema/connector_details.json",
"description": "../description.md",
"install_text": "Use this quick setup to create an integration between Chirpstack and TagoIO if you didn't find your specific device in the list.\n##\nBy default, it will not add a payload parser, as there is no specific information about this device.\n\nYou can build your own payload parser for this device. Check out the 'Payload Parser' tab inside the device information later.\n",
"install_end_text": "",
"device_annotation": "",
"device_parameters": [],
"networks": [
"../../../../network/lorawan-chirpstack/v1.0.0/payload.js"
]
}
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions decoders/connector/citykinect/custom-citykinect/connector.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../../../schema/connector.json",
"name": "Custom CityKinect",
"images": {
"logo": "./assets/logo.png"
},
"versions": {
"v1.0.0": {
"src": "./v1.0.0/payload.js",
"manifest": "./v1.0.0/payload-config.jsonc"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Connect any device using CityKinect LoraWaN network
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../../../schema/connector_details.json",
"description": "../description.md",
"install_text": "Use this quick setup to create an integration between CityKinect and TagoIO if you don’t find your specific device in the list.\n\n##\nBy default, it will not add a payload parser, as there is no specific information about this device.\n\nYou can build your own payload parser for this device. Check out the 'Payload Parser' tab inside the device information later.\n##\n",
"install_end_text": "",
"device_annotation": "",
"device_parameters": [],
"networks": [
"../../../../network/lorawan-citykinect/v1.0.0/payload.js"
]
}
Loading