arlo Kameras mit der CCU steuern

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

pen
Beiträge: 274
Registriert: 16.02.2020, 11:19
System: CCU
Wohnort: Chemnitz
Hat sich bedankt: 1 Mal
Danksagung erhalten: 30 Mal

arlo Kameras mit der CCU steuern

Beitrag von pen » 02.05.2020, 18:54

Hallo zusammen,

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.
Zur Einrichtung können die Variablen automatisiert erzeugt werden. Dazu können die folgenden zwei Skripte verwendet 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);
}
Nach dem die Logindaten geändert wurden, mit OK Skript-Editor verlassen und mit einem weiteren Klick auf OK das Programm speichern. Dabei wird dieses ausgeführt. Nun kann unter "Status und Bedienung" > "Systemvariable" überprüft werden, ob die Variablen aller erzeugt wurden und die Variablen "arloEMail" und "arloPasswordEncrypted" die Zugangsdaten enthalten.

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
Im nächsten Schritt müssen die gerätespezifischen Systemvariablen erzeugt werden. Das nachfolgende (zweite Setup-)Sktipt kann auch dann verwendet werden, wenn dem System neue Kameras oder Basisstationen hinzugefügt wurden. Es prüft, welche Systemvariablen bereits vorhanden sind und erzeugt nur die noch nicht vorhandenen Variablen. In der WebUI wird ein neues Programm erstellt um im Aktivitäts-Teil das folgende Skript hinterlegt:

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);
	}
}
Nun mit OK den Skript-Editor verlassen und mit einem weiteren Klick auf OK das Programm speichern. Dabei wird dieses ausgeführt. Nun kann unter "Status und Bedienung" > "Systemvariable" überprüft werden, ob die gerätespezifischen Variablen erzeugt wurden. Außerdem müssen die Variablen "arloCentralDeviceIDs", "arloCentralXCloudIDs" und "arloCameraDeviceIDs" Werte enthalten.

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"));
    
Der aktuelle Status des arlo Systems kann mit Hilfe des folgenden Skripts abgefragt werden:

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");
	}
}
Zusätzlich habe ich für die Visualisierung (bei mir mediola aio creator neo) jeweils die letzten Links zu dem Snapshot-Bild und zum Video sowie den Zeitpunkt der Aufnahme gespeichert. Dafür nutzte ich das folgende Script:

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"));
Wenn dieses Skript durchgelaufen ist, sollten die Kamera-spezifischen Variablen auch gefüllt worden sein. Zu beachten ist folgendes: Es wird grundsätzlich ein Link zu einen Bild hinterlegt, auch wenn von der Kamera noch keine Aufnahme bereit steht. Mit der ersten Aufnahme steht dann ein Bild zur Verfügung.

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
Zuletzt geändert von pen am 09.04.2021, 19:46, insgesamt 13-mal geändert.

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 16.07.2020, 11:51

Hi pen

Ich suche schon seit längerem eine einfach Möglichkeit die CCU 3 mit ARLO und NEO zu verbinden.
Da bin ich hier auf Deinen Beitrag gestoßen.

Ich habe das alles so gemacht wie Du beschrieben hast.
Funktioniert alles bis auf die Link-Abfrage.
Hier bekomme ich nur die ??? in den Systemvariablen angezeigt.

Kannst Du mir da auf die Sprünge helfen?

Und wenn Du gerade dabei bist, wie binde ich das ganze dann in NEO ein?

Das wäre super nett von Dir.

Gruß

pen
Beiträge: 274
Registriert: 16.02.2020, 11:19
System: CCU
Wohnort: Chemnitz
Hat sich bedankt: 1 Mal
Danksagung erhalten: 30 Mal

Re: arlo Kameras mit der CCU steuern

Beitrag von pen » 19.07.2020, 23:06

Hallo CC3_User,

eine Aktualisierung des Aktualisierungs-Skript wurde eben eingefügt (V2.1). Probiere mal bitte, ob es nun geht.

