Skip to content

Commit

Permalink
Fix saving for 1.1.2+ firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
Elanis committed Apr 29, 2023
1 parent 01c3d0a commit 64d4521
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 25 deletions.
48 changes: 46 additions & 2 deletions getData.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,54 @@
from PyP100 import PyP110

import sys

p110 = PyP110.P110(sys.argv[1], sys.argv[2], sys.argv[3]) #Creating a P110 plug object
###################
# https://github.com/fishbigger/TapoP100/pull/87
###################
import json
import logging
import time

_LOGGER = logging.getLogger(__name__)

class P110B(PyP110.P110):
def getEnergyData(self, startT, endT, intervalT):
URL = f"http://{self.ipAddress}/app?token={self.token}"
Payload = {
"method": "get_energy_data",
"params":{ "end_timestamp": endT, "interval": intervalT, "start_timestamp": startT},
"requestTimeMils": int(round(time.time() * 1000)),
}

headers = {
"Cookie": self.cookie
}

EncryptedPayload = self.tpLinkCipher.encrypt(json.dumps(Payload))

SecurePassthroughPayload = {
"method":"securePassthrough",
"params":{
"request": EncryptedPayload
}
}
_LOGGER.debug("getEnergyUsage %s", self.ipAddress)
r = self.session.post(URL, json=SecurePassthroughPayload, headers=headers, timeout=2)

decryptedResponse = self.tpLinkCipher.decrypt(r.json()["result"]["response"])

return json.loads(decryptedResponse)

###################

p110 = P110B(sys.argv[1], sys.argv[2], sys.argv[3]) #Creating a P110 plug object

p110.handshake() #Creates the cookies required for further methods
p110.login() #Sends credentials to the plug and creates AES Key and IV for further methods

#PyP110 has all PyP100 functions and additionally allows to query energy usage infos
print(p110.getEnergyUsage()) #Returns dict with all the energy usage
#print(p110.getEnergyUsage()) #Returns dict with all the energy usage
print(p110.getEnergyUsage())
print(p110.getEnergyData(int(sys.argv[4]), int(sys.argv[5]), 43200))
print(p110.getEnergyData(int(sys.argv[4]), int(sys.argv[5]), 1440))
print(p110.getEnergyData(int(sys.argv[4]), int(sys.argv[5]), 60))
45 changes: 43 additions & 2 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,60 @@ console.log(config);
(async() => {
console.log('Loading power data ...');

const start = new Date(Date.now());
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
start.setMilliseconds(0);

const end = new Date(start.getTime());
end.setHours(12);

console.log(start.getTime() / 1000);
console.log(end.getTime() / 1000);

for(const ip of ips) {
console.log('Loading power data ...', ip);

await new Promise((resolve, reject) => {
// Yeaaap, this is ugly, but I tried to rewrite python module as JS Code, and failed, so, let's get lazy
const pythonProcess = child_process.spawn('python', [__dirname + '/getData.py', ip, username, password]);
const pythonProcess = child_process.spawn('python', [__dirname + '/getData.py', ip, username, password, start.getTime() / 1000, end.getTime() / 1000]);
pythonProcess.stdout.on('data', (data) => {
//console.log(data.toString());

const results = data.toString().replaceAll('\'', '"').replace('\r', '').split('\n');

const genericData = JSON.parse(results[0]);

const hourly = JSON.parse(results[3]);
const daily = JSON.parse(results[2]);
daily.result.data = daily.result.data.slice(0, 29);
const monthly = JSON.parse(results[1]);
monthly.result.data = monthly.result.data.filter(x => x !== 0);

// Reformat
const reformattedData = {
result: {
today_runtime: genericData.result.today_runtime,
month_runtime: genericData.result.month_runtime,
today_energy: genericData.result.today_energy,
month_energy: genericData.result.month_energy,
local_time: genericData.result.local_time,
current_power: genericData.result.current_power,
past24h: hourly.result.data,
past30d: daily.result.data,
past1y: monthly.result.data,
past7d: [],
},
error_code: null,
};

//console.log(reformattedData);

AppDataManager.saveObject(
'power-tplink-tapo-p110',
`${ip}--${Date.now()}`,
JSON.parse(data.toString().replaceAll('\'', '"')));
reformattedData);

resolve();
});
Expand Down
21 changes: 0 additions & 21 deletions main.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,6 @@ export default class TpLinkP110PowerStatsSubmitter {
}
);

//// PAST 7d
const past7d = parsedContent.result.past7d;
past7d.pop(); // Remove "today"
const past7dData = past7d.flat().reverse();
date = new Date(Date.parse(parsedContent.result.local_time.split(' ')[0] + ' 23:30', { setZone: true, zone: 'Europe/Paris' }))
date.setDate(date.getDate() - 1);

await TpLinkP110PowerStatsSubmitter.pushData(
past7dData,
date,
'hourly',
(currDate) => {
currDate.setHours(currDate.getHours() - 1);
return currDate
}, {
ip: file.split('--')[0],
source: file,
type: 'past7d'
}
);

//// PAST 30d
const past30dData = parsedContent.result.past30d.reverse();
// Remove first element as it's probably an unfinished day
Expand Down

0 comments on commit 64d4521

Please sign in to comment.