I am encountering an issue while trying to connect to your MQTT broker at `mqtt.tago.io` on port `1883`.
Despite following the official documentation precisely and ensuring my device token is correct, the connection fails with the error: “Connection refused: Bad username or password”.
Currently the connection with our MQTT broker is available for Starter and Scale accounts. But we understand how important MQTT connectivity is and we’re here to help.
I’ve escalated your case to our team, and they’ve already contacted you via email to assist you further. Please check your inbox.
Also, we’ve edited your post to hide part of your device token by replacing it with “xxx”. This token is a sensitive piece of information — anyone with access to it could potentially send data to your device.
Let me know if you need anything else!
I also experienced this problem. I recently created a free account to test the Tago IO platform. Several videos I watched online talked about the platform’s features, which led me to try it.
I ran into this problem and only discovered it after watching a more recent video on the Tago IO channel.
Now I find myself unable to test and learn about the platform, which makes me very sad.
I have a client who needs to implement an asset monitoring platform in the oil and gas sector, but this limitation prevents me from knowing if Tago IO will be the best tool for my needs.
I completely understand your frustration. Let me help you with that.
There is an alternative solution available. The Relay:
The TagoIO MQTT Relay is specifically designed to solve this exact problem. This open-source Rust application acts as a bridge between any MQTT broker and TagoIO, and it works with Free accounts. Here’s how you can set it up:
Use any external MQTT broker (like HiveMQ public broker, Eclipse Mosquitto, or EMQX)
Configure the relay to forward data from your MQTT broker to TagoIO devices
Test your complete IoT workflow without upgrading your account
The relay is completely free and allows you to evaluate TagoIO’s data processing, visualization, and automation capabilities with real MQTT data.
If you want, you can schedule a demo and talk to our team so we can discuss how we can help you to offer a solution for your client by clicking the link below and filling out the form: Request Demo.
If you need anything else, we’re here to help you!
I implemented the Relay, but I can’t insert the data into the widget. The data arrives in TagoIO with the payload variable and the value {“variable”:“tension”, “value”:“110”}.
I expected it to arrive with the voltage variable and the value 110, but my data is the payload variable.
Is there a video that shows the entire relay implementation process until the data is displayed on the dashboard?
I’ve read several topics and watched your videos, but I can’t make any progress. I noticed that a lot has changed in the platform, and the videos haven’t been updated yet.
All data sent via the MQTT Relay is sent as a single payload variable. I would suggest you utilize the network payload parser to parse which device should receive the data. After that you can use that device’s connector payload parser to parse the payload variable into the exact format you need.
I’ve already completed the entire process in the video above, and it’s working perfectly. My question now is how to decode the data with the payload parser for both the network and the connector.
Send me an example of the payload variable your device is receiving and what format you are looking for, I’ll create a initial parser for you which should help you out.
/**
* Parses MQTT payload containing JSON data with variable and value information
*
* @param {string} jsonPayload - The JSON string payload to be parsed
* @param {string} group - The group identifier for the data
* @param {string} receivedTime - The time the payload was received
* @param {Object} metadata - Additional metadata from the original payload
* @returns {Array} An array of data objects formatted for TagoIO storage
**/
function parseMQTTJsonPayload(jsonPayload, group, receivedTime, metadata) {
const data = [];
const time = receivedTime || new Date().toISOString();
try {
// Parse the JSON string from the payload value
const parsedJson = JSON.parse(jsonPayload);
// Validate that the parsed JSON has the expected structure
if (parsedJson && typeof parsedJson === "object" && parsedJson.variable && parsedJson.value !== undefined) {
// Create the data object for TagoIO
const dataObject = {
variable: parsedJson.variable,
value: parsedJson.value,
group: group || undefined,
time: time,
metadata: {
// Preserve original MQTT metadata
...metadata,
// Add any additional metadata from the parsed JSON if present
...(parsedJson.metadata || {})
}
};
// Add unit if present in the parsed JSON
if (parsedJson.unit) {
dataObject.unit = parsedJson.unit;
}
// Add location if present in the parsed JSON
if (parsedJson.location && parsedJson.location.lat && parsedJson.location.lng) {
dataObject.location = {
lat: parsedJson.location.lat,
lng: parsedJson.location.lng
};
}
data.push(dataObject);
} else {
// Handle invalid JSON structure
data.push({
variable: "parser_error",
value: "Invalid JSON structure: missing 'variable' or 'value' fields",
group: group || undefined,
time: time,
metadata: metadata || {}
});
}
} catch (error) {
// Handle JSON parsing errors
data.push({
variable: "parser_error",
value: `JSON parsing failed: ${error.message}`,
group: group || undefined,
time: time,
metadata: metadata || {}
});
}
return data;
}
// Main decoder logic - Extract MQTT payload data
const mqttPayload = payload.find((item) => item.variable === "payload");
if (mqttPayload && mqttPayload.value) {
// Extract metadata and other properties
const group = mqttPayload.group;
const metadata = mqttPayload.metadata || {};
// Parse the JSON payload and transform to TagoIO format
const parsedData = parseMQTTJsonPayload(mqttPayload.value, group, mqttPayload.time, metadata);
// Replace original payload with parsed data
payload = parsedData;
}
Following the Relay tutorial should guide you to set the Middleware URL in your TagoIO Network. Once you’ve set it up correctly, you can use Analysis to publish through the utility at https://js.sdk.tago.io/classes/Network.html#publishtorelay
Example:
import { Analysis, Resources, Utils } from "jsr:@tago-io/sdk";
async function run(context) {
// Publish to Relay: topic and payload for your external broker
await Resources.integration.networks.publishToRelay({
device: "DEVICE_ID",
topic: "devices/relay-test",
message: "001201",
options: { qos: 0 }, // optional
});
console.log("Published via Relay");
}
Analysis.use(run);
Great job getting your device talking to TagoIO through MQTT Bridge and publishing via publishToRelay. To send commands from the dashboard in a structured way, I recommend using an Input Form widget and setting it to trigger your Analysis.
How to set it up
Add an Input Form widget to your dashboard.
Create the Fields you need for each command parameter (e.g., mode, setpoint, output_pct, etc.).
In the widget’s Action settings, choose “Trigger Analysis” and select your Analysis.
When the user submits the form, the field values will be delivered to your Analysis in the scope parameter. You can then parse those values and build the exact payload your device expects.
Example (adapting your Analysis)
Suppose your Input Form has fields:
command (e.g., “set_mode”, “set_output”)
value (e.g., “AUTO” or 73)
Your Analysis can read from scope and publish to your broker:
import { Analysis, Network } from "jsr:@tago-io/sdk";
async function run(context, scope) {
const network \= new Network({ token: "YOUR-NETWORK-TOKEN" });
// scope will contain an array of variables coming from the Input Form
// Example extraction helper:
const get \= (key) \=> (scope.find((x) \=> x.variable \=== key) || {}).value;
const command \= get("command");
const value \= get("value");
// Build your device message based on the form inputs
// Replace this logic with your device’s protocol
const topic \= "/tanacas/123456";
const message \= command \=== "set\_mode"
? (value \=== "AUTO" ? "001201" : "001200")
: command \=== "set\_output"
? \`02${String(value).padStart(3, "0")}\`
: "";
if (!message) {
context.log("Invalid command payload");
return;
}
await network.publishToRelay({
device: "688988e9544bbb0xxxxxxxxx",
topic,
message,
options: { qos: 0 },
});
context.log("Command sent via Relay");
}
export default new Analysis({ token: "ANALYSIS-TOKEN" }).run(run);
Tips
The Field “Key” names you configure in the Input Form become the variable names found in scope (scope.variable and scope.value). Use clear, consistent keys.
Validate and normalize inputs (limits, types, mapping to hex/binary) before building the payload.
Keep tokens in environment vars or Analysis secrets when possible.
If your commands require binary or hex encoding, convert the scope values accordingly before publishToRelay.
I need to send three analog data points and one digital data point from a button.
With the components I used in the dashboard as shown in the image I sent, I can now write data from the buckets to four variables. Couldn’t I send this data by directly retrieving the information from the buckets with my analysis?
In the screenshot you shared, I don’t see an Analysis selected to trigger when the “Enviar” button is pressed. Please confirm whether you assigned an Analysis to that button.
The code I provided is only an example and must be adapted to your use case. If you get stuck at any step, share which part is failing and I’ll help you resolve it.