### Install and Run TagoCore from Source Source: https://docs.tago.io/tagocore/installation After extracting the source code, use these commands to install dependencies, build the console, and start the TagoCore server. ```shell just install just build-console just server ``` -------------------------------- ### Quick Start: List Devices with Python SDK Source: https://docs.tago.io/docs/tagoio/analysis/sdk/python-sdk A basic example to authenticate with your TagoIO account using an access token and list your devices. Replace 'your-token' with your actual account token. ```python from tagoio_sdk import Account account = Account({"token": "your-token"}) devices = account.devices.list() print(devices) ``` -------------------------------- ### Basic Module Setup Source: https://docs.tago.io/tagocore/plugins/create/module Demonstrates the basic setup for a TagoCore module, including importing the ServiceModule and creating a setup object with 'id' and 'name'. ```javascript const { ServiceModule } = require("@tago-io/tcore-sdk"); const setup = { id: "my-service", name: "Pretty name of service", }; new ServiceModule(setup); ``` -------------------------------- ### Start HTTP Server with Express Source: https://docs.tago.io/tagocore/plugins/create/service This snippet demonstrates how to start an HTTP server using Express when the plugin loads. It handles GET requests to the root path and ensures the server is properly closed on destruction. ```javascript const { ServiceModule } = require("@tago-io/tcore-sdk"); const express = require("express"); const app = express(); let server = null; const myService = new ServiceModule({ id: "hello-world-service", name: "Hello World service", }); // `onLoad` is used to run your code. // This function will be called once when your plugin gets loaded. myService.onLoad = async () => { app.get("/", function (req, res) { res.send("Hello World"); }); server = app.listen(3000); }; // `onDestroy` is used to clean up your code. // This function will never be called before `onLoad`. myService.onDestroy = async () => { server.close(); }; ``` -------------------------------- ### Orbiwise Integration Example Source: https://docs.tago.io/docs/tagoio/integrations/networks/orbiwise-lorawan Example of additional parameters for TagoIO authorization, including username, password, and DASS URL. ```text tagoio;iot;; ``` -------------------------------- ### Start Development Server Source: https://docs.tago.io/docs/tagoio/widgets/custom-widget/echarts-custom-widget-tutorial- Start the local development server to host your custom widget. This command is typically run in the project's terminal. ```bash npm start ``` -------------------------------- ### Install Project Dependencies Source: https://docs.tago.io/docs/tagoio/widgets/custom-widget/echarts-custom-widget-tutorial- Install all required Node.js dependencies for the custom widget project using npm. ```bash npm install ``` -------------------------------- ### Full Variable Example Source: https://docs.tago.io/docs/tagotip/specification/tagotip-specification An example demonstrating a variable with all optional suffixes included in the correct order. ```plaintext temperature:=32.5#C@=39.74,-104.99@1694567890000^reading_001{source=dht22,quality=high} ``` -------------------------------- ### Install TagoCore Plugin SDK Source: https://docs.tago.io/tagocore/plugins/create Install the TagoCore Plugin SDK to add functionality to your plugin. ```bash npm install @tago-io/tcore-sdk ``` -------------------------------- ### Install TagoIO Python SDK Source: https://docs.tago.io/docs/tagoio/analysis/sdk/python-sdk Install the TagoIO Python SDK using pip. This command should be run in your terminal or command prompt. ```bash pip install tagoio-sdk ``` -------------------------------- ### Install TagoIO SDK and TagoIO-Builder Source: https://docs.tago.io/docs/tagoio/analysis/running-analysis-as-external-using-nodejs Installs the necessary TagoIO SDK for analysis development and the TagoIO-Builder for uploading compiled scripts. Use '--save' to add the SDK to your project's dependencies. ```bash npm install --save @tago-io/sdk npm install -g @tago-io/builder ``` -------------------------------- ### Plugin Module Types Example Source: https://docs.tago.io/tagocore/plugins/create/manifest An example array showing how to specify the types of modules your plugin utilizes, such as 'service' and 'encoder'. ```json ["service", "encoder"] ``` -------------------------------- ### TagoTiP/S Downlink with Command Example Source: https://docs.tago.io/docs/tagotip/specification/tagotips-specification This example illustrates how a server queues a command for a device and wraps it in an encrypted envelope. The device decrypts the envelope, identifies the command, and processes the payload. ```text Server has queued command for sensor-01. Server wraps response in envelope using sensor-01's Device Hash, Flags = 0x03 (ACK), and a unique nonce seed. Headless inner frame: CMD|ota=https://example.com/v2.1.bin Device decrypts using its Encryption Key and the reconstructed nonce. AEAD decryption verifies authenticity; device reads method=ACK from Flags, parses STATUS=CMD, DETAIL=ota=https://example.com/v2.1.bin. ``` -------------------------------- ### Plugin Permissions Example Source: https://docs.tago.io/tagocore/plugins/create/manifest An example array listing the TagoCore API permissions your plugin requires, such as 'action', 'analysis', 'device', and 'device-data'. ```json ["action", "analysis", "device", "device-data"] ``` -------------------------------- ### Install Tago Library Source: https://docs.tago.io/docs/tagoio/tutorials/beagle-bone-black Command to install the Tago library using pip. Ensure Python 2.7.9 or later is used. ```bash sudo pip install -U tago ``` -------------------------------- ### Email Subject and Body Example Source: https://docs.tago.io/tagodeploy/project/monitoring/actions These examples show how to construct an email subject and body using variables to provide specific alert details. The variables are dynamically replaced with actual data when the alert triggers. ```text - **Subject**: `[Critical] Main Database - CPU Utilization at 92%` ``` ```text - **Subject**: `[{thresholdName}] {serviceName} - {metric} at {metricValue}` - **Body**: `{metric} on {serviceName} crossed the {thresholdName} threshold. Current value: {metricValue}. Severity: {severity}. Time: {timestamp}.` ``` -------------------------------- ### TagoTiP/S Data Point Example Source: https://docs.tago.io/docs/tagotip/specification/tagotip-specification An example of a data point using TagoTiP/S, which includes encryption overhead and a smaller frame size. ```text Headless inner frame (81 bytes): sensor-01|@1694567890000^batch_42[temperature:=32#F@=39.74,-104.99{source=dht22}] (removed "PUSH|4deedd7bab8817ec|" = 22 bytes) Envelope: 1 (flags) + 4 (counter) + 8 (auth hash) + 8 (device hash) + 81 (ciphertext) + 8 (auth tag) = 110 bytes ``` -------------------------------- ### TagoTiP MQTT PUSH Payload Examples Source: https://docs.tago.io/docs/tagotip/transports/mqtt Examples of structured variables and passthrough data for PUSH operations to `$tip/{serial}/push`. Includes formats with sequence counters. ```plaintext [temp:=32#C;humidity:=65#%] @=39.74,-104.99@1694567890000^batch_42[temp:=32#C] >xDEADBEEF01020304 >b3q2+7wECAwQ= !42|[temp:=32#C;humidity:=65#%] ``` -------------------------------- ### Arduino ESP32 UDP Example Source: https://docs.tago.io/docs/tagotip/transports/udp This example demonstrates how to send data to TagoTip using UDP on an ESP32. It includes WiFi connection, data formatting, sending, and optional response handling. Ensure your WiFi credentials and token hash are correctly set. ```cpp #include #include const char* SSID = "your-wifi"; const char* PASSWORD = "your-password"; const char* TIP_HOST = "udp.tip.us-e1.tago.io"; const int TIP_PORT = 5683; const char* TOKEN_HASH = "4deedd7bab8817ec"; // replace with yours const char* SERIAL_N = "sensor-01"; // replace with yours WiFiUDP udp; void setup() { Serial.begin(115200); WiFi.begin(SSID, PASSWORD); while (WiFi.status() != WL_CONNECTED) delay(500); Serial.println("WiFi connected"); } void loop() { float temperature = analogRead(34) * 0.1; // example reading char frame[256]; snprintf(frame, sizeof(frame), "PUSH|%s|%s|[temperature:=%.1f#C]", TOKEN_HASH, SERIAL_N, temperature); udp.beginPacket(TIP_HOST, TIP_PORT); udp.print(frame); udp.endPacket(); // read response (optional for fire-and-forget) delay(100); int len = udp.parsePacket(); if (len > 0) { char buf[128]; udp.read(buf, sizeof(buf) - 1); buf[len] = '\0'; Serial.println(buf); // ACK|OK|1 } delay(10000); // send every 10 seconds } ``` -------------------------------- ### Node.js Analysis Execution Example Source: https://docs.tago.io/tagocore/analysis This example shows the command TagoCore uses to execute a Node.js analysis script. Ensure the binary path and file path are correctly configured. ```shell /Users/tagocore/.nvm/versions/node/v14.17.3/bin/node /Users/tagocore/project-code/index.js ``` -------------------------------- ### TagoTiP MQTT PULL Payload Examples Source: https://docs.tago.io/docs/tagotip/transports/mqtt Examples of comma-separated variable names for PULL operations to `$tip/{serial}/pull`. Includes formats with sequence counters. ```plaintext temperature,humidity !7|temperature,humidity ``` -------------------------------- ### Remote Imports in Python Analysis Source: https://docs.tago.io/docs/tagoio/analysis/sdk/python-sdk Example of importing necessary modules within a TagoIO Python Analysis script. These packages will be installed automatically at runtime. ```python from tagoio_sdk import Analysis from pandas import DataFrame import requests ``` -------------------------------- ### Define Plugin Configuration Field Source: https://docs.tago.io/tagocore/plugins/create Add a `configs` field to your `ServiceModule` setup to allow users to input values through the plugin's UI. This example defines a required numeric field for a port number. ```javascript const { ServiceModule } = require("@tago-io/tcore-sdk"); const service = new ServiceModule({ id: "getting-started-service", name: "Getting Started Service", configs: [ { type: "number", // type of the field, there are many types field: "port", // unique identifier for this field name: "Port", // visual label for the field required: true, // obligatory }, ], }); ``` -------------------------------- ### Initialize Node.js Project Source: https://docs.tago.io/tagocore/plugins/create Use this command to start a new Node.js project in your plugin's directory. ```bash npm init --yes ``` -------------------------------- ### Arduino ESP32 TagoTiP MQTT Client Example Source: https://docs.tago.io/docs/tagotip/transports/mqtt A complete Arduino sketch for ESP32 demonstrating how to connect to WiFi, establish an MQTT connection to TagoTiP, subscribe to ACK messages, and publish data periodically. ```cpp #include #include const char* SSID = "your-wifi"; const char* PASSWORD = "your-password"; const char* MQTT_HOST = "mqtt.tip.us-e1.tago.io"; const int MQTT_PORT = 1883; const char* MQTT_USER = "4deedd7b"; // first 8 hex chars of auth hash const char* MQTT_PASS = "ab8817ec"; // last 8 hex chars of auth hash const char* SERIAL_N = "sensor-01"; WiFiClient wifi; PubSubClient mqtt(wifi); char pushTopic[64]; char ackTopic[64]; void onMessage(char* topic, byte* payload, unsigned int length) { char msg[256]; memcpy(msg, payload, min(length, sizeof(msg) - 1)); msg[min(length, sizeof(msg) - 1)] = '\0'; Serial.print("ACK: "); Serial.println(msg); // check for commands if (strncmp(msg, "CMD|", 4) == 0) { Serial.print("Command: "); Serial.println(msg + 4); } } void setup() { Serial.begin(115200); WiFi.begin(SSID, PASSWORD); while (WiFi.status() != WL_CONNECTED) delay(500); Serial.println("WiFi connected"); snprintf(pushTopic, sizeof(pushTopic), "$tip/%s/push", SERIAL_N); snprintf(ackTopic, sizeof(ackTopic), "$tip/%s/ack", SERIAL_N); mqtt.setServer(MQTT_HOST, MQTT_PORT); mqtt.setCallback(onMessage); } void reconnect() { while (!mqtt.connected()) { if (mqtt.connect("esp32-client", MQTT_USER, MQTT_PASS)) { mqtt.subscribe(ackTopic, 1); Serial.println("MQTT connected"); } else { delay(5000); } } } void loop() { if (!mqtt.connected()) reconnect(); mqtt.loop(); static unsigned long lastSend = 0; if (millis() - lastSend > 10000) { lastSend = millis(); float temperature = analogRead(34) * 0.1; char payload[128]; snprintf(payload, sizeof(payload), "[temperature:=%.1f#C]", temperature); mqtt.publish(pushTopic, payload, false); } } ``` -------------------------------- ### TagoTiP/S Downlink Inner Frame Examples Source: https://docs.tago.io/docs/tagotip/specification/tagotips-specification Shows the structure of downlink inner frames for ACK methods in TagoTiP/S. The format starts with STATUS and can include details, variable assignments, commands, or a PONG response. ```plaintext OK|3 ``` ```plaintext OK|[temperature:=32#F@1694567890000] ``` ```plaintext CMD|ota=https://example.com/v2.1.bin ``` ```plaintext PONG ``` -------------------------------- ### Calendar Input Form Payload Example Source: https://docs.tago.io/docs/tagoio/widgets/input-widgets/input-form/field-types-for-input-form This JSON payload demonstrates the structure of data received from a Calendar input field in the Input Form widget. It includes the main value and metadata containing start and end dates. ```json { "variable": "location", "value": "Start: 2021-06-04T03:00:00Z, End: 2021-06-11-T02:59:59Z", "metadata": { "end_date": "2021-06-11T02:59:59Z", "start_date": "2021-06-04T03:00:00Z" } } ``` -------------------------------- ### Use User Configuration Values in Plugin Lifecycle Source: https://docs.tago.io/tagocore/plugins/create Utilize the `onLoad` and `onDestroy` functions to access user-defined configuration values and manage plugin resources. This example starts an Express HTTP server on a user-specified port and closes it on destruction. ```javascript const { ServiceModule } = require("@tago-io/tcore-sdk"); const express = require("express"); const app = express(); let server = null; const service = new ServiceModule({ id: "getting-started-service", name: "Getting Started Service", configs: [ { type: "number", field: "port", name: "Port", required: true, }, ], }); service.onLoad = async (userValues) => { if (!userValues.port) { throw new Error("Invalid port"); } app.get("/", (req, res) => res.send("Hello World")); server = app.listen(userValues.port); }; service.onDestroy = () => { server.close(); }; ``` -------------------------------- ### Example of File Address Generation Source: https://docs.tago.io/docs/tagoio/devices/data-management/chunk-management Demonstrates how a file address template is translated into an actual file path, including the device ID and date range. ```text /device/6297aa7691e70a00654f9816/2022-04-01_2022-06-30.csv ``` -------------------------------- ### Initialize LoRa Module and Network Parameters Source: https://docs.tago.io/docs/tagoio/tutorials/lorawan-publication-of-environmental-measurements-with-a-lora-e5-module Imports necessary libraries, defines LoRaWAN parameters (DevAddr, AppEui, AppKey), and initializes the LoRa driver. Includes a callback function for received data and functions to print LoRa parameters and join the network. ```python # Importing different drivers import machine from stm32_LoRa import * from utime import sleep_ms UART_WB55 = const(2) devAddr = "44 10 BA 4A" appEui = "00 00 00 00 00 00 00 00" appKey = "55 10 67 98 B2 15 EE 4E D0 33 19 DC 65 27 88 AB" def DataReceived(Port=0, DataReceived=b""): print("#### = Data received") print(f"Data received on PORT: {Port}, Size = {len(DataReceived)}, Data = {[hex(x) for x in list(DataReceived)]}") loRa = LoRa(9600, UART_WB55, DataReceiveCallback=DataReceived) status = loRa.setIdentify(DevAddr=devAddr, AppEui=appEui, AppKey=appKey) def PrintLoRaParameters(): identify = loRa.getIdentify() if identify != -1: print("#####################################################################") print("########## INITIALIZE ########") print("#####################################################################") print("LORA_DRIVER_VERSION : " + loRa.getDriverVersion()) print("#### " + loRa.getMode() + " ####") print("#### AppKey: " + identify["AppKey"]) print("#### DevEUI: " + identify["DevEui"]) print("#### AppEUI: " + identify["AppEui"]) print("#### DevAddr: " + identify["DevAddr"]) else: print("#### = Read identify fail. Reboot!") sleep_ms(2000) machine.reset() def JoinNetwork(): joinStatus = False tryJoin = 0 while not joinStatus: print("#### = Try join n°" + str(tryJoin+1)) status = loRa.join() if status == -1: print("#### = Join Fail, retry in 10 seconds.") tryJoin += 1 else: joinStatus = True print("#### = Join success.") ``` -------------------------------- ### Accessing Module Configurations Source: https://docs.tago.io/tagocore/plugins/create/module Shows how to define configuration parameters for a module using the 'configs' property in the setup object and how to access their latest values within the 'onLoad' function. ```javascript const { ServiceModule } = require("@tago-io/tcore-sdk"); const service = new ServiceModule({ id: "my-service", name: "Service", configs: [ { name: "Token", field: "token", type: "string", required: true, }, ], }); service.onLoad = async () => { // Retrieves the latest config values from TagoCore const configs = await service.configs; const token = configs.token; }; ``` -------------------------------- ### PULL Example: Retrieve Single Variable Source: https://docs.tago.io/docs/tagotip/specification/tagotip-specification Example of a PULL request for a single variable 'temperature' and its successful response. ```text → PULL|4deedd7bab8817ec|weather-denver|[temperature] ← ACK|OK|[temperature:=32#F@1694567890000] ``` -------------------------------- ### PULL Example: Retrieve Variable with Location Source: https://docs.tago.io/docs/tagotip/specification/tagotip-specification Example of a PULL request for a variable, demonstrating the response with location data included. ```text → PULL|4deedd7bab8817ec|drone-07|[speed] ← ACK|OK|[speed:=10#km/h@=39.74,-104.99@1694567890000] ``` -------------------------------- ### Deno Configuration for Analysis Source: https://docs.tago.io/docs/tagoio/analysis/running-analysis-as-external-using-deno This JSON configuration file sets up tasks for Deno, specifically defining a 'start' task to run the analysis script. It includes essential permissions for network access and environment variable reading. ```json { "tasks": { "start": "deno run --allow-net --allow-env analysis.ts" } } ``` -------------------------------- ### Example Data Payload Source: https://docs.tago.io/docs/tagoio/devices/sending-data A standard example payload for sending data, including variable, unit, value, time, and location. ```JSON { "variable": "temperature", "unit": "F", "value": 55, "time": "2015-11-03 13:44:33", "location": { "lat": 42.2974279, "lng": -85.628292 } } ``` -------------------------------- ### Node.js Local Development Workflow Source: https://docs.tago.io/docs/tagoio/analysis/index Install Node.js dependencies and use the TagoIO builder to pack your Analysis for upload. This workflow requires local development tools. ```bash # Local development workflow npm install @tago-io/sdk axios tagoio-builder pack # Upload the generated .tago file ``` -------------------------------- ### Cron Expression Example Source: https://docs.tago.io/docs/tagoio/actions/action-cron This is an example cron expression used in TagoIO's Recurrence options. It specifies the schedule for a task to run. ```cron 00 00 */1 * Mon ``` -------------------------------- ### Full Conversation Flow Example Source: https://docs.tago.io/docs/tagotip/specification/tagotip-specification Demonstrates a complete interaction including PING, PUSH, PULL, and error handling with ACK responses. ```TagoTip → PING|4deedd7bab8817ec|weather-denver ← ACK|PONG → PUSH|4deedd7bab8817ec|weather-denver|[temperature:=32#F;humidity:=65#%;active?=true] ← ACK|OK|3 → PULL|4deedd7bab8817ec|weather-denver|[temperature] ← ACK|OK|[temperature:=32#F@1694567890000] ← ACK|CMD|reboot → PUSH|4deedd7bab8817ec|weather-denver|[invalid=broken ← ACK|ERR|invalid_payload ```