Live MQTT control
The Live MQTT control is meant for live control. For sending schedules ahead of time, see Scheduled MQTT Control instead.
This guide will help you configure MQTT on your SmartgridOne Controller to remotely control and monitor battery and solar panel installations.
What you need
- SmartgridOne Controller with internet connectivity.
- MQTT credentials: This can be requested by sending an email to support@eniris.be.
- Python development environment (or any other MQTT client). This guide uses a basic example written in Python to get you started with MQTT and sending commands. We recommend to use Python for the ease of use, but any other MQTT client is supported.
Extra information
MQTT is a fast communication protocol over the internet. It is a publish/subscribe message systems, which allows for a direct connection between your machine and the SmartgridOne Controller. Your assets are classified into solar, battery, EV, and HVAC groups.
First-time Configuration (Starting point for new users)
I have a SmartgridOne Controller that I'd like to setup for MQTT Remote Control.
1. Check your network
Ensure that your network allows mqtt network traffic over port 1883. You can do this using command:
nc -zv mqtt.eniris.be 1883
When this command is not available, you can alternatively download and execute this python code.
When in in doubt, consult your network engineer or temporarily use your phone's 4G/5G hotspot when connection errors occur.
When port 1883 is not accessible from your network, we offer a backup at port 80. This can be configured in your MQTT-client at a later step in this manual.
2. Add your devices
Login to the commissioning interface and make sure the devices are added to the SmartgridOne Controller.
3. Add the MQTT external signal




4. Enable MQTT remote signal
The field 'VPP ID' must be left empty.
The fallback mechanism timeout tells the SmartgridOne Controller how long it should wait for new commands. When the SmartgridOne Controller stops receiving commands, it automatically picks up the default strategy after this timeout.
After, select all devices that you'd wish to include in MQTT Remote Control.


5. Remote signal is added
The MQTT Remote Control interface has now been activated on the SmartgridOne Controller.
We are now ready to send some basics commands using a simple example. The Status column tells you if any command is active.

