Skip to content

Commit

Permalink
Fixes analysis and services for handling sensor uplinks
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuscardosodeveloper committed Jan 9, 2024
1 parent f01f8d4 commit 1509f44
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 68 deletions.
41 changes: 15 additions & 26 deletions src/analysis/uplinkHandler.ts → src/analysis/uplink-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@
* - Add, edit and delete a Sensor.
* - Add, edit and delete a User.
* - Add, edit and delete scheduled reports.
*
* How to setup this analysis
* Make sure you have the following enviroment variables:
* - config_token: the value must be a token from a HTTPs device, that stores general information of the application.
* - account_token: the value must be a token from your profile. See how to generate account-token at: https://help.tago.io/portal/en/kb/articles/495-account-token.
*/

import { Utils, Account, Device, Analysis } from "@tago-io/sdk";
import { Data } from "@tago-io/sdk/out/common/common.types";
import { TagoContext } from "@tago-io/sdk/out/modules/Analysis/analysis.types";
import { Analysis, Utils } from "@tago-io/sdk";
import { Data, TagoContext } from "@tago-io/sdk/lib/types";

import sensorUplinkStatus from "../services/uplinks/sensorUplinkStatus";
import sensorUplinkLocation from "../services/uplinks/sensorUplinkLocation";
import sensorUplinkTempHum from "../services/uplinks/sensorUplinkTempHum";
import { sensorUplinkLocation } from "../services/uplinks/sensor-uplink-location";
import { sensorUplinkStatus } from "../services/uplinks/sensor-uplink-status";
import { sensorUplinkTempHum } from "../services/uplinks/sensor-uplink-temp-hum";

