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
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") 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. Hierzu ein Benutzer-Konto mit "Full Management"-Rechten hinsichtlich Protect im Web-Interface unter People nutzen (die Login-Credentials im Code unten anpassen).
Dafür einfach ein .py-File (z.B. "UnifiRecMode.py") mit folgendem Inhalt anlegen und über den File manager 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 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m never python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m detections
python3 /opt/loxberry/webfrontend/html/XL/user/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
Sobald die offizielle API den Endpoint exponiert sollte das Ganze aber auch ohne Loxberry möglich sein...