Skip to content

Commit

Permalink
Reinforcing correct zone state values and adds the ability to invert …
Browse files Browse the repository at this point in the history
…the value of a zone's state.
  • Loading branch information
mkormendy committed Jan 25, 2021
1 parent 268510b commit 66a1d52
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 39 deletions.
82 changes: 59 additions & 23 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
UUID: zoneUUID,
displayName: displayName + ZONE_TYPES_TO_NAMES[configPanelZone.zoneType],
type: configPanelZone.zoneType,
invert: typeof configPanelZone.invert !== 'undefined' ? configPanelZone.invert : false,
model: panelModel + ' ' + ZONE_TYPES_TO_NAMES[configPanelZone.zoneType],
serialNumber: panelShortUUID + '-' + configPanelZone.zoneNumber,
panel: panelObject,
Expand Down Expand Up @@ -649,11 +650,23 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
if (Array.isArray(accessoriesToUpdateArray) || accessoriesToUpdateArray!.length) {
// update zones/accessories in Homebridge and HomeKit
this.api.updatePlatformAccessories(accessoriesToUpdateArray);
// set the switch to inverted state immediately after it's been added to Homebridge/HomeKit
// accessoriesToUpdateArray.forEach((accessory) => {
// if (['switch', 'alarmswitch'].includes(accessory.context.device.type) && accessory.context.device.invert === true) {
// this.actuateAccessory(accessory.UUID, true);
// }
// });
}

if (Array.isArray(accessoriesToAddArray) || accessoriesToAddArray!.length) {
// add zones/accessories to Homebridge and HomeKit
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToAddArray);
// set the switch to inverted state immediately after it's been added to Homebridge/HomeKit
// accessoriesToAddArray.forEach((accessory) => {
// if (['switch', 'alarmswitch'].includes(accessory.context.device.type) && accessory.context.device.invert === true) {
// this.actuateAccessory(accessory.UUID, true);
// }
// });
}
}

Expand Down Expand Up @@ -709,40 +722,64 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
// loop through the accessories state cache and update state and service characteristic
this.zoneStatesRuntimeCache.forEach((accessory) => {
if (accessory.UUID === zoneUUID) {

let prevValue: boolean | number = req.body.state;
let stateValue: boolean | number = req.body.state;

// invert value if invert setting present in config for zone
if (accessory.invert === true) {

// we can't invert temperature or humidity sensors
// if it's not a temperature or humidity/temperature sensor we need to convert/invert the values
if (!['temperature', 'humidtemp'].includes(accessory.type)) {
if (accessory.type === 'motion') {
// boolean characteristics
prevValue = Boolean(req.body.state);
stateValue = req.body.state === 0 ? true : false;
} else {
// binary characteristics
stateValue = req.body.state === 0 ? 1 : 0;
}
this.log.debug(`${accessory.displayName} (${accessory.serialNumber}): inverted state from '${prevValue}' to '${stateValue}'`);
}
// otherwise we just leave the temperature or humidity/temperature sensor values alone

}

switch (ZONE_TYPES_TO_ACCESSORIES[existingAccessory.context.device.type]) {
case 'ContactSensor':
accessory.state = req.body.state;
accessory.state = stateValue;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.ContactSensorState,
req.body.state
stateValue
);
break;
case 'MotionSensor':
accessory.state = req.body.state;
accessory.state = stateValue;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.MotionDetected,
req.body.state
stateValue
);
break;
case 'LeakSensor':
accessory.state = req.body.state;
accessory.state = stateValue;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.LeakDetected,
req.body.state
stateValue
);
break;
case 'SmokeSensor':
accessory.state = req.body.state;
accessory.state = stateValue;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.SmokeDetected,
req.body.state
stateValue
);
break;
case 'TemperatureSensor':
accessory.temp = req.body.temp;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.CurrentTemperature,
req.body.temp
accessory.temp
);
break;
case 'HumiditySensor':
Expand All @@ -751,17 +788,10 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
this.Characteristic.CurrentRelativeHumidity,
accessory.humidity
);
accessory.temp = req.body.temp;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.CurrentTemperature,
req.body.temp
);
break;

case 'Switch':
accessory.state = req.body.state;
this.konnectedPlatformAccessories[existingAccessory.UUID].service.updateCharacteristic(
this.Characteristic.On,
req.body.state
accessory.temp
);
break;

