MiroxQL Query Language
MiroxQL (Mirox Query Language) is the canonical way to define custom calculated metrics on the Mirox platform. You write a short formula that combines your existing export metrics into a new metric, and it becomes available everywhere export metrics are used — programmatic access to your data runs through MiroxQL and the Export Metric API, not through any separate raw-data integration.
Overview
MiroxQL is a simple expression language for defining custom calculated metrics based on existing metrics. It lets you create tailored performance indicators, combine multiple data sources, and implement custom business logic without writing code.
What is MiroxQL?
MiroxQL allows you to transform and combine existing export metrics into new calculated metrics. All calculations are performed server-side, ensuring consistency and eliminating the need for post-processing.
MiroxQL Is a Brand for the Metric-Formula Feature
"MiroxQL" is the presentation name for the custom metric-formula capability. There is no endpoint literally called MiroxQL — your formulas are created and managed through the metric-formula API at /v1/export/metric/formula and become available wherever export metrics are used.
Open in Mirox: create and manage your formulas in the formula editor under Data Export ▸ Metrics. On the Data Export page, open the Metrics tab to add a custom metric and write its MiroxQL formula.
Key Concepts
Metric References
All metric references in MiroxQL must be prefixed with the @ symbol:
@energy_grid_daily
@gti_sensor_daily
@availability_technical
The metric IDs must correspond to valid export metrics available in the system. See Available Export Metrics for the complete list.
Configuration References
Park configuration values can be referenced using the $ prefix with dot notation:
$park.peak_production_w
$park.latitude
$park.information.inverter_max_power_w
This allows formulas to use configured values like installed capacity, location, and plant build details. The available configuration fields are:
| Reference | Description | Unit |
|---|---|---|
$park.peak_production_w | Total peak production capacity | W |
$park.latitude | Geographic latitude | ° |
$park.longitude | Geographic longitude | ° |
$park.self_consumption | Self-consumption factor (0.0 to 1.0) | ratio |
$park.information.string_peak_power_w | Total peak power from all strings | W |
$park.information.inverter_max_power_w | Maximum inverter power capacity | W |
$park.information.inverter_total | Number of inverters | — |
$park.information.gak_total | Number of generator connection boxes (GAKs) | — |
$park.information.strings_total | Number of strings | — |
$park.information.modules_total | Number of solar modules | — |
These are the same fields advertised by the formula editor's configuration-field list, so you can confirm the current set directly in the app.
Data Types
MiroxQL works with numeric values:
- Integers:
1000,42,365 - Decimals:
0.85,3.14,99.5 - Results: All calculations return floating-point numbers
Supported Operations
Arithmetic Operations
| Operator | Description | Example | Result |
|---|---|---|---|
+ | Addition | @energy_grid_daily + @energy_shutdown_grid_daily | Sum of values |
- | Subtraction | @production_actual - @energy_grid_daily | Difference |
* | Multiplication | @specific_yield * 1000 | Scaled value |
/ | Division | @energy_grid_daily / $park.peak_production_w | Ratio |
% | Modulo | @value % 100 | Remainder |
Division by Zero: Automatically returns 0 instead of raising an error.
Comparison Operations
| Operator | Description | Example | Result |
|---|---|---|---|
== | Equal to | @gti_weather_daily == 0 | Boolean (1 or 0) |
!= | Not equal to | @gti_sensor_daily != 0 | Boolean |
< | Less than | @availability_technical < 95 | Boolean |
<= | Less than or equal | @temperature <= 25 | Boolean |
> | Greater than | @gti_sensor_daily > 0 | Boolean |
>= | Greater than or equal | @pr_actual >= @pr_target | Boolean |
Logical Operations
| Operator | Description | Example | Result |
|---|---|---|---|
&& | Logical AND | @gti_sensor_daily > 0 && @energy_grid_daily > 0 | Both must be true |
|| | Logical OR | @gti_sensor_daily == 0 || @gti_weather_daily == 0 | At least one true |
! | Logical NOT | !(@availability_technical < 95) | Inverts boolean |
Conditional Expressions
The ternary operator allows conditional logic:
condition ? value_if_true : value_if_false
Example: Use sensor data if available, otherwise use weather data
@gti_sensor_daily > 0 ? @gti_sensor_daily : @gti_weather_daily
Functions
| Function | Description | Example | Result |
|---|---|---|---|
max(a, b) | Returns maximum of two values | max(@energy_grid_daily, 0) | Larger value |
min(a, b) | Returns minimum of two values | min(@availability, 100) | Smaller value |
Operator Precedence
Operations are evaluated in the following order (highest to lowest):
- Parentheses
() - Functions
max(),min() - Multiplication, Division, Modulo
*,/,% - Addition, Subtraction
+,- - Comparison
<,<=,>,>= - Equality
==,!= - Logical AND
&& - Logical OR
||
Use parentheses to override precedence: (@a + @b) * @c
Creating Custom Metrics
MiroxQL formulas can be used to create custom metrics that are calculated on-demand and made available for export alongside the standard metrics. Each custom metric requires several configuration parameters:
Metric Configuration
Metric ID (metric_id):
- Unique identifier for the metric
- Must start with a letter or underscore
- Can contain letters, numbers, and underscores
- Example:
pr_weather_corrected,specific_yield_normalized
Name (name):
- Human-readable display name
- Used in exports and reports
- Example: "Performance Ratio (Weather-Corrected)"
Description (description):
- Optional explanation of what the metric calculates
- Helps other users understand the metric's purpose
Unit (unit):
- Unit of measurement for the metric
- Example:
kWh,%,Wh/W,kWh/m²
Formula (formula):
- The MiroxQL expression that calculates the metric value
- Must reference at least one existing metric with
@prefix - Example:
(@energy_grid_daily + @energy_shutdown_grid_daily) / @energy_report * 100
Scale and Digits Parameters
Raw Units and Scale Factors
Always calculate formulas in raw units (not converted to kilo, mega, etc.) and use the scale parameter to convert during export. This is crucial when formulas have dependencies on other formula results.
Example: Calculate energy in Wh (raw), then set scale=0.001 to export as kWh.
Formula: @energy_grid_daily + @energy_shutdown_grid_daily
Unit: kWh
Scale: 0.001 # Divides result by 1000 during export
The scale factor is applied only during data export, not during formula calculation. This ensures that dependent formulas receive unscaled values and can perform accurate calculations.
Scale (scale):
- Scaling factor applied to the result during export
- Default:
1.0(no scaling) - Common values:
0.001- Convert Wh to kWh0.000001- Convert Wh to MWh100- Convert ratio to percentage
- Applied formula:
exported_value = calculated_value * scale
Digits (digits):
- Number of decimal places for rounding in exports
- Range: 0-10, default: 2
- Applied only during export, not during calculation
Rounding During Export Only
The digits parameter controls rounding for data export only, not for formula calculations. Internal calculations always use full precision to avoid cumulative rounding errors.
Example: A formula calculating @energy_grid_daily / $park.peak_production_w might produce 0.003456789. With digits=4, it exports as 0.0035, but other formulas referencing this metric still use the full precision value 0.003456789.
Calculation Periods and Aggregation Methods
The system supports two aggregation methods for custom metrics, which can be configured during API export.
Daily Aggregation (Default):
The formula runs once per day using daily metric values. Daily results are then summed or averaged for the export period. This is ideal for energy sums and daily performance calculations.
Example - Energy sum formula:
Formula: @energy_grid_daily + @energy_shutdown_grid_daily
For a monthly export:
- Day 1:
1000 + 50 = 1050kWh - Day 2:
1100 + 45 = 1145kWh - ... (continues for all days)
- Monthly total: Sum of all daily results =
1050 + 1145 + ...
Period Aggregation:
Base metrics are aggregated to the period first (weekly/monthly totals), then the formula runs once on these aggregated values. This is ideal for performance ratios and efficiency calculations over periods.
Example - Performance ratio formula:
Formula: @energy_grid_daily / @energy_report * 100
For a monthly export:
- Monthly grid energy: Sum of all daily
@energy_grid_dailyvalues - Monthly target energy: Sum of all daily
@energy_reportvalues - Monthly PR:
monthly_grid_energy / monthly_target_energy * 100
Choosing Aggregation Method
Use daily aggregation to calculate daily and sum/average the results (e.g., energy sums). Use period aggregation to calculate based on period totals (e.g., monthly performance ratios). The aggregation method is specified during API export configuration.
Custom Metric Example
Complete example of a custom metric definition:
{
"metric_id": "energy_total_incl_losses",
"name": "Total Energy Including Losses",
"description": "Sum of grid energy and all shutdown losses",
"unit": "kWh",
"scale": 0.001,
"digits": 2,
"formula": "@energy_grid_daily + @energy_shutdown_grid_daily + @energy_shutdown_external_daily"
}
This creates a metric that:
- Calculates in Wh (raw unit)
- Exports in kWh (scaled by 0.001)
- Rounds to 2 decimal places in exports
- Maintains full precision for dependent formulas
Formula Examples
Basic Calculations
Total Energy Including Losses
@energy_grid_daily + @energy_shutdown_grid_daily + @energy_shutdown_external_daily
Specific Yield (Wh per Watt installed)
@energy_grid_daily / $park.peak_production_w
Performance Ratio (Actual vs. Target)
(@energy_grid_daily / @energy_target) * 100
Conditional Logic
Validated Irradiance (Prefer Sensor, Fallback to Weather)
@gti_sensor_daily > 0 ? @gti_sensor_daily : @gti_weather_daily
Weather Data Usage Indicator
@gti_sensor_daily > 0 ? 0 : 100
Capped Availability (Never Exceed 100%)
min(@availability_calculated, 100)
Complex Validation
Validated Sensor Data (With Quality Check)
@gti_sensor_daily > 0 && (@gti_weather_daily == 0 || (@gti_sensor_daily / @gti_weather_daily) >= 0.2) ? @gti_sensor_daily : @gti_weather_daily
This formula:
- Checks if sensor data exists (
@gti_sensor_daily > 0) - Validates sensor is reasonable compared to weather (at least 20% of weather value)
- Uses sensor if valid, otherwise uses weather data
Production Targets
Theoretical Production from Weather
(@gti_weather_daily / 1000) * $park.peak_production_w * 0.85
This calculates expected production based on:
- Weather irradiance (converted from Wh/m² to kWh/m²)
- Installed capacity
- Assumed system efficiency (0.85 or 85%)
Production with Loss Adjustment
max(@energy_grid_daily - @losses_noncompensable, 0)
Ensures result is never negative using max().
Performance Ratios
Performance Ratio (Corrected for Losses)
(@energy_grid_daily + @energy_shutdown_grid_daily + @energy_shutdown_external_daily) / @energy_target * 100
Report Performance Index
(@pr_actual_corrected / @pr_report) * 100
Loss Analysis
Total Compensable Losses
@energy_shutdown_grid_daily + @energy_shutdown_external_daily
Loss Percentage
(@energy_shutdown_grid_daily + @energy_shutdown_external_daily) / (@energy_grid_daily + @energy_shutdown_grid_daily + @energy_shutdown_external_daily) * 100
Non-Compensable Losses
max(@energy_target - @energy_grid_daily - @energy_shutdown_grid_daily - @energy_shutdown_external_daily, 0)
Best Practices
Formula Design
- Keep Formulas Simple: Break complex calculations into multiple metrics
- Use Meaningful Names: Name calculated metrics clearly (
pr_weather_based, notcalc1) - Document Assumptions: Note efficiency factors, conversions, or special logic
- Handle Edge Cases: Use conditional logic to avoid division by zero or negative values
- Validate Results: Test formulas with known data before deployment
Metric Dependencies
When using calculated metrics in other formulas:
- Avoid Circular Dependencies: Metric A cannot depend on Metric B if B depends on A
- Build Hierarchically: Base metrics → intermediate calculations → final metrics
- Reuse Components: Create reusable intermediate metrics for common calculations
Unit Conversions
Be mindful of units when combining metrics:
# Convert kWh/m² to Wh/m² by multiplying by 1000
(@gti_sensor_daily * 1000)
# Convert Wh to kWh by dividing by 1000
(@production_wh / 1000)
# Normalize energy by installed capacity (Wh per Watt)
@energy_grid_daily / $park.peak_production_w
Null/Missing Data
MiroxQL treats missing data as 0. To handle missing data explicitly:
# Check if data exists before using it
@metric > 0 ? @metric : @fallback_metric
# Indicate when data is missing
@metric > 0 ? 1 : 0
Formula Validation
Syntax Requirements
Valid formulas must:
- Reference at least one metric (with
@prefix) or config value (with$prefix) - Have balanced parentheses
- Not have consecutive operators (except with
!) - Use valid operator syntax
Common Errors
| Error | Cause | Solution |
|---|---|---|
Missing @ prefix | energy_grid_daily + 100 | Add prefix: @energy_grid_daily + 100 |
| Unbalanced parentheses | (@a + @b | Close parentheses: (@a + @b) |
| Invalid metric ID | @nonexistent_metric | Use valid metric ID |
| Consecutive operators | @a + * @b | Remove extra operator: @a * @b |
| Missing config value | $park.missing_value | Ensure config exists |
Integration with Export Templates
Calculated metrics using MiroxQL can be included in export templates:
- Define the Formula: Create a custom metric with a MiroxQL formula
- Add to Template: Include the metric ID in an export template
- Export Data: The metric is calculated on-demand during export
For template management, see Export Metric API - Template System.
Use Cases
Performance Monitoring
Create KPIs tailored to your specific needs:
- Custom performance ratios
- Adjusted availability metrics
- Loss categorization
Contractual Compliance
Implement contract-specific calculations:
- Performance guarantees with exclusions
- Compensable vs. non-compensable losses
- Adjusted production targets
Portfolio Analysis
Aggregate and normalize across parks:
- Normalized specific yield
- Weather-adjusted comparisons
- Efficiency benchmarking
Operational Intelligence
Derive actionable insights:
- Data quality indicators
- System health scores
- Anomaly detection flags
Limitations
Performance Considerations
- Formulas are evaluated for each time period in the export
- Very complex formulas may impact export performance
- Recursive dependencies increase calculation time
Calculation Scope
- Formulas operate on daily aggregated values
- Cannot access sub-daily granularity
- Cannot perform lookback or rolling window calculations
- Cannot access historical data beyond the current row
Data Availability
- Calculated metrics require all dependent metrics to be available
- Missing base metrics result in incomplete calculated metrics
- Config values must be set in park configuration
Related Documentation
- Export Metric API - Export metrics and templates
- Reports - Using calculated metrics in reports
- External Report Generation - Automated workflows
- Metric Collection Architecture - Understanding raw metrics