Skip to content

Commit

Permalink
Merge pull request #7 from hgoscenski/debounce_login
Browse files Browse the repository at this point in the history
Draft: Initial attempt at naive debounce for login api
  • Loading branch information
jfarmer08 authored Feb 8, 2024
2 parents 8f58216 + 5efe84f commit 2a56055
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 22 deletions.
8 changes: 8 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
USERNAME=username
PASSWORD=password
KEY_ID=keyId
API_KEY=apiKey
PERSIST_PATH=./scratch
LOG_LEVEL=debug
API_LOG_ENABLED=true
LOCAL_DEV=true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

node_modules/*
example/node_modules/*
example/scratch/*
example/scratch/*
.env
46 changes: 32 additions & 14 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
//const WyzeAPI = require('../src/index') // Local Debug
const WyzeAPI = require("wyze-api")
const Logger = require("@ptkdev/logger");
let WyzeAPI = null;
if (process.env.LOCAL_DEV) {
WyzeAPI = require('../src/index'); // Local Debug
} else {
WyzeAPI = require("wyze-api");
}

const Logger = require("@ptkdev/logger");
const logger = new Logger();

const options = {
username: "username",
password: "password",
keyId: "keyId",
apiKey: "apiKey",
persistPath: "./scratch",
logLevel: "debug",
apiLogEnabled: true
username: process.env.USERNAME,
password: process.env.PASSWORD,
keyId: process.env.KEY_ID,
apiKey: process.env.API_KEY,
persistPath: process.env.PERSIST_PATH,
logLevel: process.env.LOG_LEVEL,
apiLogEnabled: process.env.API_LOG_ENABLED,
}
const wyze = new WyzeAPI(options,logger)
const wyze = new WyzeAPI(options, logger);

; (async () => {
async function loginCheck(iterations = 2) {
var count = 0;
while (count < iterations) {
await wyze.maybeLogin();
wyze.access_token = "";
count += 1;
}
}

async function deviceListCheck() {
const devices = await wyze.getDeviceList()
logger.debug(JSON.stringify(devices))
})()
logger.debug(JSON.stringify(devices))
}


(async () => {
// await deviceListCheck();
// await loginCheck(4);
})()
49 changes: 42 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ const fs = require("fs").promises;
const path = require("path");
const getUuid = require("uuid-by-string");

const payloadFactory = require("./payloadFactory");
const crypto = require("./crypto");
const constants = require("./constants");
const util = require("./util");
const payloadFactory = require('./payloadFactory');
const crypto = require('./crypto');
const constants = require('./constants');
const util = require('./util');
const { time } = require('console');

module.exports = class WyzeAPI {
constructor(options, log) {
Expand Down Expand Up @@ -54,6 +55,9 @@ module.exports = class WyzeAPI {

this.dumpData = false; // Set this to true to log the Wyze object data blob one time at startup.

this.lastLoginAttempt = 0;
this.loginAttemptDebounceMilliseconds = 1000;

// Token is good for 216,000 seconds (60 hours) but 48 hours seems like a reasonable refresh interval 172800
if (this.refreshTokenTimerEnabled === true) {
setInterval(this.refreshToken.bind(this), 172800);
Expand Down Expand Up @@ -202,7 +206,38 @@ module.exports = class WyzeAPI {
}

if (!this.access_token) {
await this.login();
let now = new Date().getTime();
// check if the last login attempt occurred too recently
if (this.apiLogEnabled) this.log.debug("Last login " + this.lastLoginAttempt + " debounce " + this.loginAttemptDebounceMilliseconds + " now " + now);
if (this.lastLoginAttempt + this.loginAttemptDebounceMilliseconds < now) {
// reset loginAttemptDebounceMilliseconds if last attempted login occurred more than 12 hours ago
if (this.lastLoginAttempt - now > 60 * 1000 * 60 * 12) {
this.loginAttemptDebounceMilliseconds = 1000;
} else {
// max debounce of 5 minutes
this.loginAttemptDebounceMilliseconds = Math.min(this.loginAttemptDebounceMilliseconds * 2, 1000 * 60 * 5);
}

this.lastLoginAttempt = now;
await this.login();
} else {
this.log.warning("Attempting to login before debounce has cleared, waiting " + this.loginAttemptDebounceMilliseconds / 1000 + " seconds");

var waitTime = 0;
while (waitTime < this.loginAttemptDebounceMilliseconds) {
await this.sleep(2);
waitTime = waitTime + 2000;
if (this.access_token) {
break;
}
}

if (!this.access_token) {
this.lastLoginAttempt = now;
this.loginAttemptDebounceMilliseconds = Math.min(this.loginAttemptDebounceMilliseconds * 2, 1000 * 60 * 5);
await this.login();
}
}
}
}

Expand Down Expand Up @@ -1416,7 +1451,7 @@ module.exports = class WyzeAPI {
return Math.max(min, Math.min(number, max));
}

sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms * 1000));
sleep(seconds) {
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
};

0 comments on commit 2a56055

Please sign in to comment.