Skip to content

Commit

Permalink
Merge pull request #65 from LtHummus/add-humidity-from-external-sensor
Browse files Browse the repository at this point in the history
Add humidity from external sensor
  • Loading branch information
fjs21 authored Jul 1, 2022
2 parents 2018041 + 80c28b9 commit 2535fbd
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 6 deletions.
79 changes: 78 additions & 1 deletion src/ductless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export class KumoPlatformAccessory_ductless {
private Fan: Service;
private PowerSwitch: Service;
private Dehumidifier: Service;
private Humidity: Service | null;
private HumidityBattery: Service | null;


private lastupdate;
private lastquery;
Expand All @@ -34,6 +37,16 @@ export class KumoPlatformAccessory_ductless {
) {
this.directAccess = this.platform.config.directAccess;

const useExternalSensor = this.directAccess &&
this.accessory.context.device.activeThermistor !== undefined &&
this.accessory.context.device.activeThermistor !== 'unset';

if (useExternalSensor) {
this.platform.log.info('device %s uses external sensor %s',
this.accessory.context.serial,
this.accessory.context.device.activeThermistor);
}

// determine device profile and additional sensors to tailor accessory to
// the capabilities of the kumo device
// (not yet implemented)
Expand Down Expand Up @@ -79,6 +92,21 @@ export class KumoPlatformAccessory_ductless {
this.Fan.setCharacteristic(this.platform.Characteristic.Name, 'Fan');
this.PowerSwitch.setCharacteristic(this.platform.Characteristic.Name, 'Power');

this.Humidity = useExternalSensor ? this.accessory.getService(
this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor) : null;

this.HumidityBattery = useExternalSensor ? this.accessory.getService(
this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery) : null;

if (this.Humidity) {
this.Humidity.setCharacteristic(this.platform.Characteristic.Name, 'Humidity Sensor');
}

if (this.HumidityBattery) {
this.HumidityBattery.setCharacteristic(this.platform.Characteristic.Name, 'Humidity Sensor Battery');
this.HumidityBattery.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
}

// create handlers for characteristics
this.HeaterCooler.getCharacteristic(this.platform.Characteristic.Active)
.on('get', this.handleActiveGet.bind(this))
Expand Down Expand Up @@ -147,6 +175,11 @@ export class KumoPlatformAccessory_ductless {
// .on('get', this.handleDehumidiferActiveGet.bind(this))
// .on('set', this.handleDehumidiferActiveSet.bind(this));

if (this.Humidity) {
this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
.on('get', this.handleHumidityGet.bind(this));
}

this.updateDevice();

// setup interval for updating device for historyService
Expand Down Expand Up @@ -239,6 +272,14 @@ export class KumoPlatformAccessory_ductless {
callback(null, this.Dehumidifier.getCharacteristic(this.platform.Characteristic.On).value);
}

async handleHumidityGet(callback) {
if (!this.Humidity) {
return;
}
await this.updateAccessoryCharacteristics();
callback(null, this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity).value);
}

async updateAccessoryCharacteristics() {
// updateAccessoryCharacteristics

Expand All @@ -259,6 +300,7 @@ export class KumoPlatformAccessory_ductless {
this.updateFanSwingMode();
this.updatePowerSwitchOn();
this.updateDehumidifierSwitchOn();
this.updateCurrentRelativeHumidity();

//this.platform.log.debug('updateAccessoryCharacteristic completed (%s)', this.accessory.context.serial)
return true;
Expand Down Expand Up @@ -306,12 +348,47 @@ export class KumoPlatformAccessory_ductless {
return false;
}
this.platform.log.debug('%s (queryDevice_Direct): success.', this.accessory.displayName);

if (this.Humidity) {
this.platform.log.debug('querying external sensors on %s', this.accessory.context.serial);
const sensorData = await this.platform.kumo.queryDeviceSensors_Direct(this.accessory.context.serial);
if (sensorData) {
this.accessory.context.sensors = sensorData;
}
}
}

// update device contect
this.accessory.context.device = device;
return true;
}
}

private updateCurrentRelativeHumidity() {
if (!this.Humidity || !this.HumidityBattery) {
return;
}
let currentValue: number = <number>this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity).value;
if (this.accessory.context.sensors && this.accessory.context.sensors.length) {
const ourSensor = this.accessory.context.sensors[0];
currentValue = ourSensor.humidity;
this.platform.log.debug('setting humidity to %s', currentValue);

if (ourSensor.battery) {
if (ourSensor.battery < 10) {
this.platform.log.warn('!!!The sensor attached to device %s has a low battery!!!', this.accessory.context.serial)

this.Humidity.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
} else {
this.Humidity.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
}

this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.BatteryLevel, ourSensor.battery);
}
}
this.Humidity.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, currentValue);
}

