Skip to content

Commit

Permalink
Get initial device status before setting up homebride accessory handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
dkerr64 committed Dec 1, 2023
1 parent c409666 commit cbed6ce
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 59 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"displayName": "Homebridge YoLink",
"name": "homebridge-yolink",
"version": "1.4.3-beta.3",
"version": "1.4.3-beta.4",
"description": "Connect to YoLink.",
"license": "Apache-2.0",
"repository": {
Expand Down
9 changes: 5 additions & 4 deletions src/contactDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ export async function initContactSensor(this: YoLinkPlatformAccessory): Promise<
const accessory: PlatformAccessory = this.accessory;
const device: YoLinkDevice = accessory.context.device;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
this.contactService = accessory.getService(platform.Service.ContactSensor) || accessory.addService(platform.Service.ContactSensor);
this.contactService.setCharacteristic(platform.Characteristic.Name, device.name);
this.contactService.getCharacteristic(platform.Characteristic.ContactSensorState)
.onGet(handleGet.bind(this));

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
12 changes: 8 additions & 4 deletions src/garageDoor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ export async function initGarageDoor(this: YoLinkPlatformAccessory): Promise<voi
this.currentState = undefined;
this.initializeDeviceVars(platform, doorSensor);


// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, doorSensor));
// above must await because we use doorSensor in handleGet for doorController
await this.refreshDataTimer(handleGetBlocking.bind(this, doorController));

// Once we have initial data, setup all the Homebridge handlers
if (doorSensor.hasBattery) {
doorSensor.batteryService = accessory.getService('Battery 2')
|| accessory.addService(platform.Service.Battery, 'Battery 2', 'battery2');
Expand All @@ -51,10 +59,6 @@ export async function initGarageDoor(this: YoLinkPlatformAccessory): Promise<voi
.onGet(() => {
return (false);
});

await this.refreshDataTimer(handleGetBlocking.bind(this, doorSensor));
// above must await because we use doorSensor in handleGet for doorController
await this.refreshDataTimer(handleGetBlocking.bind(this, doorController));
}

/***********************************************************************
Expand Down
6 changes: 3 additions & 3 deletions src/infraredRemoter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export async function initInfraredRemoter(this: YoLinkPlatformAccessory): Promis
const nLearned = device.data.keys.reduce((n: number, x: boolean) => (x === true) ? n + 1 : n, 0);
platform.verboseLog(`Initialize infrared remoter with ${nLearned} button${(nLearned > 1) ? 's' : ''}`);

// timer to regularly update the data... really only to monitor battery level.
await this.refreshDataTimer(handleGet.bind(this, -1));

// serviceLabel required when multiple services of same type on one accessory
this.serviceLabel = accessory.getService(platform.Service.ServiceLabel) || accessory.addService(platform.Service.ServiceLabel);
this.serviceLabel.setCharacteristic(platform.Characteristic.Name, device.name);
Expand Down Expand Up @@ -62,9 +65,6 @@ export async function initInfraredRemoter(this: YoLinkPlatformAccessory): Promis
.onSet(handleSet.bind(this, i));
}
});

// timer to regularly update the data... really only to monitor battery level.
await this.refreshDataTimer(handleGet.bind(this, -1));
}

/***********************************************************************
Expand Down
31 changes: 16 additions & 15 deletions src/leakDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export async function initLeakSensor(this: YoLinkPlatformAccessory): Promise<voi
const accessory: PlatformAccessory = this.accessory;
const device: YoLinkDevice = accessory.context.device;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
this.leakService = accessory.getService(platform.Service.LeakSensor) || accessory.addService(platform.Service.LeakSensor);
this.leakService.setCharacteristic(platform.Characteristic.Name, device.name);
this.leakService.getCharacteristic(platform.Characteristic.LeakDetected)
Expand All @@ -26,18 +31,14 @@ export async function initLeakSensor(this: YoLinkPlatformAccessory): Promise<voi
if (device.config.temperature) {
// If requested add a service for the internal device temperature.
this.thermoService = accessory.getService(platform.Service.TemperatureSensor)
|| accessory.addService(platform.Service.TemperatureSensor);
|| accessory.addService(platform.Service.TemperatureSensor);
this.thermoService.setCharacteristic(platform.Characteristic.Name, device.name + ' Temperature');
this.thermoService.getCharacteristic(platform.Characteristic.CurrentTemperature)
.onGet(handleGet.bind(this, 'thermo'));
} else {
// If not requested then remove it if it already exists.
accessory.removeService(accessory.getService(platform.Service.TemperatureSensor)!);
}

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down Expand Up @@ -90,7 +91,7 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'mai
this.leakService
.updateCharacteristic(platform.Characteristic.StatusActive, true)
.updateCharacteristic(platform.Characteristic.StatusFault, false);
switch(devSensor) {
switch (devSensor) {
case 'thermo':
rc = device.data.state.devTemperature;
break;
Expand All @@ -100,15 +101,15 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'mai
}
}
this.logDeviceState(device, `Leak: ${device.data.state.state}, Battery: ${device.data.state.battery}, ` +
`DevTemp: ${device.data.state.devTemperature}\u00B0C ` +
`(${(device.data.state.devTemperature*9/5+32).toFixed(1)}\u00B0F)`);
`DevTemp: ${device.data.state.devTemperature}\u00B0C ` +
`(${(device.data.state.devTemperature * 9 / 5 + 32).toFixed(1)}\u00B0F)`);
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
this.leakService
.updateCharacteristic(platform.Characteristic.StatusActive, false)
.updateCharacteristic(platform.Characteristic.StatusFault, true);
}
} catch(e) {
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
platform.log.error('Error in LeakDevice handleGet' + platform.reportError + msg);
} finally {
Expand Down Expand Up @@ -151,19 +152,19 @@ export async function mqttLeakSensor(this: YoLinkPlatformAccessory, message): Pr
device.updateTime = Math.floor(new Date().getTime() / 1000) + device.config.refreshAfter;
const mqttMessage = `MQTT: ${message.event} for device ${device.deviceMsgName}`;
const event = message.event.split('.');
const batteryMsg = (device.hasBattery && message.data.battery) ? `, Battery: ${message.data.battery}`: '';
const batteryMsg = (device.hasBattery && message.data.battery) ? `, Battery: ${message.data.battery}` : '';
const alertMsg = (message.data.alertType) ? `, Alert: ${message.data.alertType}` : '';
const devTempMsg = (message.data.devTemperature) ? `, DevTemp: ${message.data.devTemperature}\u00B0C ` +
`(${(message.data.devTemperature*9/5+32).toFixed(1)}\u00B0F)` : '';
`(${(message.data.devTemperature * 9 / 5 + 32).toFixed(1)}\u00B0F)` : '';

switch (event[1]) {
case 'Alert':
// falls through
// falls through
case 'StatusChange':
// falls through
// falls through
case 'Report':
if (!device.data) {
// in rare conditions (error conditions returned from YoLink) data object will be undefined or null.
// in rare conditions (error conditions returned from YoLink) data object will be undefined or null.
platform.log.warn(`Device ${device.deviceMsgName} has no data field, is device offline?`);
this.leakService.updateCharacteristic(platform.Characteristic.StatusFault, true);
break;
Expand All @@ -189,7 +190,7 @@ export async function mqttLeakSensor(this: YoLinkPlatformAccessory, message): Pr
default:
platform.log.warn(mqttMessage + ' not supported.' + platform.reportError + JSON.stringify(message));
}
} catch(e) {
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
platform.log.error('Error in mqttLeakSensor' + platform.reportError + msg);
} finally {
Expand Down
9 changes: 5 additions & 4 deletions src/lightbulbDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export async function initLightbulb(this: YoLinkPlatformAccessory, onState: stri
this.setOn = setOn;
this.setOff = setOff;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'on'));

// Once we have initial data, setup all the Homebridge handlers
this.lightbulbService = accessory.getService(platform.Service.Lightbulb) || accessory.addService(platform.Service.Lightbulb);
this.lightbulbService.setCharacteristic(platform.Characteristic.Name, device.name);
this.lightbulbService.getCharacteristic(platform.Characteristic.On)
Expand All @@ -31,10 +36,6 @@ export async function initLightbulb(this: YoLinkPlatformAccessory, onState: stri
this.lightbulbService.getCharacteristic(platform.Characteristic.Brightness)
.onGet(handleGet.bind(this, 'brightness'))
.onSet(handleSet.bind(this, 'brightness'));

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'on'));
}

/***********************************************************************
Expand Down
9 changes: 5 additions & 4 deletions src/lockDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export async function initLockDevice(this: YoLinkPlatformAccessory): Promise<voi
this.setLock = 'lock';
this.setUnlock = 'unlock';

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
this.lockService = accessory.getService(platform.Service.LockMechanism)
|| accessory.addService(platform.Service.LockMechanism);
this.lockService.setCharacteristic(platform.Characteristic.Name, device.name);
Expand Down Expand Up @@ -57,10 +62,6 @@ export async function initLockDevice(this: YoLinkPlatformAccessory): Promise<voi
platform.verboseLog('Lock door bell onGet called');
return (platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
});

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
9 changes: 5 additions & 4 deletions src/motionDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export async function initMotionSensor(this: YoLinkPlatformAccessory): Promise<v
const accessory: PlatformAccessory = this.accessory;
const device: YoLinkDevice = accessory.context.device;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
this.motionService = accessory.getService(platform.Service.MotionSensor) || accessory.addService(platform.Service.MotionSensor);
this.motionService.setCharacteristic(platform.Characteristic.Name, device.name);
this.motionService.getCharacteristic(platform.Characteristic.MotionDetected)
Expand All @@ -34,10 +39,6 @@ export async function initMotionSensor(this: YoLinkPlatformAccessory): Promise<v
// If not requested then remove it if it already exists.
accessory.removeService(accessory.getService(platform.Service.TemperatureSensor)!);
}

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
8 changes: 5 additions & 3 deletions src/outletDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export async function initOutletDevice(this: YoLinkPlatformAccessory, onState: s
platform.verboseLog(`Device ${device.deviceMsgName} has ${this.nOutlets} outlets`);
}

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 0));

// Once we have initial data, setup all the Homebridge handlers
if (this.nOutlets === 1) {
this.outlet.push({});
this.outlet[0].service = accessory.getService(platform.Service.Outlet)
Expand Down Expand Up @@ -79,9 +84,6 @@ export async function initOutletDevice(this: YoLinkPlatformAccessory, onState: s
.onSet(handleSet.bind(this, i));
}
}
// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 0));
}

/***********************************************************************
Expand Down
9 changes: 5 additions & 4 deletions src/powerDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export async function initPowerSensor(this: YoLinkPlatformAccessory): Promise<vo

this.currentState = undefined;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
if (serviceType === 'contact') {
// In case it was previously set as outlet, remove it...
accessory.removeService(accessory.getService(platform.Service.Outlet)!);
Expand All @@ -41,10 +46,6 @@ export async function initPowerSensor(this: YoLinkPlatformAccessory): Promise<vo
.onGet(handleGet.bind(this))
.onSet(handleSet.bind(this));
}

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
8 changes: 5 additions & 3 deletions src/statelessSwitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export async function initStatelessSwitch(this: YoLinkPlatformAccessory, nButton
device.config.doublePress ??= (platform.config.doublePress ??= 800);
this.button = [];

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
// serviceLabel required when multiple services of same type on one accessory
this.serviceLabel = accessory.getService(platform.Service.ServiceLabel)
|| accessory.addService(platform.Service.ServiceLabel);
Expand Down Expand Up @@ -65,9 +70,6 @@ export async function initStatelessSwitch(this: YoLinkPlatformAccessory, nButton
// If not requested then remove it if it already exists.
accessory.removeService(accessory.getService(platform.Service.TemperatureSensor)!);
}

// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
9 changes: 6 additions & 3 deletions src/switchDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ export async function initSwitchDevice(this: YoLinkPlatformAccessory, onState, s
if ((device.type === 'Finger') || (device.type === 'GarageDoor')) {
this.setMethod = 'toggle';
}

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));

// Once we have initial data, setup all the Homebridge handlers
this.switchService = accessory.getService(platform.Service.Switch) || accessory.addService(platform.Service.Switch);
this.switchService.setCharacteristic(platform.Characteristic.Name, device.name);
this.switchService.getCharacteristic(platform.Characteristic.On)
.onGet(handleGet.bind(this))
.onSet(handleSet.bind(this));
// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this));
}

/***********************************************************************
Expand Down
8 changes: 5 additions & 3 deletions src/thermoHydroDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export async function initThermoHydroDevice(this: YoLinkPlatformAccessory): Prom
const accessory: PlatformAccessory = this.accessory;
const device: YoLinkDevice = accessory.context.device;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'both'));

// Once we have initial data, setup all the Homebridge handlers
if (String(device.config.hide).toLowerCase() === 'thermo') {
platform.log.info(`Hide Thermometer service because config.[${device.deviceId}].hide is set to "thermo"`);
accessory.removeService(accessory.getService(platform.Service.TemperatureSensor)!);
Expand All @@ -41,9 +46,6 @@ export async function initThermoHydroDevice(this: YoLinkPlatformAccessory): Prom
this.hydroService.getCharacteristic(platform.Characteristic.CurrentRelativeHumidity)
.onGet(handleGet.bind(this, 'hydro'));
}
// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'both'));
}

/***********************************************************************
Expand Down
9 changes: 5 additions & 4 deletions src/valveDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export async function initValveDevice(this: YoLinkPlatformAccessory): Promise<vo
const accessory: PlatformAccessory = this.accessory;
const device: YoLinkDevice = accessory.context.device;

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'both'));

// Once we have initial data, setup all the Homebridge handlers
this.valveService = accessory.getService(platform.Service.Valve) || accessory.addService(platform.Service.Valve);
this.valveService.setCharacteristic(platform.Characteristic.Name, device.name);
this.valveService.getCharacteristic(platform.Characteristic.Active)
Expand All @@ -27,10 +32,6 @@ export async function initValveDevice(this: YoLinkPlatformAccessory): Promise<vo
.onGet(handleInUse.bind(this));
this.valveService.getCharacteristic(platform.Characteristic.ValveType)
.onGet(handleType.bind(this));

// Call get handler to initialize data fields to current state and set
// timer to regularly update the data.
await this.refreshDataTimer(handleGetBlocking.bind(this, 'both'));
}

/***********************************************************************
Expand Down

0 comments on commit cbed6ce

Please sign in to comment.