Radix IoT Documentation

Knowledge Base

Choose a product to explore guides, documentation, and how-to articles.

Mango

Mango

SCADA & IoT platform for building automation, energy management, and industrial monitoring.

24 Guides Available
Mango 4.x & 5.x
Coming Soon
errProof

errProof

Quality management and error-proofing platform for manufacturing and operational excellence.

0 Guides Available

On this page

Installing Mango 4 on Windows

Category: Installation · Version: Mango 4.x · Difficulty: Beginner · 10 min read

Overview

This guide walks you through installing Mango 4 on a Windows machine from scratch. By the end, you'll have a running Mango instance accessible from your browser.

Prerequisites

Step 1: Install Java 11

Mango 4 requires Java 11. Download and install it first.

  1. Download AdoptOpenJDK 11 (now Eclipse Temurin) from the official site
  2. Run the installer and select Add to PATH during setup
  3. Verify the installation by opening Command Prompt and running:
java -version

You should see output containing openjdk version "11.x.x".

WARNING: Mango 4 is not compatible with Java 17 or higher. Make sure you install Java 11 specifically.

Step 2: Download Mango

  1. Log in to the Mango store at store.infiniteautomation.com
  2. Navigate to your licensed products or start a free trial
  3. Download the latest Mango 4.x release ZIP file
  4. Extract the ZIP to a directory like C:\\mango

Step 3: Configure Environment Properties

Before starting Mango, review the configuration:

  1. Navigate to C:\\mango\\overrides\\properties
  2. Open or create mango.properties
  3. Set your database and key paths:
# Database location (default is H2)
db.type=h2
db.url=jdbc:h2:./databases/mah2

# Web server port
web.port=8080

# SSL (optional for production)
ssl.on=false

Step 4: Start Mango

Open Command Prompt as Administrator and run:

cd C:\\mango
bin\\start.bat

Watch the console output for:

INFO  - Mango started in X seconds

Step 5: Access Mango

  1. Open your browser and navigate to http://localhost:8080
  2. Log in with the default credentials:
DANGER: Change the default admin password immediately after first login. Go to Administration > Users and update the password.

Step 6: Install as a Windows Service (Optional)

To run Mango as a background service that starts automatically:

  1. Open Command Prompt as Administrator
  2. Navigate to your Mango directory
  3. Run:
bin\\install-service.bat
  1. Open Windows Services (services.msc) and find "Mango"
  2. Set startup type to Automatic
  3. Start the service

Verification

Confirm your installation is working:

Troubleshooting

Port 8080 already in use?

Edit mango.properties and change web.port to another value like 8443.

Java not found error?

Ensure Java 11 is on your PATH. Run java -version to verify.

Service won't start?

Check logs/ma.log for errors. Common issues include incorrect file permissions or missing Java installation.

Installing Mango 5 on Linux (Ubuntu/Debian)

Category: Installation · Version: Mango 5.x · Difficulty: Intermediate · 12 min read

Overview

This guide covers installing Mango 5 on Ubuntu 20.04/22.04 or Debian 11/12. Mango 5 introduces an updated architecture with improved module management and a modern UI.

Prerequisites

INFO: Mango 5 requires Java 17, unlike Mango 4 which uses Java 11. Make sure you install the correct version.

Step 1: Update System and Install Java 17

sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk

Verify the installation:

java -version

Expected output: openjdk version "17.x.x"

Set JAVA_HOME:

echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
source ~/.bashrc

Step 2: Create Mango User

For security, run Mango under a dedicated service account:

sudo useradd -r -m -d /opt/mango -s /bin/bash mango

Step 3: Download and Extract Mango

cd /opt/mango
sudo -u mango wget https://store.infiniteautomation.com/downloads/mango-5.x.x.zip
sudo -u mango unzip mango-5.x.x.zip

Step 4: Configure Mango

Edit the environment properties:

sudo -u mango nano /opt/mango/overrides/properties/mango.properties

Key settings:

# Web port
web.port=8080

# Database (H2 for testing, MySQL/PostgreSQL for production)
db.type=h2
db.url=jdbc:h2:/opt/mango/databases/mangodb

# Timezone
timezone=America/New_York

Step 5: Create a systemd Service

Create the service file:

sudo nano /etc/systemd/system/mango.service

Paste the following:

[Unit]
Description=Mango Automation
After=network.target

[Service]
Type=simple
User=mango
Group=mango
WorkingDirectory=/opt/mango
ExecStart=/usr/bin/java -jar /opt/mango/boot/ma-bootstrap.jar
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable mango
sudo systemctl start mango

Step 6: Verify Installation

Check the service status:

sudo systemctl status mango

View logs:

sudo journalctl -u mango -f

Access Mango at http://your-server-ip:8080.

Step 7: Configure Firewall

sudo ufw allow 8080/tcp
sudo ufw reload

Verification Checklist

Troubleshooting

Service fails to start?

Check logs with journalctl -u mango -n 50. Common causes: wrong Java version, permission issues on /opt/mango.

Cannot access from another machine?

Ensure firewall allows port 8080 and Mango is not bound to localhost only.

Out of memory errors?

Add JVM memory flags to the ExecStart line: -Xmx2g -Xms512m

Configuring a Modbus TCP Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 8 min read

Overview

Modbus TCP is one of the most common protocols for communicating with industrial equipment. This guide shows how to configure a Modbus TCP data source in Mango to read and write registers from your devices.

Prerequisites

Step 1: Create the Data Source

  1. Navigate to Data Integration > Data Sources
  2. Click the + button to add a new data source
  3. Select Modbus IP from the dropdown
  4. Fill in the connection details:
Field Value Notes
Name Descriptive name e.g., "Building A Power Meter"
Host Device IP address e.g., 192.168.1.100
Port 502 Default Modbus port
Update Period 5 seconds Adjust based on your needs
Timeout 1000 ms Increase if device is slow
Retries 2 Number of retry attempts
  1. Click Save

Step 2: Add Data Points

For each register you want to read:

  1. Click Add Point on the data source page
  2. Configure the point:
Slave ID:        1          (device address, usually 1)
Register Range:  Holding    (Holding, Input, Coil, or Discrete)
Offset:          0          (register address from device documentation)
Data Type:       2 Byte Unsigned  (depends on your register map)
INFO: Register addressing can be confusing. Some manufacturers use 1-based addressing (register 40001) while Mango uses 0-based offsets. If the documentation says register 40001, enter offset 0 in Mango.

Step 3: Common Data Types

Modbus Data Type When to Use
2 Byte Unsigned (UINT16) Positive integers 0-65535
2 Byte Signed (INT16) Integers -32768 to 32767
4 Byte Float (FLOAT32) Decimal values (temperature, voltage)
4 Byte Unsigned (UINT32) Large positive integers (energy totals)
Binary/Coil On/Off status values

Step 4: Configure Byte Order

Different devices use different byte ordering. If your values look wrong:

TIP: If you're reading a known value (like a firmware version) and it looks garbled, try changing the byte order. This is one of the most common Modbus configuration issues.

Step 5: Enable and Verify

  1. Enable the data source (toggle the switch)
  2. Check the data points are showing values
  3. Verify values match what you expect from the device

Troubleshooting

"Illegal Data Address" error

Connection timeout

Values are wrong or garbled

Configuring a BACnet IP Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 10 min read

Overview

BACnet IP is the standard protocol for building automation systems (HVAC, lighting, access control). This guide covers discovering BACnet devices on your network and reading their data points in Mango.

Prerequisites

Step 1: Create a BACnet Local Device

Before any BACnet data source will work, create a Local Device:

  1. Navigate to Administration → BACnet Local Devices (or open /ui/admin/bacnet-local-devices)
  2. Create a Local Device and configure network fields carefully — especially Local Bind Address (wrong bind address is a common failure) and BBMD if your network uses a BACnet Broadcast Management Device
  3. Save the Local Device

You will select this Local Device when creating the data source in the next step.

Step 2: Create the BACnet Data Source

  1. Navigate to Data Sources > + > BACnet I/P
  2. Select the BACnet Local Device you created above
  3. Configure the network settings:
Field Value Notes
Name Your data source name e.g., "Building A BACnet"
Update Period 60 seconds BACnet devices are often polled less frequently
Local Bind Address 0.0.0.0 Prefer configuring bind on the Local Device; use defaults unless multi-homed
Port 47808 Default BACnet/IP port (0xBAC0)
Broadcast Address 255.255.255.255 Or your subnet broadcast
  1. Click Save

Step 3: Discover Devices

  1. On the data source page, open the Discover Devices view (not "Device Browser")
  2. Mango will send a BACnet Who-Is broadcast
  3. Devices that respond will appear in the discovery list
  4. Each device shows its instance number, name, and address
WARNING: If no devices are discovered, check that your firewall allows UDP traffic on port 47808. BACnet uses UDP broadcasts, which many firewalls block by default.

Step 4: Discover Objects on a Device

  1. Select a discovered device
  2. Click Discover Objects
  3. Mango will query the device for all its BACnet objects:

Step 5: Add Data Points

For each object you want to monitor:

  1. Select the object from the discovery results
  2. Click Add as Data Point
  3. Configure which BACnet property to read (usually Present Value)
  4. Prefer Polling for most devices. Use COV (Change of Value) only when the device supports it correctly and the project requires it — many devices do not implement COV reliably.
TIP: When bulk-adding points, add one point type per batch (all numeric, then all multistate, then binaries, then alphanumeric). Mango bulk-create uses a single type for the batch; mixing types can create the wrong point types and force delete/recreate.

Step 6: Understanding BACnet Object Types

Object Type Abbreviation Typical Use
Analog Input AI Sensor readings (temp, pressure)
Analog Output AO Control outputs (valve %, fan speed)
Analog Value AV Setpoints, calculated values
Binary Input BI Status (on/off, open/closed)
Binary Output BO Commands (start/stop)
Multi-State Input MSI Status with multiple states
Schedule SCH Time-based schedules
Trend Log TL Historical data from device

Troubleshooting

No devices discovered

Timeout errors during object discovery

COV subscriptions not working

Setting Up SSL with Nginx as a Reverse Proxy

Category: Security · Version: Mango 4.x / 5.x · Difficulty: Advanced · 15 min read

Overview

Running Mango behind an Nginx reverse proxy with SSL provides HTTPS encryption, better security, and the ability to use standard ports (443). This guide uses Let's Encrypt for free, auto-renewing SSL certificates.

Prerequisites

Step 1: Install Nginx

sudo apt update
sudo apt install -y nginx

Verify it's running:

sudo systemctl status nginx

Step 2: Install Certbot (Let's Encrypt)

sudo apt install -y certbot python3-certbot-nginx

Step 3: Configure Nginx as a Reverse Proxy

Create a new Nginx configuration:

sudo nano /etc/nginx/sites-available/mango

Add the following configuration:

server {
    listen 80;
    server_name mango.yourdomain.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 90;
    }
}
INFO: The WebSocket headers (Upgrade and Connection) are essential for Mango's real-time data updates to work through the proxy.

Enable the configuration:

sudo ln -s /etc/nginx/sites-available/mango /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 4: Obtain SSL Certificate

sudo certbot --nginx -d mango.yourdomain.com

Certbot will:

  1. Verify you own the domain
  2. Obtain the certificate
  3. Automatically modify your Nginx config to use SSL
  4. Set up auto-renewal

When prompted, select Redirect HTTP to HTTPS for best security.

Step 5: Verify Auto-Renewal

sudo certbot renew --dry-run

Let's Encrypt certificates expire every 90 days, but Certbot sets up automatic renewal via a systemd timer.

Step 6: Configure Mango for Proxy

Tell Mango it's behind a proxy by editing mango.properties:

# Tell Mango to trust the proxy headers
web.forwardedHeaders.enabled=true

Restart Mango after making this change.

Verification

Troubleshooting

502 Bad Gateway

WebSocket errors / real-time data not updating

Certificate renewal fails

Resetting the Admin Password

Category: Troubleshooting · Version: Mango 4.x / 5.x · Difficulty: Beginner · 5 min read

Overview

Lost your Mango admin password? This guide covers two methods to reset it: the configuration file method (easiest) and the direct database method.

Method 1: Configuration File Reset (Recommended)

This is the simplest approach and works on all Mango 4 and 5 installations.

Step 1: Stop Mango

# Linux
sudo systemctl stop mango

# Windows
net stop mango

Step 2: Edit the Configuration

Open mango.properties in your Mango overrides directory:

Add this line:

admin.password.reset=true

Step 3: Restart Mango

# Linux
sudo systemctl start mango

# Windows
net start mango

Step 4: Log In

The admin password has been reset to the default: admin

Log in with:

DANGER: Immediately change the password after logging in. Go to User Profile or Administration > Users and set a strong password.

Step 5: Remove the Reset Flag

Edit mango.properties again and remove or comment out the reset line:

# admin.password.reset=true

Restart Mango one more time.

Method 2: Direct Database Reset (H2)

If Method 1 doesn't work, you can reset the password directly in the database.

WARNING: Only use this method if the configuration file method fails. Direct database modifications carry risk.

Step 1: Stop Mango

Step 2: Connect to the H2 Database

Mango 4/5 ships with an H2 console. You can also use the H2 command line:

java -cp /opt/mango/boot/h2-*.jar org.h2.tools.Shell \\
  -url jdbc:h2:/opt/mango/databases/mangodb \\
  -user sa -password (leave blank)

Step 3: Reset the Password

Run this SQL command to reset the admin password to "admin":

UPDATE users SET password = '{BCRYPT}$2a$10$ikRtUlDm7layHbGYcmjumeCSvWqhFJqGjMOvKW/NJVGm42sUkzKhm' WHERE username = 'admin';

Step 4: Start Mango and Change Password

Start Mango and immediately log in and change the password.

Prevention Tips

Calculating kWh from kW Power Readings

Category: Scripting · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 8 min read

Overview

Many power meters only report instantaneous power in kilowatts (kW). To track energy consumption over time, you need to convert this to kilowatt-hours (kWh). This guide shows how to do that calculation in Mango using a meta data point.

The Math

Energy (kWh) = Power (kW) x Time (hours)

Since Mango polls at regular intervals, we calculate the energy for each interval and accumulate it:

kWh per interval = kW reading x (interval in seconds / 3600)

Method: Meta Data Point with Script

Step 1: Create a Meta Data Source

  1. Go to Data Sources > + > Meta Data Source
  2. Name it (e.g., "Energy Calculations")
  3. Save it

Step 2: Create the kWh Data Point

  1. Add a new point to the meta data source
  2. Set the data type to Numeric
  3. Add your kW power point as a Context Variable (e.g., name it power)
  4. Set the Update Event to match your kW point's polling rate

Step 3: Write the Calculation Script

// Get the current power reading in kW
var currentPower = power.value;

// Get the time difference since last update (in milliseconds)
var timeDiff = power.time - power.ago(1).time;

// Convert milliseconds to hours
var hours = timeDiff / 3600000;

// Calculate energy for this interval
var energyIncrement = currentPower * hours;

// Get the previous accumulated value (or start at 0)
var previousTotal = my.ago(1) ? my.ago(1).value : 0;

// Return the accumulated total
return previousTotal + energyIncrement;
INFO: The my.ago(1) function gets the previous value of this meta point itself, allowing us to accumulate the running total.

Step 4: Configure Point Properties

Resetting the Counter

To reset the kWh counter (e.g., at the start of each month), you can modify the script:

var currentPower = power.value;
var timeDiff = power.time - power.ago(1).time;
var hours = timeDiff / 3600000;
var energyIncrement = currentPower * hours;
var previousTotal = my.ago(1) ? my.ago(1).value : 0;

// Reset at the start of each month
var now = new Date();
var lastUpdate = new Date(my.ago(1) ? my.ago(1).time : 0);
if (now.getMonth() !== lastUpdate.getMonth()) {
    return energyIncrement; // Start fresh
}

return previousTotal + energyIncrement;

Verification

Compare your calculated kWh values against:

TIP: Small discrepancies are normal due to polling intervals. For higher accuracy, use a shorter polling interval on the kW data point (e.g., every 5 seconds instead of 30).

Troubleshooting

Values seem too high or too low

Counter jumps unexpectedly

Changing Dashboard Bar Colors Based on Point Values

Category: Dashboards · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 8 min read

Overview

A common requirement for operational dashboards is making visual elements change color based on live values — green for normal, yellow for warning, red for alarm. This guide covers three approaches for implementing dynamic color changes in Mango dashboards, from no-code configuration to fully custom styling.

Prerequisites

Method 1: Using the Dashboard Designer (No Code)

This approach works entirely within the drag-and-drop designer. It is the recommended starting point for most users.

Step 1: Add a Bar Display Component

  1. Navigate to your dashboard in the Dashboard Designer
  2. Click the Add Widget button in the toolbar
  3. Under the Indicators section, select Bar Display or Gauge
  4. Drag the widget to your desired position on the page
  5. In the widget configuration panel on the right, click Select Point and choose your numeric data point

Step 2: Configure Color Ranges

  1. In the widget configuration panel, expand the Appearance or Style section
  2. Look for Color Ranges, Thresholds, or Conditional Colors (the label varies by widget type)
  3. Click Add Range to define each color band:
Range Color Hex Code Example Use
0 - 60 Green #22C55E Normal operation
60 - 80 Yellow #EAB308 Warning range — investigate
80 - 100 Red #EF4444 Alarm / critical — take action
  1. Click Save on the dashboard
TIP: Set your thresholds to match your event detector alarm levels so the visual colors align with actual alarm states.
WARNING: In Mango 4.x, some gauge and bar widgets use a different color range configuration under Properties > Ranges. If you do not see a Color Ranges option, check the Properties tab instead.

Method 2: Custom AngularJS Page (Mango 4.x)

For full control over the styling, create a custom dashboard page with AngularJS bindings. This lets you build custom bar visualizations with smooth transitions.

