NAV Navbar
python java
  • MQTT Smart Meter Integration API
  • Connecting and Publishing Example
  • Sending Data
  • Message Format for Devices Without PV
  • Message Format for Devices with PV
  • MQTT Smart Meter Integration API

    This integration is a tool for third parties to integrate their smart meter data to enable the services the Voltaware Platform provides.

    This API is a message bus that allows devices to publish electrical readings using the MQTT protocol and our specific JSON data format.

    The messages must be exactly in the described format otherwise they will be discarded.

    The messages must be published to the exact topic otherwise they will be discarded.

    You can have multiple concurrent publishers.

    Connecting and Publishing Example

    Example of how to connect

    # Dependency [paho-mqtt](https://www.eclipse.org/paho) Version: 1.5.0
    
    import paho.mqtt.client as paho
    import ssl
    
    broker = "test-partner-broker.voltaware.com"
    port = 8883
    client_id = "python-example-client"
    username = "<your username>"
    passwd = "<your password>"
    message_topic = "<your topic>"
    message_json = "<json event format>"
    
    def on_publish(client, userdata, result):
        if result == 1:
            print("Data published!")
        else:
            print("Message not acknowledged!")
    
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected!")
            client.publish(message_topic, message_json, 2)
        else:
            print("Connection failed!")
    
    publisher = paho.Client(client_id)
    publisher.on_publish = on_publish
    publisher.on_connect = on_connect
    publisher.tls_set_context(ssl.create_default_context())
    publisher.username_pw_set(username, passwd)
    publisher.connect(broker, port)
    
    try:
        rc = 0
        while rc == 0:
            rc = publisher.loop()
        print("rc: " + str(rc))
    except KeyboardInterrupt:
        print("Exit")
    
    // Dependency [mqtt-client](https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3/1.2.2)
    
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    
    import javax.net.ssl.SSLContext;
    
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class PublisherExample {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(PublisherExample.class);
    
        public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, MqttException {
    
            final String broker = "ssl://test-partner-broker.voltaware.com:8883";
            final String clientId = "java-example-client";
            final String userName = "<your username>";
            final String passwd = "<your password>";
            final String topic = "<your topic>";
            final String messageJson = "<json event format>";
    
            final MqttClient mqttClient = new MqttClient(broker, clientId, new MemoryPersistence());
    
            try {
    
                final MqttConnectOptions mqttConnectionOptions = new MqttConnectOptions();
                mqttConnectionOptions.setKeepAliveInterval(30);
                mqttConnectionOptions.setCleanSession(true);
                mqttConnectionOptions.setUserName(userName);
                mqttConnectionOptions.setPassword(passwd.toCharArray());
                mqttConnectionOptions.setConnectionTimeout(5);
                final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
                sslContext.init(null, null, null);
                mqttConnectionOptions.setSocketFactory(sslContext.getSocketFactory());
                mqttClient.connect(mqttConnectionOptions);
    
                final MqttMessage mqttMessage = new MqttMessage(messageJson.getBytes());
                mqttMessage.setQos(2);
                mqttClient.publish(topic, mqttMessage);
                LOGGER.info("Message sent");
    
            } catch (final MqttException e) {
                LOGGER.error("Error to send to the topic!", e);
            } finally {
                mqttClient.disconnect();
                mqttClient.close();
            }
    
        }
    
    }
    

    You need these parameters to connect to the RabbitMQ Voltaware broker.

    See code samples.

    Sending Data

    Ingestion expects that all readings for a day are sent in a single message, and there needs to be a separate message for each day.

    The ideal frequency for data ingestion is daily; however, weekly and monthly submissions are also acceptable. It largely depends on when the data is available on your side, but we strongly recommend sending data daily if possible.

    Historical data for several months is accepted. However, if the period exceeds three months, automatic disaggregation will not be triggered. Please contact us to initiate the process in such cases.

    Field name Description
    deviceId string Unique identifier for your device. This will be the same identifier that must be used in the HTTP API to retrieve the disaggregation results.
    dataFrequencyMins int Frequency of consumption read. Allowed values: 15, 30 or 60.
    date ISO date Date from where all electrical readings belong, such as 2025-01-27.
    electricReadings[] array Array with all electrical readings for the given date. For example, if the reading interval is 30 minutes it must contain 48 records.
    electricReadings[].timestampUtcEpochSecs long UTC reading timestamp in seconds from Epoch.
    electricReadings[].importKwh float The amount of energy drawn from the grid in kWhs.
    electricReadings[].exportKwh float The amount of energy exported to the grid in kWhs. Required only for devices with PV (solar panels). Omit this field for devices without PV. If no energy was exported, set the value to zero.

    Message Format for Devices Without PV

    {
      "deviceId": "6ede44a4-ea21-4c17-b5c4-37eb3875e554",
      "dataFrequencyMins": 30,
      "date": "2025-01-27",
      "electricReadings": [
        {
          "importKwh": 0.6471,
          "timestampUtcEpochSecs": 1737936000 // 2025-01-27T00:00
        },
        {
          "importKwh": 0.7744,
          "timestampUtcEpochSecs": 1737937800 // 2025-01-27T00:30
        },
        {
          "importKwh": 0.5683,
          "timestampUtcEpochSecs": 1737939600 // 2025-01-27T01:00
        },
        // ... more readings ...
        {
          "importKwh": 0.0605,
          "timestampUtcEpochSecs": 1738017000 // 2025-01-27T22:30
        },
        {
          "importKwh": 0.3317,
          "timestampUtcEpochSecs": 1738018800 // 2025-01-27T23:00
        },
        {
          "importKwh": 0.3367,
          "timestampUtcEpochSecs": 1738020600 // 2025-01-27T23:30
        }
      ]
    }
    

    The field electricReadings[].exportKwh must not be present in this message format.

    Message Format for Devices with PV

    {
      "deviceId": "6ede44a4-ea21-4c17-b5c4-37eb3875e554",
      "dataFrequencyMins": 30,
      "date": "2025-01-27",
      "electricReadings": [
        {
          "importKwh": 0.6471,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1737936000 // 2025-01-27T00:00
        },
        {
          "importKwh": 0.7744,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1737937800 // 2025-01-27T00:30
        },
        {
          "importKwh": 0.5683,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1737939600 // 2025-01-27T01:00
        },
        // ... more readings ...
        {
          "importKwh": 0.0,
          "exportKwh": 0.3865,
          "timestampUtcEpochSecs": 1737990000 // 2025-01-27T12:00
        },
        {
          "importKwh": 0.0,
          "exportKwh": 0.8195,
          "timestampUtcEpochSecs": 1737991800 // 2025-01-27T12:30
        },
        {
          "importKwh": 0.0,
          "exportKwh": 0.2568,
          "timestampUtcEpochSecs": 1737993600 // 2025-01-27T13:00
        }
        // ... more readings ...
        {
          "importKwh": 0.0605,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1738017000 // 2025-01-27T22:30
        },
        {
          "importKwh": 0.3317,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1738018800 // 2025-01-27T23:00
        },
        {
          "importKwh": 0.3367,
          "exportKwh": 0.0,
          "timestampUtcEpochSecs": 1738020600 // 2025-01-27T23:30
        }
      ]
    }
    

    The field electricReadings[].exportKwh must be present on all timestamps in this message format. If no energy was exported for the timestamp, set the value to zero.