Unifi Protect - Recording Mode schalten (mit Loxberry)

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

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

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

    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 UnifiRecMode.py -m never
    python3 UnifiRecMode.py -m detections
    oder
    Code:
    python3 UnifiRecMode.py -m detections -f "Kamera Name"
    Hierzu einen virt. Ausgang anlegen zum AnyPlugin (Adresse: tcp://<<IPLoxberry>>:9095, Verbindung nach Senden schließen), darin einen virt. Ausgang 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 von Protect 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 Woche.
  • 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


    • MarkusCosi
      MarkusCosi kommentierte
      Kommentar bearbeiten
      ..klingt auch interessant! Was für ein Plugin ist das denn?

    • bazzman
      bazzman kommentierte
      Kommentar bearbeiten
      Das liegt aktuell hier https://github.com/paolobazzi/LoxBer...Unifi-Protect/ ist aber pre-pre-Alpha und einfach mal kurz an einem Abend zusammenkopiert gewesen. Kann aktuell einfach den Recording Mode meiner Kamera ein/ausschalten. Weiss noch nicht ob ich das mal noch weiter entwickle (Konfiguration, unverwendete Teile aus dem kopierten Plugin löschen) oder ob ich mal auf deine Lösung umhänge. Vielleicht bewegt sich ja Unifi mal noch und man könnte via offizieller API gehen.
  • GeoPod
    MS Profi
    • 20.01.2021
    • 552

    #3
    Vielen Dank MarkusCosi und bazzman . Wirklich sehr spannend. Wenn ich mal Zeit habe, versuche ich dies mal umzusetzen.
    Bin sehr froh, dass ich beim Hausbau neben Loxone auf Unifi gesetzt habe. Ich nutze aber nur einen Bruchteil davon aus.

    Kommentar

    • MarkusCosi
      LoxBus Spammer
      • 28.09.2023
      • 373

      #4
      ...P.S.: es empfiehlt sich, im Protect Webinterface bzw. dem dortigen "Alarm Manager" den Alarm "Admin Change Settings" zu pausieren. Andernfalls bekommt man ständig z.B. auf dem Handy Push-Benachrichtigungen über den geänderten Rec-Mode ... Im "System Log" unter "Audit" sieht man natürlich weiterhin die über das Skript oder anderweitig getriggerten Änderungen als Type "Device Settings" ...

      Kommentar

      Lädt...