Skip to content

Commit

Permalink
reauthenticate on 403
Browse files Browse the repository at this point in the history
fixes for power consumption
  • Loading branch information
apatsufas committed Oct 9, 2024
1 parent bd679fc commit fc50bc0
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 31 deletions.
Binary file modified .DS_Store
Binary file not shown.
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"displayName": "Tapo P100 Plugin",
"name": "homebridge-tapo",
"type": "module",
"private": true,
"version": "1.5.2-beta0",
"version": "1.5.2-beta2",
"description": "Homebridge Plugin for TP-Link Tapo P100 Plugs",
"license": "Apache-2.0",
"homepage": "https://github.com/apatsufas/homebridge-tapo-p100#readme",
Expand Down Expand Up @@ -38,6 +37,7 @@
],
"dependencies": {
"axios": "^1.7.7",
"cron": "^3.1.7",
"fakegato-history": "^0.6.5",
"lodash.defaults": "^4.2.0",
"utf8": "^3.0.0",
Expand Down
38 changes: 24 additions & 14 deletions src/platformL530Accessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { TPLinkPlatformAccessory } from './platformTPLinkAccessory.js';
export class L530Accessory extends TPLinkPlatformAccessory<L530> {
private adaptiveLightingController!: AdaptiveLightingController;
private readonly fakeGatoHistoryService?;
private lastMeasurement: number | null = null;

constructor(
public readonly log: Logger,
Expand Down Expand Up @@ -87,11 +86,26 @@ export class L530Accessory extends TPLinkPlatformAccessory<L530> {
.on('set', this.setSaturation.bind(this)) // SET - bind to the `setSaturation` method below
.on('get', this.getSaturation.bind(this)); // GET - bind to the `getSaturation` method below

this.service.addOptionalCharacteristic(this.platform.customCharacteristics.CurrentConsumptionCharacteristic);
this.service.getCharacteristic(this.platform.customCharacteristics.CurrentConsumptionCharacteristic)
.on('get', this.getCurrentConsumption.bind(this));

this.service.addOptionalCharacteristic(this.platform.customCharacteristics.TotalConsumptionCharacteristic);
this.service.getCharacteristic(this.platform.customCharacteristics.TotalConsumptionCharacteristic)
.on('get', this.getTotalConsumption.bind(this));

/* this.service.addOptionalCharacteristic(this.platform.customCharacteristics.ResetConsumptionCharacteristic);
this.service.getCharacteristic(this.platform.customCharacteristics.ResetConsumptionCharacteristic)
.on('set', this.resetConsumption.bind(this));*/

// Setup the adaptive lighting controller if available
if (this.platform.api.versionGreaterOrEqual && this.platform.api.versionGreaterOrEqual('1.3.0-beta.23')) {
this.log.debug('Enabling Adaptvie Lightning');
this.adaptiveLightingController = new platform.api.hap.AdaptiveLightingController(
this.service,
this.service, {
controllerMode:
this.platform.api.hap.AdaptiveLightingControllerMode.AUTOMATIC,
},
);
this.accessory.configureController(this.adaptiveLightingController);
}
Expand Down Expand Up @@ -344,23 +358,19 @@ export class L530Accessory extends TPLinkPlatformAccessory<L530> {
this.tpLinkAccessory.getEnergyUsage().then((response) => {
this.log.debug('Get Characteristic Power consumption ->', JSON.stringify(response));
if (response && response.power_usage) {
if(this.lastMeasurement){
this.log.debug('Get Characteristic Power consumption ->', JSON.stringify(response));
if (this.fakeGatoHistoryService ) {
this.fakeGatoHistoryService.addEntry({
time: new Date().getTime() / 1000,
power: response.power_usage.today > 0 ? response.power_usage.today - this.lastMeasurement > 0 ?
response.power_usage.today - this.lastMeasurement : 0 : 0,
});
}
this.log.debug('Get Characteristic Power consumption ->', JSON.stringify(response));
if (this.fakeGatoHistoryService ) {
this.fakeGatoHistoryService.addEntry({
time: new Date().getTime() / 1000,
power: this.tpLinkAccessory.getPowerConsumption().current,
});
}
this.lastMeasurement = response.power_usage.today;
}
});

setTimeout(()=>{
this.updateConsumption();
}, 300000);
}, 600000);
}

/**
Expand Down Expand Up @@ -415,7 +425,7 @@ export class L530Accessory extends TPLinkPlatformAccessory<L530> {
this.log.debug('updateState called');
this.tpLinkAccessory.getDeviceInfo(true).then((response) => {
if(response){
this.log.info('Device Info: ' + JSON.stringify(response));
this.log.debug('Device Info: ' + JSON.stringify(response));
const isOn = response.device_on;
const saturation = response.saturation;
const hue = response.hue;
Expand Down
14 changes: 12 additions & 2 deletions src/platformP110Accessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ export class P110Accessory extends TPLinkPlatformAccessory<P110>{
.on('set', this.setOn.bind(this)) // SET - bind to the `setOn` method below
.on('get', this.getOn.bind(this)); // GET - bind to the `getOn` method below

this.service.addOptionalCharacteristic(this.platform.customCharacteristics.CurrentConsumptionCharacteristic);
this.service.getCharacteristic(this.platform.customCharacteristics.CurrentConsumptionCharacteristic)
.on('get', this.getCurrentConsumption.bind(this));

this.service.addOptionalCharacteristic(this.platform.customCharacteristics.TotalConsumptionCharacteristic);
this.service.getCharacteristic(this.platform.customCharacteristics.TotalConsumptionCharacteristic)
.on('get', this.getTotalConsumption.bind(this));

this.updateConsumption();

const interval = updateInterval ? updateInterval*1000 : 10000;
Expand All @@ -69,19 +77,21 @@ export class P110Accessory extends TPLinkPlatformAccessory<P110>{
}

private updateConsumption(){
this.log.debug('updateConsumption called');
this.tpLinkAccessory.getEnergyUsage().then((response) => {
this.log.debug('Get Characteristic Power consumption ->', JSON.stringify(response));
if (this.fakeGatoHistoryService && response && response.current_power) {
this.platform.log.debug('Get Characteristic Power consumption ->', response.current_power);
this.fakeGatoHistoryService.addEntry({
time: new Date().getTime() / 1000,
power: response.current_power,
power: this.tpLinkAccessory.getPowerConsumption().current,
});
}
});

setTimeout(()=>{
this.updateConsumption();
}, 300000);
}, 600000);
}

/**
Expand Down
8 changes: 6 additions & 2 deletions src/utils/l530.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default class L530 extends L520E {
if(response && response.result){
this._consumption = {
total: response.result.power_usage.today / 1000,
current: this._consumption ? response.result.power_usage.today - this._consumption.current : 0,
current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,
};
} else{
this._consumption = {
Expand All @@ -100,7 +100,7 @@ export default class L530 extends L520E {
if(response && response.result){
this._consumption = {
total: response.result.power_usage.today / 1000,
current: this._consumption ? response.result.power_usage.today - this._consumption.current : 0,
current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,
};
} else{
this._consumption = {
Expand All @@ -127,4 +127,8 @@ export default class L530 extends L520E {
public getPowerConsumption():ConsumptionInfo{
return this._consumption;
}

private toHours(minutes: number):number{
return minutes/60;
}
}
47 changes: 38 additions & 9 deletions src/utils/p100.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class P100 implements TpLinkAccessory{
private publicKey!: string;
protected ip: string;
protected cookie!: string;
protected tplink_timeout!: number;
protected token!: string;
protected terminalUUID: string;
private _plugSysInfo!: PlugSysinfo;
Expand Down Expand Up @@ -168,8 +169,8 @@ export default class P100 implements TpLinkAccessory{
.then((res: AxiosResponse) => {
this.log.debug('Received Handshake P100 on host response: ' + this.ip);

if (res.data.error_code) {
return this.handleError(res.data.error_code, '97');
if (res.data.error_code || res.status !== 200) {
return this.handleError(res.data!.error_code ? res.data.error_code : res.status, '172');
}

try {
Expand Down Expand Up @@ -222,8 +223,8 @@ export default class P100 implements TpLinkAccessory{

await this._axios.post(URL, securePassthroughPayload, config)
.then((res: AxiosResponse) => {
if (res.data.error_code) {
return this.handleError(res.data.error_code, '146');
if (res.data.error_code || res.status !== 200) {
return this.handleError(res.data!.error_code ? res.data.error_code : res.status, '226');
}
const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);
try {
Expand Down Expand Up @@ -269,13 +270,15 @@ export default class P100 implements TpLinkAccessory{
return this._axios.post(URL, data, config)
.then((res: AxiosResponse) => {
this.log.debug('Received request on host response: ' + this.ip);
if (res.data.error_code) {
return this.handleError(res.data.error_code, '309');
if (res.data.error_code || res.status !== 200) {
return this.handleError(res.data!.error_code ? res.data.error_code : res.status, '273');
}

try {
if (res.headers && res.headers['set-cookie']) {
this.log.debug('Handshake 1 cookie: ' + JSON.stringify(res.headers['set-cookie'][0]));
this.cookie = res.headers['set-cookie'][0].split(';')[0];
this.tplink_timeout = Number(res.headers['set-cookie'][0].split(';')[1]);
}
return res.data;
} catch (error) {
Expand Down Expand Up @@ -477,11 +480,16 @@ export default class P100 implements TpLinkAccessory{
return this.getSysInfo();
} catch (error) {
this.log.debug(this.newTpLinkCipher.decrypt(res.data));
this.log.debug('Status: ' + res.status);
return this.handleError(res.data.error_code, '480');
}
})
.catch((error: Error) => {
this.log.debug('469 Error: ' + JSON.stringify(error));
this.log.error('469 Error: ' + error.message);
if(error.message.indexOf('403') > -1){
this.reAuthenticate();
}
return error;
});

Expand Down Expand Up @@ -553,9 +561,11 @@ export default class P100 implements TpLinkAccessory{
protected handleError(errorCode: number | string, line: string): boolean {
//@ts-ignore
const errorMessage = this.ERROR_CODES[errorCode];
this.log.error(line + ' Error Code: ' + errorCode + ', ' + errorMessage + ' ' + this.ip);
if (typeof errorCode === 'number' && errorCode === 1003) {
this.log.info('Trying KLAP Auth');
this.is_klap = true;
} else{
this.log.error(line + ' Error Code: ' + errorCode + ', ' + errorMessage + ' ' + this.ip);
}
return false;
}
Expand Down Expand Up @@ -643,7 +653,7 @@ export default class P100 implements TpLinkAccessory{
}
})
.catch((error: Error) => {
return this.handleError(error.message, '372');
return this.handleError(error.message, '656');
});
}
return new Promise<true>((resolve, reject) => {
Expand All @@ -658,7 +668,7 @@ export default class P100 implements TpLinkAccessory{
return this.raw_request('request', data.encryptedPayload, 'arraybuffer', { seq: data.seq.toString() }).then((res) => {
return JSON.parse(this.newTpLinkCipher.decrypt(res));
}).catch((error: Error) => {
return this.handleError(error.message, '372');
return this.handleError(error.message, '671');
});
}
return new Promise<true>((resolve, reject) => {
Expand All @@ -682,4 +692,23 @@ export default class P100 implements TpLinkAccessory{
return;
});
}

private reAuthenticate():void{
if(this.is_klap){
this.handshake_new().then(() => {
this.log.info('KLAP Authenticated successfully');
}).catch(() => {
this.log.error('KLAP Handshake failed');
this.is_klap = false;
});
} else {
this.handshake().then(() => {
this.login().then(() => {
this.log.info('Authenticated successfully');
}).catch(() => {
this.log.error('Login failed');
});
});
}
}
}
4 changes: 2 additions & 2 deletions src/utils/p110.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class P110 extends P100 {
return this.handleKlapRequest(payload).then((response)=>{
if(response && response.result){
this._consumption = {
current: response.result.current_power / 1000,
current: Math.ceil(response.result.current_power / 1000),
total: response.result.today_energy / 1000,
};
} else{
Expand All @@ -44,7 +44,7 @@ export default class P110 extends P100 {
return this.handleRequest(payload).then((response)=>{
if(response && response.result){
this._consumption = {
current: response.result.current_power / 1000,
current: Math.ceil(response.result.current_power / 1000),
total: response.result.today_energy / 1000,
};
} else{
Expand Down

0 comments on commit fc50bc0

Please sign in to comment.