homebridge-tasmota
Version:
Homebridge plugin for Tasmota devices leveraging home assistant auto discovery.
180 lines • 11.4 kB
JavaScript
import createDebug from 'debug';
import { TasmotaService, isTrue } from './TasmotaService.js';
const debug = createDebug('Tasmota:binarySensor');
/**
* Platform Accessory
* An instance of this class is created for each accessory your platform registers
* Each accessory may expose multiple services of different service types.
*/
export class tasmotaBinarySensorService extends TasmotaService {
platform;
accessory;
uniq_id;
constructor(platform, accessory, uniq_id) {
super(platform, accessory, uniq_id);
this.platform = platform;
this.accessory = accessory;
this.uniq_id = uniq_id;
switch (accessory.context.device[this.uniq_id].dev_cla) {
case 'doorbell':
this.platform.log.debug('Creating %s binary sensor %s', accessory.context.device[this.uniq_id].dev_cla, accessory.context.device[this.uniq_id].name);
this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.ContactSensor, accessory.context.device[this.uniq_id].name, this.uuid);
this.service.setCharacteristic(this.platform.Characteristic.ConfiguredName, accessory.context.device[this.uniq_id].name);
if (!this.service.displayName) {
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
}
this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState);
if (this.platform.config.history) {
this.fakegato = 'contact';
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.TimesOpened);
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.LastActivation);
}
break;
case 'motion':
this.platform.log.debug('Creating %s binary sensor %s', accessory.context.device[this.uniq_id].dev_cla, accessory.context.device[this.uniq_id].name);
this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.MotionSensor, accessory.context.device[this.uniq_id].name, this.uuid);
this.service.setCharacteristic(this.platform.Characteristic.ConfiguredName, accessory.context.device[this.uniq_id].name);
if (!this.service.displayName) {
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
}
this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.MotionDetected);
if (this.platform.config.history) {
this.fakegato = 'motion';
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.LastActivation);
debug('adding', this.fakegato);
}
break;
case 'contact':
this.platform.log.debug('Creating %s binary sensor %s', accessory.context.device[this.uniq_id].dev_cla, accessory.context.device[this.uniq_id].name);
this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.ContactSensor, accessory.context.device[this.uniq_id].name, this.uuid);
this.service.setCharacteristic(this.platform.Characteristic.ConfiguredName, accessory.context.device[this.uniq_id].name);
if (!this.service.displayName) {
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
}
this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState);
if (this.platform.config.history) {
this.fakegato = 'contact';
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.LastActivation);
debug('adding', this.fakegato);
}
break;
case 'door':
this.platform.log.debug('Creating %s binary sensor %s', accessory.context.device[this.uniq_id].dev_cla, accessory.context.device[this.uniq_id].name);
this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.ContactSensor, accessory.context.device[this.uniq_id].name, this.uuid);
this.service.setCharacteristic(this.platform.Characteristic.ConfiguredName, accessory.context.device[this.uniq_id].name);
if (!this.service.displayName) {
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
}
this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState);
if (this.platform.config.history) {
this.fakegato = 'motion';
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.LastActivation);
debug('adding', this.fakegato);
}
break;
case 'moisture':
this.platform.log.debug('Creating %s binary sensor %s', accessory.context.device[this.uniq_id].dev_cla, accessory.context.device[this.uniq_id].name);
this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.LeakSensor, accessory.context.device[this.uniq_id].name, this.uuid);
this.service.setCharacteristic(this.platform.Characteristic.ConfiguredName, accessory.context.device[this.uniq_id].name);
if (!this.service.displayName) {
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
}
this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.LeakDetected);
if (this.platform.config.history) {
// this.fakegato = 'motion';
this.service.addOptionalCharacteristic(this.platform.CustomCharacteristics.LastActivation);
// debug('adding', this.fakegato);
}
break;
default:
this.platform.log.error('Warning: Unhandled Tasmota binary sensor type', accessory.context.device[this.uniq_id].dev_cla);
}
this.enableFakegato();
this.enableStatus();
}
statusUpdate(topic, message) {
debug('MQTT', topic, message.toString());
this.accessory.context.timeout = this.platform.autoCleanup(this.accessory);
try {
// debug('this.uniq_id', this.uniq_id);
// debug('val_tpl', this.accessory.context.device[this.uniq_id].val_tpl);
// debug('message', message.toString());
let value = message.toString();
if (this.accessory.context.device[this.uniq_id].val_tpl) {
value = this.parseValue(this.accessory.context.device[this.uniq_id].val_tpl, message.toString());
}
// debug('value', value, typeof value);
// debug('device_class', this.device_class);
// Adjust value to format expected by sensor type
switch (this.device_class) {
case 'doorbell':
break;
case 'moisture':
// 1 / 0
debug('moisture', this.accessory.context.device[this.uniq_id].pl_on, value);
value = (this.accessory.context.device[this.uniq_id].pl_on === value
? this.platform.Characteristic.LeakDetected.LEAK_DETECTED
: this.platform.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
break;
case 'door':
if (typeof this.accessory.context.device[this.uniq_id].pl_on === 'boolean') {
value = isTrue(value);
}
value = (this.accessory.context.device[this.uniq_id].pl_on === value
? this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
: this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED);
break;
case 'motion':
// boolean
value = (this.accessory.context.device[this.uniq_id].pl_on === value);
break;
case 'contact':
// boolean
value = (this.accessory.context.device[this.uniq_id].pl_on === value
? this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
: this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED);
break;
}
if (this.characteristic?.value !== value) {
this.platform.log.info('Updating \'%s\' binary sensor to %s', this.service?.displayName, value);
let timesOpened;
switch (this.device_class) {
case 'doorbell':
timesOpened = 1 + Number(this.service?.getCharacteristic(this.platform.CustomCharacteristics.TimesOpened).value);
this.service?.updateCharacteristic(this.platform.CustomCharacteristics.TimesOpened, timesOpened);
// fall thru
/* eslint-disable no-fallthrough */
case 'moisture':
case 'motion':
case 'contact':
if (this.platform.config.history) {
const now = Math.round(new Date().valueOf() / 1000);
const lastActivation = now - this.accessory.context.fakegatoService.getInitialTime();
this.service?.updateCharacteristic(this.platform.CustomCharacteristics.LastActivation, lastActivation);
}
break;
}
}
else {
this.platform.log.debug('Updating \'%s\' binary sensor to %s', this.service?.displayName, value);
}
this.characteristic?.updateValue(value);
if (this.platform.config.history && this.fakegato && this.accessory.context.fakegatoService?.addEntry) {
debug('Updating fakegato', this.service?.displayName, {
[this.fakegato]: (this.characteristic?.value ? 1 : 0),
});
this.accessory.context.fakegatoService.appendData({
[this.fakegato]: (this.characteristic?.value ? 1 : 0),
});
}
else {
// debug('Not updating fakegato', this.service.displayName);
}
}
catch (err) {
this.platform.log.error('ERROR: Message Parse Error', topic, message.toString());
this.platform.log.debug(String((err && err.message ? err.message : err)));
}
}
}
//# sourceMappingURL=tasmotaBinarySensorService.js.map