Requirements
To use our API, please check our license model.
API description
Under smart-me API all available API commands and their description can be seen.
Implementation examples can be found below.
Obis Codes
Individual API commands used OBIS Codes as return values.
OBIS Codes are used to describe a (meter) value.
Tip for decoding: On this Website (German) you can read about the coding system. If you click on a medium there, you will see what the digits of the code stand for in each case.
Authentication
Basic Auth
smart-me API uses "Basic Authentication". Every call to the API must include the Authentication. HTTP Basic Authentication allows credentials (such as a username and password or an API token) to be transferred in HTTP headers. The secret is encoded using Base64.
OAuth 2.0
smart-me supports the authorization framework OAuth 2.0. External applications can apply for access to an account without having to know the login credentials.
OAuth information
smart-me supports the authorisation framework OAuth 2.0. External applications can request access to an account without knowing the credentials.
Setting up OAuth in the smart-me portal
The prerequisite for using oAuth is an account with the professional licence model. If you do not yet have an account with the professional licence model, you must purchase 1 licence.
Select user at the top right
Settings
API & Access Change
Add oAuth applications
Trusted (Limited to 3 Client ID)
Client ID and Client secret will be created
Public (Limited to 3 Client ID)
Client ID is created
Device (Limited to 50 Client ID)
Client ID and Client secret will be created
Required information
Name
Redirect Urls
Required permissions
Grants & Endpoints
The implementation of OAuth is not described on our wiki. For example, you can find the necessary information to implement oAuth on this page: https://oauth.net/2/
Supported Grants (Flows) for oAuth Confidential and Public Applications:
- Authorization Code
- Authorization Code with PKCE
- Implicit Flow (deprecated)
- Device Code
- Refresh Token
Supported Grants (Flows) for oAuth Device (Client Credentials) Applications:
- Client Credentials
smart-me Endpoints
- Authorization: /api/oauth/authorize/
- Token: /api/oauth/token/
- Device Code: /api/oauth/device
Realtime (Webhook) API
The smart-me Realtime (Webhooks) API allows you to subscribe to new data of a device. You can subscribe to a single device or to all devices of a user. When a device sends new data to the cloud, a webhook sends this data as a POST request to a reconfigured URL. More Information [1]
Proto File
package RealtimeApi.Containers;
import "bcl.proto"; // schema for protobuf-net's handling of core .NET types
message DeviceData {
required bcl.Guid DeviceId = 1;
required bcl.DateTime DateTime = 2;
repeated DeviceValue DeviceValues = 3;
}
message DeviceDataArray {
repeated DeviceData DeviceDataItems = 1;
}
message DeviceValue {
required bytes Obis = 1;
required double Value = 2;
}
Proto File without BCL
syntax = "proto2";
package com.company;
message TimeSpan {
required sint64 value = 1; // the size of the timespan (in units of the selected scale)
optional TimeSpanScale scale = 2; // the scale of the timespan [default = DAYS]
enum TimeSpanScale {
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
TICKS = 5;
MINMAX = 15; // dubious
}
}
message DateTime {
optional sint64 value = 1; // the offset (in units of the selected scale) from 1970/01/01
optional TimeSpanScale scale = 2; // the scale of the timespan [default = DAYS]
optional DateTimeKind kind = 3; // the kind of date/time being represented [default = UNSPECIFIED]
enum TimeSpanScale {
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
TICKS = 5;
MINMAX = 15; // dubious
}
enum DateTimeKind
{
// The time represented is not specified as either local time or Coordinated Universal Time (UTC).
UNSPECIFIED = 0;
// The time represented is UTC.
UTC = 1;
// The time represented is local time.
LOCAL = 2;
}
}
message Guid {
required fixed64 lo = 1; // the first 8 bytes of the guid (note:crazy-endian)
required fixed64 hi = 2; // the second 8 bytes of the guid (note:crazy-endian)
}
message DeviceData {
required Guid DeviceId = 1;
required DateTime DateTime = 2;
repeated DeviceValue DeviceValues = 3;
}
message DeviceDataArray {
repeated DeviceData DeviceDataItems = 1;
}
message DeviceValue {
required bytes Obis = 1;
required double Value = 2;
}
API - Goldaprtner
To use our API - Goldpartner, you must have the smart-me Goldpartner license model. Further information on this license model can be obtained via the sales department.
Get all devices
Gets all devices assigned to the partner
GET /PartnerAllDevices
Get all devices from one Account
Gets all devices assigned to one of the users assigned to the partner (Get Id with "Get users" )
GET /PartnerAllDevices/{id} - only for one device
Get all device informations
Gets all information for all devices assigned to the partner user or to a sub-user of the partner
GET /PartnerAllDeviceInformations
GET /PartnerAllDeviceInformations/{id} - only for one device
Get fast send device values
Force a device to send the data every second (if supported). This for about 30s
GET /partner/fastsenddevicevalues
Get Folder menu
Gets the folder menu items for a user of a partner
GET /partner/foldermenu/{id}
Update folder menu
Creates and updates the folder menu items for a user. Attention: All existing configuration (folder, billing, export, ...) is deleted!!
POST /partner/foldermenu/{id}
Get users
Get the information about all users of the partner
GET /partner/user
Update user
Updates the email and/or the password of a user. The user must be created by the partner.
POST /partner/user/{id}
Sign up user
Creates a new user and assign it to the partner user
POST /SignUpPartner
Get values in past multiple
Gets multiple values of a device. The device must be installed in an account assigned to your partner account.
GET /partner/ValuesInPastMultiple
Get visualization configuration
Gets the visualization configuration for all folders of a user
GET /partner/visualizationconfiguration/{id}
Update firmware
Update the Firmware (if available) for the given devices
POST /UpdateFirmwarePartner
PartnerVisualization
Gets the visualization configuration for all folders of a user
GET /partner/visualizationconfiguration/{id}
Examples
API examples
REST API Samples
This allows you to pick up any data sets that we provide. https://api.smart-me.com/swagger/index.html
HTML / Javascript (Show all devices with meter reading and last connection)
<html>
<style>
table, th, td {
border:1px solid black;
}
</style>
<head>
<title>smart-me REST API Sample</title>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
</div>
<div>
<label for="pass">Password:</label>
<input type="password" id="pass" name="password" minlength="8" required />
</div>
<button id="myButton">Start Request</button>
<h1>Get all devices</h1>
<ul id="DeviceList">
</ul>
<script type="text/javascript">
function GetAllDevices() {
var smartmeUserName = document.getElementById("username").value;
var smartmePassword = document.getElementById("pass").value;
//var smartmeUserName = "xxx";
//var smartmePassword = "xxx";
var targetUrl = "https://api.smart-me.com/Devices/";
$.ajax({
url: targetUrl,
type: "get",
cache: false,
headers: {
"Authorization": "Basic " + btoa(smartmeUserName + ":" + smartmePassword)
},
dataType: "json",
error: function(jqXHR, exception) {
alert(exception);
},
success: function(json) {
$("#DeviceList").append(("<table>"))
$("#DeviceList").append(("<tr align=left><th>Serial</th><th>Name</th><th>CounterReading</th><th>CounterReadingUnit</th><th>Last Connection (Zulu Time) </th></tr>"))
json.forEach(function(element) {
$("#DeviceList").append(("<tr><td>") + element.Serial + "</td><td>" + element.Name + "</td><td>" + element.CounterReading + "</td><td>" + element.CounterReadingUnit + "</td><td>" + element.ValueDate + "</td></tr>");
});
$("#DeviceList").append(("</table>"))
}
});
}
myButton.onclick = GetAllDevices;
</script>
</body>
<footer>
<p>DISCLAIMER: This script is provided as-is, without any warranty or guarantee of any kind. The author accepts no liability for any issues, damages, or consequences that may arise from the use of this script. Users are responsible for reviewing and understanding the script before implementation. Additionally, no support or assistance will be provided for the installation, customization, or troubleshooting of this script. Use at your own risk.</p>
<p>HAFTUNGSAUSSCHLUSS: Dieses Skript wird im Ist-Zustand ohne jegliche Garantie oder Gewährleistung bereitgestellt. Der Autor übernimmt keine Haftung für Probleme, Schäden oder Folgen, die sich aus der Verwendung dieses Skripts ergeben können. Die Benutzer sind dafür verantwortlich, das Skript vor der Implementierung zu überprüfen und zu verstehen. Außerdem wird keine Unterstützung oder Hilfe bei der Installation, Anpassung oder Fehlerbehebung dieses Skripts geleistet. Die Verwendung erfolgt auf eigene Gefahr..</p>
</footer>
</html>
HTML / Javascript (Get M-Bus Gateway und M-Bus Devices Infos)
<html>
<style>
table, th, td {
border:1px solid black;
}
</style>
<head>
<title>smart-me REST API Sample</title>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
</div>
<div>
<label for="pass">Password:</label>
<input type="password" id="pass" name="password" required />
</div>
<h1></h1>
<button id="mBusInfo">M-Bus Info</button>
<h1>M-Bus Info</h1>
<ul id="MBusInfo">
</ul>
<h1>M-Bus Devices Last Readout > 24 Hours </h1>
<ul id="MBusDeviceOffline">
</ul>
<h1>M-Bus Devices Info</h1>
<ul id="MBusDeviceInfo">
</ul>
<script type="text/javascript">
var mBusIds = [];
var smartmeUserName = ""
var smartmePassword = ""
var targetUrl = "https://api.smart-me.com/DevicesByEnergy?meterEnergyType=8";
var deviceUrl = "https://api.smart-me.com/Devices/"
var mbusGWUrl = "https://api.smart-me.com/gateway/mbus/";
function GetAllDevicesfetch() {
//smartmeUserName = "";
//smartmePassword = "";
smartmeUserName = document.getElementById("username").value;
smartmePassword = document.getElementById("pass").value;
mBusIds = [];
fetch(targetUrl, {
method: "GET",
headers: {
"Authorization": "Basic " + btoa(smartmeUserName + ":" + smartmePassword),
"Content-Type": "application/json"
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(json => {
$("#MBusInfo").empty();
$("#MBusInfo").append(("<table>"))
$("#MBusInfo").append(("<tr align=left><th>Name</th><th>Serial</th><th>ReadoutInterval</th><th>State</th><th>Last Connection (Zulu Time) </th></tr>"))
json.forEach(function(element) {
mBusIds.push(element.Id)
});
mbusid();
$("#MBusInfo").append(("</table>"));
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
}
function mbusid(){
$("#MBusDeviceInfo").empty();
$("#MBusDeviceInfo").append(("<table>"));
$("#MBusDeviceInfo").append(("<tr align=left><th>Name</th><th>Serial</th><th>Device Name</th><th>SecondaryAddress</th><th>State</th><th>Last Seen (Zulu Time) </th></tr>"));
$("#MBusDeviceOffline").empty();
$("#MBusDeviceOffline").append(("<table>"));
$("#MBusDeviceOffline").append(("<tr align=left><th>Name</th><th>Serial</th><th>Device Name</th><th>SecondaryAddress</th><th>State</th><th>Last Seen (Zulu Time) </th></tr>"));
mBusIds.forEach(function(element) {
var newurl = mbusGWUrl+element
fetch(newurl, {
method: "GET",
headers: {
"Authorization": "Basic " + btoa(smartmeUserName + ":" + smartmePassword),
"Content-Type": "application/json"
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(json => {
var StateName = json.State
switch (json.State) {
case 0:
StateName = "LastReadoutOk";
break;
case 1:
StateName = "SearchInProgress";
break;
case 2:
cStateName = "FailedOnOneOrMoreMeter";
break;
case 3:
StateName = "TooManySearchErrors";
break;
default:
StateName = "Unknown State";
}
var intervalName = json.ReadoutInterval;
switch (json.ReadoutInterval) {
case 0:
intervalName = "Intervall_2s";
break;
case 1:
intervalName = "Intervall_10s";
break;
case 2:
intervalName = "Intervall_1min";
break;
case 3:
intervalName = "Intervall_5min";
break;
case 4:
intervalName = "Intervall_15min";
break;
case 5:
intervalName = "Intervall_30min";
break;
case 6:
intervalName = "Intervall_60min";
break;
case 7:
intervalName = "Intervall_6hours";
break;
case 8:
intervalName = "Intervall_12hours";
break;
case 9:
intervalName = "Intervall_24hours";
break;
default:
intervalName = "Unknown Interval";
}
$("#MBusInfo").append(("<tr><td>") + json.Name + "</td><td>" + json.SerialNumber + "</td><td>" + intervalName + "</td><td>" + StateName + "</td><td>" + json.LastSeen + "</td></tr>");
var a = json.Meters
if (json.Meters.length == 0 ){
$("#MBusDeviceInfo").append(("<tr><td>") + json.Name + "</td><td>" + json.SerialNumber + "</td><td>" + "No Devices" + "</td><td>" + "No Devices" + "</td><td>" + "No Devices" + "</td><td>" + "No Devices" + "</td></tr>");
}
a.forEach(function(element) {
var StateName = element.State;
switch (element.State) {
case 0:
StateName = "LastReadoutOk";
break;
case 1:
StateName = "LastReadoutFailed";
break;
case 2:
StateName = "ReadoutStarted";
break;
case 3:
StateName = "CRCError";
break;
default:
StateName = "Unknown State";
}
var newurl = deviceUrl+element.Id
fetch(newurl, {
method: "GET",
headers: {
"Authorization": "Basic " + btoa(smartmeUserName + ":" + smartmePassword),
"Content-Type": "application/json"
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(deviceInfo => {
var dateString = deviceInfo.ValueDate
var dateToCheck = new Date(dateString);
var currentDate = new Date();
var timeDifference = currentDate - dateToCheck;
var hoursDifference = timeDifference / (1000 * 60 * 60);
if (hoursDifference > 24) {
$("#MBusDeviceOffline").append(("<tr><td>") + json.Name + "</td><td>" + json.SerialNumber + "</td><td>" + element.Name + "</td><td>" + element.SecondaryAddress + "</td><td>" + StateName + "</td><td>" + deviceInfo.ValueDate + "</td></tr>");
}
$("#MBusDeviceInfo").append(("<tr><td>") + json.Name + "</td><td>" + json.SerialNumber + "</td><td>" + element.Name + "</td><td>" + element.SecondaryAddress + "</td><td>" + StateName + "</td><td>" + deviceInfo.ValueDate + "</td></tr>");
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
});
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
});
$("#MBusDeviceInfo").append(("</table>"));
}
mBusInfo.onclick = GetAllDevicesfetch;
</script>
</body>
<footer>
<p>DISCLAIMER: This script is provided as-is, without any warranty or guarantee of any kind. The author accepts no liability for any issues, damages, or consequences that may arise from the use of this script. Users are responsible for reviewing and understanding the script before implementation. Additionally, no support or assistance will be provided for the installation, customization, or troubleshooting of this script. Use at your own risk.</p>
<p>HAFTUNGSAUSSCHLUSS: Dieses Skript wird im Ist-Zustand ohne jegliche Garantie oder Gewährleistung bereitgestellt. Der Autor übernimmt keine Haftung für Probleme, Schäden oder Folgen, die sich aus der Verwendung dieses Skripts ergeben können. Die Benutzer sind dafür verantwortlich, das Skript vor der Implementierung zu überprüfen und zu verstehen. Außerdem wird keine Unterstützung oder Hilfe bei der Installation, Anpassung oder Fehlerbehebung dieses Skripts geleistet. Die Verwendung erfolgt auf eigene Gefahr..</p>
</footer>
</html>
Create or update devices
Heat meter
API Method: 'POST /api/devices'
Info: To create a device don't send a ID.
Payload:
{
"Id": "b0ec0030-9f97-4c3c-897f-8175074177bc",
"Name": "Wärme Zähler Test",
"Serial": 2233445566,
"DeviceEnergyType": "MeterTypeHeat",
"ActivePower": 5.89,
"CounterReading": 1234.56,
}
API Client Library for .Net
To integrate smart-me API functionality into your .Net application you can use this library. It makes HTTP requests to the smart-me REST API. All HTTP request and response bodies are mapped to .Net classes.
Realtime (Webhook) API Example
The smart-me Realtime API sends the data serialized with google protobuffer
Proto File
package RealtimeApi.Containers;
import "bcl.proto"; // schema for protobuf-net's handling of core .NET types
message DeviceData {
required bcl.Guid DeviceId = 1;
required bcl.DateTime DateTime = 2;
repeated DeviceValue DeviceValues = 3;
}
message DeviceDataArray {
repeated DeviceData DeviceDataItems = 1;
}
message DeviceValue {
required bytes Obis = 1;
required double Value = 2;
}
Proto File without BCL
syntax = "proto2";
package com.company;
message TimeSpan {
required sint64 value = 1; // the size of the timespan (in units of the selected scale)
optional TimeSpanScale scale = 2; // the scale of the timespan [default = DAYS]
enum TimeSpanScale {
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
TICKS = 5;
MINMAX = 15; // dubious
}
}
message DateTime {
optional sint64 value = 1; // the offset (in units of the selected scale) from 1970/01/01
optional TimeSpanScale scale = 2; // the scale of the timespan [default = DAYS]
optional DateTimeKind kind = 3; // the kind of date/time being represented [default = UNSPECIFIED]
enum TimeSpanScale {
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
TICKS = 5;
MINMAX = 15; // dubious
}
enum DateTimeKind
{
// The time represented is not specified as either local time or Coordinated Universal Time (UTC).
UNSPECIFIED = 0;
// The time represented is UTC.
UTC = 1;
// The time represented is local time.
LOCAL = 2;
}
}
message Guid {
required fixed64 lo = 1; // the first 8 bytes of the guid (note:crazy-endian)
required fixed64 hi = 2; // the second 8 bytes of the guid (note:crazy-endian)
}
message DeviceData {
required Guid DeviceId = 1;
required DateTime DateTime = 2;
repeated DeviceValue DeviceValues = 3;
}
message DeviceDataArray {
repeated DeviceData DeviceDataItems = 1;
}
message DeviceValue {
required bytes Obis = 1;
required double Value = 2;
}
Parsing example
Example data
0A5A0A1209E9FCD03B8E9F834111B3D10C1622A22CA1120B08C0C9EAD3A98FE93710051A110A060100010800FF11333333331FAE3C411A110A060100020800FF1100000000000000001A110A060100010700FF11713D0AD7A3303840
Device ID (UUID / GUID)
UUID Data: 0xE9, 0xFC, 0xD0, 0x3B, 0x8E, 0x9F, 0x83, 0x41, 0xB3, 0xD1, 0x0C, 0x16, 0x22, 0xA2, 0x2C, 0xA1
GUID: 3bd0fce9-9f8e-4183-b3d1-0c1622a22ca1
Datetime (UTC)
The Field 1 contains the offset in ticks since 1970-01-01
Seconds since 1970-01-01: 15712284449788512 / 10000000 = 1571228444 (Unix time stamp UTC)
-> 16.10.2019 12:20:44 (UTC)
Device values
Field 1 contains the OBIS code. Field 2 contains the value.
01-00-01-08-00-FF: (1-0:1.8.0*255): Active energy total import: 1879583.2 mWh = 1879.5832 Wh