Skip to content

Instantly share code, notes, and snippets.

@gudongfeng
Created May 3, 2020 06:05
Show Gist options
  • Save gudongfeng/16fb67b6c6a26fdba597166cfd67bca6 to your computer and use it in GitHub Desktop.
Save gudongfeng/16fb67b6c6a26fdba597166cfd67bca6 to your computer and use it in GitHub Desktop.
const { Client } = require('tplink-smarthome-api');
const _ = require('lodash');
const fs = require('fs');
const client = new Client();
const deviceInfoFilePath = '/tmp/devicelist.json';
var devicesInfo = {};
function writeStatusToFile(object) {
// Write the status to file
fs.writeFileSync(deviceInfoFilePath, JSON.stringify(object, null, 2));
};
function difference(object, base) {
function changes(object, base) {
return _.transform(object, function (result, value, key) {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key])
? changes(value, base[key])
: value;
}
});
}
return changes(base, object);
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
// Clean the device file at the first run.
fs.writeFileSync(deviceInfoFilePath, '');
// Search for all plugs and then write then to file
client.on('device-new', (device) => {
device.startPolling(500);
// Listen to the plug power event, update the cache file accordingly.
device.on('power-update', (powerOn) => {
const fileContents = fs.readFileSync(deviceInfoFilePath);
if (fileContents == '') {
writeStatusToFile(devicesInfo);
}
// Update device info object
if (!(device.host in devicesInfo)) {
devicesInfo[device.host] = { name: device.alias, status: powerOn };
writeStatusToFile(devicesInfo);
}
if (device.host in devicesInfo && powerOn != devicesInfo[device.host]['status']) {
devicesInfo[device.host] = { name: device.alias, status: powerOn };
writeStatusToFile(devicesInfo);
}
});
});
console.log('Start discovering devices');
client.startDiscovery({ discoveryTimeout: 0 });
console.log('Finished discovering devices');
fs.watchFile(deviceInfoFilePath, () => {
const fileContents = fs.readFileSync(deviceInfoFilePath);
const newDevicesInfo = JSON.parse(fileContents);
const diff = difference(devicesInfo, newDevicesInfo);
devicesInfo = newDevicesInfo;
if (!isEmpty(diff)) {
// Send the new status to the device
for (const key in diff) {
const plug = client.getPlug({ host: key });
console.log(`Devices status have been updated`);
plug.setPowerState(diff[key]['status']);
}
}
});
{
"name": "kasacontrol",
"version": "1.0.0",
"description": "",
"main": "kasaControl.js",
"scripts": {
"start": "node kasaControl.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "dongfeng gu",
"license": "ISC",
"dependencies": {
"lodash": "^4.17.15",
"tplink-smarthome-api": "^2.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment