Kamera Blink

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Gast

    #1

    Kamera Blink

    Hallo,

    Ich hoffe es kann mir jemand helfen. Bin hier ziemlich neu, also Entschuldigung, falls ich das Thema hier falsch Poste. Ich habe das Blink System gefunden (https://www.blinkforhome.de), und wollte fragen, ob jemand so eine Kamera schon mit Loxone in Verwendung hat bzw ob man sie zum Loxone System hinzufügen kann. Der Preis ist momentan recht gut und ich überlege mir diese zu kaufen.

    Danke für die Hilfe.

    Grüße
    Max
  • com4t
    Azubi
    • 10.01.2021
    • 1

    #2
    Ist hier eigentlich schonmal jemand weiter gekommen?
    Hier gibt es ja ne recht schöne Schnittstellen Beschreibung: https://github.com/MattTW/BlinkMonitorProtocol
    Bei mir hakt es grade dabei den digitalen Ausgang richtig zu setzen.
    Der curl Befehl ist:
    curl --request POST --url https://rest-prod.immedia-semi.com/a...1234/state/arm --header 'token-auth: {Auth_Token}'

    Ich habe
    - einen virtuellen Ausgang gesetzt mit der Adresse: https://rest-e003.immedia-semi.com
    - einen virtuellen Ausgangsbefehl gesetzt mit:
    . Befehl bei EIN: /api/v1/accounts/1234/networks/1234/state/arm
    . HTTP-Erweiterung bei EIN: token-auth: {Auth_Token}
    . HTTP_Methode bei EIN: POST
    . Äquivalent bei AUS mit "disarm"

    Hat wer eine Idee, was falsch ist?

    Kommentar


    • Patrick_92
      Patrick_92 kommentierte
      Kommentar bearbeiten
      Hey,

      hast du es inzwischen gelöst bekommen?

    • com4t
      com4t kommentierte
      Kommentar bearbeiten
      HI Patrick,
      ich bin hier leider nicht weiter gekommen, hab mich aber auch nicht mehr hinter geklemmt. Hast du ein Ansatz?
  • Viperdriver2000
    Smart Home'r
    • 24.02.2021
    • 82

    #3
    Ich bin am überlegen mir eine blink zu kaufen.
    Möchte damit die türklingel erweitern.
    Hat das jemand zum laufen bekommen?

    Vielen Dank

    Kommentar

    • julianbmw
      LoxBus Spammer
      • 14.09.2018
      • 261

      #4
      wäre wirklich fein wenn man Blink integrieren könnte -> kosten ja auch nix die dinger

      Kommentar

      • Miep Miep
        MS Profi
        • 18.01.2017
        • 520

        #5
        Ist das nur ne Cloudlösung ? In USA betreiben die ja recht dystopische Ansätze die Besitzer zu überreden prophylaktisch der Polizei Zugriff zu geben. Und die Polizei ist Werbepartner und bekommt Prämien wenn besonders viele Kameras in ihren Bezirken verkauft wurden.

        Das fand ich mega abschreckend.
        Zuletzt geändert von Miep Miep; 29.07.2021, 19:40.
        Es ist nie zu spät für eine glückliche Kindheit.

        Kommentar

      • julianbmw
        LoxBus Spammer
        • 14.09.2018
        • 261

        #6
        jein es gibt jetzt die Möglichkeit für ein Syncmodul in das ein usb stick gesteckt werden muss... vloud kostet glaube ich son 3.- im Monat

        Kommentar

        • Viperdriver2000
          Smart Home'r
          • 24.02.2021
          • 82

          #7
          ich weiß schon älter und ich habe auch schon mal gefragt aber ich liebäugle immer noch mit den cams (aufgrund des Preises und da man keine Kabel verlegen muss).

          hat schon jemand eine integration hinbekommen?

          Kommentar

          • julianbmw
            LoxBus Spammer
            • 14.09.2018
            • 261

            #8
            Leider nein aber im Homeassistant hab ich sie zumindest schon mal drin

            Kommentar

            • butsify
              Azubi
              • 31.01.2025
              • 3

              #9
              Hallo!

              Ich dachte ich teile hier einmal meine Integration von Blink

              Grundsätzlich braucht es 3 Komponenten:
              - LoxBerry (bei mir auf einem Raspberry Pi 3)
              - Any Plugin (Shoutout an Christian Fenzl)
              - blinkpy

              Disclaimer: Für die Umsetzung braucht es schon gefestigte Kenntnisse in der Loxone Config, sowie Erfahrung mit den verschiedenen Komponenten. Ich werde wenn möglich auf Rückfragen antworten, aber ich übernehme keine Verantwortung für Fehler, Sicherheitslücken oder sonst Irgendwas.

              Da die Installation aller 3 gut beschrieben ist, gehe ich darauf jetzt nicht im Detail ein. Einzig wichtig ist, dass ihr für die Python Themen pip3 und python3 bei den Befehlen verwendet, damit unter LoxBerry/DietPi auch die richtigen Python Versionen verwendet werden.

              Anmerkung: Die Blink API ist nicht offiziell dokumentiert. Noch dazu ist die API sehr "sensibel". Heißt übersetzt, dass man sehr vorsichtig mit den Requests umgehen muss, weil man sonst sehr schnell in Service protection limits reinkommt, was ein Timeout von unbestimmter Zeit bedeutet. Die Blink App ist davon aber nicht betroffen und funktioniert weiterhin.

              Python Scripts

              Insgesamt habe ich 7 Python Scripte im Einsatz. Die Scripte sind alle quick and dirty und ich schere mich nicht um das Error Handling. Ich bin auch kein Python Profi, daher kann es gut sein, dass das Ganze schöner geht, aber für mich ist nur wichtig, dass es geht.

              PHP-Code:
              # blink_start.py
              # Authentifizierung gegenüber der Blink API, sowie Speicherung der Zugangsdaten und des Tokens in der blink_credentials.json
              
              import asyncio
              import sys
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth({"username": "<BlinkUsername>", "password": "<BlinkPasswort>"}, no_prompt=True, session=session)
                  await blink.start()
                  return blink
              
              async def main():
                  session = ClientSession()
                  blink = await start(session)
                  await blink.save("blink_credentials.json")
                  await session.close()
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  loop.run_until_complete(main()) 
              

              Sobald ihr das Script ausgeführt habt, bekommt ihr euren MFA Code aufs Handy oder per Email. Diesen müsst ihr wiederum an Blink übergeben:

              PHP-Code:
              # blink_verify.py
              # Übergabe des Codes an Blink
              # Erwartet als Parameter den Code
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              
              pin = sys.argv[1]
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"), no_prompt = True)
                  await blink.start()
                  return blink
              
              async def verify(blink, pin):
                  await blink.auth.send_auth_key(blink, pin)
                  await blink.setup_post_verify()
                  return pin
              
              async def main(pin):
                  session = ClientSession()
                  blink = await start(session) # Könnte man sicherlich aus dem letzten Script übergeben, aber ich hol mir das Objekt  immer neu
                  pin = await verify(blink, pin)
                  await session.close()
                  return pin
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main(pin))) 
              

              Das nächste Script fragt den Onlinestatus der eigenen Blink Umgebung ab:

              PHP-Code:
              # blink_online.py
              # Abfrage des Onlinestatus
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"), no_prompt = True)
                  try:
                      await blink.start()
                      return blink
                  except ValueError:
                      return None
              
              async def main():
                  session = ClientSession()
                  blink = await start(session)
                  if blink is None:
                      return 0
                  await session.close()
                  if blink.available == True:
                      return 1
                  else:
                      return 0
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main()))

              Als nächstes die Abfrage des Armstates, also ob eure Bewegungserkennung aktiviert ist oder nicht:

              PHP-Code:
              # blink_armstate.py
              # Abfrage des Armstatus eures Systems
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"))
                  await blink.start()
                  return blink
              
              async def main():
                  session = ClientSession()
                  blink = await start(session)
                  sync = blink.sync["<NameEurersSystems>"]
                  await session.close()
                  if sync.arm == True:
                      return 1
                  else:
                      return 0
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main())) 
              

              Als nächstes das Script zum setzen des Armstate

              PHP-Code:
              # blink_arm.py # Setzt den Armstate des Systems
              # Erwartet "arm" oder "disarm" als Parameter
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              
              command = sys.argv[1]
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"))
                  await blink.start()
                  return blink
              
              async def main(command):
                  session = ClientSession()
                  blink = await start(session)
                  sync = blink.sync["<NameEurersSystems>"]
                  if command == "arm":
                      await sync.async_arm(True)
                  elif command == "disarm":
                      await sync.async_arm(False)
                  await blink.refresh()
                  await session.close()
                  if sync.arm == True:
                      return 1
                  else:
                      return 0
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main(command)))
              

              Das nächste Script kümmert sich um die Kommunikation mit den einzelnen Kameras:

              PHP-Code:
              # blink_camera.py
              # Set und Get der Kamera Daten
              # Erwartet als ersten Parameter den Namen der Kamera
              # Erwartet als zweiten Parameter, was gemacht werden soll:
              # "armstate" - Status der Bewegungserkennung der Kamera
              # "temp" - Aktuelle Temparatur an der Kamera
              # "battery" - Batteriestatus
              # "arm" - Aktivieren der Bewegungserkennung
              # "disarm" - Deaktivieren der Bewegungserkennung
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              
              cameraname = sys.argv[1]
              command = sys.argv[2]
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"))
                  await blink.start()
                  return blink
              
              async def arm(camera, blink, armbool):
                  await camera.async_arm(armbool)
                  await blink.refresh()
                  if camera.arm == True:
                      return 1
                  else:
                      return 0
              
              async def main(cameraname, command):
                  session = ClientSession()
                  blink = await start(session)
                  sync = blink.sync["<NameEurersSystems>"]
                  camera = sync.cameras[cameraname]
              
                  if command == "armstate":
                      if camera.arm == True:
                          returnvalue = 1
                      else:
                          returnvalue = 0
                  elif command == "temp":
                      returnvalue = camera.temperature_c
                  elif command == "battery":
                      returnvalue = camera.battery
                  elif command == "arm":
                      returnvalue = await arm(camera, blink, True)
                  elif command == "disarm":
                      returnvalue = await arm(camera, blink, False)
              
                  await session.close()
                  return returnvalue
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main(cameraname, command)))
              

              Zu guter Letzt das Script für das Aktualisieren und Abspeichern des Vorschaubildes:

              PHP-Code:
              # blink_camera_refresh_image.py
              # Erwartet als Parameter den Kameranamen
              
              import sys
              import asyncio
              from aiohttp import ClientSession
              from blinkpy.blinkpy import Blink
              from blinkpy.auth import Auth
              from blinkpy.helpers.util import json_load
              from PIL import Image, ImageDraw, ImageFont
              from datetime import datetime
              
              
              async def start(session: ClientSession):
                  blink = Blink(session=session)
                  blink.auth = Auth(await json_load("blink_credentials.json"))
                  await blink.start()
                  return blink
              
              async def main(cameraname):
                  session = ClientSession()
                  blink = await start(session)
                  sync = blink.sync["<NameEurersSystems>"]
                  camera = sync.cameras[cameraname]
                  await camera.snap_picture()
                  picture = await camera.image_to_file('/opt/loxberry/blink/Images/' + cameraname + '.jpg') # Hier den Pfad für die Bilder anpassen
                  await session.close()
                  image_path = '/opt/loxberry/blink/Images/' + cameraname + '.jpg' # Hier den Pfad für die Bilder anpassen
                  image = Image.open(image_path)
                  draw = ImageDraw.Draw(image)
                  font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"
                  font_size = 24
                  font = ImageFont.truetype(font_path, font_size)
                  timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                  text_position = (10, 10)
                  text_color = "white"
                  draw.text(text_position, timestamp, font=font, fill=text_color) # Hier wird ein Zeitstempel in das Bild mit eingefügt
                  output_image_path = '/opt/loxberry/blink/Images/' + cameraname + '.jpg'
                  image.save(output_image_path)
                  return
              
              
              if __name__ == "__main__":
                  loop = asyncio.get_event_loop()
                  print(loop.run_until_complete(main(sys.argv[1]))) 
              

              Damit man die Bilder in weiterer Folge in der Loxone Config verwenden kann, starte ich noch einen einfachen http Server. Dafür habe ich ein Shell Script erstellt, welches auch beim Start vom Raspberry losläuft.

              Code:
              #!/bin/bash
              cd /opt/loxberry/blink/Images # Pfad zu den Bildern (der Gleiche wie oben)
              python3 -m http.server​
              Loxone Config

              Soweit waren das einmal die Scripts. Wenn ihr noch bei mir seit, dann geht es jetzt mit der Loxone Konfiguration weiter Dafür müsst ihr wie oben erwähnt Any Plugin auf eurem Loxberry installieren. Die Einstellungen sollten so aussehen:
              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Screenshot 2025-01-31 103820.png
