예제 #1
0
    def login(self, username, password):
        with self._lock:

            # attempt login
            self.username = username
            self.password = password
            self._session = requests.Session()
            if self._arlo._http_connections != 0 and self._arlo._http_max_size != 0:
                self._arlo.debug('custom connections {}:{}'.format(
                    self._arlo._http_connections, self._arlo._http_max_size))
                self._session.mount(
                    'https://',
                    requests.adapters.HTTPAdapter(
                        pool_connections=self._arlo._http_connections,
                        pool_maxsize=self._arlo._http_max_size))
            body = self.post(LOGIN_URL, {
                'email': self.username,
                'password': self.password
            })
            if body is None:
                self._arlo.debug('login failed')
                return False

            # save new login information
            self._token = body['token']
            self._user_id = body['userId']
            self._web_id = self._user_id + '_web'
            self._sub_id = 'subscriptions/' + self._web_id

            # update sessions headers
            # XXX allow different user agent
            headers = {
                #'DNT': '1',
                'Accept': 'application/json, text/plain, */*',
                'schemaVersion': '1',
                'Host': 'arlo.netgear.com',
                'Content-Type': 'application/json; charset=utf-8;',
                'Referer': 'https://arlo.netgear.com/',
                'Authorization': self._token
            }
            if self._arlo._user_agent == 'apple':
                headers[
                    'User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202 NETGEAR/v1 (iOS Vuezone)'
            else:
                headers[
                    'User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36'

            self._session.headers.update(headers)
            self._arlo.debug(
                'Fetching device list after login (seems to make arming/disarming more stable)'
            )
            self.get(DEVICES_URL + "?t={}".format(time_to_arlotime()))
            return True
예제 #2
0
    def mode(self, mode_name):
        mode_id = self._name_to_id(mode_name)
        if mode_id:

            # Schedule or mode? Manually set schedule key.
            if self._id_is_schedule(mode_id):
                active = 'activeSchedules'
                inactive = 'activeModes'
                self._save_and_do_callbacks(SCHEDULE_KEY, mode_name)
            else:
                active = 'activeModes'
                inactive = 'activeSchedules'
                self._save_and_do_callbacks(SCHEDULE_KEY, None)

            # Post change.
            self._arlo.debug(self.name + ':new-mode=' + mode_name + ',id=' +
                             mode_id)
            if self._v1_modes:
                self._arlo._bg.run(self._arlo._be.notify,
                                   base=self,
                                   body={
                                       "action": "set",
                                       "resource": "modes",
                                       "publishResponse": True,
                                       "properties": {
                                           "active": mode_id
                                       }
                                   })
            else:
                self._arlo._bg.run(self._arlo._be.post,
                                   url=AUTOMATION_URL,
                                   params={
                                       'activeAutomations': [{
                                           'deviceId':
                                           self.device_id,
                                           'timestamp':
                                           time_to_arlotime(),
                                           active: [mode_id],
                                           inactive: []
                                       }]
                                   })
        else:
            self._arlo.warning('{0}: mode {1} is unrecognised'.format(
                self.name, mode_name))
예제 #3
0
 def mode(self, mode_name):
     mode_id = self._name_to_id(mode_name)
     if mode_id:
         self._arlo.debug(self.name + ':new-mode=' + mode_name + ',id=' +
                          mode_id)
         self._arlo._bg.run(self._arlo._be.post,
                            url=AUTOMATION_URL,
                            params={
                                'activeAutomations': [{
                                    'deviceId':
                                    self.device_id,
                                    'timestamp':
                                    time_to_arlotime(),
                                    'activeModes': [mode_id],
                                    'activeSchedules': []
                                }]
                            })
     else:
         self._arlo.warning('{0}: mode {1} is unrecognised'.format(
             self.name, mode_name))
예제 #4
0
 def _refresh_devices( self ):
     self._devices = self._be.get( DEVICES_URL + "?t={}".format(time_to_arlotime()) )
예제 #5
0
    def __init__(self,
                 username,
                 password,
                 name='aarlo',
                 storage_dir='/config/.aarlo',
                 dump=False,
                 max_days=365,
                 db_motion_time=30,
                 db_ding_time=10,
                 request_timeout=60,
                 stream_timeout=0,
                 recent_time=600,
                 last_format='%m-%d %H:%M',
                 no_media_upload=False,
                 user_agent='apple'):

        try:
            os.mkdir(storage_dir)
        except:
            pass

        self._name = name
        self._user_agent = user_agent
        self._bg = ArloBackground(self)
        self._st = ArloStorage(self, name=name, storage_dir=storage_dir)
        self._be = ArloBackEnd(self,
                               username,
                               password,
                               dump=dump,
                               storage_dir=storage_dir,
                               request_timeout=request_timeout,
                               stream_timeout=stream_timeout)
        self._ml = ArloMediaLibrary(self, max_days=max_days)

        self._lock = threading.Lock()
        self._bases = []
        self._cameras = []
        self._doorbells = []
        self._recent_time = recent_time
        self._last_format = last_format
        self._no_media_upload = no_media_upload

        # on day flip we reload image count
        self._today = datetime.date.today()

        # default blank image whe waiting for camera image to appear
        self._blank_image = base64.standard_b64decode(BLANK_IMAGE)

        # slow piece.
        # get devices and fill local db, and create device instance
        self.info('pyaarlo starting')
        self._devices = self._be.get(DEVICES_URL +
                                     "?t={}".format(time_to_arlotime()))
        self._parse_devices()
        for device in self._devices:
            dname = device.get('deviceName')
            dtype = device.get('deviceType')
            if device.get('state', 'unknown') != 'provisioned':
                self.info('skipping ' + dname + ': state unknown')
                continue

            if dtype == 'basestation' or device.get(
                    'modelId'
            ) == 'ABC1000' or dtype == 'arloq' or dtype == 'arloqs':
                self._bases.append(ArloBase(dname, self, device))
            if dtype == 'camera' or dtype == 'arloq' or dtype == 'arloqs':
                self._cameras.append(ArloCamera(dname, self, device))
            if dtype == 'doorbell':
                self._doorbells.append(
                    ArloDoorBell(dname,
                                 self,
                                 device,
                                 motion_time=db_motion_time,
                                 ding_time=db_ding_time))

        # save out unchanging stats!
        self._st.set(['ARLO', TOTAL_CAMERAS_KEY], len(self._cameras))
        self._st.set(['ARLO', TOTAL_BELLS_KEY], len(self._doorbells))

        # always ping bases first!
        self._ping_bases()

        # queue up initial config retrieval
        self.debug('getting initial settings')
        self._bg.run_in(self._refresh_cameras, 2)
        self._bg.run_in(self._initial_refresh, 5)
        self._bg.run_in(self._ml.load, 10)

        # register house keeping cron jobs
        self.debug('registering cron jobs')
        self._bg.run_every(self._fast_refresh, FAST_REFRESH_INTERVAL)
        self._bg.run_every(self._slow_refresh, SLOW_REFRESH_INTERVAL)