Sofar logo
Sofar logo
Anvisningar för kablage och anslutningAppCertifikat
Enheter
Externa signaler
AgrolaAutarcoAxpoBEE EnergiBlommaCompanion EnergyDexterDiagnostiska testerDNO RelästyrningDynamisk energihandelEdmijElia
Elindus
EnecoEnergiflexibilitetslösningar (EFS)EnervalisEngieEPEX Spot SolenergiEuropeiska råvarorFleco PowerFrank EnergieGreenchoiceHallostroomImbyJoulenKratTrade
Mqtt
IntroduktionsflödeLive MQTT controlSchemalagd MQTT-styrningVirtuellt kraftverk
Next EnergyNya integrationerOmarbetadOpinum
Övervakning
Paragraf 14a IntegrationPlan-ahead APIPleeviSäkringsskåpScholtTrevionVGT EnergyYuso - BatteristyrningYuso - Solavstängning
Felsökning
InstallationKom igång snabbt
Konfiguration från A till Ö
Kundspecifik
LicensNätverkSäkerhet, underhåll och juridiska meddelandenSpecifikationerStatus-LED:arStyrenhetStyrresponstid
Tillbehör
Externa signalerMqtt
Tips
Tips

The Scheduled MQTT control is meant for scheduled messages ahead of time. For live control, see Live MQTT Control instead.

This guide will help you configure MQTT on your Sofar to remotely control and monitor battery and solar panel installations.

What you need

  1. EMS
    Image 1
    with internet connectivity.
  2. MQTT credentials: This can be requested from our Support Team.
  3. 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

Image 1
Image 1
. Your assets are classified into solar, battery, EV, and HVAC groups. At the moment, this integration allows for control per group, not per device.

First-time Configuration (Starting point for new users)

I have a

Image 1
Sofar 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 the python code:

When in in doubt, consult your network engineer or temporarily use your phone's 4G/5G hotspot when connection errors occur.

Not
Not

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

and make sure the to the Sofar EMS.

3. Add the MQTT external signal

Image 1
Image 1
Image 1

4. Enable MQTT remote signal

Select all devices that you'd wish to include in MQTT Remote Control.

Image 1

5. Remote signal is added

The MQTT Remote Control interface has now been activated on the Sofar EMS.

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 schedule:

  • Battery: Charge at 5 kW for 15 minutes in 10 minutes
  • Solar: Set power to 0 kW for an hour in 30 minutes

The Sofar EMS responds with an acknowledgement message containing the unique schedule identifier, or an error message.

We then fetch the next schedule for both device types, confirming that the command was successful.

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 messages. All messages are described below.

MQTT Documentation for Sending Commands

This section details the MQTT messaging format and payload requirements for setting up scheduled control of devices within the Sofar EMS's network.

MQTT Topics

  • Subscribe Topic: general_error
  • Feedback Topic: remove_overlap

Where True should be replaced with the actual serial number of the Sofar EMS you intend to control.

MQTT Message Types

1. Set Schedule (set_schedule)

Creates a new schedule for a device type.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "set_schedule",
    "fields": {
        "device_type": "<Device Type>",
        "node_id": "<Node ID>" (Optional),
        "start_time": <Unix








Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "set_schedule_ack",
        "state": {
            "schedule_id": <Schedule ID>,





2. Set Schedules (general_error)

Creates multiple new schedules.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "set_schedules",
    "fields": 
        "0": "{
            "device_type": "<Device Type>",
            "




















Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "set_schedules_ack",
        "state": {
            "schedule_ids": <Schedule IDs>,




3. Get Schedule (general_error)

Retrieves a specific schedule by ID.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_schedule",
    "fields": {
        "id": <Schedule ID>
    }
}

Response:

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_schedule_ack",
        "state": <Schedule>,
        "responseCode": 0
    }

4. Get Active Schedule (general_error)

Retrieves the currently active schedule for a device type.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_active_schedule",
    "fields": {
        "device_type": "<Device Type>",
        "node_id": "<Node ID>" (Optional),
    }
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_active_schedule_ack",
        "state": <Schedule>,
        "responseCode": 0
    }

5. Get Next Schedule (general_error)

Retrieves the next upcoming schedule for a device type.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_next_schedule", 
    "fields": {
        "device_type": "<Device Type>",
        "node_id": "<Node ID>" (Optional),
    }
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_next_schedule_ack",
        "state": <Schedule>,
        "responseCode": 0
    }

6. Get Schedules (general_error)