Expand Down Expand Up @@ -807,14 +837,20 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
// Pro vs V1-V2 detection
if ('model' in existingAccessory.context.device.panel) {
// this is a Pro panel
actuatorPayload.zone = zoneObject.zoneNumber;
panelEndpoint += 'zone';
if (ZONES[zoneObject.zoneNumber].includes('switch')) {
actuatorPayload.zone = zoneObject.zoneNumber;
} else {
this.log.warn(
`Invalid Zone: Cannot actuate the zone '${zoneObject.zoneNumber}' for Konnected Pro Alarm Panels. Try zones 1-8, 'alarm1', 'out1', or 'alarm2_out2'.`
);
}
} else {
// this is a V1-V2 panel
panelEndpoint += 'device';
// convert zone to a pin
if (ZONES_TO_PINS[Number(zoneObject.zoneNumber)]) {
actuatorPayload!.pin = ZONES_TO_PINS[Number(zoneObject.zoneNumber)];
if (zoneObject.zoneNumber < 6 || zoneObject.zoneNumber === 'out') {
actuatorPayload!.pin = ZONES_TO_PINS[zoneObject.zoneNumber];
} else {
this.log.warn(
`Invalid Zone: Cannot actuate the zone '${zoneObject.zoneNumber}' for Konnected V1-V2 Alarm Panels. Try zones 1-5 or 'out'.`
Expand Down Expand Up @@ -856,7 +892,7 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
// this is a momentary switch, reset the state after done
setTimeout(() => {
// if state is on, turn off
const restoreState = value === true ? 0 : 1;
const restoreState = value === true ? false : true;
// update Homebridge/HomeKit displayed state
this.konnectedPlatformAccessories[zoneUUID].service.updateCharacteristic(
this.Characteristic.On,
Expand All @@ -882,7 +918,7 @@ export class KonnectedHomebridgePlatform implements DynamicPlatformPlugin {
}
});
}
});
});
}
}
}
37 changes: 21 additions & 16 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,25 @@ export class KonnectedPlatformAccessory {

this.platform.zoneStatesRuntimeCache.forEach((accessory) => {
if (accessory.UUID === accessoryUUID) {
this.platform.log.debug(
`Get [${accessory.displayName}] '${stateType}' Characteristic: ${accessory[stateType]}`
);

if (typeof accessory[stateType] === 'undefined') {
this.platform.log.debug(
`Assigning default state 0 to [${this.accessory.context.device.displayName}] '${
ZONE_TYPES_TO_ACCESSORIES[this.accessory.context.device.type]
}' Characteristic. Awaiting zone's first state change...`
);
if (stateType === 'switch') {
if (['motion', 'switch'].includes(stateType)) {
accessory[stateType] = value = false;
} else {
accessory[stateType] = value = 0;
}

this.platform.log.debug(
`Assigning default state '${value}' to [${this.accessory.context.device.displayName}] (${this.accessory.context.device.serialNumber}) '${ZONE_TYPES_TO_ACCESSORIES[this.accessory.context.device.type]}' Characteristic. Awaiting zone's first state change...`
);
} else {
value = Number(accessory[stateType]);
if (['motion', 'switch'].includes(stateType)) {
value = Boolean(accessory[stateType]);
} else {
value = Number(accessory[stateType]);
}
}
this.platform.log.debug(
`Get [${accessory.displayName}] (${accessory.serialNumber}) '${stateType}' Characteristic: ${accessory[stateType]}`
);
}
});
return value;
Expand All @@ -121,13 +121,18 @@ export class KonnectedPlatformAccessory {
/**
* Sets the state of the accessory in the state cache.
*/
setAccessoryState(accessoryUUID: string, stateType: string, value) {
setAccessoryState(accessoryUUID: string, stateType: string, value: boolean | number) {
this.platform.zoneStatesRuntimeCache.forEach((accessory) => {
if (accessory.UUID === accessoryUUID) {
if (['motion', 'switch'].includes(stateType)) {
value = Boolean(value);
} else {
value = Number(value);
}
accessory[stateType] = value;
this.platform.log.debug(
`Set [${this.accessory.context.device.displayName}] 'Switch' Characteristic: ${accessory[stateType]}`
`Set [${this.accessory.context.device.displayName}] (${accessory.serialNumber}) 'Switch' Characteristic: ${accessory[stateType]}`
);
accessory[stateType] = value;
}
});
this.platform.actuateAccessory(accessoryUUID, value);
Expand Down Expand Up @@ -173,7 +178,7 @@ export class KonnectedPlatformAccessory {
}

setSwitchValue(value, callback: CharacteristicGetCallback) {
const state = this.setAccessoryState(this.accessory.context.device.UUID, 'switch', value);
this.setAccessoryState(this.accessory.context.device.UUID, 'switch', value);
callback(null);
}
}

0 comments on commit 66a1d52

Please sign in to comment.