an dieser Stelle möchte ich eine Lösung zur Steuerung von arlo Kameras mit der CCU vorstellen. Die arlo-API ist nicht öffentlich, es gibt aber einige Projekte und recht gute Dokumentationen (bspw. https://robertogallea.com/posts/develop ... system-api). Für weiterführende Dinge (bspw. Abfrage des Status) kann man die Web-App im Browser analysieren. Die API beantwortet die Anfragen im JSON-Format. Die Skripte benötigen keinerlei zusätzliche Software und wurde bisher nur auf der CCU3 getestet.
Ein paar allgemeine Hinweise:
- Die Skripte funktionieren, bis auf das Skript zum setzten der Zugangsdaten, ohne das daran Anpassungen vorgenommen werden müssen. Alle notwendigen Variablen werden mit dem zweiten Skript ausgelesen und entsprechend gesetzt.
- Es werden mehrere Kameras unterstützt. Eine Unterstützung mehrerer Basisstationen in einem Account ist theoretisch eingearbeitet, aber auf Grund einer fehlenden zweiten Basis und einiger Unklarheiten (nicht-dokumentierte API) noch nicht getestet.
- Eine Funktionalität mit aktivierter Zwei-Faktor-Authentifizierung ist nicht getestet (und ich gehe davon aus, das dies auch nicht funktionieren wird).
- Das Token ist 30 15 Tage gültig. Sind seit der letzten Aktualisierung des Tokens mehr als 30 15 Tage vergangen, wird ein neues Token erstellt.
- Die mit den neueren Kameras (Ultra, Pro3, ...) eingeführte "lokaler Speicher"-Funktion wird (zur Zeit) nicht unterstützt.
- Sollten bei der Abfrage Fehler auftreten, werden diese Fehler nun im Systemlog gespeichert. Nach dem das Systemlog heruntergeladen wurde, kann einfach mittels arloAPI nach entsprechenden Einträgen gesucht werden.
Update 09.04.2021: arlo scheint nun erst zu machen mit der 2FA. Laut Forum ist die Umstellung aller Accounts bis 18.04.2021 abgeschlossen und es gibt ab dann keine Möglichkeit mehr, ohne 2FA mit der API zu kommunizieren. Damit funktionieren diese Scripts nicht mehr.
Das nachfolgende (erste Setup-)Skript braucht nur einmalig bei aufgerufen zu werden. Es erzeugt alle benötigten Variablen, die immer benötigt werden (also nicht von den Geräten abhängig sind) und setzt ebenfalls die Zugangsdaten (die vorher angespasst werden müssen). Dafür wird ein neues Programm erstellt um im Aktivitäts-Teil das folgende Skript hinterlegt:
Code: Alles auswählen
! arlo Systemvariablen erzeugen und Logindaten setzten
! Passwort muss BASE64-codiert sein
! v1.1 - 20200920 [pen]
! Logindaten für arlo anpassen
string emailAdresse="xxx@yy.ttt";
string passwordEncrypted="BASE64codiertesPasswort";
! ab hier keine Änderungen nötig
string svName;
object svObj;
! Systemvariable arloEMail erstellen
svName="arloEMail";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("EMail Adresse für die arlo Anmeldung");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloPasswordEncrypted erstellen
svName="arloPasswordEncrypted";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("verschlüsseltes Passwort für die arlo Anmeldung");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Logindaten setzten
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").State(emailAdresse);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").State(passwordEncrypted);
! Systemvariable arloCameraDeviceIDs erstellen
svName="arloCameraDeviceIDs";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("DeviceIDs der Kameras im arlo System");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloCentralDeviceIDs erstellen
svName="arloCentralDeviceIDs";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("GeräteIDs der Zentralen im arlo System");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloCentralXCloudIDs erstellen
svName="arloCentralXCloudIDs";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("XCloudIDs der Zentralen im arlo System");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloCurrentState erstellen
svName="arloCurrentState";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("aktueller Modus des arlo Systems");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloLastConnectionResult erstellen
svName="arloLastConnectionResult";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Ergebnis der letzten Kommunikation mit arlo");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloLastConnectionTime erstellen
svName="arloLastConnectionTime";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Zeitpunkt der letzten Kommunikation mit arlo");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloLastLinkUpdateTime erstellen
svName="arloLastLinkUpdateTime";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("letzte Aktualisierung der arlo Links");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloLastStatusUpdateTime erstellen
svName="arloLastStatusUpdateTime";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("letzte Aktualisierung des arlo Systemstatus");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloToken erstellen
svName="arloToken";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Token der arlo Anmeldung");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloTokenGenerationTime erstellen
svName="arloTokenGenerationTime";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Zeitpunkt zu dem das arlo Token erzeugt wurde");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable arloUserID erstellen
svName="arloUserID";
svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("BenutzerID im arlo System");
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
Folgende Systemvariablen (alle vom Typ "Zeichenkette") müssten erstellt worden sein:
Code: Alles auswählen
arloEMail
arloPasswordEncrypted
arloToken
arloTokenGenerationTime
arloLastConnectionResult
arloLastConnectionTime
arloUserID
arloCentralDeviceIDs
arloCentralXCloudIDs
arloCameraDeviceIDs
arloCurrentState
Code: Alles auswählen
! arlo IDs abrufen, Systemvariablen befüllen und Systemvariablen für Kameras und Zentralen erzeugen
! kann auch zur Erweiterung eines bestehenden Setups verwendet werden
! v3.0 - 20200903 [pen]
string res;
string err;
string success;
string token;
string userID;
string tempDeviceID;
string tempDeviceType;
string tempXCloudID;
string centralDeviceIDs;
string centralDeviceID;
string cameraDeviceIDs;
string cameraDeviceID;
string centralXCloudIDs;
integer posStart;
integer posEnd;
time tokenGenerationTime;
time now=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
! Token überprüfen
tokenGenerationTime=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").Value().ToInteger().ToTime();
! Prüfen ob ein Token gespeichert und wenn ja ob es neuer als 15 Tage (1296000) ist
if((tokenGenerationTime.ToInteger()==0) || ((tokenGenerationTime.ToInteger()+1296000) < now))
{
!Kein gültiges Token vorhanden, neues Token erzeugen
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/auth' -H 'Content-Type: application/json; charset=utf-8' -H 'Referer: https://my.arlo.com/' -d '{\"email\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").Value() # "\",\"password\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").Value() # "\",\"language\":\"de\",\"EnvSource\":\"prod\"}'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming getToken: " # res);
quit;
}
! Token suchen
posStart=res.Find("\"token\"");
posEnd=res.Length()-posStart;
token=res.Substr(posStart, posEnd);
posStart=token.Find(":");
posEnd=token.Length()-posStart;
token=token.Substr(posStart, posEnd);
posStart=2;
posEnd=token.Find(",")-posStart;
token=token.Substr(posStart, posEnd-1);
! Token validieren
system.Exec("echo '" # token # "' | base64", &res, &err);
tokenBase64=res.Replace("\n","");
posEnd=tokenBase64.Length()-4;
tokenBase64=tokenBase64.Substr(0,posEnd);
nowTokenValidate=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20" # nowTokenValidate.ToInteger() # "' -H 'Authorization: " # tokenBase64 # "' -H 'Referer: https://my.arlo.com/'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateToken: " # res);
quit;
}
! Token Validierung erfolgreich
posStart=res.Find("\"tokenValidated\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find("}");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success<>"true")
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateTokenState: " # res);
quit;
}
! Token und Zeitpunkt speichern
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").State(token);
tokenGenerationTime=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").State(tokenGenerationTime.ToInteger());
}
else
{
token=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").Value();
}
system.Exec("curl --max-time 5 -H \"Authorization: " # token # "\" -X GET \"https://my.arlo.com/hmsweb/users/devices\"", &res, &err);
! Erfolg oder nicht erfolg prüfen
posStart=res.Find("\"success\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success==true)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("erfolgreich");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
}
else
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec ("logger -t arloAPI -p user.debug updateLinks getDevices: " # res);
quit;
}
! UserID suchen
posStart=res.Find("\"userId\"");
posEnd=res.Length()-posStart;
userID=res.Substr(posStart, posEnd);
posStart=userID.Find(":");
posEnd=userID.Length()-posStart;
userID=userID.Substr(posStart, posEnd);
posStart=2;
posEnd=userID.Find(",")-posStart;
userID=userID.Substr(posStart, posEnd-1);
! DeviceIDs suchen
posStart=res.Find("\"deviceId\"");
while(posStart>=0)
{
posEnd=res.Length()-posStart;
tempDeviceID=res.Substr(posStart, posEnd);
posStart=tempDeviceID.Find(":");
posEnd=tempDeviceID.Length()-posStart;
tempDeviceID=tempDeviceID.Substr(posStart, posEnd);
posStart=2;
posEnd=tempDeviceID.Find(",")-posStart;
tempDeviceID=tempDeviceID.Substr(posStart, posEnd-1);
! DeviceType suchen
posStart=res.Find("\"deviceType\"");
posEnd=res.Length()-posStart;
tempDeviceType=res.Substr(posStart, posEnd);
posStart=tempDeviceType.Find(":");
posEnd=tempDeviceType.Length()-posStart;
tempDeviceType=tempDeviceType.Substr(posStart, posEnd);
posStart=2;
posEnd=tempDeviceType.Find(",")-posStart;
tempDeviceType=tempDeviceType.Substr(posStart, posEnd-1);
if(tempDeviceType=="basestation")
{
! XCloudID suchen
posStart=res.Find("\"xCloudId\"");
posEnd=res.Length()-posStart;
tempXCloudID=res.Substr(posStart, posEnd);
posStart=tempXCloudID.Find(":");
posEnd=tempXCloudID.Length()-posStart;
tempXCloudID=tempXCloudID.Substr(posStart, posEnd);
posStart=2;
posEnd=tempXCloudID.Find(",")-posStart;
tempXCloudID=tempXCloudID.Substr(posStart, posEnd-1);
if(centralDeviceIDs.Length().ToInteger()==0)
{
centralDeviceIDs=tempDeviceID;
}
else
{
centralDeviceIDs=centralDeviceIDs # "," # tempDeviceID;
}
if(centralXCloudIDs.Length().ToInteger()==0)
{
centralXCloudIDs=tempXCloudID;
}
else
{
centralXCloudIDs=centralXCloudIDs # "," # tempXCloudID;
}
}
elseif(tempDeviceType=="camera")
{
if(cameraDeviceIDs.Length().ToInteger()==0)
{
cameraDeviceIDs=tempDeviceID;
}
else
{
cameraDeviceIDs=cameraDeviceIDs # "," # tempDeviceID;
}
}
! XCloudID suchen
posStart=res.Find("\"xCloudId\"");
posEnd=res.Length()-posStart;
res=res.Substr(posStart, posEnd);
posStart=res.Find(":");
posEnd=res.Length()-posStart;
res=res.Substr(posStart, posEnd);
posStart=res.Find("\"deviceId\"");
}
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloUserID").State(userID);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralDeviceIDs").State(centralDeviceIDs);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralXCloudIDs").State(centralXCloudIDs);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraDeviceIDs").State(cameraDeviceIDs);
! Erzeugung der Systemvariablen für die Kameras
cameraDeviceIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraDeviceIDs").Value();
foreach(cameraDeviceID, cameraDeviceIDs.Split(","))
{
! Systemvariable (Zeichenkette) für URL des Standbilds der Kamera
string svName="arloCameraImageURL" # cameraDeviceID;
object svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Standbild der Kamera " # cameraDeviceID);
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable (Zeichenkette) für Zeitpunkt des Videos der Kamera
string svName="arloCameraVideoTime" # cameraDeviceID;
object svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Zeitpunkt des letzten Videos der Kamera " # cameraDeviceID);
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
! Systemvariable (Zeichenkette) für URL des Videos der Kamera
string svName="arloCameraVideoURL" # cameraDeviceID;
object svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("letztes Video der Kamera " # cameraDeviceID);
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
}
! Erzeugung der Systemvariablen für die Zentralen
centralDeviceIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralDeviceIDs").Value();
foreach(centralDeviceID, centralDeviceIDs.Split(","))
{
! Systemvariable vom Typ Zeichenkette wird definiert und mit Startwert gefüllt
string svName="arloCentralState" # centralDeviceID;
object svObj=dom.GetObject(svName);
if(!svObj)
{
svObj = dom.CreateObject(OT_VARDP);
dom.GetObject(ID_SYSTEM_VARIABLES).Add(svObj.ID());
svObj.Name(svName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("aktueller Status der Basis " # centralDeviceID);
svObj.ValueUnit("");
svObj.DPArchive(false);
svObj.State("???");
svObj.Internal(false);
svObj.Visible(true);
dom.RTUpdate(false);
}
}
Damit ist das Setup abgeschlossen.
Zum aktivieren beziehungsweise deaktivieren können die beiden folgenden Skripte genutzt werden. Sie können in andere Programme integriert werden.
- arlo System aktivieren:
Code: Alles auswählen
! arlo System aktivieren ! v3.0 - 20200903 [pen] string res; string err; string success; string token; string centralDeviceIDs; string centralDeviceID; string centralXCloudIDs; string centralXCloudID; integer posStart; integer posEnd; integer cnt; time tokenGenerationTime; time now=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); ! Token überprüfen tokenGenerationTime=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").Value().ToInteger().ToTime(); ! Prüfen ob ein Token gespeichert und wenn ja ob es neuer als 15 Tage (1296000) ist if((tokenGenerationTime.ToInteger()==0) || ((tokenGenerationTime.ToInteger()+1296000) < now)) { !Kein gültiges Token vorhanden, neues Token erzeugen system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/auth' -H 'Content-Type: application/json; charset=utf-8' -H 'Referer: https://my.arlo.com/' -d '{\"email\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").Value() # "\",\"password\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").Value() # "\",\"language\":\"de\",\"EnvSource\":\"prod\"}'", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"code\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd-1); if(success<>200) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming getToken: " # res); quit; } ! Token suchen posStart=res.Find("\"token\""); posEnd=res.Length()-posStart; token=res.Substr(posStart, posEnd); posStart=token.Find(":"); posEnd=token.Length()-posStart; token=token.Substr(posStart, posEnd); posStart=2; posEnd=token.Find(",")-posStart; token=token.Substr(posStart, posEnd-1); ! Token validieren system.Exec("echo '" # token # "' | base64", &res, &err); tokenBase64=res.Replace("\n",""); posEnd=tokenBase64.Length()-4; tokenBase64=tokenBase64.Substr(0,posEnd); nowTokenValidate=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20" # nowTokenValidate.ToInteger() # "' -H 'Authorization: " # tokenBase64 # "' -H 'Referer: https://my.arlo.com/'", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"code\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd-1); if(success<>200) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming validateToken: " # res); quit; } ! Token Validierung erfolgreich posStart=res.Find("\"tokenValidated\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find("}"); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd); if(success<>"true") { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming validateTokenState: " # res); quit; } ! Token und Zeitpunkt speichern dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").State(token); tokenGenerationTime=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").State(tokenGenerationTime.ToInteger()); } else { token=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").Value(); } ! Status auf aktiviert setzten centralDeviceIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralDeviceIDs").Value(); centralXCloudIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralXCloudIDs").Value(); foreach(centralDeviceID, centralDeviceIDs.Split(",")) { centralXCloudID=centralXCloudIDs.StrValueByIndex(",",cnt); system.Exec("curl --max-time 10 -H \"Content-Type: application/json;charset=UTF-8\" -H \"Authorization: " #token# "\" -H \"xCloudId: "#centralXCloudID#"\" -d '{\"from\":\""#dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloUserID").Value()#"_web\",\"to\":\""#centralDeviceID#"\",\"action\":\"set\",\"resource\":\"modes\",\"transId\":\"web!3975ac7b.ebb3a8!1504266382584\",\"publishResponse\":true,\"properties\":{\"active\":\"mode1\"}}' -X POST \"https://my.arlo.com/hmsweb/users/devices/notify/"#centralDeviceID#"\"", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"success\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd); if(success<>true) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec ("logger -t arloAPI -p user.debug arming action: " # res); quit; } cnt=cnt+1; } dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("erfolgreich"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("aktiviert"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastStatusUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
- arlo System deaktivieren:
Code: Alles auswählen
! arlo System deaktivieren ! v3.0 - 20200903 [pen] string res; string err; string success; string token; string centralDeviceIDs; string centralDeviceID; string centralXCloudIDs; string centralXCloudID; integer posStart; integer posEnd; integer cnt; time tokenGenerationTime; time now=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); ! Token überprüfen tokenGenerationTime=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").Value().ToInteger().ToTime(); ! Prüfen ob ein Token gespeichert und wenn ja ob es neuer als 15 Tage (1296000) ist if((tokenGenerationTime.ToInteger()==0) || ((tokenGenerationTime.ToInteger()+1296000) < now)) { !Kein gültiges Token vorhanden, neues Token erzeugen system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/auth' -H 'Content-Type: application/json; charset=utf-8' -H 'Referer: https://my.arlo.com/' -d '{\"email\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").Value() # "\",\"password\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").Value() # "\",\"language\":\"de\",\"EnvSource\":\"prod\"}'", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"code\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd-1); if(success<>200) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming getToken: " # res); quit; } ! Token suchen posStart=res.Find("\"token\""); posEnd=res.Length()-posStart; token=res.Substr(posStart, posEnd); posStart=token.Find(":"); posEnd=token.Length()-posStart; token=token.Substr(posStart, posEnd); posStart=2; posEnd=token.Find(",")-posStart; token=token.Substr(posStart, posEnd-1); ! Token validieren system.Exec("echo '" # token # "' | base64", &res, &err); tokenBase64=res.Replace("\n",""); posEnd=tokenBase64.Length()-4; tokenBase64=tokenBase64.Substr(0,posEnd); nowTokenValidate=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20" # nowTokenValidate.ToInteger() # "' -H 'Authorization: " # tokenBase64 # "' -H 'Referer: https://my.arlo.com/'", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"code\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd-1); if(success<>200) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming validateToken: " # res); quit; } ! Token Validierung erfolgreich posStart=res.Find("\"tokenValidated\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find("}"); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd); if(success<>"true") { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec("logger -t arloAPI -p user.debug arming validateTokenState: " # res); quit; } ! Token und Zeitpunkt speichern dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").State(token); tokenGenerationTime=system.Date("%Y-%m-%d %H:%M:%S").ToTime(); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").State(tokenGenerationTime.ToInteger()); } else { token=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").Value(); } ! Status auf deaktiviert setzten centralDeviceIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralDeviceIDs").Value(); centralXCloudIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralXCloudIDs").Value(); foreach(centralDeviceID, centralDeviceIDs.Split(",")) { centralXCloudID=centralXCloudIDs.StrValueByIndex(",",cnt); system.Exec("curl --max-time 10 -H \"Content-Type: application/json;charset=UTF-8\" -H \"Authorization: " #token# "\" -H \"xCloudId: "#centralXCloudID#"\" -d '{\"from\":\""#dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloUserID").Value()#"_web\",\"to\":\""#centralDeviceID#"\",\"action\":\"set\",\"resource\":\"modes\",\"transId\":\"web!3975ac7b.ebb3a8!1504266382584\",\"publishResponse\":true,\"properties\":{\"active\":\"mode0\"}}' -X POST \"https://my.arlo.com/hmsweb/users/devices/notify/"#centralDeviceID#"\"", &res, &err); ! Erfolg oder nicht erfolg suchen posStart=res.Find("\"success\""); posEnd=res.Length()-posStart; success=res.Substr(posStart, posEnd); posStart=success.Find(":")+1; posEnd=success.Length()-posStart; success=success.Substr(posStart, posEnd); posEnd=success.Find(","); if(posEnd==-1) { posEnd=success.Find("}"); } success=success.Substr(0,posEnd); if(success<>true) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); system.Exec ("logger -t arloAPI -p user.debug disarming action: " # res); quit; } cnt=cnt+1; } dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("erfolgreich"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M")); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("deaktiviert"); dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastStatusUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
Code: Alles auswählen
! arlo Status aktualisieren und in Systemvariable schreiben
! v3.0 - 20200903 [pen]
string res;
string err;
string success;
string token;
string centralDeviceIDs;
string centralDeviceID;
string centralXCloudIDs;
string centralXCloudID;
string mode;
integer posStart;
integer posEnd;
integer cnt;
time tokenGenerationTime;
time now=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
! Token überprüfen
tokenGenerationTime=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").Value().ToInteger().ToTime();
! Prüfen ob ein Token gespeichert und wenn ja ob es neuer als 15 Tage (1296000) ist
if((tokenGenerationTime.ToInteger()==0) || ((tokenGenerationTime.ToInteger()+1296000) < now))
{
!Kein gültiges Token vorhanden, neues Token erzeugen
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/auth' -H 'Content-Type: application/json; charset=utf-8' -H 'Referer: https://my.arlo.com/' -d '{\"email\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").Value() # "\",\"password\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").Value() # "\",\"language\":\"de\",\"EnvSource\":\"prod\"}'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming getToken: " # res);
quit;
}
! Token suchen
posStart=res.Find("\"token\"");
posEnd=res.Length()-posStart;
token=res.Substr(posStart, posEnd);
posStart=token.Find(":");
posEnd=token.Length()-posStart;
token=token.Substr(posStart, posEnd);
posStart=2;
posEnd=token.Find(",")-posStart;
token=token.Substr(posStart, posEnd-1);
! Token validieren
system.Exec("echo '" # token # "' | base64", &res, &err);
tokenBase64=res.Replace("\n","");
posEnd=tokenBase64.Length()-4;
tokenBase64=tokenBase64.Substr(0,posEnd);
nowTokenValidate=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20" # nowTokenValidate.ToInteger() # "' -H 'Authorization: " # tokenBase64 # "' -H 'Referer: https://my.arlo.com/'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateToken: " # res);
quit;
}
! Token Validierung erfolgreich
posStart=res.Find("\"tokenValidated\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find("}");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success<>"true")
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateTokenState: " # res);
quit;
}
! Token und Zeitpunkt speichern
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").State(token);
tokenGenerationTime=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").State(tokenGenerationTime.ToInteger());
}
else
{
token=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").Value();
}
centralXCloudIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCentralXCloudIDs").Value();
centralXCloudID=centralXCloudIDs.StrValueByIndex(",",cnt);
system.Exec("curl --max-time 10 -H \"Content-Type: application/json;charset=UTF-8\" -H \"Authorization: " #token# "\" -H \"xCloudId: "#centralXCloudID#"\" -X GET \"https://my.arlo.com/hmsweb/users/devices/automation/active\"", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"success\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success==true)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("erfolgreich");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
}
else
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec ("logger -t arloAPI -p user.debug updateState action: " # res);
quit;
}
! Status auswerten
posStart=res.Find("\"activeModes\"");
posEnd=res.Length()-posStart;
mode=res.Substr(posStart, posEnd);
posStart=mode.Find("[");
posEnd=mode.Length()-posStart;
mode=mode.Substr(posStart, posEnd);
posStart=2;
posEnd=mode.Find("]")-posStart;
mode=mode.Substr(posStart, posEnd-1);
if(mode=="mode0")
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("deaktiviert");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastStatusUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
}
elseif(mode=="mode1")
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("aktiviert");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastStatusUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
}
else
{
posStart=res.Find("\"activeSchedules\"");
posEnd=res.Length()-posStart;
mode=res.Substr(posStart, posEnd);
posStart=mode.Find("[");
posEnd=mode.Length()-posStart;
mode=mode.Substr(posStart, posEnd);
posStart=2;
posEnd=mode.Find("]")-posStart;
mode=mode.Substr(posStart, posEnd-1);
if(mode.Contains("schedule"))
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("Zeitsteuerung " # mode.Replace("schedule.", ""));
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastStatusUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
}
else
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCurrentState").State("unbekannt");
}
}
Code: Alles auswählen
! arlo Video- und Snapshot-Links aktualisieren und in Systemvariablen schreiben
! v3.0 - 20200903 [pen]
string res;
string res2;
string err;
string success;
string token;
string cameraDeviceIDs;
string cameralDeviceID;
string centralXCloudIDs;
string centralXCloudID;
string dateTo;
string dateFrom;
string timeTo;
string snapshotTime;
string snapshot;
string thumbnail;
integer posStart;
integer posEnd;
integer cnt;
time tokenGenerationTime;
time now=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
time timeTimeTo;
! Token überprüfen
tokenGenerationTime=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").Value().ToInteger().ToTime();
! Prüfen ob ein Token gespeichert und wenn ja ob es neuer als 15 Tage (1296000) ist
if((tokenGenerationTime.ToInteger()==0) || ((tokenGenerationTime.ToInteger()+1296000) < now))
{
!Kein gültiges Token vorhanden, neues Token erzeugen
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/auth' -H 'Content-Type: application/json; charset=utf-8' -H 'Referer: https://my.arlo.com/' -d '{\"email\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloEMail").Value() # "\",\"password\":\"" # dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloPasswordEncrypted").Value() # "\",\"language\":\"de\",\"EnvSource\":\"prod\"}'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming getToken: " # res);
quit;
}
! Token suchen
posStart=res.Find("\"token\"");
posEnd=res.Length()-posStart;
token=res.Substr(posStart, posEnd);
posStart=token.Find(":");
posEnd=token.Length()-posStart;
token=token.Substr(posStart, posEnd);
posStart=2;
posEnd=token.Find(",")-posStart;
token=token.Substr(posStart, posEnd-1);
! Token validieren
system.Exec("echo '" # token # "' | base64", &res, &err);
tokenBase64=res.Replace("\n","");
posEnd=tokenBase64.Length()-4;
tokenBase64=tokenBase64.Substr(0,posEnd);
nowTokenValidate=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
system.Exec("curl --max-time 5 'https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20" # nowTokenValidate.ToInteger() # "' -H 'Authorization: " # tokenBase64 # "' -H 'Referer: https://my.arlo.com/'", &res, &err);
! Erfolg oder nicht erfolg suchen
posStart=res.Find("\"code\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd-1);
if(success<>200)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateToken: " # res);
quit;
}
! Token Validierung erfolgreich
posStart=res.Find("\"tokenValidated\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find("}");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success<>"true")
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
system.Exec("logger -t arloAPI -p user.debug arming validateTokenState: " # res);
quit;
}
! Token und Zeitpunkt speichern
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").State(token);
tokenGenerationTime=system.Date("%Y-%m-%d %H:%M:%S").ToTime();
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloTokenGenerationTime").State(tokenGenerationTime.ToInteger());
}
else
{
token=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloToken").Value();
}
! Heutiges Datum für Abruf festlegen
timeTimeTo=system.Date("%d.%m.%Y").ToTime();
dateTo=timeTimeTo.Format("%F");
dateTo=dateTo.Replace("-", "");
! 8 Tage abziehen
timeTimeTo=timeTimeTo-691200;
dateFrom=timeTimeTo.Format("%F");
dateFrom=dateFrom.Replace("-", "");
centralXCloudID=centralXCloudIDs.StrValueByIndex(",",0);
system.Exec("curl --max-time 10 -H \"Content-Type: application/json;charset=UTF-8\" -H \"Authorization: " #token# "\" -H \"xCloudId: "#centralXCloudID#"\" -d '{\"dateFrom\":\""#dateFrom#"\",\"dateTo\":\""#dateTo#"\"}' -X POST \"https://my.arlo.com/hmsweb/users/library\"", &res, &err);
! Erfolg oder nicht erfolg prüfen
posStart=res.Find("\"success\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":")+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success<>true)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
quit;
}
system.Exec("curl --max-time 10 -H \"Content-Type: application/json;charset=UTF-8\" -H \"Authorization: " #token# "\" -H \"xCloudId: "#centralXCloudID#"\" -X GET \"https://my.arlo.com/hmsweb/users/devices\"", &res2, &err);
! Erfolg oder nicht erfolg prüfen
posStart=res.Find("\"success\"");
posEnd=res.Length()-posStart;
success=res.Substr(posStart, posEnd);
posStart=success.Find(":");
posStart=posStart+1;
posEnd=success.Length()-posStart;
success=success.Substr(posStart, posEnd);
posEnd=success.Find(",");
if(posEnd==-1)
{
posEnd=success.Find("}");
}
success=success.Substr(0,posEnd);
if(success==true)
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("erfolgreich");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
}
else
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionResult").State("fehlerhaft");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastConnectionTime").State(system.Date("%d.%m.%Y %H:%M"));
quit;
}
snapshotTime="";
snapshot="";
thumbnail="";
posStart=0;
posEnd=0;
cameraDeviceIDs=dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraDeviceIDs").Value();
foreach(cameralDeviceID, cameraDeviceIDs.Split(","))
{
snapshotTime="";
snapshot="";
thumbnail="";
posStart=0;
posEnd=0;
posStart=res.Find(cameralDeviceID);
posEnd=res.Length();
time t=0;
if(posStart >= 0)
{
posEnd=posEnd-posStart;
snapshotTime=res.Substr(posStart, posEnd);
snapshot=res.Substr(posStart, posEnd);
thumbnail=res.Substr(posStart, posEnd);
posStart=snapshotTime.Find("\"localCreatedDate\"");
posEnd=snapshotTime.Length()-posStart;
snapshotTime=snapshotTime.Substr(posStart, posEnd);
posStart=snapshotTime.Find(":");
posEnd=snapshotTime.Length()-posStart;
snapshotTime=snapshotTime.Substr(posStart, posEnd);
posStart=1;
posEnd=snapshotTime.Find(",")-posStart;
snapshotTime=snapshotTime.Substr(posStart, posEnd-3);
system.Exec("date -d @" # snapshotTime # " +'%Y-%m-%d %H:%M:%S'", &snapshotTime, &err);
t=snapshotTime.ToTime();
snapshotTime=t.Format("%d.%m.%Y %H:%M:%S");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoTime"#cameralDeviceID).State(snapshotTime);
posStart=snapshot.Find("\"presignedContentUrl\"");
posEnd=snapshot.Length()-posStart;
snapshot=snapshot.Substr(posStart, posEnd);
posStart=snapshot.Find(":");
posEnd=snapshot.Length()-posStart;
snapshot=snapshot.Substr(posStart, posEnd);
posStart=2;
posEnd=snapshot.Find(",")-posStart;
snapshot=snapshot.Substr(posStart, posEnd-1);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoURL"#cameralDeviceID).State(snapshot);
posStart=thumbnail.Find("\"presignedThumbnailUrl\"");
posEnd=thumbnail.Length()-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd);
posStart=thumbnail.Find(":");
posEnd=thumbnail.Length()-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd);
posStart=2;
posEnd=thumbnail.Find(",")-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd-1);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraImageURL"#cameralDeviceID).State(thumbnail);
}
else
{
! mittels GetDevices letztes Bild abrufen, wenn kein Video in der Library vorhanden ist
posStart=res2.Find(cameralDeviceID);
posEnd=res2.Length();
!time t=0;
if(posStart >= 0)
{
posEnd=posEnd-posStart;
thumbnail=res2.Substr(posStart, posEnd);
posStart=thumbnail.Find("\"presignedLastImageUrl\"");
if(posStart>0)
{
posEnd=thumbnail.Length()-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd);
posStart=thumbnail.Find(":");
posEnd=thumbnail.Length()-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd);
posStart=2;
posEnd=thumbnail.Find(",")-posStart;
thumbnail=thumbnail.Substr(posStart, posEnd-1);
if(thumbnail.Contains(cameralDeviceID))
{
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraImageURL"#cameralDeviceID).State(thumbnail);
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoURL"#cameralDeviceID).State("kein Video");
}
else
{
! kein lastImage für die Kamera vorhanden
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraImageURL"#cameralDeviceID).State("kein Bild");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoTime"#cameralDeviceID).State("");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoURL"#cameralDeviceID).State("kein Video");
}
}
else
{
! kein lastImage für die Kamera vorhanden
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraImageURL"#cameralDeviceID).State("kein Bild");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoTime"#cameralDeviceID).State("");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoURL"#cameralDeviceID).State("kein Video");
}
}
else
{
! kein lastImage für die Kamera vorhanden
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraImageURL"#cameralDeviceID).State("kein Bild");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoTime"#cameralDeviceID).State("");
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloCameraVideoURL"#cameralDeviceID).State("kein Video");
}
}
}
dom.GetObject(ID_SYSTEM_VARIABLES).Get("arloLastLinkUpdateTime").State(system.Date("%d.%m.%Y %H:%M"));
Die letzten beiden Skripts (Aktualisierung des Status und Aktualisierung der Links) können regelmäßig ausgeführt werden. Dadurch hat man einerseits meistens den aktuellen Status in der Visualisierung und andererseits einen Link zum letzten Video.
Vielleicht ist dies eine Unterstützung für den einen oder anderen, der dieses System einsetzt und dem die Zeitsteuerung auch zu unflexibel ist und eine dauer-aktiv-Schaltung den ganzen Tag ebenfalls stört.
Wer die Skripte auf einer CCU2 oder RaspberryMatic ausprobieren möchte, kann dies gern tun und eventuell eine kurze Rückmeldung geben. Gleiches gilt für Setups mit mehreren Basisstationen im Zusammenspiel mit dem (de)aktivieren des Systems. Natürlich sind auch alle anderen Rückmeldungen willkommen.
Viel Spaß bei der Umsetzung
pen
Änderungen:
26.07.2020: Verbesserung des Einrichtungsprozesses; Aktualisierungsintervall des Tokens verringert; Erweiterung der Hinweise
19.07.2020: Aktualisierungs-Skript aktualisiert
08.09.2020: Login-/Tokengenerierungsprozess angepasst
20.09.2020: Username und Passwort wurde vom ersten Script nicht gesetzt
09.04.2021: Hinweis zur ab 18.04.2021 obligatorischen 2FA hinzugefügt