New Device: Energy Monitoring Support
Opened this issue · 0 comments
shivanathd commented
Hi Everyone, I dont know how to code this but i used CHAT-GPT canvas and tried creating the code , Assuming we're planning to use Fakegato - History Library ([)](https://github.com/simont77/fakegato-history)
I wish if someone can look at the code, and if we can implement the Power Metering to all the devices it would be great to pull this into EVE app..
cc: @iRayanKhan
// Code from GPT
const TuyaDevice = require('tuya-device');
const fakegatoHistory = require('fakegato-history');
const { Service, Characteristic } = require('homebridge');
class TuyaPowerAccessory {
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.name = config.name;
this.deviceId = config.deviceId;
this.accessToken = config.accessToken;
this.dpCurrent = config.dpCurrent || '18';
this.dpVoltage = config.dpVoltage || '20';
this.dpPower = config.dpPower || '19';
this.tuyaDevice = this.initializeTuyaDevice();
// Setup Fakegato History Service to track energy data with manual timer
this.historyService = new fakegatoHistory('energy', this, {
storage: 'fs',
path: this.api.user.persistPath(),
disableTimer: true,
disableRepeatLastData: true,
});
// Register Service and Characteristics for Power
this.service = new Service.Outlet(this.name);
this.service
.getCharacteristic(Characteristic.On)
.on('set', this.setOn.bind(this))
.on('get', this.getOn.bind(this));
this.service
.getCharacteristic(Characteristic.OutletInUse)
.on('get', this.getOutletInUse.bind(this));
// Adding characteristics to track power consumption
this.currentConsumptionCharacteristic = this.service.addCharacteristic(Characteristic.CurrentConsumption);
this.totalConsumptionCharacteristic = this.service.addCharacteristic(Characteristic.TotalConsumption);
this.voltageCharacteristic = this.service.addCharacteristic(Characteristic.Voltage);
this.electricCurrentCharacteristic = this.service.addCharacteristic(Characteristic.ElectricCurrent);
this.currentConsumptionCharacteristic.on('get', this.getCurrentConsumption.bind(this));
this.voltageCharacteristic.on('get', this.getVoltage.bind(this));
this.electricCurrentCharacteristic.on('get', this.getElectricCurrent.bind(this));
// Periodically fetch power consumption data every 10 minutes
this.refreshPowerConsumption();
}
// Initialize Tuya Device
initializeTuyaDevice() {
return new TuyaDevice({ id: this.deviceId, key: this.accessToken });
}
// Method to periodically refresh power data
refreshPowerConsumption() {
setInterval(async () => {
try {
const powerData = await this.fetchPowerData();
if (powerData) {
const { current, voltage, power } = powerData;
// Add entry to the Fakegato history service
this.historyService.addEntry({ time: Math.round(new Date().valueOf() / 1000), power: power });
// Update HomeKit characteristics with the latest power data
this.currentConsumptionCharacteristic.updateValue(power);
this.voltageCharacteristic.updateValue(voltage);
this.electricCurrentCharacteristic.updateValue(current);
}
} catch (error) {
this.log.error('Error fetching power data:', error);
}
}, 600000); // Refresh every 10 minutes
}
// Fetch power consumption data from Tuya device
async fetchPowerData() {
try {
const response = await this.tuyaDevice.get({ schema: true });
if (response && response.dps) {
// Extract power data points from the response
const powerData = {
current: response.dps[this.dpCurrent] || 0,
voltage: response.dps[this.dpVoltage] || 0,
power: response.dps[this.dpPower] || 0,
};
return powerData;
}
} catch (error) {
this.log.error('Error fetching power data from Tuya API:', error);
}
return null;
}
// Get the current power consumption
getCurrentConsumption(callback) {
this.fetchPowerData()
.then((data) => {
if (data) {
callback(null, data.power);
} else {
callback(new Error('Could not fetch current consumption'));
}
})
.catch((error) => callback(error));
}
// Get the current voltage
getVoltage(callback) {
this.fetchPowerData()
.then((data) => {
if (data) {
callback(null, data.voltage);
} else {
callback(new Error('Could not fetch voltage'));
}
})
.catch((error) => callback(error));
}
// Get the current electric current
getElectricCurrent(callback) {
this.fetchPowerData()
.then((data) => {
if (data) {
callback(null, data.current);
} else {
callback(new Error('Could not fetch electric current'));
}
})
.catch((error) => callback(error));
}
// Set the power state of the device
async setOn(value, callback) {
try {
await this.tuyaDevice.set({ dps: 1, set: value });
callback(null);
} catch (error) {
this.log.error('Error setting power state:', error);
callback(error);
}
}
// Get the current power state of the device
async getOn(callback) {
try {
const response = await this.tuyaDevice.get({ dps: 1 });
if (response && typeof response === 'boolean') {
callback(null, response);
} else {
callback(new Error('Could not fetch power state'));
}
} catch (error) {
this.log.error('Error getting power state:', error);
callback(error);
}
}
// Determine if the outlet is currently in use
getOutletInUse(callback) {
this.fetchPowerData()
.then((data) => {
if (data) {
callback(null, data.power > 0);
} else {
callback(new Error('Could not determine outlet usage'));
}
})
.catch((error) => callback(error));
}
// Return all services provided by this accessory
getServices() {
return [this.service, this.historyService];
}
}
module.exports = (homebridge) => {
fakegatoHistory(homebridge);
homebridge.registerAccessory('homebridge-tuya-power', 'TuyaPowerAccessory', TuyaPowerAccessory);
};