Zur Anzeige eines Videos in der Remote:
Dafür nutze ich das Element "Webseite". Dort kann das HTML-Gerüst angepasst werden, mittels des Video-Tags kann ein Video angezeigt werden, mit %neo_state% kannst Du den dem Webseiten-Element zugewisenen Status abrufen:

Code: Alles auswählen

<video width="1280" height="720" controls>
  <source  src="%neo_state%" type="video/mp4">
  Ihr Browser kann dieses Video nicht wiedergeben.
</video>
Das funktioniert unter Windows problemlos (nutze ein 10" Tablet für die Remote), wie das unter Android/iOS aussieht kann ich nicht sagen.

Viel Erfolg

pen

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 20.07.2020, 09:08

Hi pen

Super. Dank Dir.
Ich probiere das heute Abend mal aus.
Melde mich ob es funktioniert hat.

Gruß

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 21.07.2020, 07:28

Hi pen

Funktioniert alles super.
Vielen Dank für die Hilfe.

Ist es eigentlich möglich, den Zeit-Stempel der Aufnahmen "arloCameraVideoTime" auch irgendwie in NEO anzeigen zu lassen?
Das wäre noch genial.

Eine kleine Anmerkung zu Deinem Leitfaden, der im Grunde super geschrieben ist.
Ich musste erst verstehen, das ich für JEDE Kamera diese 3 Systemvariablen anlegen musste. (Also 3 Kameras --> 9 Variablen)
Das überliest man leicht. Du könntest die Systemvariable "arloCameraDeviceIDs" in dem Zusammenhang etwas ausführlicher beschreiben.

arloCameraImageURL*
arloCameraVideoURL*
arloCameraVideoTime*
* = DeviceID der Kamera, direkt ohne Lehrzeichen o.ä.

Gruß

pen
Beiträge: 274
Registriert: 16.02.2020, 11:19
System: CCU
Wohnort: Chemnitz
Hat sich bedankt: 1 Mal
Danksagung erhalten: 30 Mal

Re: arlo Kameras mit der CCU steuern

Beitrag von pen » 21.07.2020, 17:08

Hallo CC3_User,
CC3_User hat geschrieben:
21.07.2020, 07:28
Ist es eigentlich möglich, den Zeit-Stempel der Aufnahmen "arloCameraVideoTime" auch irgendwie in NEO anzeigen zu lassen?
Ja, das ist möglich. Du kannst die Systemvariable in NEO importieren und anzeigen lassen:
Remote_Video.png
[Der Kamera "Eingang" ist neu und hat noch kein Video aufgenommen, deswegen fehlt dort die Zeitangabe]
CC3_User hat geschrieben:
21.07.2020, 07:28
Ich musste erst verstehen, das ich für JEDE Kamera diese 3 Systemvariablen anlegen musste. (Also 3 Kameras --> 9 Variablen)
Das überliest man leicht. Du könntest die Systemvariable "arloCameraDeviceIDs" in dem Zusammenhang etwas ausführlicher beschreiben.
Ja, ich habe mittlerweile auch ein zweistufiges Setup-Script fast fertig, dass die notwendigen Variablen automatisch anlegt, auch dann, wenn einige bereits vorhanden sind (z.B. bei einer Erweiterung des Systems).

Die Variable "arloCameraDeviceIDs" enthält alle IDs der Kameras mit einem Komma getrennt. Ich benötige dies, um mit foreach für jede Kamera die entsprechenden Werte in der Antwort der API zu suchen.

Viele Grüße

pen

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 22.07.2020, 09:54

Hallo pen

Super. Vielen Dank für die Informationen.
Werde aber zeitlich bedingt wohl erst am Wochenende zum Testen kommen.

Nochmals danke für die freundliche Hilfe.

Ich denke, jetzt habe ich erstmal ein paar Abende zu tun :D
Mal sehen, wie es läuft.

Gruß
CC3_User

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 23.07.2020, 13:31

Hi pen

Habe da noch so zwei blöde Fragen.
Anscheinend ändert sich durch den Status / Link Refresh die URL von Zeit zu Zeit.
Wie bekomme ich es den hin, immer die akt. URL in NEO zu erhalten?
Kann ich da irgendwo die Systemvariable eintragen?

Irgendwie schaffe ich es auch nicht, ein ganzes Bild meiner Kameras im festgelegten Frame zu sehen.
Es erscheint immer nur ein Ausschnitt.
Welches NEO-Werkzeug nimmst Du denn in Deinem Bild für die Frames der Kameras?

Dank Dir.

pen
Beiträge: 274
Registriert: 16.02.2020, 11:19
System: CCU
Wohnort: Chemnitz
Hat sich bedankt: 1 Mal
Danksagung erhalten: 30 Mal

Re: arlo Kameras mit der CCU steuern

Beitrag von pen » 23.07.2020, 17:03

Hallo CC3_User,
CC3_User hat geschrieben:
23.07.2020, 13:31
Anscheinend ändert sich durch den Status / Link Refresh die URL von Zeit zu Zeit.
Wie bekomme ich es den hin, immer die akt. URL in NEO zu erhalten?
Ich habe für die Kameras eine Unterseite, die ich von der Hauptseite aus erreichen kann. Durch den Aufruf habe ich immer die aktuellen Werte der Systemvariablen. Alternativ könntest Du einen Refresh der Seite in einem bestimmten Intervall angeben.
Bei mir wird der Staus jede halbe Stunde aktualisiert. Die Links lasse ich nur aktualisieren, wenn arlo auch aktiviert ist. Dies geschieht dann ebenfalls zu jeder halben Stunde oder außerplanmäßig, wenn die Alarmanlage [und somit auch arlo] deaktivert wird.
Ansonsten sind die Links 24 Stunden gültig, dass ist von arlo in der URL mit angegeben.
CC3_User hat geschrieben:
23.07.2020, 13:31
Kann ich da irgendwo die Systemvariable eintragen?
Welches NEO-Werkzeug nimmst Du denn in Deinem Bild für die Frames der Kameras?
Ich nehme auch für die Bildanzeige je Kamera ein Element vom Typ "Webseite" und weise dem die entsprechende Systemvariable "..ImageURL..." zu. Das HTML Gerüst habe ich wie folgt geändert:

Code: Alles auswählen

<img width=600 src="%neo_state%">
CC3_User hat geschrieben:
23.07.2020, 13:31
Irgendwie schaffe ich es auch nicht, ein ganzes Bild meiner Kameras im festgelegten Frame zu sehen.
Es erscheint immer nur ein Ausschnitt.
Ich verstehe nicht ganz, was Du meinst. Kann es sein, dass Du die Bildgröße mittels "width"-Attribut [siehe img-Tag für html] noch anpassen musst, da Dein Element zu klein ist?

Viele Grüße

pen

CC3_User
Beiträge: 11
Registriert: 16.07.2020, 11:43
System: CCU

Re: arlo Kameras mit der CCU steuern

Beitrag von CC3_User » 23.07.2020, 19:56

Hi pen

Ok. Ich nutze ebenfalls den Typ "Webseite"
Trotzdem bekomme ich nur ein weißes Bild angezeigt, wenn ich die Image-Variable zuweise.

Vielleicht kurz zur Klärung.

Der Typ Webseite hat 3 mögliche Punkte zur Parametrierung.
- Webseite
- Status
- HTML-Gerüst

Ich hatte die ganze Zeit den Inhalt der Variable ...ImageURL... in den URL-Link der Webseite kopiert. --> Ist aber ja kontraproduktiv!
Nun habe ich im Status die ...ImageURL... zugewiesen. ---> Ergebnis ist ein weißes Bild im Webseiten-Fenster!
Das HTML-Gerüst (Hauptbereich) habe ich nach Deiner Vorgabe für Images angepasst. Danke dafür übrigens :-)
Autofresh habe ich mal zum Testen auf 30 s eingestellt.
Scrollen ist aus.
Ich glaube, ich mach da noch was entscheidendes falsch?

Du schreibst auch, dass Du für die Kameras eine Unterseite angelegt hast.
Wird durch diesen Aufruf (Button) das CU Programm zum Refresh des Status / Links aufgerufen?

Gruß und Dank Dir.
CC3_User

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“