Nach langer Pause endlich ein erster konkreter Schritt in diesem Projekt:
Die Gardena-API ist sehr "informatisch", ein Wald von ids und relations, der zwar systematisch, aber auch etwas überkomplex scheint.
Mit einem kleinen Satz Hilfsroutinen (die ins mainscript eingefügt werden müssen, damit sie allen zukünftigen Gardena-Scripted-Devices zur Verfügung stehen) lässt sich der "Wald" aber einigermassen navigieren:
// Global Variables for Gardena API access
// Access parameters - insert your own values here
glob gardena_appkey = '2f660663-2b00-45f3-808e-702fa09cb8d7'
glob gardena_user = 'user@domain.ch'
glob gardena_pw = 'supersecret'
// temp variables
glob gardena_authinfo = false
glob gardena_reqcount = 0
// ... other global var definitions go here
// Global Functions for Gardena API access
// perform a new login, update glob gardena_authinfo
function gardena_login()
{
var data = format(
"client_id=%s&grant_type=password&username=%s&password=%s",
urlencode(gardena_appkey, true),
urlencode(gardena_user, true),
urlencode(gardena_pw, true)
)
var request = {
'url' : 'https://api.authentication.husqvarnagroup.dev/v1/oauth2/token',
'method' : 'POST',
'headers' : {
'Content-Type' : 'application/x-www-form-urlencoded',
'accept' : 'application/json'
},
}
try {
var ans = json(httprequest(request, data))
gardena_authinfo = if(isok(ans.access_token), ans, false)
}
catch as err {
log(4, "Error authenticating with Gardena/Husquarna API: %s", err)
gardena_authinfo = false;
}
}
function gardena_apicall(endpoint, jsonrequest)
{
if (!gardena_authinfo) {
gardena_login()
}
try {
if (!gardena_authinfo) throw('API not authenticated')
var request = {
'headers' : {
'accept' : 'application/vnd.api+json',
'Authorization-Provider' : 'husqvarna'
},
}
request.url = format("https://api.smart.gardena.dev/v1/%s", endpoint)
request.headers['X-Api-Key'] = gardena_appkey
request.headers['Authorization'] = 'Bearer ' + gardena_authinfo.access_token
if (isvalid(jsonrequest)) {
request.method = 'PUT'
request.headers['Content-Type'] = 'application/vnd.api+json'
request.data = string(jsonrequest)
}
else {
request.method = 'GET'
}
var textans = httprequest(request);
try {
var ans = json(textans)
}
catch {
var ans = textans // just return the (possibly empty) text answer
}
return ans
}
catch as err {
log(4, "Error accessing Gardena API: %s", err)
return err
}
}
function gardena_command(serviceid, req)
{
try {
req.data.id = format('request-%d', gardena_reqcount)
gardena_reqcount = gardena_reqcount + 1
gardena_apicall('command/' + serviceid, req)
}
catch as err {
log(4, "Error sending Gardena command: %s", err)
return err
}
}
function gardena_valvelist()
{
try {
var locs = gardena_apicall('locations');
var locid = locs.data[0].id; // just take first location for now
var status = gardena_apicall('locations/'+locid)
var i = 0;
var objs = status.included;
var valvelist = ''
while (i<elements(objs)) {
var obj = objs[i]
if (obj.type=='VALVE') {
valvelist = valvelist + format("%s : VALVE %s, activity=%s\n", obj.id, obj.attributes.name.value, obj.attributes.activity.value)
}
i=i+1
}
return valvelist
}
catch as err {
return err;
}
}
function gardena_valvecontrol(serviceid, minutes)
{
var req = {
"data" : {
"type": "VALVE_CONTROL",
"attributes": {
"command": false
}
}
}
if (minutes>0) {
// turn on
req.data.attributes.command = "START_SECONDS_TO_OVERRIDE"
req.data.attributes.seconds = minutes*60
}
else {
req.data.attributes.command = "STOP_UNTIL_NEXT_TASK"
}
gardena_command(serviceid, req)
}
Die 3 Parameter am Anfang müssen richtig gesetzt werden. Den gardena_appkey
erhält man über das Developer-Portal von Husquarna. Dort muss man sich mit user/pw einloggen und dann gemäss den Getting Started-Anweisungen Punkt 1 und 2 ausführen. Punkt 3, der eigentliche API-Zugriff, ist in obigem Code enthalten.
Sobald die Application erstellt und der entsprechende Application key in der gardena_appkey
-Variablen in obigem Script zusammen mit Login und Passwort hinterlegt ist, können erste Versuche via p44script-REPL gemacht werden:
gardena_valvelist()
...liefert eine Liste aller Ventile im System (oder einen Fehler wenn was schiefgeht). Die sieht dann etwa so aus:
035c1204-db7b-4097-98d6-faa51bd1fca3:1 : VALVE Garten, activity=CLOSED
035c1204-db7b-4097-98d6-faa51bd1fca3:2 : VALVE Treibhaus, activity=CLOSED
Diese Liste braucht es, um die ids der einzelnen Ventile herauszufinden, die es dann zur Ansteuerung braucht.
Um die Ansteuerung zu testen, einfach die entsprechende id mit gardena_valvecontrol
verwenden wie folgt:
// Ventil "Garten" für 5 minuten öffnen
gardena_valvecontrol('035c1204-db7b-4097-98d6-faa51bd1fca3:1', 5)
// Ventil wieder schliessen (vor Ablauf der 5 min)
gardena_valvecontrol('035c1204-db7b-4097-98d6-faa51bd1fca3:1', 0)
Wenn das soweit funktioniert, können wir in einem nächsten Schritt scripted devices einrichten 😀