Modul für Netgear Arlo-Kameras

Begonnen von maluk, 02 Dezember 2018, 22:20:58

Vorheriges Thema - Nächstes Thema

tobias.vorberg

Nach dem ich python und pip upgedatet habe und dann nochmal
sudo apt install python3 python3-pip
sudo pip3 install cloudscraper

drüber laufen gelassen habe, läuft es wieder.
Zwischendurch habe ich einen alten Pi komlett neu aufgesetzt mit neuem FHEM und da lief es auch auf anhieb. also war klar das es irgedwie mit updaten gehen musste.

tobias.vorberg

Nach dem ich python und pip upgedatet habe und dann nochmal
sudo apt install python3 python3-pip
sudo pip3 install cloudscraper

drüber laufen gelassen habe, läuft es wieder.
Zwischendurch habe ich einen alten Pi komlett neu aufgesetzt mit neuem FHEM und da lief es auch auf anhieb. also war klar das es irgedwie mit updaten gehen musste.

choetzu

Zitat von: tobias.vorberg am 11 Mai 2023, 17:25:48sudo pip3 install cloudscraper

super, danke. Das wars bei mir... nun gehts wieder
Raspi3, EnOcean, Zwave, Homematic

mrb

Hallo,

vielleicht stelle ich mich dumm an aber ich bin direkt nach der anleitung Wiki vorgeangen. Jetzt habe ich noch rausgefunden das man eine Perldatei noch braucht /opt/fhem/contrib/49_Arlo.py um genau zu sein. diese habe ich dann gleich mit fhem:dialout versehen. Was braucht man noch alles da es nicht bei mir geht :(
Auch habe ich rausgefunden das man eine ZweiFaktorAuthorisierung über Email braucht und es nicht über die APP geht :( den das hatte ich so eigentlich eingestellt. Habe dann einen eigenen Account über gmx erstellt und wollte ihm halt meine Kameras freigeben. Aber auch da klappt es nicht. Ich habe damit dieser nicht den Fehler fabriziert beim define die Passwörter im Klartext angegeben :( und auch den Emailserver im Attr versehen. Klar habe ich davor bei gmx auch den IMAP Zugang freigeschaltet.
Die 49_Arlo.pm existierte schon bei mir und kann es also nicht sein.

Zu Hilfe. Ich möchte doch nur die letzten Bilder meiner Arlos im Webfrontend sehen und das Deaktivieren/Aktivieren über PRESENCE nutzen

tobias.vorberg

Hm, also bei mir klapp es nach der Anleitung https://wiki.fhem.de/wiki/Arlo sehr gut.

Bitte check doch mal die Python-Version. Das war neulich bei mir das Problem. Nach einem Update von Python lief dann alles wieder.
Wichtig ist auch noch, dass in dem benutzten E-Mail-Account keine "alten" 2FA-Mails liegen. Die sollten alle gelöscht sein.

mrb

also ich habe jetzt einen apt udate | apt upgradegemacht und er hat tatsächlich ein paar dinge noch angemekert. also brav geupdatet und dann gehoft das er jetzt tut aber er bleibt wie auf dem Screenshot zu sehen bei python-login stehen.
Du darfst diesen Dateianhang nicht ansehen.
Du darfst diesen Dateianhang nicht ansehen. 
Nach ner Zeit sagt er "login timeout"

Muss die 49_arlo.pm angepasst werden da ich das per update von Fhem genutzt habe.

mrb

#471
und im übrigen im fhemwiki steht ja nicht drinnen das man die py datei nach /opt/fhem/contrib einfügen muss und welche musste ich mir auch hier aus dem Forum zurecht suchen habe jetzt diese hier

import base64
import sys
import time
import cloudscraper
import email
import imaplib
import re

class Arlo:
    def __init__(self, tfa_mail_check) -> None:
        self._tfa_mail_check = tfa_mail_check
        browser = {
            'browser': 'chrome',
            'platform': 'linux',
            'mobile': False
        }
        self._session = cloudscraper.create_scraper(browser=browser)
        self._headers = {
            "Accept": "application/json, text/plain, */*",
            "Referer": "https://my.arlo.com",
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36",
            "Source": "arloCamWeb"
        }
        self._baseUrl = "https://ocapi-app.arlo.com/api/"
        self._token = None

    def login(self, username, password):
        status("login")
        json = {"email": username, "password": encode(password), "language": "en", "EnvSource": "prod"}
        attempt = 0
        while attempt < 3:
            attempt += 1
            try:
                r = self._session.post(self._baseUrl + "auth", json=json, headers=self._headers)
                if r.status_code == 200:
                    data = _get_data(r)
                    if data is not None:
                        self._request_factors(data)
                    return
                if r.status_code == 400:
                    error("Bad auth request - probably the credentials are wrong.")
                    return
            except Exception as e:
                log(e)
            time.sleep(3)
        status("loginFailed")

    def _request_factors(self, data):
        status("getFactors")
        self._token = data["token"]
        self._headers["Authorization"] = encode(self._token)
        r = self._session.get(self._baseUrl + "getFactors?data=" + str(data["authenticated"]), headers=self._headers)
        data = _get_data(r)
        if data is None:
            error("getFactors not successful, response code " + str(r.status_code))
            return

        factor_id = None
        for factor in data["items"]:
            if factor["factorType"] == "EMAIL":
                self._auth_tfa(factor["factorId"])
                return
        error("email factor not found.")

    def _auth_tfa(self, factor_id):
        status("startAuth")
        json = {"factorId": factor_id}
        r = self._session.post(self._baseUrl + "startAuth", json=json, headers=self._headers)
        data = _get_data(r)
        if data is None:
            error("startAuth not successful, response code " + str(r.status_code))
            return
        factor_auth_code = data["factorAuthCode"]

        status("waitFor2FA")
        self._tfa_mail_check.open()
        code = self._tfa_mail_check.get()
        self._tfa_mail_check.close()
        log("Try to login with code " + code)

        status("finishAuth")
        json = {"factorAuthCode": factor_auth_code, "otp": code}
        r = self._session.post(self._baseUrl + "finishAuth", json=json, headers=self._headers)
        data = _get_data(r)
        if data is None:
            error("finishAuth not successful, response code " + str(r.status_code))
            return

        self._token = data["token"]
        self._headers["Authorization"] = encode(self._token)
        r = self._session.get(self._baseUrl + "validateAccessToken?data=" + str(data["authenticated"]),
                              headers=self._headers)
        if r.status_code != 200:
            error("validateAccessToken not successful, response code " + str(r.status_code))
            return

        print("cookies:", self._get_cookie_header())
        print("token:", self._token)
        print("userId:", data["userId"])
        print("end")

    def _get_cookie_header(self):
        cookie_header = ""
        for cookie in self._session.cookies:
            if cookie_header != "":
                cookie_header += "; "
            cookie_header += cookie.name + "=" + cookie.value
        return cookie_header
def _get_data(r):
    if r.status_code != 200:
        return None
    try:
        body = r.json()
    except Exception as e:
        return None

    if "meta" in body:
        if body["meta"]["code"] == 200:
            return body["data"]
    elif "success" in body:
        if body["success"]:
            if "data" in body:
                return body["data"]
    return None


class TfaMailCheck:
    def __init__(self, mail_server, username, password) -> None:
        self._imap = None
        self._mail_server = mail_server
        self._username = username
        self._password = password

    def open(self):
        self._imap = imaplib.IMAP4_SSL(self._mail_server)
        res, status = self._imap.login(self._username, self._password)
        if res.lower() != "ok":
            return False
        res, status = self._imap.select()
        if res.lower() != "ok":
            return False
        res, ids = self._imap.search(None, "FROM", "do_not_reply@arlo.com")
        for msg_id in ids[0].split():
            self._determine_code_and_delete_mail(msg_id)
        if res.lower() != "ok":
            return False
    def get(self):
        timeout = time.time() + 100
        while True:
            time.sleep(5)
            if time.time() > timeout:
                return None

            try:
                self._imap.check()
                res, ids = self._imap.search(None, "FROM", "do_not_reply@arlo.com")
                for msg_id in ids[0].split():
                    code = self._determine_code_and_delete_mail(msg_id)
                    if code is not None:
                        return code

            except Exception as e:
                return None

    def _determine_code_and_delete_mail(self, msg_id):
        res, msg = self._imap.fetch(msg_id, "(RFC822)")
        for part in email.message_from_bytes(msg[0][1]).walk():
            if part.get_content_type() == "text/html":
                for line in part.get_payload().splitlines():
                    code = re.match(r"^\W*(\d{6})\W*$", line)
                    if code is not None:
                        self._imap.store(msg_id, "+FLAGS", "\\Deleted")
                        return code.group(1)

    def close(self):
        self._imap.close()
        self._imap.logout()


def status(status):
    print("status:", status, flush=True)

def log(msg):
    print("log:", msg, flush=True)

def error(msg):
    print("error:", msg, flush=True)

def encode(s):
    return base64.b64encode(s.encode()).decode()


if __name__ == '__main__':
    if len(sys.argv) < 6:
        error("5 arguments expected: arlo user, arlo password, imap server, email user, email password")
    tfa_mail_check = TfaMailCheck(sys.argv[3], sys.argv[4], sys.argv[5])
    arlo = Arlo(tfa_mail_check)
    arlo.login(sys.argv[1], sys.argv[2])

EDIT:
habe auch keine Email von Arlo an das GMX konto erhalten. Also scheint er sich nicht mal korrekt anzumelden und soweit zu kommen das er die 2fa braucht

mrb

#472
Zitat von: tobias.vorberg am 10 Mai 2023, 21:35:09Hat noch jemand Probleme mit dem Login?
Seit heute geht plötzlich der Login nicht mehr.
Ich konnte bis jetzt nichts finden.
Auffällig ist nur, dass auch keine E-Mails für die 2FA im Postfach landen.

Bevor ich nun eine große Fehleranalyse starte wollte ich hier nur mal kurz nachfragen.
Danke für Infos.

Hier hast du das ja auch geschrieben das genaue verhalten. Login geht nicht und keine emails zur 2fa

Edit: Manuel kann ich mich mit den angegebenen Daten 1a anmeldung und bekomme auch die 2FA-Email

tobias.vorberg

Also irgendetwas ist da bei dir nicht richtig.
Wie oben schon geschrieben habe ich gerade einen frischen PI mit "Debian version: 11 (bullseye)" aufgesetzt; FHEM neu installiert und ARLO installiert nach Wiki https://wiki.fhem.de/wiki/Arlo

Es lief dann sofort.
Ich wollte aber meine alte Installation nicht wegwerfen und habe mit den Befehlen
sudo apt install python3 python3-pip
sudo pip3 install cloudscraper
bei meiner alten Installation alles wieder zum Laufen gebracht.
Man muss nichts an der 49_arlo.pm anpassen.



mrb

#474
okay. ich habe halt nen ne vm installiert, aber darf das nen unterschied machen? Gibts irgend ein Debuglog?

edit:
Was mir noch kommt könnte es an den Sonderzeichen vom Passwort liegen?

Edit2:
habe jetzt mal die passwörter trivialisiert und es geht immer noch nicht. also ein debuglog was er genau macht wäre sehr sehr hilfreich

ojb

Hallo,

obwohl ich nichts geändert habe, bekomme seit kurzem immer 'loginFailed'. Trotz 'verbose 5' sehe ich nichts im Log.
Hat das Problem sonst noch jemand?
Was kann ich tun?

Liebe Grüße
Oli
FHEM unter Debian auf Asus EEBox: KNX (Wetterstation, Rollläden, Beleuchtung), Maple-CUN (Temperatur und Feuchte über 1-Wire, Intertechno-Funksteckdosen), PV-Anlage mit Plenticore und BYD, Viessmann Wärmepumpe, 1-Wire (Temperatur, Feuchte, Stromverbrauch), Husquarna-Automower, ...

GSK19

kann ich bestätigen, bei mir ist es leider genauso. Python, PIP und Cloudscraper sind aktuell, aber es endet permanent in LoginFailed oder LoginTimeout. Der Login über einen Browser klappt einwandfrei, aber eben  nicht mehr über FHEM.

mi.ke

Bei mir geht ebenfalls nix mehr.

Login scheint zu funtionieren, aber kein Reading wird mehr aktuallisiert
FHEM 5.9 | RPi4 + 5 x RPi(Z) + FB7590 + FB 6890 LTE via LAN und WAN (VPN) verbunden.
2 x CUL868 + 3 x RFXTRX(e) + 6 x HMwLanGW + 4 x z2tGw + 5 x LGW + 2 x IRBlast + CO2 +++
FS20, FHT, FMS, Elro(mod), CM160, Revolt, LGTV, STV, AVR, withings, HM-sec-*, HM-CC-RT-DN, AMAD, PCA301, arlo, Aqara

mi.ke

Zitat von: mi.ke am 21 Juni 2023, 18:59:41Bei mir geht ebenfalls nix mehr.

Login scheint zu funtionieren, aber kein Reading wird mehr aktuallisiert


Korrigiere:


Arlo call was not successful: {"success":false,"data":{"error":"2015","message":"Your session has expired. Please log in.","reason":"Access token is required."}


FHEM 5.9 | RPi4 + 5 x RPi(Z) + FB7590 + FB 6890 LTE via LAN und WAN (VPN) verbunden.
2 x CUL868 + 3 x RFXTRX(e) + 6 x HMwLanGW + 4 x z2tGw + 5 x LGW + 2 x IRBlast + CO2 +++
FS20, FHT, FMS, Elro(mod), CM160, Revolt, LGTV, STV, AVR, withings, HM-sec-*, HM-CC-RT-DN, AMAD, PCA301, arlo, Aqara

mrb

okay vielleicht auch mein problem :D wird sich hoffentlich der entwickler mal dran machen das zu fixen