private updateHeaterCoolerActive() {
// HeaterCooler Active
Expand Down
77 changes: 77 additions & 0 deletions src/ductless_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { KUMO_LAG, KUMO_DEVICE_WAIT } from './settings';
*/
export class KumoPlatformAccessory_ductless_simple {
private HeaterCooler: Service;
private Humidity: Service | null;
private HumidityBattery: Service | null;

private lastupdate;
private lastquery;
Expand All @@ -30,6 +32,16 @@ export class KumoPlatformAccessory_ductless_simple {
) {
this.directAccess = this.platform.config.directAccess;

const useExternalSensor = this.directAccess &&
this.accessory.context.device.activeThermistor !== undefined &&
this.accessory.context.device.activeThermistor !== 'unset';

if (useExternalSensor) {
this.platform.log.info('device %s uses external sensor %s',
this.accessory.context.serial,
this.accessory.context.device.activeThermistor);
}

// set accessory information
if (accessory.context.zoneTable.unitType !== undefined && accessory.context.zoneTable.unitType !== null) {
const unitType: string = this.accessory.context.zoneTable.unitType;
Expand All @@ -47,9 +59,24 @@ export class KumoPlatformAccessory_ductless_simple {
this.HeaterCooler = this.accessory.getService(
this.platform.Service.HeaterCooler) || this.accessory.addService(this.platform.Service.HeaterCooler);

this.Humidity = useExternalSensor ? this.accessory.getService(
this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor) : null;

this.HumidityBattery = useExternalSensor ? this.accessory.getService(
this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery) : null;

// set sevice names.
this.HeaterCooler.setCharacteristic(this.platform.Characteristic.Name, 'Heater/Cooler');

if (this.Humidity) {
this.Humidity.setCharacteristic(this.platform.Characteristic.Name, 'Humidity Sensor');
}

if (this.HumidityBattery) {
this.HumidityBattery.setCharacteristic(this.platform.Characteristic.Name, 'Humidity Sensor Battery');
this.HumidityBattery.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
}

// create handlers for characteristics
this.HeaterCooler.getCharacteristic(this.platform.Characteristic.Active)
.on('get', this.handleActiveGet.bind(this))
Expand Down Expand Up @@ -79,6 +106,11 @@ export class KumoPlatformAccessory_ductless_simple {
this.HeaterCooler.getCharacteristic(this.platform.Characteristic.SwingMode)
.on('set', this.handleFanSwingModeSet.bind(this));

if (this.Humidity) {
this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
.on('get', this.handleHumidityGet.bind(this));
}

this.updateDevice();

// setup interval for updating device for historyService
Expand Down Expand Up @@ -138,6 +170,14 @@ export class KumoPlatformAccessory_ductless_simple {
callback(null, this.HeaterCooler.getCharacteristic(this.platform.Characteristic.SwingMode).value);
}

async handleHumidityGet(callback) {
if (!this.Humidity) {
return;
}
await this.updateAccessoryCharacteristics();
callback(null, this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity).value);
}

async updateAccessoryCharacteristics() {
// updateAccessoryCharacteristics

Expand All @@ -155,6 +195,7 @@ export class KumoPlatformAccessory_ductless_simple {
this.updateCurrentTemperature();
this.updateFanRotationSpeed();
this.updateFanSwingMode();
this.updateCurrentRelativeHumidity();

//this.platform.log.debug('updateAccessoryCharacteristic completed (%s)', this.accessory.context.serial)
return true;
Expand Down Expand Up @@ -202,6 +243,15 @@ export class KumoPlatformAccessory_ductless_simple {
return false;
}
this.platform.log.debug('%s (queryDevice_Direct): success.');

if (this.Humidity) {
this.platform.log.debug('querying external sensors on %s', this.accessory.context.serial);
const sensorData = await this.platform.kumo.queryDeviceSensors_Direct(this.accessory.context.serial);
if (sensorData) {
this.accessory.context.sensors = sensorData;
}
}

}

// update device contect
Expand Down Expand Up @@ -316,6 +366,33 @@ export class KumoPlatformAccessory_ductless_simple {
temp: currentValue,
});
}

private updateCurrentRelativeHumidity() {
if (!this.Humidity || !this.HumidityBattery) {
return;
}
let currentValue: number = <number>this.Humidity.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity).value;
if (this.accessory.context.sensors && this.accessory.context.sensors.length) {
const ourSensor = this.accessory.context.sensors[0];
currentValue = ourSensor.humidity;
this.platform.log.debug('setting humidity to %s', currentValue);

if (ourSensor.battery) {
if (ourSensor.battery < 10) {
this.platform.log.warn('!!!The sensor attached to device %s has a low battery!!!', this.accessory.context.serial)

this.Humidity.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
} else {
this.Humidity.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
}

this.HumidityBattery.updateCharacteristic(this.platform.Characteristic.BatteryLevel, ourSensor.battery);
}
}
this.Humidity.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, currentValue);
}

private updateFanRotationSpeed() {
// FanRotationSpeed
Expand Down
14 changes: 10 additions & 4 deletions src/kumo-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ interface KumoDeviceDirectInterface {
vaneDir: string,
}

interface KumoSensorData {
battery: number;
humidity: number;
temperature: number;
uuid: string;
}

export type KumoDeviceDirect = Readonly<KumoDeviceDirectInterface>;

// Renew Kumo security credentials every so often, in hours.
Expand Down Expand Up @@ -354,22 +361,21 @@ export class KumoApi {
return true;
}

// querying sensors (not implemented as not available to test)
// querying sensors
async queryDeviceSensors_Direct(serial: string) {
const data = await this.directRequest('{"c":{"sensors":{}}}', serial);
if(!data){
return null;
}
this.log.debug(util.inspect(data, { colors: true, sorted: true, depth: 3 }));

const deviceSensors = [] as any;
const deviceSensors = [] as KumoSensorData[];
try {
const sensors = data.r.sensors;
for(const sensor in sensors) {
if(sensors[sensor].uuid !== null && sensors[sensor].uuid !== undefined) {
this.log.debug('Found sensor.uuid: %s', sensors[sensor].uuid);
const uuid:string = sensors[sensor].uuid;
deviceSensors.push(uuid);
deviceSensors.push(<KumoSensorData>sensors[sensor]);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class KumoHomebridgePlatform implements DynamicPlatformPlugin {
if(this.config.simpleDuctless) {
new KumoPlatformAccessory_ductless_simple(this, accessory);
} else {
new KumoPlatformAccessory_ductless(this, accessory);
new KumoPlatformAccessory_ductless(this, accessory);
}
} else {
this.log.info('Initializing "%s" of unitType "%s" as generic (unspecified) unit.',
Expand Down

0 comments on commit 2535fbd

Please sign in to comment.