Python demo script
A good first starting point would be to test your newly setup integration with a simple example.
This test code does a simple job of continuously sending the following commands:
- Battery: Charge at 5 kW
- Solar: Set power to 0 kW
The SmartgridOne Controller continuously responds with a 'feedback' message containing the observed grid and asset power values. This feature is also included in this example.
Please download the file below in your preferred Python IDE. Fill in your serial number and MQTT-credentials and execute the script:
When the above is successful, you can continue with sending other type of commands. All commands are described in our MQTT Remote Control Documentation.
MQTT Documentation for Sending Commands
This section details the MQTT messaging format and payload requirements for remotely controlling power policies on devices within the SmartgridOne Controller's network.
MQTT Topic
The MQTT topic used for sending commands is structured as follows:
standard1/rp_one_s/remoteControlMetrics/'controller SN'
Where 'controller SN' should be replaced with the actual serial number of the SmartgridOne Controller you intend to control.
MQTT Payload Structure
Commands are sent as JSON payloads. The payload structure is designed to specify various power management policies and setpoints for different components of the smart grid system. Here is the outline of the payload with detailed field descriptions:
{
"extraTags": {
"nodeId": "<Controller SN>_site_0"
},
"time": "<Unix Timestamp>",
"fields": {
"<Component Policy>": "<Policy Type>",
"<Component Power Setpoint>": <Setpoint in watts>
}
}
Fields description
Multiple device types (e.g. batteries + solar) can be controlled at the same time.
- extraTags (Object):
- nodeId (String): A unique identifier for the node within the SmartgridOne Controller's network. This is equal to your serial number, followed by '_site_0' for most SmartgridOne Controller devices.
- time (Integer): Unix timestamp in seconds indicating the time when the message is sent.
- fields (Object):
- <Component>_policy (String): Policy type for the component. It is optional and if not specified, the system will fallback to the SmartgridOne Controller's default setting.
- <Component>_power_setpoint_w (Float): Desired power setpoint in watts for the component. This is optional and only relevant if a corresponding policy is specified.
Components and Policies
Assets of the same type (e.g. two batteries) will be combined as one component. For example, when two 5 kWh batteries are installed, it will be treated as one 10 kWh battery.
Each component in the fields object can include a policy and a power setpoint. The following components can be controlled:
-
solar_policy and solar_power_setpoint_w:
- Controls the solar power generation policy and setpoint. Supported policies:
- Policy setpoint: Set the maximum power produced by all connected solar installations combined. Field solar_power_setpoint_w should be set to the production power limit in watts.
- Policy feed-in-restriction: Produce at full power, following current grid limits.
- Policy cost: Enables day-ahead price (EPEX Spot market) cost minimization on the solar production. When negative injection prices occur, we curtail production to own consumption. When both the offtake and injection price are negative, we switch off all solar installations. Field solar_power_setpoint_w is ignored.
- Policy off: Disables all interaction for all solar assets. Warning: limits are not being guarded in this mode. Field solar_power_setpoint_w is ignored.
- Controls the solar power generation policy and setpoint. Supported policies:
-
storage_policy and storage_power_setpoint_w:
- Controls the energy storage system policy and power discharge or charge rate.
- Policy setpoint: Set the total charge power (positive setpoint) or discharge power (negative setpoint) for the group of batteries. When multiple batteries are attached, then the setpoint is split up by available charge/discharge power to equally stress the batteries. Field storage_power_setpoint_w is set to the desired battery power.
- Policy cost: Enables day-ahead price (EPEX Spot market) cost optimization on the batteries, by charging it on the cheap hours and using the energy in the expensive hours. Field storage_power_setpoint_w is ignored.
- Policy self-consumption Enables a simple self-consumption algorithm on the batteries. Excess solar production is stored to the battery during, and when the sun is down, energy is taken from the battery. Field storage_power_setpoint_w is ignored.
- Policy off: Disables all interaction for all battery assets. Warning: limits are not being guarded in this mode. Field storage_power_setpoint_w is ignored.
- Controls the energy storage system policy and power discharge or charge rate.
-
heat_pump_policy:
- Toggles on/off heatpump systems. The minimum and maximum on times will always be respected.
- Policy cost: Enables day-ahead price (EPEX Spot market) cost optimization on the heat pumps. The local dynamic pricing algorithm decides the best on-time periods
- Policy self-consumption Turns on the heat pumps if an excess of solar energy is produced.
- Policy power_off: Power off the heat pumps.
- Policy power_on: Power on the heat pumps.
- Toggles on/off heatpump systems. The minimum and maximum on times will always be respected.
-
switched_load_policy:
- Toggles on/off relay-controlled systems. This could be the built-in relay or network-connected relays.
- Policy cost: Enables day-ahead price (EPEX Spot market) cost optimization on the relay.
- Policy self-consumption Turns on the relay if an excess of solar energy is produced.
- Policy power_off
- Policy power_on
- Toggles on/off relay-controlled systems. This could be the built-in relay or network-connected relays.
-
variable_power_load_policy and variable_power_load_power_setpoint_w:
- Manages the electric vehicle power consumption policy and setpoint.
- Policy setpoint: Set the total charge power for the group of EVs. Field variable_power_load_power_setpoint_w is set to the desired charge power.
- Policy cost: Enables day-ahead price (EPEX Spot market) cost optimization on the batteries, by charging it on the cheap hours. Field variable_power_load_power_setpoint_w is ignored.
- Policy self-consumption Enables charging if an excess of solar energy is produced. Field variable_power_load_power_setpoint_w is ignored.
- Policy off: Disables all interaction for all EV assets. Field variable_power_load_power_setpoint_w is ignored.
- Manages the electric vehicle power consumption policy and setpoint.
-
site_policy and site_power_setpoint_w:
- Manages the site export limits.
- Policy export: Set the export limit for the site. Field site_power_setpoint_w is set to the export limit.
- Policy default: Reverts the site limit to the default export power, set in the controller configuration.
- Manages the site export limits.
Device Control
Specific devices can also be controlled, instead of groups of devices based on their types. The message is identically structured:
nodeId
_policy andnodeId
_power_setpoint_w
When two commands are sent to the same asset (e.g. one device-specific command to a solar inverter, and a command to all solar devices), the device-specific control method will take preference over the device type control.
Fallback behaviour
For each component, if the _policy and _power_setpoint_w is not specified, the system will automatically use the fallback policy configured in the SmartgridOne Controller. This ensures that each device or device group operates safely and continues to function even if specific instructions are not provided.
If no command is being send at all, after 60 seconds (or configured timeout period), the default policies for assets will be reactivated.
Example payload
Below is an example of a payload to set various policies and setpoints:
{
"extraTags": {
"nodeId": "OM12404080000000000_site_0"
},
"time": 1714652046,
"fields": {
"solar_policy": "setpoint",
"solar_power_setpoint_w": 5000,
"storage_policy": "setpoint",
"storage_power_setpoint_w": -5000
}
}
In this example, the solar power is set to generate up to 5000 watts, and the energy storage system is set to either charge or discharge at a rate of 5000 watts, depending on the sign of the setpoint value. If either the solar_policy or storage_policy were omitted, the respective device would revert to the default settings determined by the SmartgridOne Controller.
MQTT Documentation for Receiving feedback
This section outlines the structure and content of the feedback messages sent by the SmartgridOne Controller via MQTT. These messages are published to the topic standard1/outbound/remoteControlMetrics/feedback/<Controller SN>
after a command has been processed.
MQTT Feedback Topic
The feedback MQTT topic is structured as follows:
standard1/outbound/remoteControlMetrics/feedback/<Controller SN>
Where <Controller SN>
should be replaced with the serial number of the SmartgridOne Controller that is sending the feedback.
MQTT Feedback Payload Structure
All assets are grouped by their type. This means that two individual solar installations of 3 kW will be treated as one 6 kW asset.
Feedback messages are formatted as JSON payloads. These payloads provide detailed feedback on the state of the system after applying the setpoint commands, considering grid/device limits. Below is the structure of the feedback payload with descriptions of its fields:
{
"time": "<Unix Timestamp>",
"data": {
"state": {
"grid": {
"active_power_W": <Grid Active Power in Watts>,
"today_imported_energy_Wh": <Grid Imported Energy in Watt-hours>,
"today_exported_energy_Wh": <Grid Exported Energy in Watt-hours>,
"import_limit_W": <Grid Import Limit in Watts>,
"export_limit_W": <Grid Export Limit in Watts>,
},
"vpp_id": "<Virtual Power Plant Identifier>",
"storage": {
"energy_stored_Wh": <Energy Stored in Watt-hours>,
"energy_capacity_Wh": <Total Energy Capacity in Watt-hours>,
"mean_soc_perc": <Mean State of Charge Percentage>,
"active_power_W": <Active Power in Watts>,
"executed_power_W": <Power Setpoint Sent to Devices in Watts>,
"executed_policy": <Policy Executed by the Controller>,
"max_charge_power_W": <Maximum Charge Power in Watts>,
"max_discharge_power_W": <Maximum Discharge Power in Watts>,
"today_charged_Wh": <Energy Charged on the Current Today in Watt-hours>,
"today_discharged_Wh": <Energy Discharged on the Current Today in Watt-hours>,
"nr_devices": <Number of Controlled Storage Devices Installed>
},
"solar": {
"active_power_W": <Solar Active Power in Watts>,
"executed_power_W": <Power Setpoint Sent to Devices in Watts>,
"executed_policy": <Policy Executed by the Controller>,
"capacity_W": <Solar Capacity in Watts>,
"today_energy_Wh": <Energy Produced Today in Watt-hours>.
"nr_devices": <Number of Controlled Solar Devices Installed>
},
"heat_pump": {
"executed_policy": <Policy Executed by the Controller>,
"operation_modes": <Heatpump Operation Modes>,
"executed_power_W": <Power Setpoint Sent to Devices in Watts>,
"nr_devices": <Number of Controlled Heat Pump Devices Installed>
},
"switched_load": {
"executed_policy": <Policy Executed by the Controller>,
"devices_on": <Number of Devices On>,
"devices_off": <Number of Devices Off>,
"executed_power_W": <Power Setpoint Sent to Devices in Watts>,
"nr_devices": <Number of Controlled Switched Load Devices Installed>
}
},
"response_code": <Response Code>
},
"fields": {},
"requestTime": "<Unix Timestamp>",
"time": "<Unix Timestamp>",
"siteNodeId": "<Controller SN>_site_0"
}
Fields description
- time (Integer): Unix timestamp indicating the time when the feedback message was sent.
- fields (Object):
- state (Object):
- vpp_id (String): Identifier for the Virtual Power Plant associated with this device.
- grid (Object):
- active_power_W (Float): Represents the current active power on the grid in watts.
- today_imported_energy_Wh (Float): The total energy taken from the grid today in watt hours. Note: Today is given in UTC time.
- today_exported_energy_Wh (Float): The total energy injected back into the grid today in watt hours. Note: Today is given in UTC time.
- import_limit_W (Float): The grid import limit in watts,
- export_limit_W (Float): The grid export limit in watts,
- storage (Object):
- energy_stored_Wh (Float): Current amount of energy stored in watt-hours.
- energy_capacity_Wh (Float): Total energy capacity of the storage system in watt-hours.
- mean_soc_perc (Float): State of charge as a percentage. This is the weighted average among all connected batteries. (when multiple batteries are connected: e.g. battery 'a' has an energy capacity of 10 kWh and a state of charge 20%; battery 'b' has an energy capacity of 20 kWh and state of charge of 50%, then the mean_soc_perc is 40%)
- active_power_W (Float): Current active power for the storage system in watts, showing charge or discharge rate.
- max_charge_power_W (Float): Maximum power at which the storage can be charged.
- max_discharge_power_W (Float): Maximum power at which the storage can be discharged.
- executed_power_W (Float): The sum of total power requested to (dis)charged from the storage assets, being send out by our control algorithm. Only applicable if 'follow_setpoint'-policy is active.
- executed_policy (Str): The policies that have been applied to the controllables.
- today_charged_Wh (Float): The total energy charged in to the controllable battery asset(s) today. Note: Today is given in UTC time.
- today_charged_Wh (Float): The total energy charged into the controllable battery asset(s) today. Note: Today is given in UTC time.
- today_discharged_Wh (Float): The total energy discharged from the controllable battery asset(s) today. Note: Today is given in UTC time.
- nr_devices (Int): The number of controllable battery assets.
- solar (Object):
- active_power_W (Float): Current active power generated by solar panels in watts.
- capacity_W (Float): Total capacity of the solar generation system in watts.
- executed_power_W (Float): The sum of total power requested from the solar assets, being send out by our control algorithm. Only applicable if 'follow_setpoint'-policy is active.
- executed_policy (Str): The policies that have been applied to the controllables.
- today_energy_Wh (Float): The total energy produced from the controllable solar asset(s) today. Note: Today is given in UTC time.
- nr_devices (Int): The number of controllable solar assets.
- heat_pump (Object):
- executed_policy (Str): The policies that have been applied to the controllables.
- operation_modes (Str): The mode of the heatpump (Blocking mode, Boosting mode, Self control mode)
- executed_power_W (Float): The expected power that it's currently using.
- nr_devices (Int): The number of controllable heatpumps.
- switched_load (Object):
- executed_policy (Str): The policies that have been applied to the controllables.
- devices_on (Int): The number of devices on.
- devices_off (Int): The number of devices off.
- executed_power_W (Float): The power that it's currently using (if available).
- nr_devices (Int): The number of controllable on/off switched loads.
- nodeId (Object):
- If a nodeId is included in the command, the feedback will contain the corresponding state of the device.
- response_code (Int):
- Indicates the status of the operation. A response_code of 0 typically means success, while other values may indicate different types of errors or status information (these should be detailed in a separate reference).
- state (Object):
Example Feedback Payload
Here is an example of a feedback message following a command to set various power setpoints:

This feedback demonstrates the system's current operational state following the execution of the setpoints, indicating the effects on solar generation, storage, and overall grid interaction.
Supported MQTT Versions and Behavior on Unauthorized Topics
When using MQTT, it is important to consider the differences in specifications between versions 3.1, 3.1.1, and 5.0, particularly regarding the broker’s behavior when clients publish to unauthorized topics.
According to the MQTT 3.1.1 specification (see OASIS MQTT 3.1.1 Specification, section MQTT-3.3.5-2), a broker must terminate the connection as soon as a client sends a PUBLISH to a topic for which it does not have permission. This behavior can lead to unexpected disconnections for clients attempting to publish to misconfigured or unauthorized topics.
In MQTT 3.1, this requirement is not present. When a client publishes to an unauthorized topic under this version, the broker typically ignores the message (silent drop) without terminating the connection. This makes MQTT 3.1 in some cases more suitable when robustness against configuration errors or temporarily missing permissions is more important than strict security enforcement.
Although MQTT 5.0 introduces the ability to work with reason codes (such as PUBACK with a refusal reason), this requires support on both the client and server sides. Migrating to MQTT 5.0 therefore involves additional implementation effort.
Consequences of Ignoring Compatibility: If a client connects using MQTT 3.1.1 and attempts to publish messages to unauthorized topics, the broker will abruptly terminate the session. This may lead to instability, loss of connectivity, or increased load due to repeated reconnect attempts.
Recommended Approach: For systems where clients may (temporarily) attempt to publish to unauthorized topics, or where error handling is not strictly implemented, we recommend using MQTT 3.1. This ensures more stable connections and avoids unintended disconnects during runtime.