Skip to content

Commit

Permalink
New: Better default device names
Browse files Browse the repository at this point in the history
Default generated names are consist of the model name and the device ID so it's easier to recognize them then adding new devices.

Additionally this commit does:

- Drop deprecated `updateReachability` and don't rely on it for initi phase
- Use constructor to init accessories
- Use object as a first argument so we can pass all props to classes
- Use better function names
  • Loading branch information
Andrey Okonetchnikov authored and okonet committed Jan 4, 2020
1 parent 75218a8 commit 1c92c5f
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 282 deletions.
102 changes: 50 additions & 52 deletions bulbs/brightness.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,58 @@
const Brightness = ({ bright: b }) => Device => class extends Device {
constructor(did, model, platform) {
super(did, model, platform);
this.bright = b;
}
const Brightness = ({ bright: b }) => Device =>
class extends Device {
constructor(props, platform) {
super(props, platform);
this.bright = b;

get bright() {
return this._bright;
}

set bright(bright) {
this._bright = Number(bright);
}
(
this.service.getCharacteristic(global.Characteristic.Brightness) ||
this.service.addCharacteristic(global.Characteristic.Brightness)
)
.on('set', async (value, callback) => {
try {
await this.setBrightness(value);
callback(null, value);
} catch (err) {
callback(err, this.bright);
}
})
.updateValue(this.bright);
}

setBrightness(brightness) {
const { brightness: transition = 400 } = this.config.transitions || {};
const req = {
method: 'set_bright',
params: [
Math.max(brightness, 1),
'smooth',
transition,
],
};
return this.sendCmd(req).then(() => { this._bright = brightness; });
}
get bright() {
return this._bright;
}

updateStateFromProp(prop, value) {
// There are different props being used for brightness
// depending on the active_mode in Ceiling lamps
if (
(this.activeMode === 0 && prop === 'bright')
|| (this.activeMode === 1 && prop === 'nl_br')
) {
this.bright = value;
this.service
.getCharacteristic(global.Characteristic.Brightness)
.updateValue(this.bright);
return;
set bright(bright) {
this._bright = Number(bright);
}
super.updateStateFromProp(prop, value);
}

configureServices() {
super.configureServices();
setBrightness(brightness) {
const { brightness: transition = 400 } = this.config.transitions || {};
const req = {
method: 'set_bright',
params: [Math.max(brightness, 1), 'smooth', transition],
};
return this.sendCmd(req).then(() => {
this._bright = brightness;
});
}

(this.service.getCharacteristic(global.Characteristic.Brightness)
|| this.service.addCharacteristic(global.Characteristic.Brightness))
.on('set', async (value, callback) => {
try {
await this.setBrightness(value);
callback(null, value);
} catch (err) {
callback(err, this.bright);
}
}).updateValue(this.bright);
}
};
updateStateFromProp(prop, value) {
// There are different props being used for brightness
// depending on the active_mode in Ceiling lamps
if (
(this.activeMode === 0 && prop === 'bright') ||
(this.activeMode === 1 && prop === 'nl_br')
) {
this.bright = value;
this.service
.getCharacteristic(global.Characteristic.Brightness)
.updateValue(this.bright);
return;
}
super.updateStateFromProp(prop, value);
}
};

module.exports = Brightness;
106 changes: 58 additions & 48 deletions bulbs/bulb.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,60 @@
const net = require('net');
const { id, name, handle } = require('../utils');
const { id, handle } = require('../utils');

class YeeBulb {
constructor(did, model, platform) {
this.did = did;
constructor(props, platform) {
const { id, model, name, endpoint, accessory } = props;
this.did = id;
this.model = model;
this.log = platform.log;
this.cmds = {};
this.sock = null;
this.accessory = null;
this.accessory = accessory;
this.config = platform.config || {};

this.endpoint = endpoint;
const { retries = 5, timeout = 100 } = this.config.connection || {};
this.retries = retries;
this.timeout = timeout;

this.accessory
.getService(global.Service.AccessoryInformation)
.setCharacteristic(global.Characteristic.Manufacturer, 'YeeLight')
.setCharacteristic(global.Characteristic.Model, this.model)
.setCharacteristic(global.Characteristic.SerialNumber, this.did);

this.service =
this.accessory.getService(global.Service.Lightbulb) ||
this.accessory.addService(new global.Service.Lightbulb(name));

this.accessory.on('identify', async (_, callback) => {
await this.identify();
callback();
});

this.service
.getCharacteristic(global.Characteristic.On)
.on('set', async (value, callback) => {
try {
await this.setPower(value);
callback(null, value);
} catch (err) {
callback(err, this.power);
}
})
.on('get', async callback => {
try {
const [value] = await this.getProperty(['power']);
this.power = value;
callback(null, this.power);
} catch (err) {
callback(err, this.power);
}
})
.updateValue(this.power);

this.accessory.initialized = true;

this.log(`Initialized device ${name} (${this.endpoint}).`);
}

get endpoint() {
Expand Down Expand Up @@ -96,7 +137,12 @@ class YeeBulb {
}

identify() {
const req = { method: 'toggle', params: [] };
// Use flash notify effect when supported
// TODO: Check support for `start_cf`
const req = {
method: 'start_cf',
params: [10, 0, '500,2,0,10,500,2,0,100'],
};
return this.sendCmd(req);
}

Expand All @@ -110,12 +156,16 @@ class YeeBulb {
// eslint-disable-next-line no-await-in-loop
return await this._sendCmd(cmd, t);
} catch (err) {
this.log.warn(`failed attempt ${i} after ${t}ms.`);
this.log.warn(
`${this.did}: failed communication attempt ${i} after ${t}ms.`
);
if (err === 'EHOSTUNREACH') break;
}
}
this.sock.destroy();
this.log.error(`failed to send cmd ${cmd.id} after ${retries} retries.`);
this.log.error(
`${this.did}: failed to send cmd ${cmd.id} after ${retries} retries.`
);
return Promise.reject(new Error(`${cmd.id}`));
}

Expand Down Expand Up @@ -169,46 +219,6 @@ class YeeBulb {
});
return true;
}

