API – Dokumentation
Hier können Sie auf die alte API Dokumentation zugreifen, für Softwareversionen V2.7.10 und niedriger.
Wir empfehlen, den Steuerrechner auf die neueste Softwareversion zu aktualisieren und die API wie hier beschrieben zu verwenden.
Einführung
Diese API wurde entwickelt, um eine kundenspezifische Steuerung in den verschiedenen Maschinensteuerungsumgebungen zu ermöglichen. Die API bietet einen programmiertechnischen Zugang zum Auslesen des Status und zur Steuerung des Kamera-Systems.
Es stehen zwei webbasierte Kommunikationsprotokolle zur Verfügung. Zum einen ist es möglich, eine zustandslose Verbindung über den Standard HTTP Get- oder Post-Request aufzubauen und die gewünschten Daten zu empfangen oder zu steuern. Zum anderen kann über eine Websocket-Verbindung ein ereignisgesteuertes System entwickelt werden. Auf diese Weise kann die vom Kunden programmierte Software auf sich ändernde Informationen reagieren, die in Echtzeit synchronisiert werden.
Http API
Die http API ist eine RESTful API. Der Steuerrechner von Rotoclear C2 stellt in der lokalen Netzwerkumgebung den Server dar und das Programm ist der Client. Die Kommunikation zwischen Server und Client erfolgt zustandslos. Das bedeutet, dass der Server nichts über die zuletzt angeforderten Daten weiß und selbst wenn die Daten noch aktuell sind, werden sie auf Anfrage erneut gesendet.
Diese API ist ideal, um ein einfaches und kleines Steuerprogramm zu schreiben. Sie ist auch leicht zu testen. Die URL von Get Requests kann direkt im Browser in das URL-Eingabefeld eingegeben werden, oder sie kann mit postman oder curl getestet werden. Alles, was benötigt wird, ist ein http Client und ein gewisses Verständnis des http Protokolls, url Abfragen, der http Header und des JSON Formats.
Verbindung
Die http API kann über beide Webserver auf dem Steuerrechner aufgerufen werden. Im Prinzip ist der Ursprung der Verbindungs-URL derselbe, unter dem wir auch den Web-Client im Browser aufrufen können. An diesen URL-Ursprung wird der Pfad '/api' angehängt (siehe 'Beispiele für Verbindungs-URLs'). Natürlich muss der entsprechende Webserver in den Verbindungseinstellungen eingeschaltet sein (siehe http- und https-Verbindung im Menü). Diese Verbindungseinstellungen enthalten auch den Port, den wir für unsere http-Client-Verbindung benötigen. Bitte beachten Sie: Aus Sicherheitsgründen ist die https-Verbindung immer zu empfehlen.
Die API antwortet auf zwei HTTP-Methoden. Die HTTP-GET-Methode kann verwendet werden, um Anfragedetails in der URL-Abfrage festzulegen. Aus praktischen Gründen ist es auch erlaubt, Parameter in der API zu setzen (was weiter unten erklärt wird). Mit der HTTP-POST-Methode können komplexere Anfragestrukturen mit einem JSON-formatierten Inhalt abgebildet werden.
Beispiele für Verbindungs-URLs:
http://rotoclear.local:80/api
https://rotoclear.local:443/api
https://192.168.0.123:3000/api
Antwort:
401 Unauthorized
Authentifizierung und Autorisierung
Außerdem benötigen wir noch das API-Token aus den Einstellungen. Dieser ist nach der Aktivierung des API-Moduls konfigurierbar. Das System verfügt über ein internes Berechtigungssystem, das für verschiedene Benutzer unterschiedliche Rechte vergeben kann. Mit der Aktivierung des API-Moduls wird zusätzlich zum "admin"-Benutzer ein "API-User"-Benutzer angelegt. Das in den Einstellungen eingestellte Token spiegelt das Passwort des 'API-Users' wider.
Authentifizierung über Parameter in der Url-Abfrage:
Der Benutzer und das Passwort können als ein Parameter in der URL-Abfrage angegeben werden. In diesem Fall werden die Schlüsselwörter "Token" und "Passwort" demselben Feld des Benutzers wie das Passwort zugeordnet. Wird der Benutzer nicht übergeben, wird der 'API-User' als Standard angenommen. (Beispiel: 'Authentifizierung in URL-Abfrage'). Diese Authetifizierungsvariante hat Vor- und Nachteile. Ein Nachteil ist, dass das Token in der URL-Abfrage in seiner Rohform lesbar ist. Ein Vorteil ist, dass eine Anfrage einfach als URL-Text gestellt werden kann, wie z.B. bei der GET-Anfrage durch Eingabe der url im Browser.
Verbindet sich ein http-Client nur mit diesen Informationen, so werden alle für den Benutzer zugelassenen Informationen als Antwort gesendet, da keine weiteren Informationen und Auswahlmöglichkeiten bereitgestellt werden.
Authentifizierung in URL-Abfrage:
http://rotoclear.local:80/api?user=API-User&token=***
https://rotoclear.local:443/api?token=***
https://192.168.0.123:3000/api?password=***
Curl Beispiel:
curl -X GET -G https://rotoclear.local:443/api -d token=***
Antwort:
200 Success.
With JsonObject as description of the state in body of the response.
Vereinfachtes und formatiertes Beispiel für den Textkörper der Antwort:
{
"oct0":"69.7°C",
"oct1":"80.0°C",
"light0":false,
"light1":false,
"hasInternet":true,
"macAddr":"00:15:5D:7E:D9:46",
"hostname":"rotoclear",
"netInfo":[
{
"name":"eth0",
"description":"eth0",
"macAddress":"00:15:5D:7E:D9:46",
"gateway":"",
"isServer":false,
"dhcp":true,
"dhcpServers":[],
"connections":[{
"address":"172.28.32.226",
"netmask":"255.255.240.0",
"broadcast":"172.28.47.255"
}],
"dhcpSelected":true,
"staticIp":"192.168.214.221",
"staticMask":"255.255.255.0",
"staticGateway":"192.168.214.1",
"staticDns":"8.8.8.8",
"staticUseGateway":false,
"staticUseDns":false
}
],
"pan0":{"x":50.31323414252154,"y":49.89594172736733},
"pan1":{"x":50,"y":50},
"pip":0,
"psi0":"1712mbar",
"psi1":"1008mbar",
"psiSetpoint":"1150mbar",
"changeVideoName":"",
"changeImageName":"",
"changePostName":"",
"record":"stop",
"recordTime":0,
"rtspPort":1025,
...
}
Authentifizierung über Basic Authentication:
Die zweite Authentifizierungsvariante ist die Basisauthentifizierung. Zu diesem Zweck wird gemäß dem RFC7617-Standard der "Authorization"-Schlüssel im http-Header angegeben. Der Wert des Autorisierungsschlüssels setzt sich aus dem Text "Basic" und dem base64-kodierten "username:password" zusammen. Weitere Informationen sollten der Dokumentation des jeweiligen http-Clients und der verwendeten Programmiersprache entnommen werden.
Basic Authentication - Curl Beispiel:
curl -X GET -G https://rotoclear.local:443/api \
-u "API-User:token"
Antwort:
200 Success.
With JsonObject as description of the state in body of the response.
Http Get-Methode
Nun, da die Verbindung und die Authentifizierung bei der API erfolgreich waren, können wir einige Details zu den Anfragen ausführen. Bei der Anfrage mit der http-Get-Methode können zusätzliche Parameter in die URL-Abfrage aufgenommen werden. Um nur den Zustand des Systems zu erhalten, kann das Schlüsselwort "get" verwendet werden, so dass die gewünschten Systemzustandsvariablen aufgelistet werden. Die Beschreibung der Zustandsvariablen finden Sie am Ende dieser Dokumentation (siehe: 'Variablen Beschreibung'). Alle dem Benutzer erlaubten Variablen können auf diese Weise abgefragt werden. Unbekannte oder nicht zugelassene Zustandsvariablen werden von der API ignoriert. Das bedeutet, dass diese Werte in der Antwort nicht aufgeführt werden.
Abfrage ausgewählter Zustandsvariablen - URL-Beispiel:
https://rotoclear.local:443/api?token=***&get=[light0,record,recordTime,pan0]
Abfrage ausgewählter Zustandsvariablen - Curl Beispiel:
curl -X GET -G https://rotoclear.local:443/api \
-d token=*** \
-d get=[light0,record,recordTime,pan0]
Antwort:
{
"light0": true,
"record": "stop",
"recordTime": 0,
"pan0": {
"x": 50.26041666666666,
"y": 50.0
}
}
Die Get-Methode kann auch verwendet werden, um Werte im Systemstatus zu setzen. Bitte beachten Sie, dass komplexe und verschachtelte Strukturvariablen nicht ohne weiteres in einer Abfrage abgebildet werden können, so dass sie mit einer GET-Anfrage nicht funktionieren. Um eine Variable zu setzen, müssen Sie einfach ihren Schlüssel mit dem Wert in der Abfrage abgleichen. Da in der Abfrage die Variablen nur in Form von Text geschrieben werden, werden diese Variablen intern in die entsprechenden Datentypen umgewandelt. Das heißt "true" oder "false" wird zu einem JSON boolean, ausgeschriebene Zahlen werden in die entsprechenden JSON-Zahlen als Integer- oder Float-Zahl umgewandelt und gesättigt. Darüber hinaus werden die Werte validiert und in einem gültigen und definierten Bereich abgefangen. Nach dem Setzen der Variablen werden die aktualisierten Zustandsvariablen in der Antwort auf die Anfrage aufgelistet.
Statusvariablen setzen - Beispiel URL:
https://rotoclear.local:443/api?token=***&light0=true&record=start
Statusvariablen setzen - Beispiel Curl:
curl -X GET -G https://rotoclear.local:443/api \
-d token=*** \
-d light0=true \
-d record=start
Antwort:
{
"light0": true,
"record": "stop",
}
Das System könnte mit einem "record": "stop" reagieren, wenn z.B. kein Speichermedium für die Aufzeichnung ausgewählt wurde.
Http Post-Methode
Es gibt auch einige etwas komplexere Datentypen im Systemstatus. Dazu gehören z. B. Netzwerk, Zeit, Stream-Pan-Einstellungen usw. Wenn Sie diese komplexeren Datentypen einstellen möchten, können Sie die http-Post-Methode verwenden. Dazu werden die Einstellungen in einem JSON-formatierten Paket an die Anfrage übergeben.
Pan für den ersten Kamerakopf einstellen - Post Request mit einem JSON Body:
curl -X POST https://rotoclear.local:443/api \
-u "API-User:***" \
-H "Content-Type: application/json" \
-d '{"pan0": {"x": -10.5, "y": -10}, "zoom0": 20000}'
Antwort:
{
"pan0": {
"x": 39.5,
"y": 40.0
},
"zoom0": 20000
}
Während die Steuerung der Kameraköpfe, d.h. das Pan und der Zoom
relativ zum aktuellen Wert berechnet werden, ist der Rückgabewert der API
immer der absolute Wert, der gerade eingestellt ist.
Der Einfachheit halber können die Werte auch über die post-Methode abgefragt werden. Dazu muss der get-Schlüssel mit einem Array von Schlüsseln in String-Form abgeglichen werden.
Weiterhin ist zu erwähnen, dass mit einer Anfrage gleichzeitig state getter und setter gesendet werden können. In der Regel werden diese in der geschriebenen Reihenfolge ausgeführt. Dasselbe gilt für die get-Anfragen, bei denen die Reihenfolge der Abfrageparameter berücksichtigt wird.
Abfragezustand - Post Request mit einem JSON Body:
curl -X POST https://rotoclear.local:443/api \
-u "API-User:***" \
-H "Content-Type: application/json" \
-d '{"get": ["light0","record","recordTime","pan0"]}'
Antwort:
{
"light0": true,
"record": "stop",
"recordTime": 0,
"pan0": {
"x": 50.26041666666666,
"y": 50.0
}
}
WebSocket API
Die Websocket API ist für die Programmierung eines ereignisbasierten Systems geeignet. Die API basiert, wie der Name schon sagt, auf dem erweiterten http API Protokoll namens Websocket. Mit einem Websocket kann eine permanente Verbindung aufgebaut werden. Um die Kommunikation über den Websocket mit der API zu verstehen, müssen wir die folgenden Punkte beachten.
1. Kommunikationsdaten und -format:
Die API kommuniziert wie die http API intern mit JSON-formatierten Daten (es gibt einige interne Ausnahmen, die aber bei normaler Verwendung nie auftreten sollten). Das bedeutet, dass eingehende Nachrichten an den Websocket-Client "immer" JSON-Objekte sind. In diesen Objekten können eine oder mehrere Zustandsvariablen des Systems aufgeführt werden. Dies bedeutet auch, dass der Websocket-Client seine Kontrollnachrichten ebenfalls im JSON-Format senden muss.
2. Abonnement:
Wenn eine Verbindung mit der API hergestellt und autorisiert wird, werden alle Variablen des Systems, für die der Benutzer autorisiert ist, automatisch abonniert. Das bedeutet, dass erstens alle diese Variablen in JSON verpackt und als Ausgangszustand an den Client gesendet werden und zweitens bei jeder Änderung des Zustands die entsprechenden Variablen erneut in Echtzeit an den Client gesendet werden. Auf diese Weise kann ein System aufgebaut werden, das in Echtzeit mit dem Steuerrechner synchronisiert ist.
3. Kontrolle:
Es ist auch möglich, dass der Websocket-Client am Zustand des Systems teilnimmt. Wie bei der http-Post-Anfrage kann der Websocket JSON-formatierte Nachrichten senden. Diese werden in Echtzeit ausgewertet und gesetzt. Dabei ist der Datentyp sowie die Schreibberechtigung für die Variablen zu beachten. Beachten Sie hierzu die Statustabelle am Ende des Dokuments.
Verbindung
Die Websocket-Verbindungen befinden sich an denselben Endpunkten wie die http API-Verbindungen. Auch hier sind beide Webserver (http- und https-Webserver) für diese Verbindung zugänglich. Wir müssen nur beachten, dass "ws" als Protokoll anstelle von "http" geschrieben werden muss.
Weitere Informationen zu Websocket-Verbindungen finden Sie in der Dokumentation des Websockets und der jeweiligen Entwicklungsprogrammiersprache Ihres Client-Systems.
Beispiele für Verbindungs-URLs:
ws://rotoclear.local:80/api
wss://rotoclear.local:443/api
wss://192.168.0.123:3000/api
In Javascript:
const socket = new WebSocket("wss://rotoclear.local:443/api");
Antwort:
401 Unauthorized
Authentifizierung und Autorisierung
Zur Authentifizierung und Autorisierung der Verbindung müssen der Token und der Benutzer in der url-Abfrage angegeben werden. Siehe auch die Authentifizierung der http API im Abschnitt: Authentifizierung in URL-Abfrage.
Herstellen einer Verbindung mit der WebSocket-API in Javascript:
const token = "***"; // query conform encoding should be considered here
const socket = new WebSocket("wss://rotoclear.local:443/api?token=" + token);
// add callbacks
socket.onerror = function(error){ console.error(error); };
socket.onmessage = function(evt) {
if (typeof evt.data === "string") {
var jsonMsg = JSON.parse(evt.data);
console.debug(jsonMsg);
// The first message will represent the entire allowed state. The following ones will represent the updates.
}
}
Beispiel
Herstellen einer Verbindung zur WebSocket-API in Nodejs:
var WebSocket = require('websocket').w3cwebsocket;
const token = "***"; // query conform encoding should be considered here
const socket = new WebSocket("wss://rotoclear.local:443/api?token=" + token);
function sendToAPI(message) {
// stringify json message
connection.send(JSON.stringify(message));
}
connection.onopen = function() {
// now we can send messages to api
sendToAPI({ "light0": true });
};
connection.onerror = function(error) { console.error(error); };
connection.onmessage = function(evt) {
if (typeof evt.data === "string") {
var stateMsg = JSON.parse(evt.data);
console.debug(stateMsg);
// Use data from api to control your system
// ....
}
};
Kamera Stream
Der Kamera-Stream kann auch über die http-Anfragen verarbeitet werden. Bitte beachten Sie, dass für den Zugriff auf den Kamera-Stream eine Authentifizierung mit den entsprechenden Anmeldedaten (Benutzername und Passwort) in der http-Anfrage erforderlich ist. Zur Authentifizierung und Autorisierung siehe http API-Authentifizierung im Abschnitt: Authentifizierung in URL-Abfrage.
1. Abrufen eines JPEG-Bildes:
Ein JPEG-Bild kann durch eine http-GET-Anfrage abgerufen werden. Dazu müssen der Pfad "/camera.jpeg" und die Authentifizierung zur Verbindung hinzugefügt werden.
Bild anfordern:
http://rotoclear.local:80/camera.jpeg?user=admin&password=***
2. MJPEG-Streaming:
Für das Streaming von MJPEG wird der Inhaltstyp "multipart/x-mixed-replace" verwendet. Der Server sendet eine kontinuierliche Reihe von JPEG-Bildern als Antwort auf die http-Anfrage. Der Inhaltstyp jedes einzelnen Bildes wird als "Content-Type: image/jpeg" angegeben.
Der Server antwortet mit einer fortlaufenden Serie von JPEG-Bildern, die im Body der http-Antwort übertragen werden. Jedes Bild hat den Inhaltstyp "image/jpeg" und wird in einer eigenen http-Nachricht gesendet. Der Client kann den MJPEG-Stream verarbeiten, indem er jedes einzelne JPEG-Bild extrahiert und anzeigt.
MJPEG anfordern:
http://rotoclear.local:80/camera.mjpeg?user=admin&password=***
Variablen Beschreibung
Die folgende Tabelle beschreibt die Zustandsvariablen. Bitte beachten Sie, dass einige Einstellungen voneinander abhängig sind. Dementsprechend validiert das System die Eingaben und löst unter bestimmten Umständen Benachrichtigungen aus.
Legende
r - lesbar
w - beschreibbar
[x,y] - Intervall der gültigen Werte.
API Key | Wert Datentyp |
Berechtigungen | Beschreibung |
---|---|---|---|
cam0Exists | Boolean | r | existence of the first camera head |
cam1Exists | Boolean | r | existence of the second camera head |
cameraSwitch | Boolean | rw | selection of the current streaming and recording camera head. false -> first camera is selected true -> second camera is selected |
lineRateA | String | r | data transmission rate of the first camera head |
lineRateB | String | r | data transmission rate of the second camera head |
ver0 | String | r | hardware and software version of the first camera head |
ver1 | String | r | hardware and software version of the second camera head |
autoRotate0 | Boolean | rw | automatic alignment of the first camera head false -> first camera is selected true -> second camera is selected |
autoRotate1 | Boolean | rw | automatic alignment of the second camera head false -> first camera is selected true -> second camera is selected |
dictRotation0 | Boolean | rw | first camera head disk rotation |
dictRotation1 | Boolean | rw | second camera head disk rotation |
rpm0 | Integer | r | read rotation speed setpoint of the first camera head |
rpm1 | Integer | r | read rotation speed setpoint of the second camera head |
RPM0 | Integer | r | measured rotation speed of the first camera head |
RPM1 | Integer | r | measured rotation speed of the second camera head |
light0 | Integer | rw | first camera head light false -> disabled true -> enabled |
light1 | Integer | rw | second camera head light false -> disabled true -> enabled |
downstat | String | r | state of the 'update process' working in the background |
fpgaTemp | String | r | temperature of the FPGA in the control box |
exposure | Boolean | rw | automatically aligned exposure of the picture false -> disabled true -> enabled |
whiteBalance | Boolean | rw | automatically white balance of the picture false -> disabled true -> enabled |
noiseSuppression | Boolean | rw | automatically noise suppression false -> disabled true -> enabled |
redGain | Integer [-128,127] | rw | red gain value works only if whiteBalance is disabled |
blueGain | Integer [-128,127] | rw | blue gain value works only if whiteBalance is disabled |
brightness | Integer [-7,7] | rw | brightness of the picture works only if exposure is disabled |
expo | Number [0.01,1000.0] | rw | exposure time [in ms] works only if exposure is disabled |
gain | Integer [0,42] | rw | gain works only if exposure is disabled |
sharpness | Integer [1,15] | rw | sharpness of the picture |
saturation | Number [-7,7] | rw | color saturation of the picture |
contrast | Number [1,2.5] | rw | contrast of the picture |
hdmiConnected | Boolean | r | indicates whether a monitor is connected to the control box |
hdmiName | String | r | name of the monitor |
cfg30 | String | r | rate of the first optical sensor of the first camera head (dependent on the quality of the connection) "0" ≙ no optical sensor found "30" ≙ optical sensor with 30fps found "60" ≙ optical sensor with 60fps found |
cfg40 | String | r | rate of the second optical sensor of the first camera head (dependent on the quality of the connection) "0" ≙ no optical sensor found "30" ≙ optical sensor with 30fps found "60" ≙ optical sensor with 60fps found |
cfg31 | String | r | rate of the first optical sensor of the second camera head (dependent on the quality of the connection) "0" ≙ no optical sensor found "30" ≙ optical sensor with 30fps found "60" ≙ optical sensor with 60fps found |
cfg41 | String | r | rate of the second optical sensor of the second camera head (dependent on the quality of the connection) "0" ≙ no optical sensor found "30" ≙ optical sensor with 30fps found "60" ≙ optical sensor with 60fps found |
oct0 | String | r | temperature of the first camera head |
oct1 | String | r | temperature of the second camera head |
cam0SelectedSensor | Integer [0,1] | rw | selected optical sensor of the first camera head Be careful, if your head does not have 2 optical sensors, it will mirror your image! |
cam1SelectedSensor | Integer [0,1] | rw | selected optical sensor of the second camera head Be careful, if your head does not have 2 optical sensors, it will mirror your image! |
language | String | rw | current selected language in menu Please note that only the selection of languages from the menu is valid. |
licenseConfig | Json Array | r | list of feature configurations in system |
licenseModules | Json Array | r | list of modules in system |
hasInternet | Boolean | r | control box has internet access |
macAddr | String | r | mac address of the first network device in hardware |
hostname | String | r | currently only read only access to hostname |
netInfo | Json Array | r | list network devices and settings |
zoom0 | Integer [0,31424] | rw | zoom of first camera head Please note: For algorithmic reasons, a relative value is always assumed when setting the value. But the response is always the absolute value. |
zoom1 | Integer [0,31424] | rw | zoom of second camera head Please note: For algorithmic reasons, a relative value is always assumed when setting the value. But the response is always the absolute value. |
pan0 | Json Object { "x": Number, "y": Number } |
rw | pan of the first camera head Please note: For algorithmic reasons, a relative value is always assumed when setting the value. But the response is always the absolute value. The values x and y are only valid in interval of [0.0,100.0] |
pan1 | Json Object { "x": Number, "y": Number } |
rw | pan of the second camera head Please note: For algorithmic reasons, a relative value is always assumed when setting the value. But the response is always the absolute value. The values x and y are only valid in interval of [0.0,100.0] |
pip | Number [0,4] | rw | picture in picture mode selection 0 ≙ only current camera 1 ≙ pip is top left 2 ≙ top right 3 ≙ bottom left 4 ≙ bottom right |
psi0 | String | r | sealing air of first camera head in bar |
psi1 | String | r | sealing air of second camera head in bar |
psiSetpoint | String | r | default sealing air set point in bar |
changeVideoName | String | rw | prefix of the recorded video file |
changeImageName | String | rw | prefix of the recorded image file |
changePostName | String | rw | postfix of the recorded file |
record | String | rw | state of recording options: "start", "pause", "release" or "stop" please note: that the recording requires some conditions such as the presence of the storage medium and sufficient storage space |
takePicture | Boolean | w | trigger snapshot |
recordTime | Number | r | traced time of current video recording |
rtspPort | Number | rw | port of rtsp server |
rtspOn | Boolean | rw | rtsp server running |
rtspStatus | Json Object | r | status of rtsp server |
diskStorages | Json Object | r | list of detected usb storages |
netStorages | Json Object | r | list of setted network storages |
recordingStorage | Json Object | r | selected manual recording storage description |
recordingStorage | String | w | select manual recording storage with uuid (select one id in diskStorages or netStorages) |
alignmentStream0 | String | rw | rotate stream of first camera head "0" ≙ 0° "1" ≙ 180° |
alignmentStream1 | String | rw | rotate stream of second camera head "0" ≙ 0° "1" ≙ 180° |
recordingResolution | String | rw | recording and stream resolution "4K": 3840x2160 "FullHD": 1920x1080 "HD": 1280x720 |
recordingFps | Integer | rw | recording and stream frames per second. options: 1, 5, 10, 15, 30, 60 |
recordingPictureQuality | Integer [1,100] | rw | quality of jpeg compressor |
mjpgStreamIsOpen | Boolean | rw | enable or disable the stream for clients without connection token |
recordingWithTimeStamp | Boolean | rw | write time into stream and recording |
recordingWithDateStamp | Boolean | rw | write date into stream and recording |
systemDescription | Json Object | r | hardware and system description of control box |
time | Json Array of numbers | r | systems time [year,month,day,hours,minutes,seconds] |
timezone | String | rw | selected timezone |
ntpHost | String | rw | address ot the ntp server |
ntpStatus | Json Object | r | State of last connection try to ntp server |
ntpSync | Boolean | rw | enable ntp syncronization |
seconds | Integer | r | epoch time seconds |
connectionUrls | Json Object | r | list of detected and assumed possible connections |
userAuthentication | Json Object | rw | enables password authentication in clients |
swVersion | String | r | current software version |
fmVersion | String | r | current firmware version |
httpOn | Boolean | rw | http webserver run setting |
httpsOn | Boolean | rw | https webserver run setting |
httpPort | Integer [1,65000] | rw | http webserver port |
httpsPort | Integer [1,65000] | rw | https webserver port |
httpStatus | Json Object | r | http webserver status |
httpsStatus | Json Object | r | https webserver status |
httpsCertificate | Json Object | r | certificate description |
Code Beispiele
Diese Code Beispiele sollen den ersten Einstieg in die Verwendung unserer API erleichtern.
- Node.js
- C#
- NIM
- Python
Node.js
#!/usr/bin/env node
// Example for Nodejs - JS
//
// 1. Connect to websocket-server
// 2. Check camera 1 is connected
// 3. If camera 1 is connected toggle the light
// 4. Take a jpg image and save it as file
// 5. Close connection
//
// Install dependencies:
// npm install websocket
//
const W3CWebSocket = require('websocket').w3cwebsocket;
const http = require('http');
const fs = require('fs');
const RotoclearIp = "192.168.178.61"
const RotoclearApiPort = "80"
const ApiToken = "1a2B3c4D5e6f7G8h"
const WebsocketApiUrlWithAuth = "ws://" + RotoclearIp + ":" + RotoclearApiPort + "/api?token=" + ApiToken
const HttpCameraImageUrlWithAuth = "http://" + RotoclearIp + ":" + RotoclearApiPort + "/camera.jpeg?user=API-User&token=" + ApiToken
const imageName = 'myNewImage.jpg'
console.log("try to establish connection to ", WebsocketApiUrlWithAuth)
var connection = new W3CWebSocket(WebsocketApiUrlWithAuth);
function sendToAPI(message) {
// Send message to api server. Only stringified json object is accepted
connection.send(JSON.stringify(message));
}
connection.onerror = function (err) {
console.log('Connection error', err.toString());
};
connection.onopen = function () {
console.log('Connection successful established');
};
connection.onclose = function (ev) {
console.log('Client closed', ev.reason);
};
connection.onmessage = function (ev) {
if (typeof ev.data === "string") {
// if data is of type string, then it is json
var api_message = JSON.parse(ev.data);
if (api_message["cam0Exists"]) {
if(api_message["light0"]) {
sendToAPI({ "light0": false });
} else {
sendToAPI({ "jpeg": true });
}
http.get(HttpCameraImageUrlWithAuth, (res) => {
let data = [];
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data.push(chunk);
});
res.on('end', () => {
const imageBuffer = Buffer.concat(data);
fs.writeFileSync(imageName, imageBuffer);
process.exit()
});
});
} else {
console.log("No camera head detected")
process.exit()
}
}
};
C#
// Dotnet c# API Example
//
// 1. Connect to websocket-server
// 2. Check camera 1 is connected
// 3. If camera 1 is connected toggle the light
// 4. Take a jpg image and save it as file
//
// Install dotnetSDK:
// see: https://docs.microsoft.com/de-de/dotnet/core/install
//
// Init project in current directory:
// dotnet new console
//
// copy the content to your Program.cs and replace the namespace "dotnet_websocket_api_example" with yours
using System.Text;
using System.Net.WebSockets;
using System.Text.Json;
using System.Net;
namespace dotnet_websocket_api_example
{
class Program
{
const string ServerIp = "192.168.178.61";
const int ServerPort = 80;
const string APIToken = "1a2B3c4D5e6f7G8h";
public static Task SendString(ClientWebSocket ws, String data)
{
var encoded = Encoding.UTF8.GetBytes(data);
var buffer = new ArraySegment<Byte>(encoded, 0, encoded.Length);
return ws.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
public static async Task<String> ReadString(ClientWebSocket ws)
{
ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[32000]);
using (var ms = new MemoryStream())
{
while (true)
{
WebSocketReceiveResult result = await ws.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.ToArray(), buffer.Offset, result.Count);
if (result.EndOfMessage) {
break;
}
}
ms.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
static async Task Main(string[] args)
{
// Define the cancellation token.
using (var socket = new ClientWebSocket())
{
try
{
await socket.ConnectAsync(new Uri("ws://" + ServerIp + ":" + ServerPort + "/api?token=" + APIToken), CancellationToken.None);
string systemStateMessage = await ReadString(socket);
JsonDocument doc = JsonDocument.Parse(systemStateMessage);
var systemStateJson = doc.RootElement;
System.Console.WriteLine(systemStateJson.ToString());
if (!systemStateJson.GetProperty("cam0Exists").GetBoolean()) {
// toggle light
if (systemStateJson.GetProperty("light0").GetBoolean())
{
await SendString(socket, "{ \"light0\": false }");
}
else
{
await SendString(socket, "{ \"light0\": true }");
}
// # get jpeg and save it
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
{
HttpResponseMessage response = await client.GetAsync("http://" + ServerIp + ":" + ServerPort + "/camera.jpeg?user=API-User&token=" + APIToken);
var jpgBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("streamImage.jpg", jpgBytes);
}
}
else
{
System.Console.WriteLine("No camera head detected");
}
}
catch (Exception ex)
{
Console.WriteLine($"ERROR - {ex.Message}");
}
}
}
}
}
NIM
# Example in NIM - Control light via websocket api
#
# 1. Connect to websocket-server
# 2. Check camera 1 is connected
# 3. If camera 1 is connected then toggle the light
# 4. Take a jpg image and save it as file
# 5. Close connection
#
# Install dependencies:
# nimble install ws
#
import std/[
strformat,
strutils,
json,
asyncdispatch,
httpclient
]
import ws
const
rotoclearIp = "192.168.178.61"
rotoclearApiPort = "80"
apiToken = "1a2B3c4D5e6f7G8h"
wsUrlWithAuthInQuery = fmt("ws://{rotoclearIp}:{rotoclearApiPort}/api?token={apiToken}")
streamImageUrlWithAuthInQuery = fmt("http://{rotoclearIp}:{rotoclearApiPort}/camera.jpeg?user=API-User&token={apiToken}")
proc runProcess() {.async.} =
# create connection
let conn = await newWebSocket(wsUrlWithAuthInQuery)
let
# after a successful authentication the response will be the whole state
response = await conn.receiveStrPacket()
currentStateJson = parseJson(response)
# print state in console
echo currentStateJson.pretty
if currentStateJson.hasKey("cam0Exists"):
if currentStateJson["cam0Exists"].getBool():
if currentStateJson["light0"].getBool():
let message = %*{ "light0": false }
await conn.send($message)
else:
let message = %*{ "light0": true }
await conn.send($message)
# get jpeg and save it
let
client = newHttpClient()
response = client.getContent(streamImageUrlWithAuthInQuery)
writeFile("currentImage.jpeg", response)
else:
echo "No camera head detected"
conn.close()
waitFor runProcess()
# Example in NIM - Use http api to get and set data
#
# 1. Connect to websocket-server
# 2. Fetch some information from the system (eg. light0, record, recordTime, pan0)
# 3. Disable light and move pan cursor from current position via post request
#
import std/[strformat, json, httpclient]
const
rotoclearIp = "192.168.178.61"
rotoclearApiPort = "80"
apiToken = "1a2B3c4D5e6f7G8h"
urlWithAuthInQuery = fmt("http://{rotoclearIp}:{rotoclearApiPort}/api?token={apiToken}")
let
client = newHttpClient()
response = client.getContent(urlWithAuthInQuery & "&get=[light0,record,recordTime,pan0]")
jsonResponse = response.parseJson()
echo jsonResponse.pretty()
# disable light and move pan cursor from current position via post request
let
message = %*{
"light0": false,
"pan0": { # relative values
"x": -20.0,
"y": -30.0
}
}
echo client.postContent(urlWithAuthInQuery, $message)
Python3
#!/usr/bin/python3
# Example in Python3
#
# 1. Connect to websocket-server
# 2. Check camera 1 is connected
# 3. If camera 1 is connected then toggle the light
# 4. Take a jpg image and save it as file
# 5. Close connection
#
# Install dependencies:
# pip install websocket-client
# pip install requests
# pip install json
#
from websocket import create_connection
import requests
import json
ROTO_CLEAR_IP = "192.168.178.61"
ROTO_CLEAR_PORT = "80"
MY_API_TOKEN = "1a2B3c4D5e6f7G8h"
WEBSOCKET_API_URL_WITH_AUTH = "ws://" + ROTO_CLEAR_IP + ":" + ROTO_CLEAR_PORT + "/api?token=" + MY_API_TOKEN
HTTP_CAMERA_IMAGE_URL_WITH_AUTH = "http://" + ROTO_CLEAR_IP + ":" + ROTO_CLEAR_PORT + "/camera.jpeg?user=API-User&token=" + MY_API_TOKEN
ws = create_connection(WEBSOCKET_API_URL_WITH_AUTH)
# after the connection the api response is the whole system state
response = ws.recv()
systemState = json.loads(response)
# print state in console
print(systemState)
if systemState["cam0Exists"]:
# toggle light
if systemState["light0"]:
jsonText = json.dumps({"light0": False})
ws.send(jsonText)
else:
jsonText = json.dumps({"light0": True})
ws.send(jsonText)
# get jpeg and save it
imageResponse = requests.get(HTTP_CAMERA_IMAGE_URL_WITH_AUTH)
f = open("myCurrentImg.jpg", "wb")
f.write(imageResponse.content)
f.close()
else:
print("No camera head detected")
ws.close()
#!/usr/bin/python3
# Example in Python3 - Use http api to get and set data
#
# 1. Connect to websocket-server
# 2. Fetch some information from the system (eg. light0, record, recordTime, pan0)
# 3. Disable light and move pan cursor from current position via post request
#
# Install dependencies:
# pip install requests
# pip install json
#
import requests
import json
ROTO_CLEAR_IP = "192.168.178.61"
ROTO_CLEAR_PORT = "80"
MY_API_TOKEN = "1a2B3c4D5e6f7G8h"
HTTP_API_URL_WITH_AUTH = "http://" + ROTO_CLEAR_IP + ":" + ROTO_CLEAR_PORT + "/api?user=API-User&token=" + MY_API_TOKEN
response = requests.get(HTTP_API_URL_WITH_AUTH +
"&get=[light0,record,recordTime,pan0]")
jsonResponse = json.loads(response.content)
print(jsonResponse)
# disable light and move pan cursor from current position via post request
message = json.dumps({
"light0": False,
"pan0": { # relative values
"x": -20.0,
"y": -30.0
}
})
response = requests.post(HTTP_API_URL_WITH_AUTH, message)
print(response.content)