Unifi Protect - Recording Mode schalten (mit Loxberry)

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • MarkusCosi
    LoxBus Spammer
    • 28.09.2023
    • 369

    #1

    Unifi Protect - Recording Mode schalten (mit Loxberry)

    Hallo zusammen,

    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. 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).
    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: protect3.jpg Ansichten: 0 Größe: 38,5 KB ID: 485838

    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"):

    Code:
    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()
    ...in der Loxone Config kann das Skript dann über einen virtuellen Ausgang und das AnyPlugin des Loxberry benutzt werden, d.h. die folgenden Befehle setzt das AnyPlugin dann ab (die kann man auch zunächst im Loxberry Terminal testen):

    Code:
    python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m never
    python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m detections
    oder
    Code:
    python3 /opt/loxberry/webfrontend/html/XL/user/UnifiRecMode.py -m detections -f "Kamera Name"
    Hierzu einen virt. Ausgang anlegen zum AnyPlugin (Adresse: tcp://192.168.1.101:9095, Verbindung nach Senden schließen), darin einen virt. Befehl (Methode: GET, digital) mit folgenden Befehlen bei EIN und AUS:
    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 unter Devices...
    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: protect.jpg Ansichten: 0 Größe: 139,4 KB ID: 485786
    In der Loxone Config kann das dann so aussehen (Schaltuhr nutzt den Modus "Abwesend" ganztägig):
    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: protect2.jpg Ansichten: 0 Größe: 21,2 KB ID: 485836

    Sobald die offizielle API den Endpoint exponiert sollte das Ganze aber auch ohne Loxberry möglich sein...
    Zuletzt geändert von MarkusCosi; vor einer Stunde.
  • bazzman
    Extension Master
    • 24.09.2019
    • 189

    #2
    Coole Sache! Ich hatte das mit einem Alpha-Status-Loxberry Plugin realisiert (mit etwas Perl Code), aber damit wäre es deutlich einfacher ;-)

    Kommentar

    Lädt...