configureServices() {
const deviceId = this.did.slice(-6);
const deviceName = name(deviceId, this.config);
this.accessory
.getService(global.Service.AccessoryInformation)
.setCharacteristic(global.Characteristic.Manufacturer, 'YeeLight')
.setCharacteristic(global.Characteristic.Model, this.model)
.setCharacteristic(global.Characteristic.SerialNumber, this.host);

this.service =
this.accessory.getService(global.Service.Lightbulb) ||
this.accessory.addService(new global.Service.Lightbulb(deviceName));

this.accessory.on('identify', async (_, callback) => {
await this.identify();
callback();
});

this.service
.getCharacteristic(global.Characteristic.On)
.on('set', async (value, callback) => {
try {
await this.setPower(value);
callback(null, value);
} catch (err) {
callback(err, this.power);
}
})
.on('get', async callback => {
try {
const [value] = await this.getProperty(['power']);
this.power = value;
callback(null, this.power);
} catch (err) {
callback(err, this.power);
}
})
.updateValue(this.power);
}
}

module.exports = YeeBulb;
71 changes: 34 additions & 37 deletions bulbs/color.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
const { isInteger } = Number;

const Color = ({ hue: h, sat: s }) => (Device) => {
const Color = ({ hue: h, sat: s }) => Device => {
let hue;
let sat;

return class extends Device {
constructor(did, model, platform) {
super(did, model, platform);
constructor(props, platform) {
super(props, platform);
this.hue = h;
this.sat = s;

const { Hue, Saturation } = global.Characteristic;

(
this.service.getCharacteristic(Hue) ||
this.service.addCharacteristic(Hue)
)
.on('set', async (value, callback) => {
try {
await this.setColor(value, null);
callback(null, this.hue);
} catch (err) {
callback(err, this.hue);
}
})
.updateValue(this.hue);

(
this.service.getCharacteristic(Saturation) ||
this.service.addCharacteristic(Saturation)
)
.on('set', async (value, callback) => {
try {
await this.setColor(null, value);
callback(null, this.sat);
} catch (err) {
callback(err, this.sat);
}
})
.updateValue(this.sat);
}

get hue() {
Expand Down Expand Up @@ -57,12 +87,7 @@ const Color = ({ hue: h, sat: s }) => (Device) => {
this.setPower(1);
const req = {
method: 'set_hsv',
params: [
hue,
sat,
'smooth',
transition,
],
params: [hue, sat, 'smooth', transition],
};
return this.sendCmd(req).then(() => {
this._hue = hue;
Expand All @@ -71,34 +96,6 @@ const Color = ({ hue: h, sat: s }) => (Device) => {
sat = null;
});
}

configureServices() {
super.configureServices();

const { Hue, Saturation } = global.Characteristic;

(this.service.getCharacteristic(Hue)
|| this.service.addCharacteristic(Hue))
.on('set', async (value, callback) => {
try {
await this.setColor(value, null);
callback(null, this.hue);
} catch (err) {
callback(err, this.hue);
}
}).updateValue(this.hue);

(this.service.getCharacteristic(Saturation)
|| this.service.addCharacteristic(Saturation))
.on('set', async (value, callback) => {
try {
await this.setColor(null, value);
callback(null, this.sat);
} catch (err) {
callback(err, this.sat);
}
}).updateValue(this.sat);
}
};
};

Expand Down

0 comments on commit 1c92c5f

Please sign in to comment.