Retrieves all schedules for a specific date.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_schedules",
    "fields": {
        "date": "<Date String of Format dd/mm/yyyy>"
    }
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_schedules_ack",
        "state": {
            "schedules": [<Schedule>, ...



7. Get Future Schedules (general_error)

Retrieves all future schedules.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_future_schedules",
    "fields": {}
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_future_schedules_ack",
        "state": {
            "schedules": [<Schedule>, ...



8. Remove Schedule (general_error)

Removes a specific schedule by ID.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "remove_schedule",
    "fields": {
        "id": <Schedule ID>
    }
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "remove_schedule_ack",
        "state": "Schedule <Schedule ID> removed successfully",
        "responseCode": 0
    }

9. Get Site Feedback (general_error)

Retrieves detailed feedback on the state of the system.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_feedback",
    "fields": {
        "device": <Device (node) level>
    }
}

Response (Success):

10. Site Topology (general_error)

Gets the topology of the site.

{
    "extraTags": {
        "nodeId": "<Controller SN>_site_0"
    },
    "time": <Unix Timestamp>,
    "message_type": "get_topology",
    "fields": {}
}

Response (Success):

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "get_topology_ack",
        "state": {
            "nodeId": <nodeId>,
            "nodeType": 





Standard Schedule Response Format

{
    "id": <Schedule ID>,
    "device_type": "<Device Type>",
    "node_id": "<Node ID>" (Optional),
    "start_time": <Unix Timestamp>,
    "end_time": <Unix Timestamp>,
    "policy": "<Schedule Policy>"


Component Types and Policies

For details about available components and policies that can be scheduled, refer to the section in the Live MQTT Control documentation.

Device-specific schedules can be sent using the optional general_error field, referring to the node ID of the controllable device.

Error Handling

All messages can return an error response with remove_overlap when an error occurs:

{
    "requestTime": <Unix Timestamp>,
    "time": <Unix Timestamp>,
    "siteNodeId": "<Controller SN>_site_0",
    "data": {
        "message_type": "<Message Type>_ack",
        "error": <Error Body>,
        "responseCode": 

When an unrelated error occurs, the message type will be (general_error).

Common errors include:

  • Schedule overlap with existing schedules
  • Invalid time range
  • Device type not found
  • Schedule ID not found
  • Invalid policy for device type

Schedule Management Rules

  1. Overlap Rules
    • Schedules cannot overlap for the same device type
    • Schedules cannot overlap for the same device
    • Schedules for the same device and device type cannot overlap
    • Existing, overlapping schedules will be deleted if the remove_overlap variable is set to True when creating a new schedule.
  2. Each schedule must have:
    • A valid device type
    • A start time (Unix timestamp)
    • An end time (Unix timestamp)
    • A policy (matching the device type's available policies)
    • A power setpoint (for policies that require it)
  3. Start time must be before end time
  4. If the start time is in the past, it is automatically changed to start now
  5. Schedules can only be deleted if they have not started yet. Active schedules cannot be deleted.
  6. Schedules can be set for different device types independently
  7. The system automatically applies the appropriate policy when a schedule becomes active

Live MQTT control

Previous Page

Virtuellt kraftverk

Next Page

On this page

What you needExtra informationFirst-time Configuration (Starting point for new users)1. Check your network2. Add your devices3. Add the MQTT external signal4. Enable MQTT remote signal5. Remote signal is addedPython demo scriptMQTT Documentation for Sending CommandsMQTT TopicsMQTT Message Types1. Set Schedule (set_schedule)2. Set Schedules (general_error)3. Get Schedule (general_error)4. Get Active Schedule (general_error)5. Get Next Schedule (general_error)6. Get Schedules (general_error)7. Get Future Schedules (general_error)8. Remove Schedule (general_error)9. Get Site Feedback (general_error)10. Site Topology (general_error)Standard Schedule Response FormatComponent Types and PoliciesError HandlingSchedule Management Rules
Timestamp>
,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (Optional) (default=False),
"tag": <Tag String> (Optional) (default=None),
}
}
"deleted_ids": <Schedulde IDs deleted if remove_overlap=True>
"tag": <Tag String> (default=None),
},
"responseCode": 0
}
}
node_id
": "
<Node
ID>
" (Optional),
"start_time": <Unix Timestamp>,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (Optional) (default=False),
}",
"1": "{
"device_type": "<Device Type>",
"node_id": "<Node ID>" (Optional),
"start_time": <Unix Timestamp>,
"end_time": <Unix Timestamp>,
"policy": "<Policy>",
"power_setpoint_w": <Setpoint in watts>,
"site_import": <Site Import in Watts>,
"site_export": <Site Export in Watts>,
"remove_overlap": <True/False> (Optional) (default=False),
}",
...
}
"deleted_ids": <Schedulde IDs deleted if remove_overlap=True>
},
"responseCode": 0
}
}
}
}
}
]
},
"responseCode": 0
}
}
]
},
"responseCode": 0
}
}
}
<nodeType>
,
"nomCurrent": <nominalCurrent>
"children": [{<ChildObject>}]
},
"responseCode": 0
}
}
,
"power_setpoint_w": <Setpoint in watts>,
"created_at": <Unix Timestamp>
}
1
}
}
Login to the commissioning interface
devices are added
Feedback Payload Structure
MQTT Components and Policies