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.
Individual API commands used OBIS codes as return values. Details about the OBIS codes are below.
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.
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;
}
Obis Codes
Individual API commands used OBIS Codes as return values.
OBIS Codes are used to describe a (meter) value.
Examples
API examples
REST API Samples
HTML / Javascript (jquery) Examples
Get all devices
<html>
<head>
<title>smart-me REST API Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Get all devices</h1>
<ul id="DeviceList">
</ul>
<script type="text/javascript">
var smartmeUserName = "YOUR_USERNAME";
var smartmePassword = "YOUR_PASSWORD";
function GetAllDevices() {
var targetUrl = "https://api.smart-me.com/api/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) {
json.forEach(function(element) {
// Do something
$("#DeviceList").append($("<li>").text(element.Name + ": " + element.CounterReadingImport + " " + element.CounterReadingUnit));
});
}
});
}
// On document load
$(document).ready(function() {
// Get all smart-me devices
GetAllDevices();
});
</script>
</body>
</html>
Create and update device
<html>
<head>
<title>smart-me REST API Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Create and update devices</h1>
<button type="button" id="CreateNewDeviceButton">Create new device</button>
<script type="text/javascript">
var smartmeUserName = "YOUR_USERNAME";
var smartmePassword = "YOUR_PASSWORD";
var counterValueImport = 0.0;
var counterValueExport = 0.0;
var activePowerTempValue = 0.1;
// The ID of the device
var deviceID = null;
function GetElectricityDevice(id, power, energyImport, energyExport) {
var deviceObject = new Object();
if (id != null) {
// Object with an ID updates the existing device. Object without an ID creates a new one
deviceObject.ID = id;
}
// Add all data
deviceObject.Name = "My test device";
deviceObject.Serial = 12345678;
deviceObject.DeviceEnergyType = "MeterTypeElectricity"; // MeterTypeWater for Water, MeterTypeGas for Gas, MeterTypeHeat for Heat
// Set active power in kW
deviceObject.ActivePower = power;
// Set countervalues import (in kWh)
deviceObject.CounterReading = energyImport;
// Set countervalues export (in kWh)
deviceObject.CounterReadingExport = energyExport;
return deviceObject;
}
function CreateUpdateDevice(deviceObject) {
var targetUrl = "https://api.smart-me.com/api/Devices/";
var postData = JSON.stringify(deviceObject);
$.ajax({
url: targetUrl,
type: "post",
cache: false,
headers: {
"Authorization": "Basic " + btoa(smartmeUserName + ":" + smartmePassword)
},
dataType: "json",
contentType: "application/json; charset=utf-8",
data: postData,
error: function(jqXHR, exception) {
alert(exception);
},
success: function(json) {
// The device was created or updated
deviceID = json.Id;
$('#CreateNewDeviceButton').text("Update device");
alert("OK! device ID: " + json.Id);
}
});
}
// On document load
$(document).ready(function() {
$('#CreateNewDeviceButton').click(function(e) {
// No Postback
e.preventDefault();
// Add some random values
activePowerTempValue += 0.1;
counterValueImport += 1.0;
counterValueExport += 0.5;
var electricityDevice = GetElectricityDevice(deviceID, activePowerTempValue, counterValueImport, counterValueExport);
// Send to cloud
CreateUpdateDevice(electricityDevice);
});
});
</script>
</body>
</html>
Create or update devices
https://smart-me.com/swagger/ui/index
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.
OAuth information and a detailed description
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.
Detailed information regarding roles, protocol flow, authorization, endpoints and tokens can be found at https://tools.ietf.org/html/rfc6749 In order to use the OAuth interface, a client ID and a client secret is required. If you do not have either a client ID or a client secret, please contact us.
Grants
smart-me supports two authorization grant types:
The implicit grant flow (Recommended if you are building a Webapp or Microapp)
The authorization code grant flow (Recommended for long term API access)
Implicit Grant
Is to be used, when the OAuth client is implemented in a browser using a scripting language such as JavaScript. Choose this if you are building a Webapp or a Microapp. Since invalid or expired access tokens cannot be refreshed with the implicit grant type, this should only be used for widgets that are displayed for a limited amount of time, e.g. one-off usage.
1. Authorization
When the user wants to use the 3rd-party application (i.e. a widget), they must be redirected to the authorisation endpoint first:
https://smart-me.com/api/oauth/authorize
client_id Will be provided by smart-me. (example: myapp)
response_type token
redirect_uri The widget URL (https), e.g. https://www.example.com
scope Specifies the scope of the access (e.g. device.read)
state Value used by the client to maintain state between the request and callback (for example an urlencoded json object)
Example
If the user is not already logged into the app, they are redirected to a login form (see on the right).
After the user is authenticated, smart-me prompts the user to authorize your widget to access their data. The user can accept or decline your app and also define the scope of data access for your widget.
When the authorization succeeded, the user gets redirected to the redirect_uri with the access token as URI fragment: https://example.com#access_token=aaaaaa&expires_in=3600&token_type=bearer&state=mystate
2. Do API calls
Your app can then use the access_token to authorize calls to the API by sending it as Authorization HTTP header:
Authorization: Bearer <access_token>
Expired access token:
When the access_token expires, the whole widget has to be reloaded to restart the authorization flow.
Authorization Code Grant
Is to be used when a server acts as OAuth2 client and the client should have a long term API access on behalf of the user. Invalid or expired access tokens can be refreshed.
Flow
You need to execute the following five steps to create an API request:
Request authorization
smart-me redirects the user to the authorization page
Request an access token
Receive the access token
Make API calls
1. Authorization
When the user wants to use the 3rd-party application (i.e. a custom App), they get redirected to the authorisation endpoint first:
https://smart-me.com/api/oauth/authorize
client_id Will be provided by smart-me. (example: myapp)
response_type code
redirect_uri The App URL, e.g. https://www.example.com
scope Specifies the scope of the access (e.g. device.read)
state Value used by the client to maintain state between the request and callback (for example an urlencoded json object)
Example
After the user is authenticated, smart-me prompts the user to authorize your App to access their data.
The user can accept or decline your app and also define the scope of data access for your App.
2. Exchange auth code
When the authorization succeeded, the user gets redirected to the redirect_uri with an auth code appended as code query parameter:
https://www.example.com/?code=mycode&state=mystate
Your app will have to use the auth code to request an access_token by sending a POST request to the token endpoint:
https://smart-me.com/api/oauth/token/
client_id Will be provided by smart-me. (example: myapp)
grant_type authorization_code
code The auth code (mycode in the example)
redirect_uri The App URL, e.g. https://www.example.com
POST https://smart-me.com/api/oauth/token client_id=myclient&grant_type=authorization_code&code=mycode&redirect_uri=https%3A%2F%2Fwww.example.com
The form data fields need to be encoded as content type application/x-www-form-urlencoded.
The response contains an access_token and a refresh_token. The access_token can then be used to make api calls on behalf of the user, while the refresh_token can be used to retrieve a new access_token.
Response
{
"access_token": "mytoken",
"expires_in": 3600,
"token_type": "bearer",
"scope": "device.read",
"refresh_token": "myrefreshtoken"
}
3. Do API calls
Your app can then use the access_token to authorize calls to the API by sending it as Authorization HTTP header:
Authorization: Bearer <access_token>
4. Refreshing expired access token
When the access_token has expired (the lifetime is 3600 seconds) or becomes invalid, you have to use the refresh_token to request a new access_token by sending a POST request to the token endpoint:
https://smart-me.com/api/oauth/token/
The required form data to refresh the access_token:
client_id Will be provided by smart-me. (example: myapp)
client_secret Will be provided by smart-me. (example: mysecret)
response_type refresh_token
refresh_token The refresh_token, (myrefreshtoken in the example)
POST https://smart-me.com/api/oauth/token client_id=myclient&client_secret=mysecret&grant_type=refresh_token&refresh_token=myrefreshtoken
The response contains an access_token and a refresh_token. The access_token can then be used to make api calls on behalf of the user, while the refresh_token can be used to retrieve a new access_token.
Response
{
"access_token": "mytoken",
"expires_in": 3600,
"token_type": "bearer",
"scope": "device.read",
"refresh_token": "myrefreshtoken"
}
Scopes
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