<div class="value-bar" ng-style="getBarStyle(myPoint.value)">
    <span class="value-text">{{myPoint.value | number:1}}%</span>
</div>

In your page controller script:

$scope.getBarStyle = function(value) {
    var color = '#22C55E'; // Green (default)

    if (value >= 80) {
        color = '#EF4444'; // Red
    } else if (value >= 60) {
        color = '#EAB308'; // Yellow
    }

    return {
        'background-color': color,
        'width': value + '%',
        'transition': 'all 0.5s ease'
    };
};

Add CSS for the bar container:

.value-bar {
    height: 30px;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 12px;
    min-width: 40px;
}

.value-text {
    color: white;
    font-weight: bold;
    font-size: 14px;
}
NOTE: This method uses AngularJS, which is the UI framework in Mango 4.x. If you are on Mango 5.x, the Dashboard Designer widgets (Method 1) are the recommended approach.

Method 3: Inline Conditional Styling with ma-point-value

For a quick color change on a text value without building a full custom bar, use an inline ng-style expression:

<ma-point-value point="myPoint"
    style="font-size: 24px; font-weight: bold;"
    ng-style="{
        'color': myPoint.value >= 80 ? '#EF4444' :
                 myPoint.value >= 60 ? '#EAB308' : '#22C55E'
    }">
</ma-point-value>

This changes the text color based on thresholds. You can apply the same pattern to background-color, border-color, or any other CSS property.

Verification

Troubleshooting

Colors not changing?

Confirm the data point is updating. Check the point value in a watch list to verify it is live. If using Method 2 or 3, ensure the point variable name matches exactly.

All bars stuck on one color?

Check your threshold boundaries. If a value sits exactly on a boundary (e.g., 60.0), confirm which range it falls into. Adjust conditions to use >= or > consistently.

Colors flash rapidly?

The data point may be oscillating around a threshold. Add a small dead band (e.g., go yellow at 60, return to green at 57) or increase the polling interval to reduce flicker.

Method 2/3 not rendering?

Verify you are on a custom AngularJS page, not a standard Dashboard Designer page. Custom pages require the User Module or a custom HTML page component.

Configuring Event Handlers and Email Alerts

Category: Events & Alarms · Version: Mango 4.x / 5.x · Difficulty: Beginner · 8 min read

Overview

Mango's event system monitors points for conditions such as high temperature or lost communication and can respond by sending email alerts. This guide covers the complete path from SMTP configuration through event detectors, email handlers, escalation, testing, and custom FreeMarker templates.

Prerequisites

Step 1: Configure the Email Sender

Go to Administration > System Settings > Email and enter the SMTP details.

Field Gmail Example Microsoft 365 Example
SMTP Host smtp.gmail.com smtp.office365.com
SMTP Port 587 587
From Address alerts@yourcompany.com alerts@yourcompany.com
Username your-email@gmail.com your-email@company.com
Password App Password Account password
TLS Enabled Enabled

Click Send Test Email to verify the configuration.

WARNING: Gmail requires an App Password rather than your regular password. Enable two-factor authentication, then create an App Password under Google Account > Security > App Passwords.

Step 2: Create an Event Detector

  1. Open the data point to monitor.
  2. Select Event Detectors.
  3. Click +.
  4. Choose a detector type and configure its condition.
Detector Type Use Case
High Limit Alert when a value exceeds a threshold
Low Limit Alert when a value drops below a threshold
State Change Alert when a Binary or Multistate point changes
No Update Alert when a point stops receiving data
No Change Alert when a value remains unchanged too long

For example, a high-temperature detector could use:

The duration prevents a brief spike from immediately raising an alarm.

TIP: For analog change, multistate state change, CUSUM, point change count, and other detectors, see Guide to Event Detector Types in Mango.

Step 3: Create an Email Event Handler

  1. Go to Event Handlers.
  2. Click +.
  3. Select Email Handler.
  4. Link the handler to the event detector.

Recipients

Add the addresses that should receive active-alarm notifications. You can also add escalation recipients who are notified if the event is not acknowledged within the configured delay.

Escalation adds recipients and notifications over time. It does not limit notification frequency.

Email Content

TIP: Including the last 5–10 values is useful for intermittent problems because recipients can see the trend leading up to an alarm without opening Mango.

Step 4: Test the Setup

  1. Set the point to a value that triggers the detector, if it is safe to do so.
  2. Otherwise, wait for a real event.
  3. Confirm the event appears on Events.
  4. Confirm the email reaches the intended recipients.

Customizing Email Content

Custom email templates use FreeMarker syntax. Variables use \${...}, directives use <#...>, and Mango macros use <@...>. Double-curly-brace syntax such as {{evt.message}} is not valid for these templates.

Custom Subject

Inside a custom template, <@subject> overrides the handler's normal Subject setting. It can accept message=, key=, or value=, or contain body content between opening and closing tags.

This example customizes both subject and body:

<@subject><@fmt message=evt.alarmLevel.description/> ALARM: <@fmt message=evt.message/></@subject>

<@fmt message=evt.message/>

Triggered: \${evt.activeTimestamp?number_to_datetime?string["yyyy/MM/dd HH:mm:ss"]}
<#if evt.rtnTimestamp??>
Returned to normal: \${evt.rtnTimestamp?number_to_datetime?string["yyyy/MM/dd HH:mm:ss"]}
</#if>

<#if renderedPointValues??>
Recent values:
<#list renderedPointValues as renderedPvt>
\${renderedPvt.value} @ \${renderedPvt.time}
</#list>
</#if>

This is an automated message from Mango.

For an urgent high-limit event, the rendered message might resemble:

Subject: Urgent ALARM: RTU-01 Temperature has exceeded 85.0°F for more than 30 seconds

RTU-01 Temperature has exceeded 85.0°F for more than 30 seconds

Triggered: 2026/08/21 14:32:07

Recent values:
81.4°F @ 2026/08/21 14:31:07
83.9°F @ 2026/08/21 14:31:22
86.2°F @ 2026/08/21 14:31:37
89.7°F @ 2026/08/21 14:31:52
92.3°F @ 2026/08/21 14:32:07

This is an automated message from Mango.

The return-to-normal line is absent while the event is active because evt.rtnTimestamp is null. The <#if evt.rtnTimestamp??> guard prevents the template from trying to format a missing timestamp.

Variable Description
evt.message Event message; render with <@fmt message=evt.message/> for localization
evt.activeTimestamp Epoch time when the event became active
evt.rtnTimestamp Epoch time when the event returned to normal; absent while active
evt.alarmLevel.description Translatable alarm-level description; render with <@fmt .../>
renderedPointValues Recent readings, available when Include last N point values is enabled
NOTE: If the handler content type is HTML & Text, Mango uses the same template for both parts. Include HTML markup in the template when HTML formatting is required.

Verification

Troubleshooting

Emails Are Not Sending

Too Many Emails

Detector Does Not Trigger

Template Fails to Render

Related Guides

Upgrading from Mango 3.x to Mango 4

Category: Installation · Version: Mango 4.x · Difficulty: Advanced · 15 min read

Overview

Upgrading from Mango 3 to Mango 4 is a major version upgrade that involves database schema changes, module updates, and configuration migration. This guide ensures a smooth transition with proper backup and rollback planning.

DANGER: Always perform this upgrade in a test environment first before upgrading production. Major version upgrades cannot be easily rolled back once the database has been migrated.

Prerequisites

Step 1: Complete Backup

Back Up Everything

# Stop Mango first
sudo systemctl stop mango

# Create a full backup
sudo tar -czf /backup/mango3-backup-$(date +%Y%m%d).tar.gz /opt/mango/

Back Up the Database Separately

For H2 databases:

cp -r /opt/mango/databases/ /backup/mango3-databases-backup/

For MySQL/MariaDB:

mysqldump -u mango -p mango_db > /backup/mango3-database-backup.sql
WARNING: Do not skip the backup step. Database migration is one-way - once the schema is upgraded, it cannot revert to Mango 3 format.

Step 2: Check Module Compatibility

Before upgrading, verify your modules are compatible with Mango 4:

  1. Go to Administration > Modules in Mango 3
  2. List all installed modules and their versions
  3. Check the Mango store for Mango 4-compatible versions

Common module changes in Mango 4:

Step 3: Install Java 11

sudo apt install -y openjdk-11-jdk

Verify:

java -version
# Should show: openjdk version "11.x.x"

