Ziel: Aufzeichnungsmodus in Unifi Protect für Kameras abhängig von Anwesenheit / Abwesenheit ändern. D.h., Video-Aufzeichnungen z.B. nur bei Abwesenheit.
Benötigt: Loxberry mit dem AnyPlugin, ggf. noch das python requests package installieren (https://requests.readthedocs.io/en/latest/user/install/)
Leider erlaubt die aktuelle offizielle API zu Protect (UniFi Protect API (7.1.76), siehe https://<<IP_UDM>>/unifi-api/protect unter "Patch camera settings", bzw. https://developer.ui.com/protect/v7....ch-v1camerasid) noch nicht den Recording Modus einzelner Kameras oder übergreifend zu ändern. Dort sind bisher nur folgende Endpunkte dokumentiert: name, osdSettings, ledSettings, lcdMessage, lcdMessage, micVolume, videoMode, hdrType, smartDetectSettings.
Die interne, inoffizielle API erlaubt dennoch ein Anpassen des Rec-Modes. Der Ansatz gestaltet sich analog zu dem PoE-Schalten eines Unifi Switches (hier). Hierzu ein Benutzer-Konto mit "Full Management"-Rechten hinsichtlich Protect im Web-Interface links unten unter People nutzen (die Login-Credentials im Code unten im .py -file anpassen, ggf. einen dedizierten Nutzer mit "local access only" einrichten).
Dazu einfach ein .py-File (z.B. "UnifiRecMode.py") mit folgendem Inhalt z.B. mit einem Texteditor anlegen und über den Dateimanager des Loxberry unter /opt/loxberry/webfrontend/html/XL/user/ ablegen (und im Loxberry-Terminal "chmod +x UnifiRecMode.py"):
import requests
import argparse
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
UDM_HOST = "https://<<IP_UDM>>"
USERNAME = "yourUserName"
PASSWORD = "yourPW"
session = requests.Session()
session.verify = False
csrf_token = None
def login():
global csrf_token
r = session.post(
f"{UDM_HOST}/api/auth/login",
json={
"username": USERNAME,
"password": PASSWORD
},
)
r.raise_for_status()
csrf_token = (
r.headers.get("x-updated-csrf-token")
or r.headers.get("x-csrf-token")
)
print("CSRF:", csrf_token)
def get_cameras():
r = session.get(f"{UDM_HOST}/proxy/protect/api/cameras")
r.raise_for_status()
return r.json()
def set_mode(cam_id, mode):
headers = {
"X-CSRF-Token": csrf_token,
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json",
}
r = session.patch(
f"{UDM_HOST}/proxy/protect/api/cameras/{cam_id}",
json={
"recordingSettings": {
"mode": mode
}
},
headers=headers,
)
print(r.status_code, r.text[:500])
r.raise_for_status()
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", required=True, help="always | detections | never")
parser.add_argument("-f", "--filter", default="", help="camera name filter substring")
args = parser.parse_args()
login()
cams = get_cameras()
for cam in cams:
name = cam.get("name", "")
cam_id = cam.get("id")
if args.filter and args.filter not in name:
continue
print(f"{name} -> {args.mode}")
try:
set_mode(cam_id, args.mode)
print(" OK")
except Exception as e:
print(f" FAIL: {e}")
if __name__ == "__main__":
main()
python3 UnifiRecMode.py -m never python3 UnifiRecMode.py -m detections
python3 UnifiRecMode.py -m detections -f "Kamera Name"
UnifiCamRecOn off command python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m detections
UnifiCamRecOff off command python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m never
Zum Check: Die Änderungen sieht man instantan in der Weboberfläche von Protect unter Devices...
In der Loxone Config kann das dann so aussehen (Schaltuhr nutzt den Modus "Abwesend" ganztägig):
Sobald die offizielle API den Endpoint exponiert sollte das Ganze aber auch ohne Loxberry möglich sein...
... Im "System Log" unter "Audit" sieht man natürlich weiterhin die über das Skript oder anderweitig getriggerten Änderungen als Type "Device Settings" ...
Kommentar