/**
*
Expand All @@ -32,32 +26,27 @@ import sensorUplinkTempHum from "../services/uplinks/sensorUplinkTempHum";
* @returns
*/
async function startAnalysis(context: TagoContext, scope: Data[]): Promise<void> {
console.debug("SCOPE:", JSON.stringify(scope, null, 4));
console.debug("CONTEXT:", JSON.stringify(context, null, 4));
console.debug("Running Analysis");
context.log("Running Analysis");
console.log("Scope:", scope);

// Convert the environment variables from [{ key, value }] to { key: value };
// Convert environment variables to a JSON.
const environment = Utils.envToJson(context.environment);
if (!environment) {
return;
}
console.log("Environment:", environment);

if (!environment.config_token) {
throw "Missing config_token environment var";
} else if (!environment.account_token) {
throw "Missing account_token environment var";
// Check if all tokens needed for the application were provided.
if (!environment.config_id) {
throw "Missing config_id environment var";
} else if (environment.config_id.length !== 24) {
return context.log('Invalid "config_id" in the environment variable');
}

// Just a little hack to set the device_list_button_id that come sfrom the scope
// and set it to the environment variables instead. It makes easier to use router function later.
environment._input_id = (scope as any).find((x: any) => x.device_list_button_id)?.device_list_button_id;

const config_dev = new Device({ token: environment.config_token });
const account = new Account({ token: environment.account_token });

// The router class will help you route the function the analysis must run
// based on what had been received in the analysis.
const router = new Utils.AnalysisRouter({ scope, context, environment, account, config_dev });
const router = new Utils.AnalysisRouter({ scope, context, environment });

// Sensor uplink routing
router.register(sensorUplinkLocation).whenVariables(["location"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import { Utils } from "@tago-io/sdk";
import { RouterConstructorData } from "../../types";
import { Resources } from "@tago-io/sdk";

import { RouterConstructorData } from "../../types";

/**
* Main function of receiving the uplink location
* @param config_dev Device of the configuration
* @param context Context is a variable sent by the analysis
* @param scope Scope is a variable sent by the analysis
* @param account Account instanced class
* @param environment Environment Variable is a resource to send variables values to the context of your script
*/
export default async ({ config_dev, context, scope, account, environment }: RouterConstructorData) => {
if (!account || !environment || !scope || !config_dev || !context) {
async function sensorUplinkLocation({ context, scope, environment }: RouterConstructorData) {
if (!environment || !scope || !context) {
throw new Error("Missing parameters");
}
const { device: sensor_id } = scope[0];

const sensor_dev = await Utils.getDevice(account, sensor_id);

const sensor_info = await account.devices.info(sensor_id);
const sensor_info = await Resources.devices.info(sensor_id);

const sensor_location = scope.find((x) => x.variable === "location");
if (!sensor_location) {
throw new Error("Missing location");
}

await sensor_dev.sendData({
await Resources.devices.sendDeviceData(sensor_id, {
variable: "status_history",
value: `Lat: ${(sensor_location.location as any).coordinates[1]} Lng: ${(sensor_location.location as any).coordinates[0]}`,
group: sensor_location.group,
Expand All @@ -37,9 +33,9 @@ export default async ({ config_dev, context, scope, account, environment }: Rout
return;
} //"Skipped. No group addressed to the sensor."

const group_dev = await Utils.getDevice(account, group_id);
const [dev_id] = await Resources.devices.getDeviceData(group_id, { variables: "dev_id", groups: sensor_id, qty: 1 });

const [dev_id] = await group_dev.getData({ variables: "dev_id", groups: sensor_id, qty: 1 });
await Resources.devices.editDeviceData(group_id, { ...dev_id, location: sensor_location.location });
}

await group_dev.editData({ ...dev_id, location: sensor_location.location });
};
export { sensorUplinkLocation };
Original file line number Diff line number Diff line change
@@ -1,40 +1,36 @@
import { Utils, Device } from "@tago-io/sdk";
import { Resources } from "@tago-io/sdk";

import { RouterConstructorData } from "../../types";

/**
* Function that update the status history
* @param sensor_dev Device of the sensor
* @param sensor_dev
* @param current_sensor_info Current information of the sensor
*/
const updateStatusHistory = async (sensor_dev: Device, current_sensor_info: any) => {
const updateStatusHistory = async (sensor_id: string, current_sensor_info: any) => {
const status_history = `# - Sensor reported a new status.`;

await sensor_dev.sendData({ variable: "status_history", value: status_history.replace("#", String(current_sensor_info.desc).toUpperCase()) });
await Resources.devices.sendDeviceData(sensor_id, { variable: "status_history", value: status_history.replace("#", String(current_sensor_info.desc).toUpperCase()) });
};

/**
* Main function of receiving the uplink status
* @param config_dev Device of the configuration
* @param context Context is a variable sent by the analysis
* @param scope Scope is a variable sent by the analysis
* @param account Account instanced class
* @param environment Environment Variable is a resource to send variables values to the context of your script
*/
export default async ({ config_dev, context, scope, account, environment }: RouterConstructorData) => {
if (!account || !environment || !scope || !config_dev || !context) {
async function sensorUplinkStatus({ context, scope, environment }: RouterConstructorData) {
if (!environment || !scope || !context) {
throw new Error("Missing parameters");
}
const { device: sensor_id } = scope[0];

const sensor_info = await account.devices.info(sensor_id);
const sensor_dev = await Utils.getDevice(account, sensor_id);
const sensor_info = await Resources.devices.info(sensor_id);

const org_id = sensor_info.tags.find((x) => x.key === "organization_id")?.value;
if (!org_id) {
throw new Error("Organization not found in Tago");
}
const org_dev = await Utils.getDevice(account, org_id);
const [dev_id_data] = await org_dev.getData({ variables: "dev_id", groups: sensor_id, qty: 1 });

const sensor_status = scope.find((x) => x.variable === "status");
if (!sensor_status) {
Expand All @@ -53,19 +49,17 @@ export default async ({ config_dev, context, scope, account, environment }: Rout
return;
} //"Different uplink message";

await updateStatusHistory(sensor_dev, current_sensor_info);
await updateStatusHistory(sensor_id, current_sensor_info);

const group_id = sensor_info.tags.find((x) => x.key === "group_id")?.value;

if (!group_id) {
return;
} //"Skipped. No group addressed to the sensor."

const group_dev = await Utils.getDevice(account, group_id);

const layers = await group_dev.getData({ variables: "layers", qty: 9999 });
const layers = await Resources.devices.getDeviceData(group_id, { variables: "layers", qty: 9999 });

const [dev_id] = await group_dev.getData({ variables: "dev_id", groups: sensor_id, qty: 1 });
const [dev_id] = await Resources.devices.getDeviceData(group_id, { variables: "dev_id", groups: sensor_id, qty: 1 });
if (!dev_id.metadata) {
throw new Error("dev_id.metadata not found in Tago");
}
Expand All @@ -78,5 +72,7 @@ export default async ({ config_dev, context, scope, account, environment }: Rout
dev_id.metadata.color = current_sensor_info.color;
dev_id.metadata.icon = current_sensor_info.icon;

await group_dev.editData({ ...dev_id, metadata: dev_id.metadata });
};
await Resources.devices.editDeviceData(group_id, { ...dev_id, metadata: dev_id.metadata });
}

export { sensorUplinkStatus };
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { Utils } from "@tago-io/sdk";
import { RouterConstructorData } from "../../types";
import { Resources } from "@tago-io/sdk";

import { RouterConstructorData } from "../../types";

/**
* Main function of receiving the uplink temperature and humidity
* @param config_dev Device of the configuration
* @param context Context is a variable sent by the analysis
* @param scope Scope is a variable sent by the analysis
* @param account Account instanced class
* @param environment Environment Variable is a resource to send variables values to the context of your script
*/
export default async ({ config_dev, context, scope, account, environment }: RouterConstructorData) => {
if (!account || !environment || !scope || !config_dev || !context) {
async function sensorUplinkTempHum({ context, scope, environment }: RouterConstructorData) {
if (!environment || !scope || !context) {
throw new Error("Missing parameters");
}
const { device: sensor_id } = scope[0];

const sensor_dev = await Utils.getDevice(account, sensor_id);
const sensor_temp = scope.find((x) => x.variable === "temperature");
const sensor_hum = scope.find((x) => x.variable === "relative_humidity");
if (!sensor_temp || !sensor_hum) {
Expand All @@ -27,9 +24,11 @@ export default async ({ config_dev, context, scope, account, environment }: Rout
sensor_hum?.value ? sensor_hum?.value : "N/A"
}${sensor_hum?.unit ? sensor_hum?.unit : ""}`;

await sensor_dev.sendData({
await Resources.devices.sendDeviceData(sensor_id, {
variable: "status_history",
value: status_history_value,
group: sensor_temp.group,
});
};
}

export { sensorUplinkTempHum };

0 comments on commit 1509f44

Please sign in to comment.