Step 4: Download Mango 4

  1. Download the latest Mango 4.x release from the Mango store
  2. Extract it to a NEW directory (don't overwrite Mango 3):
sudo mkdir /opt/mango4
sudo unzip mango-4.x.x.zip -d /opt/mango4/

Step 5: Migrate Configuration

Copy your customized configuration from Mango 3 to Mango 4:

# Copy environment properties
cp /opt/mango/overrides/properties/mango.properties \\
   /opt/mango4/overrides/properties/mango.properties

# Copy any custom files
cp -r /opt/mango/overrides/ /opt/mango4/overrides/

Review mango.properties for any deprecated settings. Key changes in Mango 4:

Mango 3 Property Mango 4 Equivalent
db.url Same (but verify path)
web.port Same
ssl.* Updated format - check docs

Step 6: Point to Your Existing Database

In mango.properties, ensure the database URL points to your existing database:

db.type=h2
db.url=jdbc:h2:/opt/mango/databases/mangodb
INFO: When Mango 4 starts with a Mango 3 database, it will automatically run the migration scripts. This may take several minutes for large databases.

Step 7: Start Mango 4

cd /opt/mango4
sudo -u mango bin/start.sh

Watch the logs carefully:

tail -f /opt/mango4/logs/ma.log

Look for:

Step 8: Verify the Upgrade

Step 9: Update the Service File

If running as a systemd service, update the paths:

sudo nano /etc/systemd/system/mango.service
# Update WorkingDirectory and ExecStart to /opt/mango4/
sudo systemctl daemon-reload
sudo systemctl start mango

Rollback Plan

If something goes wrong:

  1. Stop Mango 4
  2. Restore the Mango 3 backup:
sudo systemctl stop mango
sudo rm -rf /opt/mango/databases
sudo tar -xzf /backup/mango3-backup-*.tar.gz -C /
sudo systemctl start mango
  1. Verify Mango 3 is running correctly
  2. Investigate the upgrade issues before trying again

Common Upgrade Issues

"Module not compatible" errors

Database migration fails

Dashboard pages missing or broken

Configuring User Roles and Permissions

Category: Configuration · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 8 min read

Overview

Mango uses a role-based permissions system to control who can see and do what. Properly configured permissions ensure operators only see their relevant equipment, while administrators retain full control.

Understanding Mango's Permission Model

Mango 4.x / 5.x Permission System

Mango 4 introduced a new permission model based on roles:

Built-in Roles

Role Description
superadmin Full access to everything
user Default role for standard users
anonymous Public access (use carefully)

Step 1: Create Custom Roles

  1. Go to Administration > Roles
  2. Click + to create a new role
  3. Give it a descriptive name:

Examples:

Step 2: Create User Accounts

  1. Go to Administration > Users
  2. Click + to create a new user
  3. Fill in user details and assign roles:
Username:  jsmith
Name:      John Smith
Email:     jsmith@company.com
Roles:     building-a-operator, read-only-viewer
TIP: Assign multiple roles to a user when they need access to different areas. Permissions are additive - the user gets the combined access of all their roles.

Step 3: Set Permissions on Data Points

For each data point (or data source), configure who can access it:

  1. Open the data point's settings
  2. Find the Permissions section
  3. Set:

Bulk Permission Assignment

For many data points, use the Bulk Data Point Editor:

  1. Go to Data Point Details > Bulk Edit
  2. Filter by data source or tags
  3. Apply permissions to all selected points at once

Step 4: Set Permissions on Views and Pages

For dashboard pages and views:

  1. Open the view/page settings
  2. Set Read Permission to control who can see it
  3. Set Edit Permission to control who can modify it

Step 5: Configure Watchlist Permissions

Watchlists can be shared with specific roles:

  1. Create or edit a watchlist
  2. Set the Read Permission to the appropriate role
  3. Users with that role will see the watchlist in their menu

Best Practices

  1. Principle of Least Privilege - Give users only the access they need
  2. Use Roles, Not Individual Permissions - Easier to manage at scale
  3. Create Role Hierarchies - Use naming conventions like site-a-read, site-a-write
  4. Test with a Non-Admin Account - Log in as a regular user to verify permissions work
  5. Document Your Permission Structure - Keep a spreadsheet mapping roles to resources

Common Patterns

Pattern: Site-Based Access

Roles: site-a-operator, site-b-operator, all-sites-admin
Data Points: Tag by site, assign read permission to site role

Pattern: Read vs. Write Separation

Roles: hvac-viewer, hvac-operator
Data Points: Read permission = hvac-viewer; Set permission = hvac-operator

The Three-Layer Permission Chain

When a user opens a dashboard backed by watch lists and data points, all three objects must grant access for widgets to display data:

  1. Dashboard permission — Can the user open the dashboard?
  2. Watch list permission — Can the user access the watch list feeding the widgets?
  3. Data point permission — Can the user read the individual data points?

Missing any single layer results in blank widgets or a permission error. This is the most common cause of "I can see the dashboard but the data is blank" support tickets. For a detailed guide on per-object permissions, multi-tenant patterns, and role inheritance, see the Object-Level Permissions article.

Troubleshooting

User can't see any data points

User can open dashboard but widgets are blank

"Does not hold required role" error

Bulk import fails with permission error

Getting Started with the Mango REST API

Category: Integration · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 10 min read

Overview

Mango provides a comprehensive REST API that lets you interact with the system programmatically. Use it to build custom integrations, automate tasks, pull data into external systems, or build custom UIs.

API Documentation

Mango includes built-in Swagger API documentation:

  1. Navigate to http://your-mango:8080/swagger-ui.html
  2. Browse all available endpoints, parameters, and response formats
  3. Try endpoints directly from the Swagger interface

Authentication

Method 1: Token-Based Authentication (Recommended)

Generate an authentication token:

curl -X POST http://localhost:8080/rest/latest/login \\
  -H "Content-Type: application/json" \\
  -d '{"username": "admin", "password": "admin"}'

Response includes a token:

{
  "token": "your-auth-token-here"
}

Use the token in subsequent requests:

curl http://localhost:8080/rest/latest/data-points \\
  -H "Authorization: Bearer your-auth-token-here"

Method 2: Basic Authentication

For simple scripts, use HTTP Basic Auth:

curl -u admin:admin http://localhost:8080/rest/latest/data-points
WARNING: Basic auth sends credentials with every request. Use token-based auth for production integrations and always use HTTPS.

Common API Endpoints

Read a Data Point's Current Value

# By XID
curl http://localhost:8080/rest/latest/point-values/latest/DP_TEMP_001 \\
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

{
  "xid": "DP_TEMP_001",
  "value": 72.5,
  "timestamp": 1707400000000,
  "annotation": null
}

Query Historical Data

# Get values for a time range
curl "http://localhost:8080/rest/latest/point-values/DP_TEMP_001?from=2024-01-01T00:00:00Z&to=2024-01-02T00:00:00Z&limit=1000" \\
  -H "Authorization: Bearer YOUR_TOKEN"

Set a Data Point Value

curl -X PUT http://localhost:8080/rest/latest/point-values/DP_SETPOINT_001 \\
  -H "Authorization: Bearer YOUR_TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{"dataType": "NUMERIC", "value": 75.0}'

List All Data Sources

curl http://localhost:8080/rest/latest/data-sources \\
  -H "Authorization: Bearer YOUR_TOKEN"

Get System Events

curl "http://localhost:8080/rest/latest/events?alarmLevel=URGENT&active=true" \\
  -H "Authorization: Bearer YOUR_TOKEN"

Example: Python Integration

import requests

MANGO_URL = "http://localhost:8080"
USERNAME = "admin"
PASSWORD = "admin"

# Authenticate
session = requests.Session()
response = session.post(f"{MANGO_URL}/rest/latest/login", json={
    "username": USERNAME,
    "password": PASSWORD
})
token = response.json().get("token")

# Set auth header
headers = {"Authorization": f"Bearer {token}"}

# Get current value of a data point
response = session.get(
    f"{MANGO_URL}/rest/latest/point-values/latest/DP_TEMP_001",
    headers=headers
)
print(f"Current temperature: {response.json()['value']}")

# Get historical data
response = session.get(
    f"{MANGO_URL}/rest/latest/point-values/DP_TEMP_001",
    headers=headers,
    params={
        "from": "2024-01-01T00:00:00Z",
        "to": "2024-01-02T00:00:00Z",
        "limit": 100
    }
)
for point in response.json():
    print(f"  {point['timestamp']}: {point['value']}")

Discovering RQL Queries

TIP: You can reverse-engineer the exact RQL query Mango uses for any filtered view. Open your browser dev tools (F12), go to the Network tab, then apply a filter on a watchlist or data point table in Mango. Inspect the XHR request URL to see the RQL query string Mango generated. Copy that query and use it directly in your own API calls.

Rate Limiting and Best Practices

NOTE: API permissions mirror your Mango user permissions. If your API user cannot see a data source in the UI, API calls for that data source will return 403 Forbidden. Create a dedicated API user with only the roles and permissions needed for your integration.

Troubleshooting

401 Unauthorized

403 Forbidden

404 Not Found

Deploying Mango 5 with Docker

Category: Installation · Version: Mango 5.x · Difficulty: Intermediate · 12 min read

Overview

Mango 5 is distributed as OCI-compliant container images hosted on the GitHub Container Registry (GHCR). Running Mango in Docker simplifies deployment, enables reproducible environments, and makes it straightforward to pair Mango with production-grade databases like PostgreSQL, MySQL, MariaDB, ClickHouse, or TimescaleDB.

Prerequisites

Step 1: Pull the Mango Image

Images are published for both amd64 and arm64 architectures (arm64 from v5.3.0+).

# For production, pin to a specific version
docker pull ghcr.io/radixiot/mango:5.5.4
WARNING: Always pin a specific version tag in production. Using latest can cause unintended upgrades when containers are recreated.

Step 2: Configure Port Mappings

Port Protocol Service Required
8443 TCP HTTPS web UI Yes
8080 TCP HTTP web UI Optional
9090 TCP gRPC API If using gRPC clients
47808 UDP BACnet/IP If polling BACnet devices
502 TCP Modbus TCP If polling Modbus devices
docker run -d -p 8443:8443 -p 9090:9090 -p 47808:47808/udp ghcr.io/radixiot/mango:5.5.4
INFO: BACnet uses UDP. Append /udp to the port mapping or the container will not receive BACnet traffic.

Step 3: Persist Data with Volumes

Without a volume, all configuration and data are lost when the container stops.

Named Volume (recommended):

docker volume create mango-data
docker run -d -v mango-data:/opt/mango-data -p 8443:8443 ghcr.io/radixiot/mango:5.5.4

Bind Mount:

mkdir -p /srv/mango-data && chown -R 1000:1000 /srv/mango-data
docker run -d -v /srv/mango-data:/opt/mango-data -p 8443:8443 ghcr.io/radixiot/mango:5.5.4
WARNING: The container runs as UID 1000 on v5.3.0 and v5.5.0+. Ensure bind mount directories have correct ownership.

Step 4: Configure via Environment Variables

Prefix Mango properties with mango_ and replace dots with underscores:

docker run -d \\\\
  -e mango_db_type=postgres \\\\
  -e mango_db_url=jdbc:postgresql://db-host/mango \\\\
  -e mango_db_username=mango \\\\
  -e mango_db_password=secretpassword \\\\
  -v mango-data:/opt/mango-data -p 8443:8443 ghcr.io/radixiot/mango:5.5.4

Or use an environment file: docker run --env-file mango.env ...

Step 5: Set Up Static GUID Licensing

Without a stable GUID, your license will not persist across container recreations. Format: 2- followed by a lowercase UUID v4.

export MA_GUID="2-$(uuidgen | tr '[:upper:]' '[:lower:]')"
docker run -d -e MA_GUID=$MA_GUID -v mango-data:/opt/mango-data -p 8443:8443 ghcr.io/radixiot/mango:5.5.4

Step 6: Deploy with Docker Compose (PostgreSQL)

services:
  mango:
    image: ghcr.io/radixiot/mango:5.5.4
    restart: unless-stopped
    ports:
      - "8443:8443"
    volumes:
      - mango-data:/opt/mango-data
    environment:
      MA_GUID: "2-a3f7b291-48d5-4c0e-9182-7de3440cf8a1"
      mango_db_type: postgres
      mango_db_url: jdbc:postgresql://postgres/mango
      mango_db_username: mango
      mango_db_password: mango_password
    depends_on:
      postgres:
        condition: service_healthy
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: mango
      POSTGRES_USER: mango
      POSTGRES_PASSWORD: mango_password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: "pg_isready -U mango"
      interval: 10s
      timeout: 30s
      start_period: 30s
volumes:
  mango-data:
  postgres-data:
TIP: For ClickHouse or TimescaleDB as a time-series layer, add the database service and set mango_db_nosql_enabled=false plus the appropriate mango_db_tsl_* variables.

Troubleshooting

Problem Cause Solution
Container exits immediately Volume permission mismatch Run chown -R 1000:1000 on the host directory
License not found after restart GUID changes between runs Set MA_GUID environment variable
Cannot connect to database Service not healthy yet Add depends_on with condition: service_healthy
BACnet devices not discovered Port mapped as TCP Use -p 47808:47808/udp
OOM kills Default JVM heap too small Pass -Xms1024M -Xmx2048M as container args

Configuring SNMP Data Sources with Network Discovery

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 8 min read

Overview

SNMP (Simple Network Management Protocol) enables Mango to monitor network infrastructure such as switches, routers, UPS systems, printers, and environmental sensors. Mango's SNMP Network Discovery tool automates device interrogation by performing an SNMP walk and letting you select which objects to poll.

Prerequisites

SNMP Version Comparison

Feature v1 v2c v3
Authentication Community string Community string Username + auth protocol
Encryption None None DES, AES-128/256
Bulk GET support No Yes Yes
64-bit counters No Yes Yes
WARNING: SNMP v1 and v2c transmit community strings in plain text. Use v3 for devices on untrusted networks.

Step 1: Access the SNMP Import Tool

Navigate to Administration > Admin Home > Utilities and locate the SNMP Import tool.

Step 2: Create an SNMP Data Source

Click + NEW DATA SOURCE and configure:

TIP: Start with a 60-second update period. Decrease it after confirming the device handles the load.

Step 3: Upload MIB Files (Optional)

MIB files translate numeric OIDs into readable names (e.g., 1.3.6.1.2.1.1.5.0 becomes sysName.0).

  1. Obtain the MIB file from your device vendor
  2. Upload it in the SNMP Import tool before starting the walk

Step 4: Execute the SNMP Walk

  1. Select your data source from the dropdown
  2. Click START SNMP WALK
  3. Review discovered OIDs with their names, values, and data types
WARNING: A full SNMP walk on a managed switch or complex device can return thousands of OIDs. Do not import everything -- select only the OIDs you actually need to monitor. Importing thousands of points creates unnecessary polling load on both Mango and the device.
TIP: Use the Host Testing tab to query individual OIDs and verify their values before committing to a full import. This is useful for confirming that a specific OID returns the data you expect without creating any Mango points.

Step 5: Create Mango Points

  1. Check the boxes next to OIDs you want to monitor
  2. Switch to the Preview tab to review point names
  3. Click CREATE MANGO POINTS

Points begin polling on the next update cycle. Use the Bulk Data Point Editor to batch-modify properties afterward.

Troubleshooting

Problem Cause Solution
Walk returns no results Community string mismatch Verify the string matches device config
Walk times out Firewall blocking UDP 161 Confirm port is open; test with snmpwalk
OIDs show numeric only No MIB loaded Upload vendor MIB before walking
Points show UNRELIABLE Device slow to respond Increase timeout and retry count
v3 auth failure Mismatched credentials Verify USM username, auth protocol, passphrase

Configuring LDAP and Active Directory Authentication

Category: Security · Version: Mango 4.x / 5.x · Difficulty: Advanced · 10 min read

Overview

Mango supports LDAP and Microsoft Active Directory as external authentication providers. This enables centralized access management, automatic user creation on first login, and three role synchronization modes.

Prerequisites

Step 1: Configure the LDAP Connection

ldap.authentication.url=ldap://dc01.example.com:389/dc=example,dc=com
ldap.authentication.managerDn=cn=mango-svc,ou=Service Accounts,dc=example,dc=com
ldap.authentication.managerPassword=YourServiceAccountPassword
ldap.authentication.order=0
WARNING: Use ldaps:// (port 636) in production. Plain LDAP transmits credentials in clear text.

For Active Directory, add:

ldap.authentication.isActiveDirectory=true
ldap.authentication.activeDirectory.domain=example.com
ldap.authentication.activeDirectory.rootDn=dc=example,dc=com

Step 2: Configure User Lookup

DN Pattern Matching (simple directory):

ldap.authentication.userDnPatterns=uid={0},ou=People

Search-Based Lookup (complex directory):

ldap.authentication.userSearchBase=ou=People
ldap.authentication.userSearchFilter=(uid={0})
INFO: For AD, use (sAMAccountName={0}) as the search filter.

Step 3: Map User Attributes

ldap.authentication.nameAttribute=cn
ldap.authentication.emailAttribute=mail
ldap.authentication.passwordAttribute=userPassword
ldap.authentication.groupRoleAttribute=cn

Step 4: Configure Group-to-Role Mapping

ldap.authentication.groupSearchBase=ou=Groups
ldap.authentication.groupSearchFilter=(uniqueMember={0})

Step 5: Choose a Role Synchronization Mode

Mode Behavior Best For
LDAP_ONLY Roles replaced from LDAP at every login Fully centralized management
MANGO_ONLY LDAP roles ignored; assign manually in Mango Mango-specific roles
LDAP_ADDITIVE LDAP roles added to existing Mango roles Hybrid environments
ldap.authorization.roleSyncMode=LDAP_ADDITIVE
DANGER: With LDAP_ONLY, users lose all manually assigned Mango roles on every login.

Step 6: Enable Automatic User and Role Creation

ldap.authorization.createNewRoles=true
ldap.authorization.newRoleRegex=^mango-.*
TIP: The regex filter prevents cluttering Mango with irrelevant directory groups. Use a naming convention like mango-operators.

Complete AD Example

ldap.authentication.url=ldaps://dc01.example.com:636/dc=example,dc=com
ldap.authentication.managerDn=cn=mango-svc,ou=Service Accounts,dc=example,dc=com
ldap.authentication.managerPassword=S3cur3P@ssw0rd
ldap.authentication.order=0
ldap.authentication.isActiveDirectory=true
ldap.authentication.activeDirectory.domain=example.com
ldap.authentication.userSearchBase=ou=Corporate Users
ldap.authentication.userSearchFilter=(sAMAccountName={0})
ldap.authentication.nameAttribute=displayName
ldap.authentication.emailAttribute=mail
ldap.authentication.groupSearchBase=ou=Groups
ldap.authentication.groupSearchFilter=(member={0})
ldap.authorization.roleSyncMode=LDAP_ADDITIVE
ldap.authorization.createNewRoles=true
ldap.authorization.newRoleRegex=^mango-.*

Restart Mango after saving. Users can then log in with directory credentials.

Troubleshooting

Problem Cause Solution
"Bad credentials" Wrong bind DN or search filter Test with ldapsearch from the host
User has no roles Group search filter mismatch Verify groupSearchFilter resolves user DN
Connection refused on 636 TLS cert not trusted Import CA cert into Java truststore
Users lose roles after login LDAP_ONLY mode Switch to LDAP_ADDITIVE
Slow logins Search base too broad Narrow userSearchBase to specific OU

Configuring the MQTT Sparkplug Data Source

Category: Data Sources · Version: Mango 5.x · Difficulty: Intermediate · 12 min read

Overview

MQTT Sparkplug B is an IIoT interoperability specification built on MQTT that provides automatic device discovery through birth/death certificate messages. The Mango MQTT Sparkplug data source connects to a Sparkplug-compliant broker and automatically generates data points when edge devices publish BIRTH messages.

Prerequisites

Step 1: Create the Data Source

Navigate to Data Sources, click Add, and select MQTT Sparkplug.

Step 2: Configure the Broker Connection

Protocol URL Format Default Port
Plain TCP tcp://broker-hostname:1883 1883
SSL/TLS ssl://broker-hostname:8883 8883
WARNING: Each Mango instance must use a unique Client ID. Duplicate IDs cause connection flapping.

Connection Tuning

Parameter Default Description
Keep Alive Interval 60 s Heartbeat for broker availability
Connection Timeout 30 s Max wait for TCP connection
Auto Reconnect Enabled Exponential backoff (1 s to 2 min)

Step 3: Set the SCADA Host ID

Enter a unique identifier (e.g., mango-primary). Edge nodes can be configured to only publish when the primary host is connected.

Step 4: Configure SSL (Optional)

For ssl:// connections, paste the X.509 CA Certificate in PEM format into the certificate field.

Step 5: Add Edge Nodes

  1. Click Add in the Edge Nodes section
  2. Enter the Group ID (e.g., PlantA) and Edge Node ID (e.g., PLC-Line1)
  3. Mango publishes a rebirth request; the edge node responds with a BIRTH message
  4. Data points are automatically created from the BIRTH payload

Topic Filters and QoS

Step 6: Manage Auto-Generated Points

After BIRTH messages arrive, configure each point's logging mode, permissions, and device name. Use Copy Rebirth Permissions to propagate node permissions to child points.

TIP: Use bulk edit to quickly configure logging across dozens of auto-discovered points.

Troubleshooting

Symptom Likely Cause Resolution
Data source "Disconnected" Wrong broker URL or firewall Verify URL; test with mosquitto_sub
Connect/disconnect cycling Duplicate Client ID Ensure globally unique Client ID
No data points appear Edge node offline or ID mismatch Verify BIRTH messages; check IDs (case-sensitive)
SSL handshake failure Wrong CA certificate Confirm cert matches broker's chain
Stale values QoS mismatch Set QoS to 1

Creating Excel Reports with Scheduled Email Delivery

Category: Reporting & Analytics · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 14 min read

Overview

The Excel Reports module creates automated, template-driven reports that pull historical point values into an Excel workbook and deliver them by email on a schedule. Define named ranges in a template, map them to data points and time periods, and Mango fills in the numbers — including statistics like averages, sums, and min/max values.

Prerequisites

Step 1: Create the Excel Template

Creating Named Ranges

  1. Add header labels in the top row (e.g., Timestamp, BoilerTemp, FlowRate)
  2. Select the header row and data cells below
  3. Go to Formulas > Create from Selection, check Top row
TIP: Use simple names without spaces: boiler_temp_daily, chiller_kw_monthly.

Layout Tips

Step 2: Create the Report in Mango

  1. Navigate to Analytics > Excel Reports
  2. Click Add, enter a name, and upload your .xlsx template

Step 3: Configure Time Periods

Range Type Behavior Example
Past Now minus interval to now Past 24 hours
Previous Complete prior period Previous month
Current Period start to now Current week so far
Ago A specific past period 2 months ago

Configure a Rollup to aggregate raw samples into fixed intervals (e.g., 15-minute averages).

WARNING: Without a rollup, a point logging every second produces 86,400 rows per day. Always use rollups for high-frequency data.

Step 4: Map Data Points to Named Ranges

  1. Click Add Point under the time period
  2. Select a data point and enter the matching Named Range from your template
  3. Optionally set a Timestamp Named Range for the time column

Automatic Statistical Ranges

When you map boiler_temp, Mango auto-generates:

Range Value
boiler_temp.average Mean
boiler_temp.sum Sum
boiler_temp.minimum Lowest value
boiler_temp.maximum Highest value
boiler_temp.count Sample count

Step 5: Schedule the Report

Use the Cron Builder or enter a custom expression:

# Weekdays at 6 AM
0 0 6 ? * MON-FRI

# First of every month at midnight
0 0 0 1 * ?
INFO: Scheduled reports for disabled user accounts will not run.

Step 6: Configure Email Delivery

Add recipients (users, mailing lists, or addresses), choose an email template, and optionally enable compression. Click Run Now to test.

Troubleshooting

Symptom Likely Cause Resolution
Named range not populated Name mismatch Verify exact spelling in Excel Name Manager
Empty data columns No history for time period Check point logging type and date range
Scheduled report never runs Owner account disabled Re-enable the user account
Email not received SMTP not configured Test under System Settings > Email
Very large file No rollup on high-freq points Add a rollup to reduce rows

Troubleshooting Mango Startup Issues After Upgrade

Category: Troubleshooting · Version: Mango 4.x / 5.x · Difficulty: Advanced · 16 min read

Overview

After upgrading Mango, the most common failure is the application stalling at around 40% on the loading screen. This usually indicates a database migration problem, a corrupted NoSQL (MapDB) database, or a resource constraint. This guide covers systematic diagnosis using logs, SAFE mode, and Java tools.

DANGER: Never force-kill or power-cycle while Mango is running. Hard shutdowns can corrupt MapDB.

Prerequisites

Step 1: Check the Logs

tail -f /opt/mango/logs/ma.log

Look for: stack traces, database upgrade messages, NoSQL repair messages, or "Too many open files" errors.

Step 2: Why Startup Stalls at 40%

Two main causes:

  1. Module/database version mismatch — installing fresh Mango then copying an old database
  2. MapDB corruption from a hard shutdown — Mango auto-repairs but it takes time

Correct Upgrade Procedure

  1. Extract new Mango to a fresh directory — do not start it
  2. Copy your database from the old installation
  3. Start Mango — modules and schema upgrade together
WARNING: Starting new Mango first then copying an old database causes the module table to be out of sync.

Step 3: Start in SAFE Mode

SAFE mode disables all data sources, letting Mango start without connecting to external devices.

Linux:

touch /opt/mango/data/core/SAFE

Windows:

type nul > "C:\\\\mango\\\\data\\\\core\\\\SAFE"

Restart Mango. If it starts, re-enable data sources one at a time to find the culprit.

WARNING: Export data source configurations before SAFE mode — it disables them at the database level.

Step 4: Thread Dump with jstack

PID=$(systemctl show --property MainPID --value mango)
jstack -l $PID > /tmp/mango_threads.txt

Look for BLOCKED or WAITING threads. Capture multiple dumps 10-15 seconds apart to identify stuck threads.

Step 5: Memory Analysis with jmap

# Memory histogram
jmap -histo $PID > /tmp/mango_mem.txt

# Full heap dump for Eclipse MAT
jmap -dump:format=b,file=/tmp/mango_heap.hprof $PID

Step 6: Flight Recording with jcmd

jcmd $PID JFR.start duration=60s filename=/tmp/mango.jfr

Open in JDK Mission Control to analyze CPU, memory, and I/O during startup.

Step 7: Check System Resource Limits

Open File Descriptors

ls /proc/$PID/fd | wc -l

Set db.nosql.maxOpenFiles to ~2x your data point count. Increase OS limits in /etc/security/limits.conf:

mango    soft    nofile    65536
mango    hard    nofile    65536

Disk Space

df -h /opt/mango
DANGER: A SIGBUS crash in hs_err_pid*.log almost always means the disk is full.

Quick Reference

Symptom Cause Solution
Stuck at 40%, upgrade SQL in log Module/DB mismatch Copy DB before first start
Stuck at 40%, MapDB repair NoSQL corruption Wait 30+ minutes
Starts in SAFE but not normally Bad data source Re-enable one at a time
OutOfMemoryError Heap too small Increase -Xmx
"Too many open files" Low fd limit Increase nofile and maxOpenFiles
SIGBUS in hs_err Disk full Free space immediately

Configuring the Meta Data Source for Derived Data Points

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 12 min read

Overview

The Meta data source creates derived data points whose values are computed from one or more existing points using JavaScript. Scripts run on the Mozilla Rhino engine embedded in Mango's JVM and can perform unit conversions, combine multiple inputs, apply conditional logic, or generate entirely new time-series from raw measurements.

Prerequisites

Step 1: Create the Meta Data Source

  1. Navigate to Data Sources > + > Meta Data Source
  2. Enter a descriptive name (e.g., "Building A Calculations")
  3. Click Save
INFO: A single Meta data source can hold many derived points. Group related calculations together for easier management.

Step 2: Add a Meta Data Point

  1. Click Add Point on the Meta data source page
  2. Set the Data Type for the result (Numeric, Binary, Multistate, or Alphanumeric)
  3. Choose the Update Event that triggers the script:
Update Event Behavior
Context update Runs when any context point receives a new value
Cron pattern Runs on a schedule (e.g., every 5 minutes)
Point update (specific) Runs when a single designated context point updates
  1. Optionally set an Execution Delay (milliseconds) to allow multiple context points to settle before the script fires

Step 3: Configure Context Variables

Context variables map existing data points into the script's namespace.

  1. Click Add Context in the point editor
  2. Select a data point from the picker
  3. Assign a Variable Name (e.g., supplyTemp, returnTemp)

Use these variable names inside the script to access point values:

// Each context variable is a ScriptPointValueSetter object
var supply = supplyTemp.value;     // Current value
var ts     = supplyTemp.time;      // Timestamp (epoch ms)
var prev   = supplyTemp.ago(1);    // Previous value object
var older  = supplyTemp.ago(2);    // Two values back
TIP: Use p.ago(1).value to get the previous sample and p.ago(1).time for its timestamp. The ago() function walks backwards through the point's logged history.
WARNING: Meta points fail silently if any context point is disabled. The script simply will not execute and no error appears in the UI. If a meta point stops updating, check that all of its context points are enabled and actively receiving values.
INFO: Context variables can reference points from any data source in your system, not just points within the same data source. Use device ID tags or a consistent naming convention to pull points across Modbus, BACnet, SNMP, or other data sources into a single meta point calculation.

Step 4: Write the Script

The script must return a value matching the point's data type. Common patterns:

Unit Conversion (Fahrenheit to Celsius)

return (supplyTemp.value - 32) * 5 / 9;

Combining Multiple Points (Delta T)

var delta = supplyTemp.value - returnTemp.value;
return Math.abs(delta);

Conditional Logic (Operating Mode)

// Returns a multistate value: 0=Off, 1=Heating, 2=Cooling
if (!fanStatus.value) return 0;
if (supplyTemp.value > returnTemp.value) return 1;
return 2;

Weighted Average

var totalFlow = flow1.value + flow2.value;
if (totalFlow === 0) return 0;
return (temp1.value * flow1.value + temp2.value * flow2.value) / totalFlow;

Step 5: Setting Custom Timestamps

By default the result timestamp is the current time. Override it by setting the TIMESTAMP variable:

// Use the source point's timestamp instead of "now"
TIMESTAMP = supplyTemp.time;
return (supplyTemp.value - 32) * 5 / 9;
WARNING: The TIMESTAMP variable must be set to an epoch-millisecond value. Setting it to an invalid number produces unpredictable logging behavior.

Step 6: Data Type Conversion

Return the correct JavaScript type for the configured data type:

Point Data Type Script Return Example
Numeric Number return 72.5;
Binary Boolean return temp.value > 80;
Multistate Integer return 2;
Alphanumeric String return "Zone A: " + temp.value;

Step 7: Using Generate History (Backfill)

The Generate History feature reruns the script across a historical time range, useful when you add a new derived point and need to populate past values.

  1. Save and enable the meta point
  2. Click the Generate History button on the point's detail page
  3. Set the From and To date range
  4. Click Generate

Mango replays each context point's historical values through the script and logs the results.

WARNING: Generate History can be resource-intensive for large date ranges. Run it during off-peak hours and limit ranges to what you actually need.

Script Logging and Debugging

Use LOG.info(), LOG.warn(), or LOG.error() to write messages to ma.log:

LOG.info("Supply: " + supplyTemp.value + " Return: " + returnTemp.value);
var delta = supplyTemp.value - returnTemp.value;
if (delta < 0) {
    LOG.warn("Negative delta T detected: " + delta);
}
return delta;

Check output in /opt/mango/logs/ma.log or the Mango Internal Logs page.

Troubleshooting

Script error: "variable is not defined"

Point shows no value after enabling

Generate History produces no results

Performance issues with many meta points

Backing Up Your Mango System

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Beginner · 10 min read

Overview

Mango stores information in three places that require separate backup strategies: the SQL database, MangoNoSQL historical point values, and portable JSON configuration exports. A complete disaster-recovery plan covers all three.

Backup Type Contains Location or Format
SQL database Users, data sources, data points, event detectors, permissions, and other configuration Under {data directory}/databases/; scheduled backup is a ZIP
MangoNoSQL Historical point values and annotations stored by ias-tsdb Native MangoNoSQL backup files
JSON configuration Portable data sources, points, handlers, users, roles, and related configuration JSON file
WARNING: Do not copy live database files. Database locks and in-memory state can make the copy inconsistent or corrupt. Stop Mango before manual file copying, or use the built-in backup functions while Mango is running.

Prerequisites

Step 1: Configure Scheduled Backups

Under Administration > System Settings, configuration and SQL backups have separate tabs and schedules:

SQL Database Backup Defaults

Setting Default Notes
Backup Enabled Yes Runs scheduled backups
Backup Hour / Minute 0 / 5 (00:05) Uses server time
Backup File Count 10 Number of SQL backup files retained
Backup Location {data directory}/backup Relative to the configured data directory

JSON Configuration Backup Defaults

Setting Default Notes
Backup Enabled Yes Runs scheduled JSON exports
Backup Hour / Minute 0 / 5 (00:05) Uses server time
Backup File Count 10 Number of JSON files retained

MangoNoSQL Backup Defaults

MangoNoSQL is the standard historical point-value store, backed by ias-tsdb. It has separate backup settings.

Setting Default Notes
Backup Enabled true Uses the module's scheduler
Backup File Count 365 Approximately one year of daily backups
NOTE: MangoNoSQL backups can be much larger than SQL or JSON backups because they contain historical point values. Adjust retention to available storage.
NOTE: Scheduled backups use the server's clock, not the browser's local timezone. Plan the 00:05 schedule around server time and operational load.
NOTE: Verify the latest backup before upgrades, maintenance, or major configuration changes. An untested backup should not be treated as recoverable.

Step 2: Run Manual Backups

Each mechanism has its own trigger:

These produce separate files rather than one combined archive:

Step 3: Export JSON Configuration

  1. Go to Data Integration > Configuration Import/Export.
  2. Select all configuration or specific object types.
  3. Click Export.
  4. Store the resulting .json file securely.

JSON exports can include data sources, data points, event detectors, event handlers, users, roles, and JSON Data stores.

NOTE: JSON exports contain configuration, not historical point values. Back up MangoNoSQL and the SQL database as well.

Step 4: Verify Backup Files

Check the directory and test SQL ZIP integrity:

# Adjust the path for your configured data directory
ls -lh /opt/mango/data/backup/

# Test SQL backup archives
unzip -t /opt/mango/data/backup/core-database-*.zip

Periodically perform a full restore on a non-production instance.

Restoring from Backup

Prefer Mango's built-in restore controls. They run against the live service and avoid manual file replacement.

Restore the SQL Database

  1. Go to Administration > System Settings > H2/SQL Database Backup Settings.
  2. Use Restore Database to choose the backup.
  3. Run the restore.

The built-in restore operates in place over the live connection; stopping Mango is not required.

NOTE: As a fallback, stop Mango before manually replacing files under {data directory}/databases/. The default H2 database file is mah2.mv.db, but filenames vary by database type. Restore Database is the supported path.

Restore JSON Configuration

  1. Go to Data Integration > Configuration Import/Export.
  2. Paste or upload the JSON.
  3. Click Import.
  4. Review errors and skipped items.
WARNING: Import matches objects by XID. Matching XIDs update existing objects; new XIDs create objects. Importing into an existing system can overwrite configuration.

Restore MangoNoSQL Time-Series Data

Use the built-in restore control on the MangoNoSQL settings page. Select the native backup and run the restore. This is the supported alternative to manually copying ias-tsdb files.

Remote Backup Best Practices

Example nightly off-site copy:

0 3 * * * rsync -avz /opt/mango/data/backup/ backupuser@remote-server:/backups/mango/

Verification

Troubleshooting

Backup Is Missing or Zero Bytes

Restore Control Fails or Is Missing

JSON Import Skips Objects

MangoNoSQL Uses Too Much Storage

Related Guides

Understanding Rollups and Statistics for Time Series Data

Category: Data Management · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 11 min read

Overview

When you query historical data in Mango, you rarely want every raw sample. A data point logging every 5 seconds produces 17,280 values per day. Rollups aggregate those raw samples into meaningful summaries -- averages, totals, minimums, maximums -- over fixed time periods. They are used throughout Mango in charts, watchlist tables, Excel reports, and REST API responses.

What Is a Rollup?

A rollup divides a time range into equal intervals (called rollup periods) and applies an aggregation function to each interval. For example, requesting a 1-hour AVERAGE rollup over 24 hours returns 24 values -- one average per hour.

Raw samples:  |...........|...........|...........|
              0h          1h          2h          3h
Rollup:       [  avg=72.3 ]  [  avg=73.1 ]  [  avg=71.8 ]

Numeric Rollups

These rollups apply to Numeric (analog) data points:

Rollup Description Common Use
AVERAGE Arithmetic mean of all samples in the period Temperature trending, general monitoring
MINIMUM Lowest value in the period Finding dips, low-water marks
MAXIMUM Highest value in the period Peak detection, capacity planning
SUM Sum of all sample values Batch counting, pulse accumulation
COUNT Number of samples in the period Data quality verification
FIRST First value in the period Start-of-period snapshot
LAST Last value in the period End-of-period snapshot
DELTA Difference between last and first value Consumption from accumulating meters
INTEGRAL Time-weighted integral (area under the curve) Energy (kWh from kW), flow totals
START Value at the exact start of the period Opening value
ACCUMULATOR Running total assuming increasing counter Meter totals, odometer-style readings
ALL Returns all raw samples (no aggregation) Data export, debugging
NONE Single value for entire range Latest value queries
TIP: DELTA is ideal for utility meters that report cumulative readings. If a meter reads 10,500 kWh at the start of the day and 10,620 kWh at the end, the DELTA rollup returns 120 kWh consumed.
INFO: INTEGRAL performs time-weighted integration using the trapezoidal method. For a point in kW, the integral rollup returns kWh. The unit is automatically the source unit multiplied by hours.

Non-Numeric Rollups

For Binary, Multistate, and Alphanumeric data points, only a subset of rollups are available:

Rollup Applies To Description
FIRST All types First value in the period
LAST All types Last value in the period
COUNT All types Number of samples
ALL All types All raw samples
START All types Value at period start

Statistics by Data Type

When you request detailed statistics (not a single rollup), Mango returns a statistics object that varies by data type:

Analog Statistics (Numeric Points)

Statistic Description
average Time-weighted average
minimum Minimum value and its timestamp
maximum Maximum value and its timestamp
sum Sum of all values
count Number of samples
integral Time-weighted integral
delta Last value minus first value
first First sample (value + time)
last Last sample (value + time)
start Value at period start (value + time)

Runtime List (Binary / Multistate Points)

Statistic Description
runtime Duration spent in each state (ms)
proportion Percentage of time in each state (0.0 - 1.0)
count Number of transitions
first First state in the period
last Last state in the period

For a binary point tracking a pump, the runtime list shows how many milliseconds the pump was ON vs OFF, and the proportion (e.g., 0.75 = 75% runtime).

Value Change Counts (Alphanumeric Points)

Statistic Description
count Total number of values logged
changeCount Number of times the value changed
first First value
last Last value

Using Rollups in Charts

When configuring charts in the Dashboard Designer or custom pages:

  1. Select the data point(s) to display
  2. Set the Time Range (e.g., past 24 hours)
  3. Choose a Rollup (e.g., AVERAGE)
  4. Set the Rollup Period (e.g., 15 minutes)

Choosing the Right Rollup Period

Time Range Suggested Rollup Period Resulting Points
Past 1 hour 1 minute 60
Past 24 hours 15 minutes 96
Past 7 days 1 hour 168
Past 30 days 6 hours 120
Past 1 year 1 day 365
TIP: Aim for 50-500 data points per chart series. Too many points slow down rendering; too few lose important detail.
WARNING: Reports and charts that query raw data without rollups will show gaps wherever samples are missing or irregular. Always apply a rollup to ensure consistent time intervals in your output, even if the underlying data has gaps or jitter.

Using Rollups in the REST API

Query rolled-up values using the point-values endpoint:

# Get hourly averages for the past 24 hours
curl "http://localhost:8080/rest/latest/point-values/DP_TEMP_001?from=2024-01-01T00:00:00Z&to=2024-01-02T00:00:00Z&rollup=AVERAGE&timePeriod=HOURS&timePeriods=1" \\
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

[
  { "timestamp": 1704067200000, "value": 72.3 },
  { "timestamp": 1704070800000, "value": 73.1 },
  { "timestamp": 1704074400000, "value": 71.8 }
]

API Parameters for Rollups

Parameter Values Description
rollup AVERAGE, DELTA, MINIMUM, MAXIMUM, SUM, COUNT, INTEGRAL, FIRST, LAST, ALL, NONE Aggregation function
timePeriod SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS Rollup period unit
timePeriods Integer Number of time period units per rollup

Practical Examples

Example 1: Daily Energy Consumption

For a kW power meter, use the INTEGRAL rollup with a 1-day period to get daily kWh values without writing any scripts.

Example 2: Peak Demand Detection

Use the MAXIMUM rollup with a 15-minute period to find the highest demand interval, which is how most utilities calculate demand charges.

Example 3: Equipment Runtime Report

For a binary pump-status point, query the statistics endpoint to get the runtime proportion. A proportion of 0.82 means the pump ran 82% of the queried period.

Example 4: Data Quality Check

Use the COUNT rollup to verify how many samples were logged per hour. If your point polls every 10 seconds, you expect 360 samples per hour. Significantly fewer indicates data gaps.

Troubleshooting

Rollup returns null or no data

INTEGRAL values seem wrong

DELTA returns negative values

Chart shows flat lines instead of curves

Understanding Mango 5 Architecture: Pi-Portfolio, Pi-Link, Pi-Mesh, and Pi-Flow

Category: Getting Started · Version: Mango 5.x · Difficulty: Beginner · 10 min read

Overview

Mango 5 represents a ground-up rethinking of the Mango platform, organized around four purpose-built components: Pi-Portfolio for multi-site management, Pi-Link for secure edge-to-cloud communication, Pi-Mesh for high-performance time-series storage, and Pi-Flow for streamlined device commissioning. Together they form a vertically integrated stack designed for managing large-scale building and industrial IoT deployments.

This article is a conceptual architecture overview. For installation steps, see the Mango 5 installation and Docker deployment guides.

The Four Core Components

Pi-Portfolio \u2014 Multi-Site Portfolio Manager

Pi-Portfolio is the cloud-hosted management layer that provides a unified operational view across every connected site without requiring custom dashboard development.

Key capabilities:

TIP: Pi-Portfolio eliminates the "dashboard development bottleneck" that plagued earlier Mango deployments. Instead of building bespoke pages for each customer or site, the portfolio manager renders standardized views from your equipment model automatically.

Pi-Link \u2014 Edge-to-Cloud Communication

Pi-Link is the secure transport layer between edge Mango instances and the cloud Pi-Portfolio. It replaces legacy VPN tunnels and REST API polling with a modern, purpose-built communication channel.

Key capabilities:

How mTLS works in Pi-Link:

Edge Mango                          Cloud (Pi-Portfolio)
    |                                       |
    |--- Client Certificate (X.509) ------->|
    |<-- Server Certificate (X.509) --------|
    |                                       |
    |=== Mutually Authenticated TLS Tunnel ==|
    |--- gRPC data stream ----------------->|
    |<-- gRPC commands ---------------------|
INFO: Unlike traditional VPN tunnels that require network-level configuration and static IP addresses, Pi-Link operates at the application layer. Edge devices only need outbound HTTPS access \u2014 no inbound firewall ports, no static IPs, no VPN appliances.

Pi-Mesh \u2014 Specialized Time-Series Database

Pi-Mesh is a purpose-built time-series database engine that replaces the legacy NoSQL/MapDB storage layer used in Mango 4.

Key capabilities:

Performance context:

Operation Legacy NoSQL (Mango 4) Pi-Mesh (Mango 5)
1-year daily rollup (single point) Seconds Milliseconds
Multi-point trend chart (24 hours) Seconds Milliseconds
Portfolio-wide energy summary Minutes Seconds
TIP: Pi-Mesh performance improvements are most dramatic on large deployments with thousands of points and years of retained history. Single-site systems will still benefit, but the difference scales with data volume.

Pi-Flow \u2014 Redesigned Commissioning UI

Pi-Flow replaces the legacy Mango configuration interface with a streamlined commissioning workflow optimized for speed and repeatability.

Key capabilities:

Additional Mango 5 Capabilities

Native MQTT Publisher

Mango 5 includes a built-in MQTT publisher that pushes point values to any standard MQTT broker without requiring additional modules or custom scripting. Configure topic patterns, QoS levels, and payload format directly in the point settings.

CSV Bulk Import/Export

Beyond Pi-Flow's commissioning use, CSV import/export enables:

How the Components Work Together

 [Edge Site 1]         [Edge Site 2]         [Edge Site N]
  Mango + Pi-Flow       Mango + Pi-Flow       Mango + Pi-Flow
  (commissioning)       (commissioning)       (commissioning)
       |                     |                     |
       |--- Pi-Link -------->|--- Pi-Link -------->|
       |    (gRPC / mTLS)    |    (gRPC / mTLS)    |
       v                     v                     v
  +---------------------------------------------------------+
  |                    Cloud Platform                        |
  |  Pi-Portfolio (multi-site views, drag-and-drop mgmt)    |
  |  Pi-Mesh (centralized time-series storage and queries)  |
  +---------------------------------------------------------+
  1. Pi-Flow is used at each edge site to commission devices \u2014 adding data sources, mapping points via CSV import, and validating connectivity
  2. Pi-Link securely transports data from edge instances to the cloud, buffering locally during outages and resyncing automatically
  3. Pi-Mesh stores and indexes time-series data from all sites, serving fast queries for dashboards and reports
  4. Pi-Portfolio provides operators and managers a unified, zero-custom-code view across the entire portfolio

Mango 4 vs. Mango 5 at a Glance

Capability Mango 4 Mango 5
Multi-site management Custom dashboards per site Pi-Portfolio (built-in, drag-and-drop)
Edge-to-cloud transport REST API polling / VPN tunnels Pi-Link (gRPC + mTLS)
Time-series database MapDB / NoSQL Pi-Mesh (up to 100x faster)
Commissioning workflow Web UI forms, one point at a time Pi-Flow + CSV bulk import/export
Offline behavior Manual data recovery Automatic resync via Pi-Link
MQTT publishing Custom scripting or add-on module Native publisher built-in

When to Choose Mango 5

Mango 5 is the right fit when:

INFO: Mango 4 remains supported for single-site deployments that do not require edge-to-cloud communication or portfolio management capabilities.

How to Manage Disk Space and Purge Historical Data

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 10 min read

Overview

A Mango system left unmanaged will eventually consume all available disk space. Four categories account for the vast majority of storage growth: NoSQL time-series data, backup archives, event messages, and log files. This guide explains how to monitor each consumer, configure automated purge settings, and perform manual cleanup when needed.

TIP: Related guides: To proactively plan your data retention strategy before disk problems occur, see the Data Retention and Purge Policies guide. To optimize how much data is logged in the first place, see Configure Point Logging.

The Four Disk Consumers

Consumer Default Location Growth Pattern
NoSQL time-series data databases/mangoTSDB/ Largest \u2014 scales with point count and logging frequency
Backup files backup/ Grows with each scheduled or manual backup
Event messages SQL database (events table) Grows with alarm frequency and detector count
Log files logs/ Grows with log verbosity; rotates but old files accumulate

Approximate Sizing for Time-Series Data

As a planning guide, 200 million point values occupy approximately 4 GB of NoSQL storage. Actual size varies with data type and value distribution.

Points Logging Interval Values per Day Approx. Monthly Storage
100 10 seconds 864,000 ~70 MB
1,000 30 seconds 2,880,000 ~700 MB
5,000 10 seconds 43,200,000 ~3.5 GB
10,000 5 seconds 172,800,000 ~14 GB
WARNING: These are estimates. Binary and multistate points consume less storage than numeric points. High-precision floating-point values consume more.

Configuring Purge Settings

Purge settings control how long historical point values are retained before automatic deletion. They can be set at three levels, with the most specific level taking priority.

System-Level Purge (Default for All Points)

  1. Go to Administration > System Settings > Purge
  2. Set the Default Purge Period (e.g., 1 Year)
  3. Configure the Purge Run Time \u2014 typically overnight during low-activity hours (e.g., 3:00 AM)

Mango runs the purge task daily at the configured time and removes point values older than the retention period.

Data Source-Level Purge (Override per Source)

Override the system default for all points belonging to a specific data source:

  1. Open the data source's Edit page
  2. Enable Purge Override
  3. Set a custom period (e.g., 6 Months for high-frequency diagnostic data sources)

All data points in this source inherit the override unless they have their own point-level setting.

Data Point-Level Purge (Override per Point)

The most granular control \u2014 set retention on individual data points:

  1. Open the data point's Properties or Logging tab
  2. Under Purge Settings, enable the override
  3. Set the desired retention period
TIP: Use a tiered strategy: set a conservative system default (e.g., 1 year), extend retention on critical points individually (e.g., energy meters to 5 years), and shorten retention on high-frequency diagnostic points (e.g., 30 days).

NoSQL Shard File Structure

The NoSQL time-series database organizes data into shard files, each covering a fixed time period. The shard directory typically looks like:

databases/mangoTSDB/
    data_2023-01.dat
    data_2023-02.dat
    ...
    data_2024-11.dat
    data_2024-12.dat

Each file contains time-series data for all points during that time window. Older files can be identified by their date-based filenames.

Manual Shard Deletion by Date

When disk space is critically low and you need to free space immediately, you can manually delete old shard files:

  1. Stop Mango \u2014 never delete shard files while Mango is running
sudo systemctl stop mango
  1. Identify and remove shards older than your desired cutoff:
# Remove all 2022 and older shards
rm /opt/mango/databases/mangoTSDB/data_2021-*.dat
rm /opt/mango/databases/mangoTSDB/data_2022-*.dat
  1. Restart Mango:
sudo systemctl start mango
DANGER: Manual shard deletion is irreversible. The historical data in deleted files cannot be recovered. Double-check file dates before deleting and ensure you have a backup if the data may be needed later.

Built-In Disk Space Monitoring

Mango includes internal data points that monitor host system resources. Use them to set up proactive alerts before the disk fills.

  1. Locate the Internal Data Source (or System Information data source, if already created)
  2. Enable the Partition Free Space or Disk Free Bytes data point for the Mango partition
  3. Create an Event Detector with a low-limit threshold (e.g., alarm when free space drops below 2 GB)
  4. Attach an Event Handler (email, Slack, or other) to get notified

This gives your team early warning and time to act before a disk-full condition causes downtime.

Event Message Purge

Event messages (alarms, system events, audit trail entries) accumulate in the SQL database events table and can grow to millions of rows on busy systems.

Configure Event Purge

  1. Go to Administration > System Settings > Purge
  2. Set the Event Purge Period (e.g., 90 days)
  3. Optionally configure different retention for different alarm levels

Counting Events with the SQL Console

To check how many events are stored:

  1. Go to Administration > SQL Console (superadmin access required)
  2. Run:
SELECT COUNT(*) FROM events;

For a breakdown by alarm level:

SELECT alarmLevel, COUNT(*) AS total
FROM events
GROUP BY alarmLevel
ORDER BY total DESC;
TIP: If the event count is in the millions, consider reducing the event purge period or tuning noisy event detectors to reduce alarm volume at the source.

Log File Management

Mango rotates log files automatically via Log4j, but old rotated files can accumulate over time.

# Check total log directory size
du -sh /opt/mango/logs/

# Remove rotated logs older than 30 days
find /opt/mango/logs/ -name "*.log.*" -mtime +30 -delete

If logs are growing too fast, review the logging configuration in classes/log4j2.xml. Avoid running DEBUG or TRACE level logging in production \u2014 INFO is appropriate for most deployments.

Troubleshooting

Disk full \u2014 Mango will not start

Purge task does not seem to run

Disk usage growing despite purge settings

Configuring Slack Notifications for Mango Alarms

Category: Configuration · Version: Mango 4.x / 5.x · Difficulty: Beginner · 8 min read

Overview

The Slack Message event handler sends Mango alarm notifications directly to Slack channels. Instead of relying solely on email, your operations team can receive real-time alerts in the channels they already monitor. This guide walks through creating a Slack App, installing it to your workspace, and wiring it to Mango event detectors.

Prerequisites

Step 1: Create a Slack App

  1. Go to https://api.slack.com/apps
  2. Click Create New App > From scratch
  3. Enter an App Name (e.g., "Mango Alarms")
  4. Select your Slack Workspace
  5. Click Create App

You are now on the app's settings page, which you will return to for several configuration steps.

Step 2: Add a Bot User

  1. In the left sidebar, click App Home (or Bot Users on older Slack UI)
  2. Under Your App's Presence in Slack, click Review Scopes to Add
  3. Or navigate to Features > Bot Users and click Add a Bot User
  4. Set the Display Name (e.g., "Mango Alert Bot")
  5. Set the Default Username (e.g., mango-alerts)
  6. Toggle Always Show My Bot as Online to On
  7. Click Save Changes

Step 3: Configure OAuth Scopes

  1. Navigate to OAuth & Permissions in the left sidebar
  2. Scroll to Bot Token Scopes
  3. Click Add an OAuth Scope and add:
Scope Purpose
chat:write Send messages to channels the bot has been invited to
chat:write.public Send messages to any public channel without an explicit invitation
TIP: Adding chat:write.public allows the bot to post to any public channel without needing to be invited first. If you prefer tighter control, omit this scope and manually invite the bot to each channel.

Step 4: Install the App to Your Workspace

  1. Navigate to Install App in the left sidebar
  2. Click Install to Workspace
  3. Review the requested permissions and click Allow
  4. Copy the Bot User OAuth Token \u2014 it starts with xoxb-
DANGER: The bot token is a secret. Do not paste it into Slack messages, commit it to version control, or share it in documentation. Treat it with the same care as a password.

Step 5: Invite the Bot to a Channel

Open the Slack channel where you want alarm notifications to appear and type:

/invite @Mango Alert Bot

Confirm the invitation when Slack prompts you.

INFO: If you added the chat:write.public scope in Step 3, the bot can post to any public channel without an invitation. For private channels, the bot must always be explicitly invited.

Step 6: Configure the Slack Message Event Handler in Mango

  1. In Mango, navigate to Event Handlers
  2. Click + to add a new handler
  3. Select Slack Message as the handler type
  4. Fill in the configuration:
Field Value Notes
Name Descriptive label e.g., "Critical Alarms to #ops-alerts"
Bot Auth Token xoxb-... The token copied in Step 4
Channel Channel name or ID e.g., #building-alarms or C04ABCD1234
TIP: Use the channel ID rather than the channel name. Channel IDs are stable even if someone renames the channel. Find the ID by right-clicking the channel name in Slack, selecting View channel details, and scrolling to the bottom.
  1. Click Save

Step 7: Link the Handler to Event Detectors

  1. In the event handler's configuration, find the Event Types section
  2. Select the event detector(s) that should trigger Slack notifications
  3. You can link multiple detectors to the same handler, or create separate handlers for different channels

Routing by Severity

A common pattern is sending different alarm levels to different channels:

Alarm Level Slack Channel Handler Name
Information #building-info Slack \u2014 Info Alerts
Urgent #building-alerts Slack \u2014 Urgent Alerts
Critical #critical-ops Slack \u2014 Critical Alerts

Create one Slack Message event handler per channel and link each to the appropriate event detectors.

Step 8: Test the Notification

  1. Trigger the event detector \u2014 either by simulating the condition (e.g., setting a point value above the high limit) or waiting for a real event
  2. Check the target Slack channel for the notification message
  3. Verify the message includes useful context: point name, alarm level, value, and timestamp

Troubleshooting

Messages not appearing in Slack

"channel_not_found" error in logs

"not_in_channel" error

"invalid_auth" error

Messages are delayed or missing intermittently

Configuring the HTTP Retriever Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 12 min read

Overview

The HTTP Retriever data source allows Mango to pull data from external web servers, REST APIs, and other HTTP-accessible endpoints on a configurable schedule. Each poll performs an HTTP GET request, retrieves the response body, and extracts values with regular expressions matched against the raw text.

It works with text-based formats including HTML, XML, plain text, and JSON. For native JSON parsing with JSON Pointer, use the separate HTTP JSON Retriever data source.

NOTE: The HTTP Retriever treats JSON as plain text and supports regex extraction only. Use the HTTP JSON Retriever when you want to address JSON fields directly with JSON Pointer syntax.

Prerequisites

Step 1: Create the Data Source

  1. Navigate to Data Sources.
  2. Click + to add a data source.
  3. Select HTTP Retriever.
  4. Configure the basic settings:
Field Description Example
Name Descriptive name for the data source Weather API
Update Period How often Mango polls the URL 5
Update Period Type Unit for the update period Minutes

Step 2: Configure the URL

Enter the complete endpoint, including the protocol, in URL:

https://api.example.com/v1/sensors/temperature?unit=celsius

Create a separate HTTP Retriever data source for each URL, unless one endpoint returns all required values.

TIP: If an API accepts a key or token as a query parameter, include it directly in the URL:

>

https://api.weather.com/data?apiKey=YOUR_KEY&location=12345

Step 3: Handle Authentication

The HTTP Retriever has no dedicated username/password fields and cannot add custom request headers. Every poll is a plain HTTP GET request. Its available TLS settings control certificate validation, not application authentication.

API Key or Token in the URL

If the API supports query-string credentials, include them in the URL:

https://api.example.com/data?key=abc123def456

Basic Authentication and Custom Headers

The HTTP Retriever cannot directly send HTTP Basic Authentication or custom headers such as Authorization: Bearer ....

If the endpoint requires either:

TLS and Certificates

The data source provides connection-level options to verify the server certificate and hostname. You can also trust a specific PKI CA certificate or supply a trusted certificate for self-signed and internal endpoints.

Step 4: Set Timeout and Retries

Setting Recommended Value Notes
Timeout 30 seconds Increase for slow APIs or high-latency connections
Retries 2 Number of retry attempts after a failure
WARNING: A timeout longer than the update period can cause polls to stack up. Keep the timeout shorter than the configured update period.

Step 5: Add Data Points with Regex Extraction

  1. Click Add Point on the data source.
  2. Set Point Name.
  3. Set Data Type to Numeric, Binary, Multistate, or Alphanumeric as appropriate.
  4. Enter a Regex Pattern that captures the required value.

The first parenthesized capture group supplies the point value unless Point Index selects another group. Index 1 is the first capture group, index 2 the second, and so on.

HTML

For 72.5:

<span class="temp">([\\d.]+)</span>

Plain Text

For Temperature: 72.5 F:

Temperature:\\s*([\\d.]+)

CSV-Like Text

For sensor1,72.5,45.2,normal:

^[^,]+,([\\d.]+)

Step 6: Handle JSON Responses

The HTTP Retriever does not parse JSON. It runs regex patterns against the raw JSON response just as it does with any other text.

Given:

{
  "location": "Building A",
  "readings": {
    "temperature": 72.5,
    "humidity": 45.2,
    "status": "normal"
  }
}

This pattern captures the temperature:

"temperature":\\s*([\\d.]+)

Make the pattern specific enough to avoid matching the wrong field when a key appears more than once.

TIP: For deeply nested JSON or field-by-path access, use the HTTP JSON Retriever. It parses the response as JSON and supports JSON Pointer (RFC 6901), such as /readings/temperature or /Members/0/reading.
WARNING: JSON field names are case-sensitive. A pattern for "Temperature" does not match "temperature". Examine the raw response with curl or browser developer tools before writing the regex.
NOTE: Match the point's Data Type to the value returned by the API. A string such as "true" is not necessarily parsed the same way as a JSON boolean.

Step 7: Consider Encoding and Response Size

Step 8: Enable and Verify

  1. Save the data source.
  2. Enable it with the toggle.
  3. Watch the data points for incoming values.
  4. Review Data Source Events for connection or parsing errors.

Verification

Troubleshooting

Connection Refused or Timed Out

401 or 403 Response

Regex Does Not Match

Values Are Stale

Related Guides

Configuring the Serial (RS-232/RS-485) Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 14 min read

Overview

The Serial data source in Mango reads data from RS-232 or RS-485 devices connected to the Mango server via a serial port or USB-to-serial adapter. It listens for incoming messages, identifies complete message frames using a configurable terminator or timeout, and then extracts values using regex patterns. This data source is well suited for devices that transmit ASCII or hex-encoded data streams -- such as weather stations, GPS receivers, scale readouts, and custom embedded controllers.

Prerequisites

Step 1: Verify the Serial Connection

Before configuring Mango, confirm that the physical connection is working.

Linux

# List available serial ports
ls /dev/ttyUSB* /dev/ttyS* /dev/ttyACM* 2>/dev/null

# Test receiving data (press Ctrl+C to stop)
screen /dev/ttyUSB0 9600

# Or use minicom
minicom -D /dev/ttyUSB0 -b 9600

Windows

Use a terminal application such as PuTTY or Tera Term to open the COM port at the correct baud rate. Confirm you see data arriving from the device.

TIP: If you see garbled characters in the terminal, you likely have the wrong baud rate. Try common values: 9600, 19200, 38400, 57600, 115200. Once you see readable text, you have the correct settings.

Step 2: Set Serial Port Permissions (Linux)

On Linux, the Mango user must be a member of the dialout group (or the group that owns the serial device):

# Add the mango user to the dialout group
sudo usermod -a -G dialout mango

# Verify group membership
groups mango

# Restart Mango for the change to take effect
sudo systemctl restart mango
WARNING: Group changes do not take effect until the Mango process is restarted. Simply restarting the data source is not sufficient.

Step 3: Create the Data Source

  1. Navigate to Data Sources in Mango
  2. Click the + button to add a new data source
  3. Select Serial from the type dropdown
  4. Configure the data source name and update period

Step 4: Configure Serial Port Parameters

Set the communication parameters to match your device:

Parameter Common Values Notes
Port /dev/ttyUSB0, COM3 The serial port where the device is connected
Baud Rate 9600, 19200, 38400, 115200 Must match the device setting exactly
Data Bits 8 Almost always 8 for modern devices
Parity None, Even, Odd Must match the device configuration
Stop Bits 1 Some older devices use 2
Flow Control None Hardware (RTS/CTS) or software (XON/XOFF) flow control, if needed
INFO: The most common configuration for industrial devices is 9600 baud, 8 data bits, no parity, 1 stop bit -- often abbreviated as 9600 8N1.

Step 5: Configure Message Framing

Mango needs to know where one message ends and the next begins. There are two approaches:

Terminator-Based Framing

If the device ends each message with a specific character or sequence, configure the Message Terminator. Common terminators include:

Terminator Hex Value Typical Use
Carriage Return + Line Feed (\\r\\n) 0x0D 0x0A Most ASCII devices
Line Feed (\\n) 0x0A Unix-style output
Carriage Return (\\r) 0x0D Some older devices
Custom byte Varies Protocol-specific

Timeout-Based Framing

If the device does not use a consistent terminator, use a Read Timeout to frame messages. Mango accumulates incoming bytes and considers the message complete when no new bytes arrive for the specified timeout period (typically 100--500 ms). This is common for devices that send fixed-length binary frames.

Step 6: Add Data Points with Regex Extraction

Each data point uses a regex pattern to extract a value from the received message string.

Example: Weather Station

If the device sends messages like:

TEMP=72.5,HUM=45.2,WIND=12.3,DIR=NW

Create data points with these regex patterns:

Point Name Regex Pattern Data Type
Temperature TEMP=([\\d.]+) Numeric
Humidity HUM=([\\d.]+) Numeric
Wind Speed WIND=([\\d.]+) Numeric
Wind Direction DIR=(\\w+) Alphanumeric

The first capture group (the part inside parentheses) becomes the point value.

Example: Scale Readout

A digital scale might send:

  +  125.40 kg

Use the regex:

([+-]?)\\s*([\\d.]+)

Use capture group 2 for the numeric weight and optionally group 1 for the sign.

Step 7: Handle Hex Data

Some devices transmit raw binary or hex-encoded data rather than ASCII text. Mango can display the received bytes as a hex string, which you can then parse with regex.

If the hex representation of a message is:

02 41 90 00 00 03

Where bytes 1--4 contain an IEEE 754 float, you may need to use a Meta data source with a script to convert the hex bytes to a float value. The Serial data source captures the raw message, and the Meta point performs the conversion.

Converting Hex to Values with a Meta Point

Create a Meta data point that references the serial alphanumeric point and use a script to parse the hex:

var hexStr = p.value; // Raw hex string from serial point
// Parse bytes, convert to float, etc.
INFO: For complex binary protocols, consider whether a protocol-specific data source (Modbus RTU, BACnet MSTP, etc.) would be more appropriate than the generic Serial data source.

Step 8: Configure Point-to-Point vs. Listener Mode

The Serial data source operates in listener mode -- it passively receives data from the device. This is appropriate for devices that continuously transmit data at regular intervals.

If you need to send a command to the device and read the response (request/response pattern), configure:

This is useful for devices that only respond when queried, such as some sensor modules that require a read command.

Verification

Troubleshooting

"Port not found" or "Port in use" error

No data received (point values stay empty)

Garbled or partial data in point values

Regex not matching

USB-to-serial adapter not detected after reboot

Configuring a Modbus RTU (Serial) Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 14 min read

Overview

Modbus RTU (Remote Terminal Unit) is the serial variant of the Modbus protocol, commonly used in industrial environments where devices are connected over RS-485 multi-drop networks. Unlike Modbus TCP which communicates over Ethernet, Modbus RTU uses serial communication with binary framing and CRC error checking. This guide covers configuring a Modbus RTU data source in Mango to read registers from PLCs, energy meters, variable frequency drives, and other Modbus-compatible field devices.

Prerequisites

Modbus RTU vs. Modbus TCP

Feature Modbus RTU Modbus TCP
Physical Layer RS-485 serial Ethernet (TCP/IP)
Addressing Slave ID (1--247) IP address + Unit ID
Framing Binary with CRC-16 TCP packets with MBAP header
Speed Baud rate dependent (9600--115200) Network speed (10/100/1000 Mbps)
Multi-device Up to 247 devices on one bus One connection per IP
Cable Length Up to 1200 m (4000 ft) at 9600 baud Standard Ethernet limits

Step 1: Prepare the RS-485 Connection

Wiring

RS-485 uses a differential pair (A and B) for communication:

Terminal Description
A (D-) Inverting line (sometimes labeled TxD-/RxD-)
B (D+) Non-inverting line (sometimes labeled TxD+/RxD+)
GND Signal ground (recommended for long runs)
WARNING: A/B labeling is not standardized across manufacturers. If you get no response from the device, try swapping the A and B wires. This is one of the most common causes of communication failure.

Bus Termination

For cable runs longer than 30 meters (100 ft) or baud rates above 19200, install a 120-ohm termination resistor at each end of the RS-485 bus. Many USB-to-RS-485 adapters have a built-in switchable termination resistor.

Step 2: Verify Serial Port Access

# Linux: list serial ports
ls /dev/ttyUSB* /dev/ttyS* 2>/dev/null

# Add the mango user to the dialout group (if not already done)
sudo usermod -a -G dialout mango

# Restart Mango to apply group membership
sudo systemctl restart mango

Step 3: Create the Modbus Serial Data Source

  1. Navigate to Data Sources in Mango
  2. Click the + button to add a new data source
  3. Select Modbus Serial (or Modbus RTU) from the dropdown
  4. Configure the data source:
Field Value Notes
Name Descriptive name e.g., "Building A RS-485 Bus"
Update Period 5 seconds Adjust based on device response time and bus load
Quantize Checked Aligns polls to clock boundaries for consistent intervals

Step 4: Configure Serial Port Settings

Parameter Common Value Notes
Port /dev/ttyUSB0 or COM3 Must match the physical port
Baud Rate 9600 Must match all devices on the bus
Data Bits 8 Standard for Modbus RTU
Parity None or Even Modbus spec recommends Even parity with 1 stop bit
Stop Bits 1 Use 2 stop bits if parity is None (per Modbus standard)
INFO: All devices on a Modbus RTU bus must use the same baud rate, data bits, parity, and stop bits. If even one device has mismatched settings, it will cause bus errors that may affect communication with all devices.

Timeout and Retries

Setting Recommended Value Notes
Timeout 1000 ms How long to wait for a slave response
Retries 2 Number of retry attempts per failed request
Contiguous Batches Only Checked Bundles adjacent registers into fewer requests
Max Read Register Count 125 Maximum registers per single request (Modbus limit is 125)

Step 5: Add Data Points

For each value you want to read, add a data point to the data source.

  1. Click Add Point
  2. Configure the point settings:
Field Description
Slave ID The device address (1--247). Each device on the bus has a unique slave ID
Register Range The Modbus object type (see table below)
Offset The register address within the range (0-based in Mango)
Data Type How to interpret the register contents

Register Ranges (Object Types)

Range Modbus Function Code Access Typical Use
Coil FC 01 (read) / FC 05, 15 (write) Read/Write Digital outputs, relay states
Discrete Input FC 02 Read Only Digital inputs, switch status
Holding Register FC 03 (read) / FC 06, 16 (write) Read/Write Configuration, setpoints, measured values
Input Register FC 04 Read Only Measured values, sensor readings

Register Offset Conventions

Modbus register addressing is a common source of confusion:

Documentation Format Mango Offset Register Range
40001 0 Holding Register
40100 99 Holding Register
30001 0 Input Register
10001 0 Coil
00001 0 Discrete Input
TIP: Subtract the base address (40001, 30001, etc.) from the documented register number and then subtract 1 more to get the Mango 0-based offset. For example, register 40101 = 40101 - 40001 = 100, which is offset 100 in Mango.

Step 6: Configure Data Types

Select the data type that matches how the device stores values in its registers:

Mango Data Type Size Value Range Common Use
2 Byte Unsigned (UINT16) 1 register 0 to 65,535 Status codes, simple counters
2 Byte Signed (INT16) 1 register -32,768 to 32,767 Temperatures, small measurements
4 Byte Float (FLOAT32) 2 registers IEEE 754 float Precision measurements, energy
4 Byte Unsigned (UINT32) 2 registers 0 to 4,294,967,295 Energy totals, large counters
4 Byte Signed (INT32) 2 registers +/- 2.1 billion Large signed values
8 Byte Float (FLOAT64) 4 registers IEEE 754 double High-precision values
Mod 10K (BCD) 2+ registers Varies Legacy energy meters (ION, Shark)

Understanding Mod10K (Modulo 10,000)

Some older energy meters (such as Schneider ION and Electro Industries Shark) store large numbers across multiple registers using a Mod10K encoding. Each register holds a value 0--9999, and the full value is reconstructed by treating each register as a digit group:

Register 1: 0012  (high word)
Register 2: 3456  (low word)
Full value: 12 * 10000 + 3456 = 123456

Select the Mod10K data type in Mango and specify the number of registers (typically 2 or 3) to handle this automatically.

Byte Order (Endianness)

For multi-register data types (32-bit and 64-bit), configure the byte order:

TIP: If a known value (like a device serial number or firmware version) appears garbled, try each byte order option. This is the most common troubleshooting step after verifying the register offset.

Step 7: Enable and Monitor

  1. Save the data source
  2. Enable it with the toggle switch
  3. Verify data points are showing expected values
  4. Check the IO Log for this data source (modbusIO-{datasource-id}.log) to see the raw Modbus request/response traffic

A well-configured data source shows tightly grouped request/response pairs at each poll interval. If you see continuous streaming requests, the poll period may be too short relative to the number of registers being read.

Verification

Troubleshooting

"No response from slave" error

Timeout errors on some but not all devices

Values are incorrect or garbled

Intermittent communication failures

Configuring the SQL Database Data Source

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 14 min read

Overview

The SQL data source allows Mango to read data directly from external relational databases. On each poll, Mango executes a SQL SELECT query against the target database and maps the result columns to Mango data points. This is useful for integrating with enterprise systems, historian databases, building management systems, and any application that stores operational data in a SQL database. The data source supports any database that has a JDBC driver, including MySQL, MariaDB, PostgreSQL, Microsoft SQL Server, Oracle, and SQLite.

Prerequisites

Step 1: Obtain and Install the JDBC Driver

Mango uses JDBC (Java Database Connectivity) to connect to external databases. You must provide the appropriate JDBC driver for your database.

Common JDBC Drivers

Database Driver JAR Download Source
MySQL mysql-connector-java-x.x.x.jar dev.mysql.com/downloads/connector/j/
PostgreSQL postgresql-x.x.x.jar jdbc.postgresql.org
Microsoft SQL Server mssql-jdbc-x.x.x.jar docs.microsoft.com
MariaDB mariadb-java-client-x.x.x.jar mariadb.com
Oracle ojdbc11.jar oracle.com

Installing the Driver

  1. Download the JDBC driver JAR file for your database
  2. Copy the JAR file to the Mango lib directory:
# Example for MySQL
cp mysql-connector-java-8.0.33.jar /opt/mango/lib/

# Example for PostgreSQL
cp postgresql-42.6.0.jar /opt/mango/lib/
  1. Restart Mango -- the JDBC driver is loaded at startup and will not be recognized until Mango is restarted
WARNING: After adding or updating a JDBC driver, you must fully restart Mango. A data source restart alone is not sufficient because the driver is loaded by the Java classloader at application startup.

Step 2: Create the SQL Data Source

  1. Navigate to Data Sources in Mango
  2. Click the + button to add a new data source
  3. Select SQL from the data source type dropdown
  4. Configure the basic settings:
Field Description Example
Name Descriptive name for this connection "Building Management DB"
Update Period How often to execute the query 60 seconds

Step 3: Configure the Database Connection

Enter the JDBC connection details:

Connection String (JDBC URL)

The format varies by database type:

# MySQL
jdbc:mysql://db-server:3306/database_name

# PostgreSQL
jdbc:postgresql://db-server:5432/database_name

# Microsoft SQL Server
jdbc:sqlserver://db-server:1433;databaseName=database_name

# MariaDB
jdbc:mariadb://db-server:3306/database_name

# Oracle
jdbc:oracle:thin:@db-server:1521:SID

Authentication

Field Description
Driver Class Name The fully qualified Java class name of the JDBC driver
Username Database user account
Password Database user password

Common Driver Class Names

Database Driver Class Name
MySQL com.mysql.cj.jdbc.Driver
PostgreSQL org.postgresql.Driver
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver
MariaDB org.mariadb.jdbc.Driver
Oracle oracle.jdbc.OracleDriver
TIP: Create a dedicated, read-only database user for Mango to use. This follows the principle of least privilege and prevents accidental data modification.

Step 4: Write the SELECT Query

Enter the SQL query that Mango will execute on each poll. The query should return the current values you want to monitor as columns:

SELECT
    sensor_name,
    temperature,
    humidity,
    last_updated
FROM sensor_readings
WHERE location = 'Building A'
ORDER BY last_updated DESC
LIMIT 1

Query Guidelines

INFO: Mango uses the column names from the query result to map values to data points. Use column aliases if the original column names are not descriptive: SELECT temp_f AS temperature FROM readings.

Step 5: Map Query Results to Data Points

Each column in the query result can be mapped to a Mango data point.

  1. Click Add Point on the data source
  2. Configure the point:
Field Description Example
Point Name A descriptive name "Building A Temperature"
Field Name The column name (or alias) from the query result "temperature"
Data Type How to interpret the column value Numeric
Row Index Which row to use (0 for the first row) 0

Data Type Mapping

SQL Column Type Mango Data Type
INT, FLOAT, DOUBLE, DECIMAL Numeric
BIT, BOOLEAN Binary
VARCHAR, TEXT Alphanumeric
INT (with enumerated values) Multistate

Multiple Rows

If your query returns multiple rows and each row represents a different data point, you can create multiple points with different Row Index values. Row 0 is the first row, row 1 is the second, and so on.

Alternatively, restructure your query to return one row with multiple columns:

SELECT
    MAX(CASE WHEN sensor_id = 1 THEN value END) AS sensor_1_temp,
    MAX(CASE WHEN sensor_id = 2 THEN value END) AS sensor_2_temp,
    MAX(CASE WHEN sensor_id = 3 THEN value END) AS sensor_3_temp
FROM latest_readings

Step 6: Configure Write Operations (Optional)

Some versions of the SQL data source support executing INSERT or UPDATE statements when a Mango data point value is set. This allows bidirectional communication with the database.

If supported, configure a Set Statement on settable data points:

UPDATE control_settings
SET value = ?
WHERE parameter_name = 'setpoint_temp'

The ? placeholder is replaced with the value set on the Mango data point.

WARNING: Write operations modify data in the external database. Test thoroughly on a non-production database first. Ensure the Mango database user has only the minimum required permissions.

Step 7: Connection Pool Settings

For high-frequency polling or multiple SQL data sources, consider the connection pool settings:

Setting Description Default
Max Active Connections Maximum simultaneous database connections 8
Max Idle Connections Connections kept open when idle 4
Connection Timeout How long to wait for a connection from the pool 30 seconds
TIP: If you see connection timeout errors during periods of heavy polling, increase the max active connections. However, also verify your database server can handle the additional connections.

Step 8: Enable and Verify

  1. Save the data source
  2. Click Test Connection (if available) to verify the database connection
  3. Enable the data source
  4. Check that data points display values from the query results
  5. Monitor the data source for connection errors

Verification

Troubleshooting

"Driver not found" or "No suitable driver" error

"Connection refused" error

"Access denied" or authentication error

Query timeout or slow performance

Data point shows null or no value

Using the Virtual Data Source for Testing and Simulation

Category: Data Sources · Version: Mango 4.x / 5.x · Difficulty: Beginner · 10 min read

Overview

The Virtual data source generates simulated data points without any external hardware or network connections. It is built into Mango and requires no additional modules or licenses. Virtual points are invaluable for testing event detectors and handlers before deploying them on real data, building demo dashboards to showcase to stakeholders, developing and debugging scripts in Meta data points, verifying system configuration such as email alerts and escalation chains, and training new users in a safe environment.

Prerequisites

Step 1: Create the Virtual Data Source

  1. Navigate to Data Sources in Mango
  2. Click the + button to add a new data source
  3. Select Virtual from the data source type dropdown
  4. Configure the data source:
Field Value Notes
Name Descriptive name e.g., "Test Simulator" or "Demo Data"
Update Period 5 seconds How often each point generates a new value
Update Period Type Seconds Seconds, minutes, hours, or milliseconds
  1. Click Save
TIP: Use a shorter update period (1--5 seconds) for testing dashboards and visualizations so you can see data changing in real time. Use a longer period (30--60 seconds) for testing event detectors and alarms to avoid generating excessive events.

Step 2: Add Numeric Data Points

Numeric points generate decimal or integer values. They are the most commonly used virtual point type.

  1. Click Add Point on the data source
  2. Set the Data Type to Numeric
  3. Choose a Change Type to control how values are generated:

Change Types for Numeric Points

Change Type Behavior Best For
No Change Value stays constant Fixed setpoints, reference values
Increment Increases (or decreases) by a fixed amount each poll Simulating counters, energy totals
Brownian Random walk -- value drifts up and down gradually Realistic temperature, pressure, or humidity simulation
Random Completely random value within a range each poll Stress-testing dashboards with volatile data
Sinusoidal Follows a sine wave pattern Simulating cyclical processes (HVAC, tidal, solar)
Analog Attractor Drifts toward a target value with random variation Simulating a controlled process approaching a setpoint

Configuring Each Change Type

Increment:

Setting Description Example
Start Value Initial value 0
Change Amount added each poll 1.5
Roll Whether to reset at the bound Yes
Bound Reset threshold (with Roll) 1000

Brownian:

Setting Description Example
Start Value Initial value 72.0
Min Lower bound 60.0
Max Upper bound 85.0
Change Maximum change per poll 0.5

Random:

Setting Description Example
Min Minimum random value 0
Max Maximum random value 100

Sinusoidal:

Setting Description Example
Amplitude Peak deviation from center 10.0
Offset Center value 72.0
Period Time for one complete cycle 3600 seconds

Step 3: Add Binary Data Points

Binary points generate true/false (on/off) values. They are useful for simulating equipment status, door contacts, alarms, and any two-state condition.

  1. Click Add Point and set Data Type to Binary
  2. Choose a change type:
Change Type Behavior Best For
No Change Stays at the initial value Fixed reference states
Alternate Toggles between true and false each poll Simulating a blinking indicator
Random Randomly true or false each poll Testing binary event detectors

Step 4: Add Multistate Data Points

Multistate points cycle through a set of integer values, each representing a distinct state. They are useful for simulating equipment modes, alarm severities, or operating states.

  1. Click Add Point and set Data Type to Multistate
  2. Choose a change type:
Change Type Behavior Best For
No Change Stays at the initial value Fixed state reference
Increment Cycles through states sequentially Simulating mode transitions
Random Picks a random state each poll Testing multistate renderers

Configure the list of possible state values. For example, to simulate an HVAC mode:

Value Label
0 Off
1 Heating
2 Cooling
3 Fan Only

Step 5: Add Alphanumeric Data Points

Alphanumeric points generate string values. They are less commonly used but helpful for testing text-based displays and logging.

  1. Click Add Point and set Data Type to Alphanumeric
  2. Choose a change type:
Change Type Behavior
No Change Stays at the initial string value
Random Generates a random string of configurable length

Step 6: Make Points Settable

Virtual points can be configured as settable, allowing you to manually change their value from the watchlist, point details page, or dashboard.

  1. On the data point configuration, check Settable
  2. Save the point

When you set a value manually, the virtual point adopts that value immediately. Depending on the change type, subsequent polls may then modify it (Brownian, Increment) or leave it unchanged (No Change).

INFO: Settable virtual points are especially useful for testing event handlers. You can manually set a value that triggers an event detector (e.g., a high-limit alarm) and verify that the event handler (email, Slack notification) fires correctly.

Common Use Cases

Use Case 1: Testing Event Detectors

Create a Brownian numeric point simulating a temperature sensor (range 60--90, change 0.5). Configure a high-limit event detector at 85. The Brownian motion will naturally trigger the alarm periodically, letting you verify:

Use Case 2: Demo Dashboard

Build a complete demo dashboard using virtual points:

Virtual Point Configuration Dashboard Widget
Building Temperature Brownian, 65--80 Gauge widget
HVAC Mode Multistate, 0--3 Status indicator
Energy Consumption Sinusoidal, period 24h Time series chart
Door Contact Random binary Binary LED
Occupancy Count Random, 0--50 Numeric display

Use Case 3: Script Development

When developing Meta data source scripts that perform calculations on multiple input points, use virtual points as the inputs. This allows you to test the script logic independently of real data:

  1. Create virtual points that simulate the input values
  2. Create the Meta point referencing the virtual points
  3. Adjust virtual point values to test edge cases
  4. Once the script works correctly, switch the Meta point context to reference real data points

Step 7: Enable and Verify

  1. Enable the Virtual data source
  2. Open the Watchlist and add your virtual points
  3. Observe values changing at the configured update interval
  4. For settable points, try setting a value manually and confirming it takes effect

Verification

Troubleshooting

Points show no value or do not update

Brownian values hit the boundary and stay there

Increment point resets unexpectedly

Sinusoidal values appear flat

Dashboard not showing data from virtual points

Configuring Email and SMTP Settings

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Beginner · 10 min read

Overview

Mango uses outbound email for alarm notifications, event handlers, scheduled reports, and password-reset links. These features require a valid SMTP connection. This guide covers UI and properties-file configuration, common providers, testing, event handlers, and delivery troubleshooting.

Prerequisites

Step 1: Open Email System Settings

The most common method is the UI:

  1. Log in as an administrator.
  2. Go to Administration > System Settings.
  3. Select Email.

For headless or automated setups, use a properties file. Mango checks an explicit --config path first, then /mango.properties, which is the recommended location and is created for a new installation when no higher-priority file exists. Legacy fallback locations, including env.properties, are also supported.

Add overrides as systemSettings.=. Mango watches the configuration file and hot-reloads changes after it is saved; no restart is required.

Step 2: Configure SMTP

UI Field Property Override Key Description
SMTP Host systemSettings.emailSmtpHost Mail-server hostname
SMTP Port systemSettings.emailSmtpPort Usually 587 for STARTTLS or 465 for implicit SSL
From Address systemSettings.emailFromAddress Sender address
From Name systemSettings.emailFromName Sender display name
Use Authentication systemSettings.emailAuthorization true when the server requires login
Username systemSettings.emailSmtpUsername SMTP username
Password systemSettings.emailSmtpPassword SMTP password or provider token
Enable TLS systemSettings.emailTls true for STARTTLS

Related overrides include systemSettings.emailSendTimeout, systemSettings.emailContentType, and systemSettings.emailDisabled. The last setting suppresses all outbound email without removing the connection configuration.

Example /mango.properties:

systemSettings.emailSmtpHost=smtp.yourserver.com
systemSettings.emailSmtpPort=587
systemSettings.emailFromAddress=mango-alerts@yourcompany.com
systemSettings.emailFromName=Mango Automation
systemSettings.emailAuthorization=true
systemSettings.emailSmtpUsername=mango-alerts@yourcompany.com
systemSettings.emailSmtpPassword=your-password-here
systemSettings.emailTls=true
WARNING: Mango email overrides use the systemSettings.email... keys shown above. The mail.smtp.* namespace is not a Mango configuration interface.

Step 3: Configure Gmail

  1. Enable two-factor authentication under Google Account > Security.
  2. Generate an App Password under Security > App Passwords.
  3. Copy the generated password.
  4. Enter these settings:
Field Value
SMTP Host smtp.gmail.com
SMTP Port 587
From Address Your Gmail address
Username Your Gmail address
Password The App Password
TLS true
WARNING: Do not use your regular Gmail password. Use an App Password generated from Google's security settings.
NOTE: Gmail sending limits may be unsuitable for high-volume alarms. Use a dedicated transactional email service when notification volume is high.

Step 4: Configure SendGrid

  1. Create a SendGrid API key with Mail Send permission.
  2. Copy the key when it is displayed.
  3. Enter:
Field Value
SMTP Host smtp.sendgrid.net
SMTP Port 587
From Address A verified SendGrid sender
Username apikey
Password The SendGrid API key
TLS true
NOTE: The SendGrid SMTP username is literally apikey, not the account email address.

Step 5: Configure Microsoft 365

Field Value
SMTP Host smtp.office365.com
SMTP Port 587
From Address The Microsoft 365 email address
Username The full email address
Password Account password or approved credential
TLS true
WARNING: Some Microsoft 365 tenants require SMTP AUTH to be enabled for the mailbox. Ask the tenant administrator to verify the mailbox setting if authentication fails.

Step 6: Test Email Delivery

  1. Go to Administration > System Settings > Email.
  2. Click Send Test Email.
  3. Check the inbox and spam folder for the logged-in user's email address.
  4. If the test fails, review the displayed SMTP session log and ma.log.
NOTE: Send Test Email always sends to the address on the logged-in user's profile. This test flow has no recipient field.

Test network connectivity independently with:

openssl s_client -connect smtp.gmail.com:587 -starttls smtp

If the connection opens and displays a certificate, the Mango server can reach the SMTP endpoint.

WARNING: If Use Authentication is disabled when the server requires a login, Mango raises a TYPE_EMAIL_SEND_FAILURE System Event. The test-email flow also displays an error dialog with the SMTP session log.

Step 7: Use Email Event Handlers

After SMTP works:

  1. Go to Event Handlers and add an Email Event Handler.
  2. Select the events that trigger it.
  3. Add active-alarm, escalation, and return-to-normal recipients.
  4. Choose Include Name or Include Event Message for the subject.
  5. Optionally enable Include System Info, Include Log File, and recent point-value history.

The point-value count defaults to 10. It only applies when the triggering event belongs to a data point; system and data-source events have no associated point history.

For full control, configure an advanced custom FreeMarker template. It uses syntax such as:

\${evt.message}
\${evt.activeTimestamp?number_to_datetime?string["yyyy/MM/dd HH:mm:ss"]}

Verification

Troubleshooting

TLS Handshake Failed

Authentication Failed

Connection Timed Out

Messages Go to Spam

Relay Access Denied

Related Guides

Changing the Mango Server Port

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Beginner · 8 min read

Overview

By default, Mango listens on port 8080 for HTTP traffic. You may want to change this for several reasons: to avoid conflicts with other applications, to use standard web ports (80 for HTTP, 443 for HTTPS), or to comply with organizational network policies. This guide covers how to change the listening port and related considerations for both Windows and Linux.

Prerequisites

Step 1: Check for Port Conflicts

Before changing ports, make sure your target port is not already in use.

On Linux:

sudo ss -tlnp | grep :80
# or
sudo netstat -tlnp | grep :80

On Windows (Command Prompt as Administrator):

netstat -an | findstr :80

If no output is returned, the port is available.

Step 2: Edit mango.properties

Open the Mango environment properties file:

Add or modify the following properties:

# HTTP port (default: 8080)
web.port=80

# HTTPS port (used when SSL is enabled, default: 8443)
ssl.port=443

# Enable SSL (set to true if you want HTTPS)
ssl.on=false

# Redirect HTTP to HTTPS (optional, requires ssl.on=true)
ssl.redirect.port=443
INFO: If you only need HTTP, you only need to set web.port. The ssl.port and ssl.on properties are only relevant if you are configuring HTTPS directly in Mango.

Common Port Configurations

Scenario web.port ssl.on ssl.port
Development / default 8080 false —
Standard HTTP 80 false —
HTTPS only 8080 true 443
HTTPS with redirect 80 true 443
Behind a reverse proxy 8080 false —

Step 3: Restart Mango

After saving mango.properties, restart Mango for the changes to take effect.

Linux (systemd):

sudo systemctl restart mango

Windows (service):

net stop mango && net start mango

Windows (manual):

Stop the running instance (Ctrl+C in the console) and start again with bin\\start.bat.

Step 4: Privileged Ports on Linux (Below 1024)

On Linux, ports below 1024 (like 80 and 443) are privileged and require root access. Running Mango as root is not recommended for security reasons. Instead, use one of these alternatives:

Option A: iptables Port Forwarding (Recommended)

Forward traffic from port 80 to Mango's default port 8080. This lets Mango run as a non-root user while still being accessible on port 80.

# Forward port 80 to 8080
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

# Forward port 443 to 8443 (if using SSL)
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

Make the rules persistent across reboots:

# On Ubuntu/Debian
sudo apt install iptables-persistent
sudo netfilter-persistent save

# On RHEL/CentOS
sudo service iptables save

With this approach, keep web.port=8080 in mango.properties — the iptables rule handles the port mapping transparently.

Option B: setcap (Linux Capabilities)

Grant the Java binary the capability to bind to privileged ports:

sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which java))
WARNING: This grants the privilege to all Java applications on the system, not just Mango. Use this approach only if Mango is the only Java application on the server.

