Skip to content

Commit

Permalink
Add internal "created device" events
Browse files Browse the repository at this point in the history
  • Loading branch information
atrovato committed Nov 5, 2020
1 parent 6fb3e75 commit 34dddaf
Show file tree
Hide file tree
Showing 13 changed files with 267 additions and 10 deletions.
8 changes: 8 additions & 0 deletions server/lib/device/device.create.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Promise = require('bluebird');
const { BadParameters } = require('../../utils/coreErrors');
const db = require('../../models');
const { EVENTS } = require('../../utils/constants');

const getByExternalId = async (externalId) => {
return db.Device.findOne({
Expand Down Expand Up @@ -61,6 +62,8 @@ async function create(device) {
delete device.features;
delete device.params;

let actionEvent = EVENTS.DEVICE.CREATE;

// we execute the whole insert in a transaction to avoir inconsistent state
await db.sequelize.transaction(async (transaction) => {
// external_id is a required parameter
Expand All @@ -76,6 +79,8 @@ async function create(device) {
if (deviceInDb === null) {
deviceInDb = await db.Device.create(device, { transaction });
} else {
actionEvent = EVENTS.DEVICE.UPDATE;

// or update it
await deviceInDb.update(device, { transaction });

Expand Down Expand Up @@ -152,6 +157,9 @@ async function create(device) {
this.poll(newDevice);
}

// notify device is succesfully created or updated
this.notify(newDevice, actionEvent);

return newDevice;
}

Expand Down
6 changes: 5 additions & 1 deletion server/lib/device/device.destroy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { NotFoundError } = require('../../utils/coreErrors');
const { DEVICE_POLL_FREQUENCIES } = require('../../utils/constants');
const { DEVICE_POLL_FREQUENCIES, EVENTS } = require('../../utils/constants');
const db = require('../../models');

/**
Expand Down Expand Up @@ -51,6 +51,10 @@ async function destroy(selector) {
}
}
});

// notify device removal
this.notify(device, EVENTS.DEVICE.DELETE);

return null;
}

Expand Down
44 changes: 44 additions & 0 deletions server/lib/device/device.notify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const get = require('get-value');

const logger = require('../../utils/logger');
const { EVENTS } = require('../../utils/constants');

const FUNC_BY_EVENT = {
[EVENTS.DEVICE.CREATE]: 'onNewDevice',
[EVENTS.DEVICE.UPDATE]: 'onUpdateDevice',
[EVENTS.DEVICE.DELETE]: 'onDeleteDevice',
};

/**
* @description Notify a device is created.
* @param {Object} device - Created device.
* @param {string} event - Event to send.
* @example
* device.notify({ service_id: 'a810b8db-6d04-4697-bed3-c4b72c996279'}, 'device.create');
*/
function notify(device, event) {
logger.debug(`Notify device ${device.selector} creation`);

const serviceFuncName = FUNC_BY_EVENT[event];

if (!serviceFuncName) {
logger.warn(`Event ${event} not handled to notify device changes`);
} else {
// send global event
this.eventManager.emit(event, device);

// notify concerned service
const service = this.serviceManager.getServiceById(device.service_id);
if (service === null) {
logger.warn(`Service ${device.service_id} was not found.`);
} else if (typeof get(service, `device.${serviceFuncName}`) !== 'function') {
logger.info(`Function device.${serviceFuncName} in service ${service.name} does not exist.`);
} else {
service.device[serviceFuncName](device);
}
}
}

module.exports = {
notify,
};
2 changes: 2 additions & 0 deletions server/lib/device/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const { setParam } = require('./device.setParam');
const { setValue } = require('./device.setValue');
const { setupPoll } = require('./device.setupPoll');
const { newStateEvent } = require('./device.newStateEvent');
const { notify } = require('./device.notify');

const DeviceManager = function DeviceManager(
eventManager,
Expand Down Expand Up @@ -71,5 +72,6 @@ DeviceManager.prototype.saveStringState = saveStringState;
DeviceManager.prototype.setParam = setParam;
DeviceManager.prototype.setupPoll = setupPoll;
DeviceManager.prototype.setValue = setValue;
DeviceManager.prototype.notify = notify;

module.exports = DeviceManager;
2 changes: 2 additions & 0 deletions server/lib/service/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { start } = require('./service.start');
const { startAll } = require('./service.startAll');
const { getByName } = require('./service.getByName');
const { getService } = require('./service.getService');
const { getServiceById } = require('./service.getServiceById');
const { getServices } = require('./service.getServices');
const { getMessageServices } = require('./service.getMessageServices');
const { getLocalServiceByName } = require('./service.getLocalServiceByName');
Expand All @@ -16,6 +17,7 @@ Service.prototype.load = load;
Service.prototype.start = start;
Service.prototype.startAll = startAll;
Service.prototype.getService = getService;
Service.prototype.getServiceById = getServiceById;
Service.prototype.getByName = getByName;
Service.prototype.getServices = getServices;
Service.prototype.getMessageServices = getMessageServices;
Expand Down
15 changes: 15 additions & 0 deletions server/lib/service/service.getServiceById.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @public
* @description Get service by its id.
* @param {string} id - Id of the service to get.
* @returns {Object} Return the service or null if not present.
* @example
* service.getServiceById('99dc10bb-14ab-49dc-bd11-f724e98fc97c');
*/
function getServiceById(id) {
return this.stateManager.get('serviceById', id);
}

module.exports = {
getServiceById,
};
1 change: 1 addition & 0 deletions server/lib/service/service.load.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ async function load(gladys) {
const newServiceObject = this.servicesFromFiles[service](gladys, serviceInDb.id);
// saving service in stateManager
this.stateManager.setState('service', service, newServiceObject);
this.stateManager.setState('serviceById', serviceInDb.id, newServiceObject);
if (newServiceObject.message && newServiceObject.message.send) {
serviceToInsertOrUpdate.has_message_feature = true;
}
Expand Down
1 change: 1 addition & 0 deletions server/lib/state/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const StateManager = function StateManager(event) {
deviceFeature: {},
deviceFeatureByExternalId: {},
service: {},
serviceById: {},
sun: {},
system: {},
variable: {},
Expand Down
19 changes: 13 additions & 6 deletions server/test/lib/device/device.create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ const { expect } = require('chai');
const EventEmitter = require('events');
const Device = require('../../../lib/device');
const StateManager = require('../../../lib/state');
const ServiceManager = require('../../../lib/service');

const event = new EventEmitter();

describe('Device', () => {
it('should create device alone', async () => {
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const newDevice = await device.create({
service_id: 'a810b8db-6d04-4697-bed3-c4b72c996279',
name: 'Philips Hue 1',
Expand Down Expand Up @@ -36,7 +38,8 @@ describe('Device', () => {
},
],
});
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const newDevice = await device.create({
id: '7f85c2f8-86cc-4600-84db-6c074dadb4e8',
name: 'RENAMED_DEVICE',
Expand Down Expand Up @@ -69,7 +72,8 @@ describe('Device', () => {
});
it('should update device which already exist, update a feature and a param', async () => {
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const newDevice = await device.create({
id: '7f85c2f8-86cc-4600-84db-6c074dadb4e8',
name: 'RENAMED_DEVICE',
Expand Down Expand Up @@ -151,7 +155,8 @@ describe('Device', () => {
},
],
});
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
await device.create({
id: '7f85c2f8-86cc-4600-84db-6c074dadb4e8',
name: 'RENAMED_DEVICE',
Expand Down Expand Up @@ -194,7 +199,8 @@ describe('Device', () => {
},
],
});
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const newDevice = await device.create({
id: '7f85c2f8-86cc-4600-84db-6c074dadb4e8',
name: 'RENAMED_DEVICE',
Expand All @@ -215,7 +221,8 @@ describe('Device', () => {
});
it('should create device, one feature and one param', async () => {
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager);
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const newDevice = await device.create({
service_id: 'a810b8db-6d04-4697-bed3-c4b72c996279',
name: 'Philips Hue 1',
Expand Down
7 changes: 5 additions & 2 deletions server/test/lib/device/device.destroy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ const EventEmitter = require('events');
const { assert } = require('chai');
const Device = require('../../../lib/device');
const StateManager = require('../../../lib/state');
const ServiceManager = require('../../../lib/service');

const event = new EventEmitter();

describe('Device.destroy', () => {
it('should destroy device', async () => {
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager, {});
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
device.devicesByPollFrequency[60000] = [
{
selector: 'test-device',
Expand All @@ -18,7 +20,8 @@ describe('Device.destroy', () => {
});
it('should return device not found', async () => {
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager, {});
const serviceManager = new ServiceManager({}, stateManager);
const device = new Device(event, {}, stateManager, serviceManager);
const promise = device.destroy('doesnotexist');
return assert.isRejected(promise);
});
Expand Down
Loading

0 comments on commit 34dddaf

Please sign in to comment.