Ansichten: 331
Größe: 115,5 KB
ID: 453997

              Jetzt geht es ENDLICH in die Loxone Config

              Hier die ganzen Logiken in der Übersicht:

              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Screenshot 2025-01-31 104512.png
Ansichten: 150
Größe: 165,1 KB
ID: 453998

              Allgemeine Hinweise:

              Zum Aufrufen der Scripte nutze ich Virtuelle Ausgänge. Ein Beispiel (hier für den Login):

              Virtueller Ausgang:
              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Screenshot 2025-01-31 112508.png
Ansichten: 141
Größe: 11,0 KB
ID: 454001
              Virtueller Ausgang Befehl:
              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Screenshot 2025-01-31 112437.png
Ansichten: 141
Größe: 31,3 KB
ID: 454000
              Die Struktur des Befehls ist beim Any Plugin beschrieben. Die Rückgabe erfolgt über UDP und entsprechend gibt es mehrere Virtuelle UDB Eingänge und Virtuelle UDB Eingangs Befehle. Siehe dazu ebenfalls die Any Plugin Doku.

              Beschreibung:
              1. Login (Grüne Blöcke links oben)
                1. Taster in der App, welche den Virtuellen Ausgang mit dem korrekten Befehl aufruft. Hier z.B. blink_output_login rcudp command sudo python3 /opt/loxberry/blink/blink_start.py
                2. Virtueller Texteingang, wo man dann den MFA Code eingibt
                3. Übergabe des Texteingangs an den Verify Ausgang
              2. Regelmäßiger Aufruf der Scripte für die einzelnen Informationen (Blassgrüne Blöcke)
                1. Ich habe hier einen Schalter "Synchronisierung". Dieser aktiviert in weiterer Folge den Aufruf der Scripte. Als Quelle nutze ich hier einen virtuellen Eingang Online Status, welcher einen Virtuellen Status zur Anzeige in der App setzt.
                2. Zusätzlich hat der Online Eingang einen Error Output, wenn keine Daten geliefert werden (weil die Blink API mal wieder zickt). Sollte die API keine Daten schicken, dann gibt es nach 1h ein einmaliges Retry. Dafür gibt es einen UND Block (Synchronisieren war auf Ja und Error ist Ja), sowie 2 Verzögerungen (die eine, damit der Schalter noch 1 Sekunde auf On bleibt, damit ich den Ausgang in dem UND verwenden kann und die Andere für die 1h).
                3. Danach geht es weiter mit einem Impulsgeber, welcher alle 30 Minuten einen Impuls abgibt, wenn Synchronisieren auf ein ist. Hiermit steuert man den Sync Intervall.
                4. Danach kommt eigentlich 3x (genauer gesagt 4x) das Gleiche: Flankengesteuertes Wischrelay, mit Don 1s und Doff 30s, sowie jeweils die notwendigen Cycles wie der folgende Sequenzer braucht (Sequenzer 3 Ausgänge = 3 Cycles). Dies ist dafür da, damit die API nicht zu stark belastet wird.
                5. Der Sequenzer called dann die einzelnen Virtuellen Ausgangs Befehle für die Scripte. Da es nur max. 8 Ausgänge gibt, sind mehrere Sequenzer in Reihe geschalten. Ab Screenshot oben sieht man 3 und der 4. ist im Screenshot unten ersichtlich.
              3. Arm/Disarm des Systems (Blassrot)
                1. Virtueller Eingang mit dem aktuellen Status wird über eine Verzögerung (weil der Eingang manchmal kurz den falschen Wert ausgibt) und einen Flankenerkennung an einen Schalter für die UI übergeben.
                2. Der Schalter ruft wiederum über eine Flankenerkennung die Scripte auf.
              4. Arm/Disarm der einzelnen Kameras (Blassblau)
                1. Ist grundsätzlich gleich wie Punkt 3, allerdings mit einer zwischengeschalteten Ablaufsteuerung als Loadbalancer (wiedereinmal für die lahme API)
                2. Die Ablaufsteuerung läuft ständig mit einigen Sleeps (welche die CPU quasi nicht belasten) vom Start des Miniservers weg (daher Startimpuls).
                3. In der Steuerung werden die Eingänge abgefragt und wenn eine Wertänderung ansteht, dann wird diese an den Ausgang übergeben und danach 5 Sekunden gewartet.
                  Code:
                  		if AI1 = AQ1
                  		   sleep 1
                  		endif
                  		if AI1 != AQ1
                  		   set  AQ1 = AI1
                  		   sleep 5
                  		endif
                  		if AI2 = AQ2
                  		   sleep 1
                  		endif
                  		if AI2 != AQ2
                  		   set AQ2 = AI2
                  		   sleep 5
                  		endif
                  		if AI3 = AQ3
                  		   sleep 1
                  		endif
                  		if AI3 != AQ3
                  		   set AQ3 = AI3
                  		   sleep 5
                  		endif
                  		if AI4 = AQ4
                  		   sleep 1
                  		endif
                  		if AI4 != AQ4
                  		   set AQ4 = AI4
                  		   sleep 5
                  		endif
                  		if AI5 = AQ5
                  		   sleep 1
                  		endif
                  		if AI5 != AQ5
                  		   set AQ5 = AI5
                  		   sleep 5
                  		endif
                  		if AI6 = AQ6
                  		   sleep 1
                  		endif
                  		if AI6 != AQ6
                  		   set AQ6 = AI6
                  		   sleep 5
                  		endif
                  		if AI7 = AQ7
                  		   sleep 1
                  		endif
                  		if AI7 != AQ7
                  		   set AQ7 = AI7
                  		   sleep 5
                  		endif
                  		if AI8 = AQ8
                  		   sleep 1
                  		endif
                  		if AI8 != AQ8
                  		   set AQ8 = AI8
                  		   sleep 5
                  		endif
                  		goto 1
                  		end​
              Das wars eigentlich auch schon mit der Datenlogik. Schaut auf den ersten Blick unglaublich kompliziert aus, ist aber eigentlich immer wieder das Gleiche.

              Hier die Einbindung der Bilder als Intercoms:
              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Screenshot 2025-01-31 104812.png
Ansichten: 140
Größe: 54,8 KB
ID: 453999
              Beschreibung:
              1. Wieder eine Sequenzer Logik (das ist der Ausgang O4 des letzten Sequenzers im oberen Bild)
              2. Der Sequenzer ruft die Aktualisierung der Bilder auf (siehe blink_camera_refresh_image.py oben)
              3. Ein Intercom pro Kamera, welche als Videostream URL den http Server auf dem Loxberry hat, den wir bei den Scripten eingerichtet haben. z.B.: http://192.168.1.19:8000/Haustür.jpg --> Der Dateiname ist immer <Kameraname>.jpg
              4. Zusätzlich gibt es bei den Intercoms noch einen Button (O1) zum manuellen Aktualisieren
              Ich glaube, das war's jetzt.

              Viel Spaß (und Erfolg) damit

              Gruß, Tobias

              Kommentar

              Lädt...