Option C: Nginx Reverse Proxy

Use Nginx to listen on port 80/443 and proxy traffic to Mango on port 8080. This is covered in detail in the SSL Setup with Nginx Reverse Proxy article.

Step 5: Configure Firewall Rules

After changing the port, update your firewall to allow traffic on the new port.

Linux (UFW):

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

Linux (firewalld):

sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

Windows Firewall:

New-NetFirewallRule -DisplayName "Mango HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow

Step 6: Verify the Change

After restarting Mango, confirm it is listening on the new port:

Linux:

sudo ss -tlnp | grep java

Windows:

netstat -an | findstr LISTENING | findstr :80

Then open your browser and navigate to the new URL (e.g., http://your-server:80 or simply http://your-server for port 80).

Verification

Troubleshooting

"Address already in use" error on startup

"Permission denied" binding to port 80 or 443 on Linux

Mango starts but is not reachable from other machines

Browser shows "connection refused"

Port change works locally but not remotely after reboot

Installing Mango as a Windows Service

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Beginner · 10 min read

Overview

Running Mango as a Windows service ensures it starts automatically when the server boots, restarts after unexpected crashes, and runs in the background without requiring a user to be logged in. This guide covers the built-in service installer for Mango 4, the recommended approach for Mango 5 using NSSM or WinSW, and how to configure service recovery options.

Prerequisites

WARNING: Always verify that Mango starts and runs correctly from the command line (bin\\start.bat) before attempting to install it as a service. This ensures any startup errors are visible in the console before they get buried in service logs.

Step 1: Verify Java Is on the PATH

The Windows service will need to find Java. Open an elevated Command Prompt and run:

java -version

If this command is not recognized, add Java to your system PATH:

  1. Open System Properties > Advanced > Environment Variables
  2. Under System Variables, find Path and click Edit
  3. Add the path to your Java bin directory (e.g., C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.20+8\\bin for Mango 4 or the Java 17 equivalent for Mango 5)
  4. Click OK and restart your Command Prompt

You can also set JAVA_HOME:

setx JAVA_HOME "C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.20+8" /M

Step 2: Install Using the Built-in Script (Mango 4)

Mango 4 ships with a service installation script that uses a bundled service wrapper.

  1. Open Command Prompt as Administrator
  2. Navigate to the Mango directory:
cd C:\\mango
  1. Run the install script:
bin\\install-service.bat
  1. If the script completes without errors, open Services (services.msc):
INFO: To uninstall the service later, run bin\\uninstall-service.bat from an elevated Command Prompt.

Step 3: Install Using NSSM (Mango 4 or 5 — Recommended Alternative)

NSSM (Non-Sucking Service Manager) is a lightweight, open-source tool that can wrap any executable as a Windows service. It provides better logging and recovery features than many built-in wrappers.

Download and Install NSSM

  1. Download NSSM from nssm.cc
  2. Extract the ZIP and copy nssm.exe (from the win64 folder for 64-bit Windows) to a permanent location such as C:\\tools\\nssm.exe
  3. Optionally, add that folder to your system PATH

Create the Service

Open an elevated Command Prompt and run:

nssm install MangoAutomation

This opens the NSSM service configuration dialog. Fill in the following:

Application tab:

Field Value
Path C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.20+8\\bin\\java.exe
Startup directory C:\\mango
Arguments -jar bin/ma.jar
INFO: For Mango 5 with Java 17, adjust the Java path accordingly. Also check if your Mango version uses ma.jar or a different launcher — refer to start.bat for the exact command.

Details tab:

Field Value
Display name Mango Automation
Startup type Automatic (Delayed Start)

I/O tab:

Field Value
Output (stdout) C:\\mango\\logs\\service-stdout.log
Error (stderr) C:\\mango\\logs\\service-stderr.log

Environment tab:

Add any environment variables Mango needs, one per line:

JAVA_HOME=C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.20+8

Click Install service, then start it:

nssm start MangoAutomation

Managing the NSSM Service

nssm status MangoAutomation
nssm stop MangoAutomation
nssm restart MangoAutomation
nssm edit MangoAutomation     # Re-opens the configuration dialog
nssm remove MangoAutomation   # Uninstalls the service

Step 4: Install Using WinSW (Alternative for Mango 5)

WinSW (Windows Service Wrapper) is another option that uses an XML configuration file.

  1. Download WinSW-x64.exe from the WinSW GitHub releases page
  2. Rename it to mango-service.exe and place it in the Mango directory
  3. Create a configuration file named mango-service.xml in the same directory:
<service>
  <id>MangoAutomation</id>
  <name>Mango Automation</name>
  <description>Mango Automation by Radix IoT</description>
  <executable>java</executable>
  <arguments>-Xmx2048m -jar bin/ma.jar</arguments>
  <workingdirectory>C:\\mango</workingdirectory>
  <logpath>C:\\mango\\logs</logpath>
  <log mode="roll-by-size">
    <sizeThreshold>10240</sizeThreshold>
    <keepFiles>5</keepFiles>
  </log>
  <onfailure action="restart" delay="10 sec"/>
  <onfailure action="restart" delay="30 sec"/>
  <onfailure action="none"/>
  <startmode>Automatic</startmode>
</service>
  1. Install and start:
mango-service.exe install
mango-service.exe start

Step 5: Configure Service Recovery Options

Regardless of which method you use, configure Windows to automatically restart the service on failure:

  1. Open Services (services.msc)
  2. Right-click your Mango service and select Properties
  3. Go to the Recovery tab
  4. Set the following:
Failure Action Delay
First failure Restart the Service 1 minute
Second failure Restart the Service 5 minutes
Subsequent failures Restart the Service 10 minutes
  1. Set Reset fail count after to 1 day

Verification

Troubleshooting

Service starts and immediately stops

"Error 1067: The process terminated unexpectedly"

Service runs but Mango UI is not accessible

NSSM service not stopping cleanly

install-service.bat fails with "Access Denied"

Configuring MySQL as the Mango Database

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 15 min read

Overview

Mango ships with H2, an embedded Java database that requires no external setup. H2 works well for small to medium deployments, but as your system grows — more data points, higher sample rates, longer retention periods — you may benefit from switching to MySQL (or MariaDB). MySQL provides better concurrent access, more robust crash recovery, and easier integration with external backup and monitoring tools. This guide walks through the full migration process.

Prerequisites

WARNING: Switching databases does not automatically migrate your existing data. The first time Mango starts with a new MySQL database, it creates the schema from scratch. If you need to preserve historical data, you must export it before switching and import it after. For most deployments, starting fresh with MySQL and letting new data accumulate is the practical choice.

Step 1: Install MySQL

If MySQL is not already installed, install it on your target server.

Ubuntu/Debian:

sudo apt update
sudo apt install -y mysql-server
sudo systemctl start mysql
sudo systemctl enable mysql

Windows:

Download the MySQL Installer from dev.mysql.com and run the setup wizard. Select "Server only" if you do not need the GUI tools.

Verify the installation:

mysql --version

Step 2: Secure the MySQL Installation

Run the security script (Linux):

sudo mysql_secure_installation

Follow the prompts to set a root password, remove anonymous users, disable remote root login, and remove the test database.

Step 3: Create the Mango Database and User

Log in to MySQL as root and create a dedicated database and user for Mango:

sudo mysql -u root -p
CREATE DATABASE mango
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

CREATE USER 'mango'@'localhost' IDENTIFIED BY 'a-strong-password-here';

GRANT ALL PRIVILEGES ON mango.* TO 'mango'@'localhost';

FLUSH PRIVILEGES;

EXIT;
WARNING: Replace a-strong-password-here with a strong, unique password. If MySQL runs on a different host from Mango, replace localhost with the Mango server's IP address or % for any host (less secure).

Character Set and Collation

The utf8mb4 character set is required for full Unicode support. Mango stores point names, descriptions, and event messages that may contain non-ASCII characters. Using utf8mb4_unicode_ci as the collation ensures case-insensitive sorting that handles international characters correctly.

Step 4: Install the MySQL JDBC Connector

Mango needs the MySQL JDBC driver to communicate with the database.

Mango 4:

  1. Download the MySQL Connector/J JAR file from dev.mysql.com/downloads/connector/j/
  2. Select "Platform Independent" and download the ZIP archive
  3. Extract the mysql-connector-j-x.x.x.jar file
  4. Copy it to /lib/ (create the directory if it does not exist)

Mango 5:

Mango 5 may include the MySQL connector in certain builds. Check the lib directory first. If it is not present, follow the same steps as Mango 4.

INFO: Use MySQL Connector/J version 8.x for MySQL 8.0+. Older connector versions (5.x) may not support all MySQL 8.0 features and authentication methods.

Step 5: Configure mango.properties

Stop Mango before making these changes. Edit /overrides/properties/mango.properties:

# Database type
db.type=mysql

# JDBC connection URL
db.url=jdbc:mysql://localhost:3306/mango?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true

# Database credentials
db.username=mango
db.password=a-strong-password-here

# Connection pool size (adjust based on system load)
db.pool.maxActive=50
db.pool.maxIdle=10

JDBC URL Parameters Explained

Parameter Purpose
useSSL=false Disables SSL for local connections (set to true for remote)
serverTimezone=UTC Prevents timezone-related errors on startup
allowPublicKeyRetrieval=true Required for MySQL 8.0 caching_sha2_password auth
INFO: If your MySQL server is on a different machine, replace localhost with the hostname or IP address of the MySQL server.

Step 6: Configure MySQL Server Settings

For optimal performance with Mango, add or modify these settings in your MySQL configuration file (my.cnf on Linux, my.ini on Windows):

[mysqld]
# InnoDB buffer pool — set to 50-70% of available RAM on a dedicated DB server
innodb_buffer_pool_size = 2G

# Transaction log size — larger values improve write performance
innodb_log_file_size = 512M

# Max connections — should exceed Mango's db.pool.maxActive
max_connections = 100

# Packet size — Mango may send large batches of point values
max_allowed_packet = 64M

# Timezone
default-time-zone = '+00:00'

Restart MySQL after making changes:

sudo systemctl restart mysql

Step 7: Start Mango and Verify Schema Creation

Start Mango:

# Linux
sudo systemctl start mango

# Windows
bin\\start.bat

On first startup with MySQL, Mango will automatically create all required tables. Watch ma.log for:

INFO  - Creating database tables...
INFO  - Database tables created successfully
INFO  - Mango started in X seconds

Verify the tables were created:

mysql -u mango -p mango -e "SHOW TABLES;"

You should see tables including dataPoints, dataSources, events, pointValues, users, and others.

Performance Considerations: MySQL vs H2

Factor H2 MySQL
Setup complexity None (embedded) Moderate
Concurrent access Limited Excellent
Crash recovery Basic WAL Full InnoDB recovery
Backup options File copy (Mango stopped) Hot backups with mysqldump or Percona XtraBackup
Point value write throughput Good for < 500 points Better for > 500 points at high sample rates
External tool integration None Grafana, reporting tools, custom queries
Memory usage Shares JVM heap Separate process with own memory
INFO: For most deployments under 500 data points with moderate sample rates, H2 performs well and is simpler to manage. Switch to MySQL when you need external backup tools, high concurrency, or have thousands of data points logging at sub-second intervals.

Verification

Troubleshooting

"Communications link failure" or "Connection refused"

"The server time zone value is unrecognized"

"Access denied for user 'mango'@'localhost'"

"Incorrect string value" errors when inserting data

"Public Key Retrieval is not allowed"

Mango is slow after switching to MySQL

Performance Tuning: Java Heap Memory and Thread Pools

Category: System Administration · Version: Mango 4.x / 5.x · Difficulty: Advanced · 15 min read

Overview

Mango runs on the Java Virtual Machine (JVM), and its performance is heavily influenced by memory allocation, thread pool sizing, and garbage collection behavior. Out of the box, Mango's default settings work well for small to medium systems (up to a few hundred data points). As your deployment grows — thousands of data points, sub-second polling intervals, complex meta points, large dashboards — you will need to tune these parameters to prevent sluggish performance, high CPU usage, or out-of-memory errors.

Prerequisites

Step 1: Understand Mango's Memory Usage

Mango uses heap memory for:

A rough sizing guide:

Deployment Size Data Points Recommended Heap
Small < 500 1–2 GB
Medium 500–2,000 2–4 GB
Large 2,000–10,000 4–8 GB
Very Large > 10,000 8–16 GB
INFO: These are starting points. Actual memory needs depend on polling frequency, point value cache sizes, number of concurrent users, and the complexity of meta data source scripts.

Step 2: Configure JVM Heap Size

The heap size is set in the Mango startup script or options file.

Mango 4 (Windows)

Edit /bin/start.bat or /overrides/start-options.bat and find or add:

set JAVAOPTS=-Xms2g -Xmx4g

Mango 4 and 5 (Linux)

Edit /overrides/start-options.sh (create it if it does not exist):

# Minimum heap size (initial allocation)
JAVAOPTS="$JAVAOPTS -Xms2g"

# Maximum heap size (upper limit)
JAVAOPTS="$JAVAOPTS -Xmx4g"

Mango 5 (mango.properties alternative)

Some Mango 5 builds allow setting JVM options in mango.properties:

# JVM options
jvm.options=-Xms2g -Xmx4g
WARNING: Never set -Xmx higher than the physical RAM available minus what the OS and other applications need. As a rule of thumb, leave at least 2 GB for the operating system. On a server with 8 GB of total RAM, set -Xmx to no more than 6 GB.

Understanding -Xms vs -Xmx

Flag Purpose Recommendation
-Xms Initial heap size at JVM startup Set equal to or half of -Xmx
-Xmx Maximum heap size the JVM can use Size based on your deployment

Setting -Xms equal to -Xmx prevents the JVM from spending time growing the heap at runtime, which can reduce GC pauses. This is recommended for production servers.

Step 3: Configure Thread Pools

Mango uses prioritized thread pools to manage concurrent operations. These are configured in mango.properties:

# High priority — data source polling, point value writes
# Default: processor count + 1
runtime.realTimeTimer.defaultTaskQueueSize=5000
thread.pool.high.coreSize=16
thread.pool.high.maxSize=32

# Medium priority — event processing, report generation
thread.pool.medium.coreSize=8
thread.pool.medium.maxSize=16

# Low priority — background maintenance, data purging
thread.pool.low.coreSize=4
thread.pool.low.maxSize=8

Sizing Guidelines

Pool Used For Core Size Rule of Thumb
High Data source polling, point value ingestion Number of concurrent data sources
Medium Event handlers, reports, meta point execution Half of high priority
Low Purge operations, backups, maintenance tasks 2–4 for most deployments
INFO: The coreSize is the number of threads kept alive even when idle. The maxSize is the upper limit under heavy load. Threads beyond coreSize are created on demand and reclaimed after idle timeout.

When to increase thread pools:

Step 4: Enable the Internal Data Source

Mango includes a built-in data source that exposes JVM and system metrics — essential for performance tuning.

  1. Go to Data Sources and click + to add a new data source
  2. Select Internal Data Source as the type
  3. Set the poll period (every 5–10 seconds is typical for tuning)
  4. Enable the data source and add the following points:
Point What It Tells You
JVM Free Memory Available heap space — if consistently low, increase -Xmx
JVM Used Memory Current heap usage
JVM Max Memory The -Xmx value
Active Thread Count Total active threads — compare against pool max sizes
Active Database Connections If near pool max, increase db.pool.maxActive
High Priority Queue Size Tasks waiting for a high-priority thread
Medium Priority Queue Size Tasks waiting for a medium-priority thread

Create a dashboard or watch list to monitor these points in real time while making tuning adjustments.

Step 5: Garbage Collection Tuning

The JVM's garbage collector (GC) reclaims unused memory. The default collector works for most cases, but large heaps (above 4 GB) can experience long GC pauses that freeze Mango temporarily.

G1 Garbage Collector (Recommended for Heaps > 4 GB)

Add to your startup options:

JAVAOPTS="$JAVAOPTS -XX:+UseG1GC"
JAVAOPTS="$JAVAOPTS -XX:MaxGCPauseMillis=200"
JAVAOPTS="$JAVAOPTS -XX:G1HeapRegionSize=16m"

ZGC (For Very Large Heaps on Java 17+, Mango 5)

If running Mango 5 with Java 17, ZGC provides sub-millisecond GC pauses:

JAVAOPTS="$JAVAOPTS -XX:+UseZGC"
INFO: ZGC is available in Java 11 as experimental but is production-ready in Java 17+. It is ideal for deployments with heaps above 8 GB where low latency is critical.

GC Logging (For Diagnosis)

Enable GC logging to diagnose pause times:

# Java 11+ unified logging
JAVAOPTS="$JAVAOPTS -Xlog:gc*:file=logs/gc.log:time,uptime,level,tags:filecount=5,filesize=50m"

This creates rotating GC log files in the logs directory. Look for "pause" entries — if pauses exceed 500ms frequently, switch to G1GC or ZGC.

Step 6: Identify Bottlenecks with Thread Dumps

If Mango becomes unresponsive, a thread dump reveals what each thread is doing.

Linux:

# Find the Mango Java process ID
jps -l | grep ma.jar

# Take a thread dump
jstack <pid> > /tmp/mango-thread-dump.txt

Windows:

jps -l
jstack <pid> > C:\\temp\\mango-thread-dump.txt

What to look for:

INFO: Take 3–5 thread dumps about 10 seconds apart to see if threads are making progress or stuck. A thread that appears in the same stack trace across multiple dumps is likely the bottleneck.

Step 7: Additional JVM Tuning Options

For advanced deployments, consider these additional settings:

# Enable string deduplication (reduces memory for repeated strings)
JAVAOPTS="$JAVAOPTS -XX:+UseStringDeduplication"

# Set the metaspace size (for deployments with many modules)
JAVAOPTS="$JAVAOPTS -XX:MaxMetaspaceSize=512m"

# Enable JMX monitoring (for external tools like VisualVM)
JAVAOPTS="$JAVAOPTS -Dcom.sun.management.jmxremote"
JAVAOPTS="$JAVAOPTS -Dcom.sun.management.jmxremote.port=9090"
JAVAOPTS="$JAVAOPTS -Dcom.sun.management.jmxremote.authenticate=false"
JAVAOPTS="$JAVAOPTS -Dcom.sun.management.jmxremote.ssl=false"
WARNING: JMX remote access without authentication should only be enabled on trusted networks or via SSH tunneling. Do not expose JMX ports to the internet.

Verification

Troubleshooting

OutOfMemoryError: Java heap space

OutOfMemoryError: Metaspace

Mango pauses periodically for several seconds

Data source polling falls behind

High CPU usage with no corresponding throughput

Mango startup is very slow after increasing heap

Building a Full-Screen Kiosk Dashboard

Category: Dashboards · Version: Mango 4.x / 5.x · Difficulty: Intermediate · 12 min read

Overview

Kiosk dashboards are purpose-built pages displayed on wall-mounted monitors, lobby screens, or dedicated tablets. They run in a browser full-screen mode, hide all navigation and toolbars, log in automatically, and refresh data without user interaction. This guide covers every step from creating a restricted user to deploying a polished, always-on display.

Prerequisites

Step 1: Create a Restricted View-Only User

Never use admin credentials on a public display. Create a dedicated user with minimal permissions.

  1. Navigate to Administration > Users
  2. Click the New User icon
  3. Fill in the user details:
Field Recommended Value
Username kiosk-display
Password A strong random password
Permissions user only
Home URL /ui/dashboard/kiosk-home
Receive Alarm Emails None
Disabled No
Session Expiration Override — set to a long duration (e.g., 30 days)
  1. Under Data Point Permissions, grant read access only to the specific points the dashboard needs
  2. Do not grant any set permissions, edit-ui-pages, edit-ui-menus, or data source permissions
  3. Click Save
WARNING: Never use admin credentials for auto-login. The password is stored and transmitted in plain text. Always use a view-only restricted user.

Step 2: Build the Dashboard Page

Create a clean page designed specifically for full-screen display.

  1. Go to Administration > Edit Pages
  2. Click the + icon to create a new page
  3. Give it a meaningful name like Kiosk Home
  4. In the page markup, build your layout. Use
    for vertical stacking or
    for side-by-side panels:
<div layout="column" layout-fill style="padding: 16px; background: #1a1a2e; color: #ffffff;">
    <div layout="row" layout-align="space-between center">
        <h2 style="margin: 0;">Building Operations Dashboard</h2>
        <ma-now update-interval="1 second" output="updatedTime"></ma-now>
        <span>{{ updatedTime | maMoment:'format':'LTS' }}</span>
    </div>

    <div flex layout="row" layout-wrap>
        <md-card flex="50" style="margin: 8px;">
            <md-card-content>
                <h3>Zone Temperature</h3>
                <ma-get-point-value point-xid="DP_Zone1_Temp"
                    point="zone1Temp"></ma-get-point-value>
                <ma-point-value point="zone1Temp"
                    flash-on-change></ma-point-value>
            </md-card-content>
        </md-card>
    </div>
</div>
  1. Save the page with Ctrl/Cmd + S
TIP: The Mango dashboard designer is markup-based rather than drag-and-drop. The page editor provides a code view where you write HTML markup directly. For advanced customization, switch to code view to access the full markup, add custom CSS, and fine-tune layout attributes that the visual editor may not expose.

Design Tips for Kiosk Displays

Step 3: Create a Menu Item for the Kiosk Page

  1. Go to Administration > Edit Menu
  2. Click the + icon to add a new menu item
  3. Configure the item:
Field Value
Menu Text Kiosk Home
State Name kiosk-home
URL Path /dashboard/kiosk-home
Link Type Custom Page
Page Select your Kiosk Home page
Permissions user
Show Date Bar No
  1. Save the menu
TIP: Set the menu item permission so that only the kiosk user (or users with the user role) can see it. This keeps it out of admin navigation.

Step 4: Set the User Home Page

Configure the kiosk user so it lands directly on the dashboard after login:

  1. Go to Administration > Users
  2. Select the kiosk-display user
  3. Set the Home URL to /ui/dashboard/kiosk-home (matching the URL path from your menu item)
  4. Save the user

Step 5: Configure Auto-Login

Mango supports several auto-login methods. Choose the one that fits your deployment.

Method A: URL Parameters

Append credentials directly to the URL. This is the simplest approach for a single kiosk:

http://your-mango-server:8080/ui/dashboard/kiosk-home?autoLoginUsername=kiosk-display&autoLoginPassword=YourPassword&autoLoginStoreCredentials=true

Setting autoLoginStoreCredentials=true stores the credentials in the browser's local storage so the URL parameters are only needed once. After the first load, the browser remembers the credentials.

Method B: UI Settings (System-Wide Default)

For multiple kiosks using the same account, configure auto-login globally via the JSON store:

  1. Navigate to Administration > JSON Store
  2. Open the UI Settings entry
  3. Add or edit the auto-login fields in the JSON:
{
    "autoLoginUsername": "kiosk-display",
    "autoLoginPassword": "YourPassword"
}
  1. Save the JSON store entry
WARNING: Both methods store passwords in plain text. This is acceptable for a restricted, view-only kiosk user but must never be used with admin or privileged accounts.

Method C: Delete Stored Credentials

If you need to remove auto-login from a device, navigate to:

http://your-mango-server:8080/ui/?autoLoginDeleteCredentials=true

This clears any saved credentials from the browser's local storage.

Step 6: Hide the Navigation and Toolbar with CSS

Create a custom stylesheet that removes all UI chrome from the kiosk view.

  1. Navigate to Administration > UI Settings
  2. In the Miscellaneous section, click the paper clip icon next to User Stylesheet URL
  3. Create a new file called kiosk-styles.css
  4. Add CSS rules to hide the sidebar, toolbar, and other navigation elements:
/* Hide the left sidebar menu */
ma-menu {
    display: none !important;
}

/* Hide the top toolbar */
ma-toolbar {
    display: none !important;
}

/* Expand the main content area to fill the screen */
[ui-view] {
    margin: 0 !important;
    padding: 0 !important;
}

/* Remove scrollbars for a clean display */
body {
    overflow: hidden;
}

/* Force full viewport height */
ma-ui-page-view {
    height: 100vh !important;
}
  1. Save the file and then save the UI Settings page
TIP: If you only want the kiosk styles to apply for the kiosk user (not all users), skip the global stylesheet. Instead, embed a