API
Voraussetzungen
Um unsere API zu nützen, prüfen Sie bitte unser Lizenzmodell.
API Beschreibung
Unter smart-me API sind alle verfügbaren API-Befehle und deren Beschreibung ersichtlich.
Einzelne API-Befehle nützten OBIS-Codes als Rückgabewerte. Details zu den OBIS-Codes sind weiter unten.
Authentifizierung
Basic Auth
smart-me verwendet API "Basic Authentication". Jeder Aufruf der API muss die Authentifizierung beinhalten. Die HTTP-Basisauthentifizierung ermöglicht die Übertragung von Anmeldeinformationen (z. B. Benutzername und Passwort oder ein API-Token) in HTTP-Headern. Das secret wird mit Base64 kodiert.
OAuth 2.0
smart-me unterstützt das Autorisierungsframework OAuth 2.0. Externe Anwendungen können den Zugriff auf ein Konto beantragen, ohne die Anmeldedaten zu kennen. Weitere Informationen und eine detaillierte Beschreibung von OAuth finden Sie weiter unten.
Echtzeit-API (Webhook)
Die smart-me Echtzeit-API (Webhooks) ermöglicht es Ihnen, neue Daten eines Gerätes zu abonnieren. Sie können sich für ein einzelnes Gerät oder für alle Geräte eines Benutzers anmelden. Wenn ein Gerät neue Daten an die Cloud sendet, sendet ein Webhook diese Daten als POST-Anfrage an eine neu konfigurierte URL. Weitere Informationen finden Sie hier.
Proto-Datei
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-Datei ohne 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
Einzelne API-Befehle nützten OBIS-Codes als Rückgabewerte.
OBIS Codes werden verwendet, um einen (Zähler-)Wert zu beschreiben.
Tipp zur Entschlüsselung: Auf dieser Website können Sie die Systematik der Codierung nachlesen. Wenn Sie dort auf ein Medium klicken, sehen Sie, für was die Ziffern des Codes jeweils stehen.
Beispiele
API Beispiele
REST API Samples
HTML / Javascript (jquery) Beispiele
Alle Geräte abrufen
<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>
Gerät erstellen und aktualisieren
<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>
Geräte erstellen oder aktualisieren
https://smart-me.com/swagger/ui/index
Wärmezähler
API Method: 'POST /api/devices'
Hinweis: Um ein Gerät zu erstellen, wird keine ID gesendet.
Nutzlast:
{
"Id": "b0ec0030-9f97-4c3c-897f-8175074177bc",
"Name": "Wärme Zähler Test",
"Serial": 2233445566,
"DeviceEnergyType": "MeterTypeHeat",
"ActivePower": 5.89,
"CounterReading": 1234.56,
}
API-Client-Bibliothek für .Net
Um die smart-me API-Funktionalität in Ihre .Net-Anwendung zu integrieren, können Sie diese Bibliothek verwenden. Sie stellt HTTP-Anfragen an die smart-me REST API Alle HTTP-Anfrage- und Antwortkörper werden auf .Net-Klassen abgebildet.
OAuth Informationen und eine detaillierte Beschreibung
smart-me unterstützt das Autorisierungsframework OAuth 2.0. Externe Anwendungen können den Zugriff auf ein Konto beantragen, ohne die Anmeldedaten zu kennen.
Detaillierte Informationen zu Rollen, Protokollfluss, Autorisierung, Endpunkten und Token finden Sie unter https://tools.ietf.org/html/rfc6749. Um die OAuth-Schnittstelle zu nutzen, sind eine Client-ID und ein Client-Secret erforderlich. Wenn Sie weder eine Client-ID noch ein Client-Secret haben, kontaktieren Sie uns bitte.
Berechtigungen
smart-me unterstützt zwei Arten von Berechtigungserteilungen:
Der implizite Berechtigungsfluss (empfohlen, wenn Sie eine Webapp oder Microapp erstellen)
Der Berechtigungscode-Fluss (empfohlen für langfristigen API-Zugang)
OAuth Implizite Berechtigung
Implizierte Berechtigungen sind zu verwenden, wenn der OAuth-Client in einem Browser mit einer Skriptsprache wie JavaScript implementiert wird. Wählen Sie dies, wenn Sie eine Webapp oder eine Microapp erstellen. Da ungültige oder abgelaufene Zugriffstoken nicht mit dem impliziten Gewährungstyp aktualisiert werden können, sollte dies nur für Widgets verwendet werden, die nur für eine begrenzte Zeit angezeigt werden, z. B. bei einmaliger Verwendung.
1. Autorisierung
Wenn der Benutzer die Anwendung eines Drittanbieters (z. B. ein Widget) verwenden möchte, muss er zunächst zum Autorisierungsendpunkt umgeleitet werden:
https://smart-me.com/api/oauth/authorize
client_id Wird von smart-me bereitgestellt. (Beispiel: myapp)
response_type Token
redirect_uri Die URL der App (z. B. https://www.example.com)
scope Gibt den Umfang des Zugriffs an (z. B. device.read)
state Wert, der vom Client verwendet wird, um den Zustand zwischen Request und Callback zu erhalten (z. B. ein URL-encodiertes JSON-Objekt)
Beispiel
Wenn der Benutzer nicht bereits bei der App angemeldet ist, wird er zu einem Anmeldeformular weitergeleitet (Siehe rechts).
Nachdem der Benutzer authentifiziert wurde, fordert smart-me ihn auf, Ihrem Widget den Zugriff auf seine Daten zu gestatten. Der Nutzer kann Ihre App akzeptieren oder ablehnen und auch den Umfang des Datenzugriffs für Ihr Widget festlegen.
Wenn die Autorisierung erfolgreich war, wird der Benutzer zum redirect_uri mit dem Zugriffstoken als URI-Fragment umgeleitet: https://example.com#access_token=aaaaaa&expires_in=3600&token_type=bearer&state=mystate
2. API-Calls machen
Ihre App kann dann das access_token verwenden, um Calls an die API zu autorisieren, indem sie es als Autorisierungs-HTTP-Header sendet:
Authorization: Bearer <access_token>
Abgelaufenes Zugangs-Token:
Wenn das access_token abläuft, muss das gesamte Widget neu geladen werden, um den Autorisierungsfluss neu zu starten.
OAuth Berechtigungscode
Wird verwendet, wenn ein Server als OAuth2-Client fungiert und der Client einen langfristigen API-Zugang im Namen des Benutzers haben soll. Ungültige oder abgelaufene Zugangstokens können aktualisiert werden.
Ablauf
Sie müssen die folgenden fünf Schritte ausführen, um eine API request zu erstellen:
Autorisierung anfordern
smart-me leitet den Benutzer auf die Autorisierungsseite um
Anforderung eines Zugangstokens
Zugangstoken erhalten
API-Calls machen
1. Autorisierung
Wenn der Benutzer die Anwendung eines Drittanbieters (d. h. eine benutzerdefinierte App) verwenden möchte, wird er zunächst an den Autorisierungsendpunkt weitergeleitet:
https://smart-me.com/api/oauth/authorize
client_id Wird von smart-me bereitgestellt (Beispiel: myapp)
response_type Code
redirect_uri Die URL der App (https) (z. B. https://www.example.com)
scope Gibt den Umfang des Zugriffs an (z. B. device.read)
state Wert, der vom Client verwendet wird, um den Zustand zwischen Request und Callback zu erhalten (z. B. ein URL-encodiertes JSON-Objekt)
Beispiel:
https://smart-me.com/api/oauth/authorize?client_id=myapp&response_type=code&redirect_uri=https%3A%2F%2Fwww.example.com&scope=device.read&state=mystate
Nach der Authentifizierung des Benutzers fordert smart-me den Benutzer auf, Ihre App für den Zugriff auf seine Daten zu autorisieren.
Der Nutzer kann Ihre App annehmen oder ablehnen und auch den Umfang des Datenzugriffs für Ihre App festlegen.
2. Authentifizierungscode austauschen
Wenn die Autorisierung erfolgreich war, wird der Benutzer zur redirect_uri umgeleitet, wobei ein Autorisierungscode als Abfrageparameter angehängt wird:
https://example.com/?code=mycode&state=mystate
Ihre Anwendung muss den Auth-Code verwenden, um ein access_token anzufordern, indem sie eine POST-Anfrage an den Token-Endpunkt sendet:
https://smart-me.com/api/oauth/token/
client_id Wird von smart-me bereitgestellt (Beispiel: myapp)
grant_type authorization_code
code Der Autorisierungscode (Beispiel: mycode)
redirect_uri Die URL der App (z. B. 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
Die Formulardatenfelder müssen als Inhaltstyp application/x-www-form-urlencoded kodiert sein.
Die Antwort enthält ein access_token und ein refresh_token. Das access_token kann dann für Api-Aufrufe im Namen des Benutzers verwendet werden, während das refresh_token zum Abrufen eines neuen access_token verwendet werden kann.
Antwort
{
"access_token": "mytoken",
"expires_in": 3600,
"token_type": "bearer",
"scope": "device.read",
"refresh_token": "myrefreshtoken"
}
3. API-Calls machen
Ihre App kann dann das access_token verwenden, um Aufrufe an die API zu autorisieren, indem sie es als Authorization HTTP-Header sendet:
Authorization: Bearer <access_token>
4. Abgelaufenes Zugangstoken auffrischen
Wenn das access_token abgelaufen ist (die Lebensdauer beträgt 3600 Sekunden) oder ungültig wird, müssen Sie das refresh_token verwenden, um ein neues access_token anzufordern, indem Sie eine POST-Anfrage an den Token-Endpunkt senden:
https://smart-me.com/api/oauth/token/
Die erforderlichen Formulardaten zur Aktualisierung des access_token:
client_id Wird von smart-me bereitgestellt (Beispiel: myapp)
client_secret Wird von smart-me bereitgestellt (Beispiel: mysecret)
response_type refresh_token
refresh_token Der refresh_token (Beispiel: myrefreshtoken)
POST https://smart-me.com/api/oauth/token client_id=myclient&client_secret=mysecret&grant_type=refresh_token&refresh_token=myrefreshtoken
Die Antwort enthält ein access_token und ein refresh_token. Das access_token kann dann für Api-Aufrufe im Namen des Benutzers verwendet werden, während das refresh_token zum Abrufen eines neuen access_token verwendet werden kann.
Antwort
{
"access_token": "mytoken",
"expires_in": 3600,
"token_type": "bearer",
"scope": "device.read",
"refresh_token": "myrefreshtoken"
}
Scopes
Echtzeit-API (Webhook) Beispiele
Die smart-me Realtime API sendet die Daten serialisiert mit google protobuffer
Proto-Datei
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-Datei ohne 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-Beispiel
Beispieldaten
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)
Das Feld 1 enthält den Offset in Ticks seit dem 01.01.1970
Sekunden seit 01.01.1970: 15712284449788512 / 10000000 = 1571228444 (Unix time stamp UTC)
-> 16.10.2019 12:20:44 (UTC)
Device values
Feld 1 enthält den OBIS-Code, Feld 2 enthält den Wert.
01-00-01-08-00-FF: (1-0:1.8.0*255):Wirkenergie Gesamtimport: 1879583.2 mWh = 1879.5832 Wh