From e08b370aca63e5ecfa0f5f7e6d41918c9013ab71 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 15:00:10 -0700 Subject: [PATCH 1/7] Different approach. --- examples/light.js | 79 +++++++++++ lib/Thing.js | 201 +++++++++++++-------------- test/test-thing2.js | 107 +++++++++++++++ test/thing-test.js | 324 ++++++++++++++++++++++---------------------- 4 files changed, 442 insertions(+), 269 deletions(-) create mode 100644 examples/light.js create mode 100644 test/test-thing2.js diff --git a/examples/light.js b/examples/light.js new file mode 100644 index 0000000..0304771 --- /dev/null +++ b/examples/light.js @@ -0,0 +1,79 @@ +// Import the latest build of the Grow.js library +var Thing = require('../.././dist/Thing.umd.js'); + +// Declare need variable for example +var currentLightValue; +var currentTempValue; + +// Create a new light instance. Connects by default to localhost:3000 +var light = new Thing({ + uuid: '5b7ba90f-ce42-44e4-9ecb-fcb256b89352', + token: 'mGQknLsQM4fyeJWYNCPebEqQH3SCxgcP', + name: 'Light', // The display name for the thing. + desription: 'An LED light with a basic on/off api.', + + // Properties can be updated by the API + properties: { + state: { + type: String, + value: 'off' + }, + lightConditions: String + }, + + // Actions are the API of the thing. + actions: { + turn_light_on: { + name: 'On', // Display name for the action + description: 'Turns the light on.', // Optional description + schedule: 'at 9:00am', // Optional scheduling using later.js + // Is this rule pattern useful? + function: function () { + // Emit a 'light off' event, set state to on. + light.emitEvent('Light on').set('state', 'on'); + console.log('Light on'); + } + }, + turn_light_off: { + name: 'off', + schedule: 'at 8:30pm', // Run this function at 8:30pm + function: function () { + // Emit a 'light off' event, set the state property to 'off' + light.emitEvent('Light off').set('state', 'off'); + console.log('Light off'); + } + } + }, + events: { + temp_data: { + name: 'Log temperature data', + type: 'temperature', + template: 'sensor', + schedule: 'every 1 second', + function: function () { + currentTempValue = Math.random(); + + // // Send data to the Grow-IoT app. + light.log({ + type: 'temperature', + value: currentTempValue + }); + } + }, + light_data: { + name: 'Log light data', + type: 'light', + template: 'sensor', + schedule: 'every 1 second', + function: function () { + currentLightValue = Math.random(); + + // Send data to the Grow-IoT app. + light.log({ + type: 'light', + value: currentLightValue + }); + } + } + } +}); diff --git a/lib/Thing.js b/lib/Thing.js index 58bc36c..62f73ed 100644 --- a/lib/Thing.js +++ b/lib/Thing.js @@ -18,36 +18,34 @@ class Thing extends EventEmitter { _.extend(this, config); } - if (!_.isUndefined(this.events)) { - _.each(this.events, (event, key, list) => { - if (!_.isUndefined(event.on)) { - this.on(event.on, () => { - if (!_.isUndefined(event.rule)) { - if (event.rule.condition() === true) { - event.rule.consequence(); - } - } else { - event.function(); - } - }); - } - }); + // if (!_.isUndefined(this.events)) { + // _.each(this.events, (event, key, list) => { + // if (!_.isUndefined(event.on)) { + // this.on(event.on, () => { + // event.function(); + // }); + // } + // }); + // } + + if (!_.isUndefined(this.start)) { + this.start(); } - if (!_.isUndefined(this.properties)) { - for (var property in this.properties) { - // If the property is a function we initialize it. - if (typeof this.properties[property] === 'function') { - // Note this function should return property value. - this.properties[property] = this.properties[property]() - } - } - } + + // if (!_.isUndefined(this.properties)) { + // for (var property in this.properties) { + // // If the property is a function we initialize it. + // if (typeof this.properties[property] === 'function') { + // this.properties[property] = this.properties[property]() + // } + // } + // } // Callback is optional. May be used for a start function. - if (!_.isUndefined(callback)) { - callback(); - } + // if (!_.isUndefined(callback)) { + // callback(); + // } } /** @@ -55,44 +53,44 @@ class Thing extends EventEmitter { * @param {String} ID The key of the action object you want. * @returns {Object} */ - getAction (ID) { - let action = {}; - _.each(this.actions, (value, key, list) => { - if (key === ID) { - return action = value; - } else if (this.actions[key].id === ID) { - return action = value; - } - }); - - if (_.isEmpty(action)) { - return false; - } else { - return action; - } - } + // getAction (ID) { + // let action = {}; + // _.each(this.actions, (value, key, list) => { + // if (key === ID) { + // return action = value; + // } else if (this.actions[key].id === ID) { + // return action = value; + // } + // }); + + // if (_.isEmpty(action)) { + // return false; + // } else { + // return action; + // } + // } /** * Get event object by key * @param {String} ID The key / id of the event object you want. * @returns {Object} */ - getEvent (ID) { - let event = {} - _.each(this.events, (value, key, list) => { - if (key === ID) { - return event = value; - } else if (this.events[key].id === ID) { - return event = value; - } - }); - - if (_.isEmpty(event)) { - return false; - } else { - return event; - } - } + // getEvent (ID) { + // let event = {} + // _.each(this.events, (value, key, list) => { + // if (key === ID) { + // return event = value; + // } else if (this.events[key].id === ID) { + // return event = value; + // } + // }); + + // if (_.isEmpty(event)) { + // return false; + // } else { + // return event; + // } + // } /** * Update a property based on a component ID. @@ -100,41 +98,30 @@ class Thing extends EventEmitter { * @param {String} value The value to update the property to. * @param {String} key Optional. Use to update the property of an event or action. */ - set (property, value, key) { - if (_.isUndefined(key)) { - this.properties[property] = value; - this.emit('property-updated'); - } - else { - // what if they both have the same key? - let action = this.getAction(key); - let event = this.getEvent(key); - if (action) { - action[property] = value; - } else if (event) { - event[property] = value; - } - this.emit('property-updated'); - } + set (key, value) { + // if (!_.isUndefined(this.properties[key])) { + this.properties[key] = value; + this.emit('property-updated', key); + // } + // else { + // // what if they both have the same key? + // let action = this.getAction(key); + // let event = this.getEvent(key); + // if (action) { + // action[property] = value; + // } else if (event) { + // event[property] = value; + // } + // this.emit('property-updated'); + // } } /* Get a property by key. * @param {String} property * @returns {String} key Optional. Use to get an event or action property. */ - get (property, key) { - if (_.isUndefined(key)) { - return this.properties[property]; - } else { - let action = this.getAction(key); - let event = this.getEvent(key); - if (action) { - return action[property]; - } - if (event) { - return event[property]; - } - } + get (key) { + return this.properties[key]; } /** @@ -145,28 +132,28 @@ class Thing extends EventEmitter { */ call (key, options) { try { - let action = this.getAction(key); - let event = this.getEvent(key); - - if (action) { - if (!_.isUndefined(options)) { - var output = action.function(options); - } - else { - var output = action.function(); - } - this.emit(key); - } + // let action = this.getAction(key); + // let event = this.getEvent(key); - else if (event) { - if (!_.isUndefined(options)) { - var output = event.function(options); - } - else { - var output = event.function(); - } - this.emit(key); + // if (action) { + if (!_.isUndefined(options)) { + var output = this[key](options); + } + else { + var output = this[key](); } + this.emit(key); + // } + + // else if (event) { + // if (!_.isUndefined(options)) { + // var output = event.function(options); + // } + // else { + // var output = event.function(); + // } + // this.emit(key); + // } // We return any returns of called functions for testing. if (!_.isUndefined(output)) { diff --git a/test/test-thing2.js b/test/test-thing2.js new file mode 100644 index 0000000..60cb28d --- /dev/null +++ b/test/test-thing2.js @@ -0,0 +1,107 @@ +const Thing = require('../dist/Thing.umd'); +const _ = require('underscore'); + +global.expect = require('chai').expect; + +(function setup () { + beforeEach(function() { + + global.thing = { + // Meta data + uuid: null, + token: null, + name: 'Dr. Dose', // The display name for the thing. + desription: 'Dr. Dose keeps your pH balanced.', + + // Properties can be updated by the API, Metadata cannot. + properties: { + state: null, + duration: 2000, + eC_reading: null, + pH_reading: null + }, + + start: function () { + // Maybe emit an event instead? + return 'Dr. Dose initialized.'; + }, + + acid: function (duration) { + return 'acid'; + }, + + base: function (duration) { + return 'base'; + }, + + nutrient: function (duration) { + return 'nutrient: ' + duration; + }, + + ec_data: function () { + return 'ec_data'; + }, + + ph_data: function () { + return 'ph_data'; + } + } + }); + + afterEach(function() { + delete global.thing; + }); +})(); + + +describe('Thing test', () => { + // Do we really need a new thing every time? + beforeEach(() => { + global.testThing = new Thing(thing); + }); + + it('should have cloned metadata', () => { + expect(testThing.token).to.equal(null); + expect(testThing.uuid).to.equal(null); + }); + + describe('PROPERTIES', () => { + it('should get a property', () => { + expect(testThing.get('duration')).to.equal(2000); + }); + + it('should set a property', () => { + testThing.set('duration', 3000); + expect(testThing.get('duration')).to.equal(3000); + }); + + it('should emit an event when a property is set', () => { + var event = false; + testThing.on('property-updated', () => { + return event = true; + }); + testThing.set('duration', 5000); + expect(testThing.get('duration')).to.equal(5000); + expect(event).to.equal(true); + }); + }); + + describe('Methods:', () => { + it('should be able to call a method.', () => { + expect(testThing.call('acid')).to.equal('acid'); + }); + + it('should emit an event when a method is called', () => { + var event = false; + testThing.on('acid', () => { + return event = true; + }); + testThing.call('acid'); + expect(event).to.equal(true); + }); + }); + + afterEach(() => { + delete global.testThing; + }); +}); diff --git a/test/thing-test.js b/test/thing-test.js index f74fe44..629a2c1 100644 --- a/test/thing-test.js +++ b/test/thing-test.js @@ -1,162 +1,162 @@ -const Thing = require('../dist/Thing.umd'); -const _ = require('underscore'); - -global.expect = require('chai').expect; - -(function setup () { - beforeEach(function() { - - global.thing = { - name: 'Light', // The display name for the thing. - id: 'Light', - username: 'YourUsernameHere', // The username of the account you want this device to be added to. - properties: { // These can be updated by the API. - state: 'off', - lightconditions: function () { - return 'unset'; - } - }, - actions: { // a list of action objects with keys - turn_light_on: { - name: 'On', // Display name for the action - description: 'Turns the light on.', // Optional description - schedule: 'at 9:00am', // Optional scheduling using later.js - event: 'Light turned on', // Optional event to emit when called. - function: function () { - // The implementation of the action. - return 'Light on.'; - } - }, - turn_light_off: { - name: 'off', - schedule: 'at 8:30pm', - event: 'Light turned off', - function: function () { - return 'Light off.'; - } - }, - light_data: { - name: 'Log light data', // Events get a display name like actions - type: 'light', // Currently need for visualization component... HACK. - template: 'sensor', - schedule: 'every 1 second', // Events should have a schedule option that determines how often to check for conditions. - function: function () { - return 10; - } - } - }, - events: { - dark: { - name: 'It\'s dark.', - on: 'light_data', // Hook into an action. - function: function () { - return; - } - }, - light: { - name: 'It\'s light.', - on: 'light_data', - function: function () { - return; - } - } - } - } - }); - - afterEach(function() { - delete global.thing; - }); -})(); - - -describe('Thing test', () => { - beforeEach(() => { - global.testThing = new Thing(thing); - }); - - it('should have cloned metadata', () => { - expect(testThing.name).to.equal('Light'); - expect(testThing.id).to.equal('Light'); - expect(testThing.username).to.equal('YourUsernameHere'); - }); - - describe('ACTIONS', () => { - it('should register actions in the config object', () => { - expect(_.allKeys(testThing.actions).length).to.equal(3); - }); - - it('should return the right action object when given an action id.', () => { - var action = testThing.getAction('light_data') - expect(action.name).to.equal('Log light data'); - }); - - it('should be able to call a registered action.', () => { - expect(testThing.call('turn_light_on')).to.equal('Light on.'); - }); - - it('should get an action property', () => { - expect(testThing.get('name', 'turn_light_on')).to.equal('On'); - }); - - it('should set an action property', () => { - testThing.set('name', 'Robert', 'turn_light_on'); - expect(testThing.get('name', 'turn_light_on')).to.equal('Robert'); - }); - - it('should emit an event when an action is called', () => { - var event = false; - testThing.on('turn_light_on', () => { - return event = true; - }); - testThing.call('turn_light_on'); - expect(event).to.equal(true); - }); - }); - - describe('EVENTS', () => { - it('should register events in the config object', () => { - expect(_.allKeys(testThing.events).length).to.equal(2); - }); - - it('should get an event property', () => { - expect(testThing.get('name', 'dark')).to.equal('It\'s dark.'); - }); - - it('should set an event property', () => { - testThing.set('name', 'Robert', 'dark'); - expect(testThing.get('name', 'dark')).to.equal('Robert'); - }); - - it('should return the right event object when given an id.', () => { - var component = testThing.getEvent('dark'); - expect(component.name).to.equal('It\'s dark.'); - }); - }); - - describe('PROPERTIES', () => { - it('should initialize correctly', () => { - expect(testThing.get('lightconditions')).to.equal('unset'); - }); - - it('should set a property', () => { - testThing.set('lightconditions', 'dark'); - expect(testThing.get('lightconditions')).to.equal('dark'); - }); - - it('should emit an event when a property is set', () => { - var event = false; - testThing.on('property-updated', () => { - return event = true; - }); - testThing.set('lightconditions', 'light'); - expect(testThing.get('lightconditions')).to.equal('light'); - expect(event).to.equal(true); - }); - - }); - - afterEach(() => { - delete global.testThing; - }); -}); +// const Thing = require('../dist/Thing.umd'); +// const _ = require('underscore'); + +// global.expect = require('chai').expect; + +// (function setup () { +// beforeEach(function() { + +// global.thing = { +// name: 'Light', // The display name for the thing. +// id: 'Light', +// username: 'YourUsernameHere', // The username of the account you want this device to be added to. +// properties: { // These can be updated by the API. +// state: 'off', +// lightconditions: function () { +// return 'unset'; +// } +// }, +// actions: { // a list of action objects with keys +// turn_light_on: { +// name: 'On', // Display name for the action +// description: 'Turns the light on.', // Optional description +// schedule: 'at 9:00am', // Optional scheduling using later.js +// event: 'Light turned on', // Optional event to emit when called. +// function: function () { +// // The implementation of the action. +// return 'Light on.'; +// } +// }, +// turn_light_off: { +// name: 'off', +// schedule: 'at 8:30pm', +// event: 'Light turned off', +// function: function () { +// return 'Light off.'; +// } +// }, +// light_data: { +// name: 'Log light data', // Events get a display name like actions +// type: 'light', // Currently need for visualization component... HACK. +// template: 'sensor', +// schedule: 'every 1 second', // Events should have a schedule option that determines how often to check for conditions. +// function: function () { +// return 10; +// } +// } +// }, +// events: { +// dark: { +// name: 'It\'s dark.', +// on: 'light_data', // Hook into an action. +// function: function () { +// return; +// } +// }, +// light: { +// name: 'It\'s light.', +// on: 'light_data', +// function: function () { +// return; +// } +// } +// } +// } +// }); + +// afterEach(function() { +// delete global.thing; +// }); +// })(); + + +// describe('Thing test', () => { +// beforeEach(() => { +// global.testThing = new Thing(thing); +// }); + +// it('should have cloned metadata', () => { +// expect(testThing.name).to.equal('Light'); +// expect(testThing.id).to.equal('Light'); +// expect(testThing.username).to.equal('YourUsernameHere'); +// }); + +// describe('ACTIONS', () => { +// it('should register actions in the config object', () => { +// expect(_.allKeys(testThing.actions).length).to.equal(3); +// }); + +// it('should return the right action object when given an action id.', () => { +// var action = testThing.getAction('light_data') +// expect(action.name).to.equal('Log light data'); +// }); + +// it('should be able to call a registered action.', () => { +// expect(testThing.call('turn_light_on')).to.equal('Light on.'); +// }); + +// it('should get an action property', () => { +// expect(testThing.get('name', 'turn_light_on')).to.equal('On'); +// }); + +// it('should set an action property', () => { +// testThing.set('name', 'Robert', 'turn_light_on'); +// expect(testThing.get('name', 'turn_light_on')).to.equal('Robert'); +// }); + +// it('should emit an event when an action is called', () => { +// var event = false; +// testThing.on('turn_light_on', () => { +// return event = true; +// }); +// testThing.call('turn_light_on'); +// expect(event).to.equal(true); +// }); +// }); + +// describe('EVENTS', () => { +// it('should register events in the config object', () => { +// expect(_.allKeys(testThing.events).length).to.equal(2); +// }); + +// it('should get an event property', () => { +// expect(testThing.get('name', 'dark')).to.equal('It\'s dark.'); +// }); + +// it('should set an event property', () => { +// testThing.set('name', 'Robert', 'dark'); +// expect(testThing.get('name', 'dark')).to.equal('Robert'); +// }); + +// it('should return the right event object when given an id.', () => { +// var component = testThing.getEvent('dark'); +// expect(component.name).to.equal('It\'s dark.'); +// }); +// }); + +// describe('PROPERTIES', () => { +// it('should initialize correctly', () => { +// expect(testThing.get('lightconditions')).to.equal('unset'); +// }); + +// it('should set a property', () => { +// testThing.set('lightconditions', 'dark'); +// expect(testThing.get('lightconditions')).to.equal('dark'); +// }); + +// it('should emit an event when a property is set', () => { +// var event = false; +// testThing.on('property-updated', () => { +// return event = true; +// }); +// testThing.set('lightconditions', 'light'); +// expect(testThing.get('lightconditions')).to.equal('light'); +// expect(event).to.equal(true); +// }); + +// }); + +// afterEach(() => { +// delete global.testThing; +// }); +// }); From eacbed5708415d21422fc9ea5bcc8ee45037c971 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 15:02:27 -0700 Subject: [PATCH 2/7] Clean up. --- lib/Thing.js | 99 +--------------------------------------------------- 1 file changed, 1 insertion(+), 98 deletions(-) diff --git a/lib/Thing.js b/lib/Thing.js index 62f73ed..2f066fb 100644 --- a/lib/Thing.js +++ b/lib/Thing.js @@ -18,80 +18,11 @@ class Thing extends EventEmitter { _.extend(this, config); } - // if (!_.isUndefined(this.events)) { - // _.each(this.events, (event, key, list) => { - // if (!_.isUndefined(event.on)) { - // this.on(event.on, () => { - // event.function(); - // }); - // } - // }); - // } - if (!_.isUndefined(this.start)) { this.start(); } - - - // if (!_.isUndefined(this.properties)) { - // for (var property in this.properties) { - // // If the property is a function we initialize it. - // if (typeof this.properties[property] === 'function') { - // this.properties[property] = this.properties[property]() - // } - // } - // } - - // Callback is optional. May be used for a start function. - // if (!_.isUndefined(callback)) { - // callback(); - // } } - /** - * Get an action object by key - * @param {String} ID The key of the action object you want. - * @returns {Object} - */ - // getAction (ID) { - // let action = {}; - // _.each(this.actions, (value, key, list) => { - // if (key === ID) { - // return action = value; - // } else if (this.actions[key].id === ID) { - // return action = value; - // } - // }); - - // if (_.isEmpty(action)) { - // return false; - // } else { - // return action; - // } - // } - - /** - * Get event object by key - * @param {String} ID The key / id of the event object you want. - * @returns {Object} - */ - // getEvent (ID) { - // let event = {} - // _.each(this.events, (value, key, list) => { - // if (key === ID) { - // return event = value; - // } else if (this.events[key].id === ID) { - // return event = value; - // } - // }); - - // if (_.isEmpty(event)) { - // return false; - // } else { - // return event; - // } - // } - /** * Update a property based on a component ID. * @param {String} property The property of the component to be update. @@ -99,21 +30,8 @@ class Thing extends EventEmitter { * @param {String} key Optional. Use to update the property of an event or action. */ set (key, value) { - // if (!_.isUndefined(this.properties[key])) { this.properties[key] = value; this.emit('property-updated', key); - // } - // else { - // // what if they both have the same key? - // let action = this.getAction(key); - // let event = this.getEvent(key); - // if (action) { - // action[property] = value; - // } else if (event) { - // event[property] = value; - // } - // this.emit('property-updated'); - // } } /* Get a property by key. @@ -132,10 +50,6 @@ class Thing extends EventEmitter { */ call (key, options) { try { - // let action = this.getAction(key); - // let event = this.getEvent(key); - - // if (action) { if (!_.isUndefined(options)) { var output = this[key](options); } @@ -143,19 +57,8 @@ class Thing extends EventEmitter { var output = this[key](); } this.emit(key); - // } - - // else if (event) { - // if (!_.isUndefined(options)) { - // var output = event.function(options); - // } - // else { - // var output = event.function(); - // } - // this.emit(key); - // } - // We return any returns of called functions for testing. + // We return any returns of called functions. if (!_.isUndefined(output)) { return output; } From 48ef771274d257cabd1cea305a2685afe39e85f8 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 15:40:18 -0700 Subject: [PATCH 3/7] v0.2.8 --- package.json | 2 +- test/{test-thing2.js => test-thing.js} | 0 test/thing-test.js | 162 ------------------------- 3 files changed, 1 insertion(+), 163 deletions(-) rename test/{test-thing2.js => test-thing.js} (100%) delete mode 100644 test/thing-test.js diff --git a/package.json b/package.json index cf39f99..8a93c02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Thing.js", - "version": "0.2.7", + "version": "0.2.8", "description": "Create thing objects with properties, actions, and events. Use for IoT devices or even living things like plants.", "main": "dist/Thing.umd.js", "jsnext:main": "dist/Thing.es6.js", diff --git a/test/test-thing2.js b/test/test-thing.js similarity index 100% rename from test/test-thing2.js rename to test/test-thing.js diff --git a/test/thing-test.js b/test/thing-test.js deleted file mode 100644 index 629a2c1..0000000 --- a/test/thing-test.js +++ /dev/null @@ -1,162 +0,0 @@ -// const Thing = require('../dist/Thing.umd'); -// const _ = require('underscore'); - -// global.expect = require('chai').expect; - -// (function setup () { -// beforeEach(function() { - -// global.thing = { -// name: 'Light', // The display name for the thing. -// id: 'Light', -// username: 'YourUsernameHere', // The username of the account you want this device to be added to. -// properties: { // These can be updated by the API. -// state: 'off', -// lightconditions: function () { -// return 'unset'; -// } -// }, -// actions: { // a list of action objects with keys -// turn_light_on: { -// name: 'On', // Display name for the action -// description: 'Turns the light on.', // Optional description -// schedule: 'at 9:00am', // Optional scheduling using later.js -// event: 'Light turned on', // Optional event to emit when called. -// function: function () { -// // The implementation of the action. -// return 'Light on.'; -// } -// }, -// turn_light_off: { -// name: 'off', -// schedule: 'at 8:30pm', -// event: 'Light turned off', -// function: function () { -// return 'Light off.'; -// } -// }, -// light_data: { -// name: 'Log light data', // Events get a display name like actions -// type: 'light', // Currently need for visualization component... HACK. -// template: 'sensor', -// schedule: 'every 1 second', // Events should have a schedule option that determines how often to check for conditions. -// function: function () { -// return 10; -// } -// } -// }, -// events: { -// dark: { -// name: 'It\'s dark.', -// on: 'light_data', // Hook into an action. -// function: function () { -// return; -// } -// }, -// light: { -// name: 'It\'s light.', -// on: 'light_data', -// function: function () { -// return; -// } -// } -// } -// } -// }); - -// afterEach(function() { -// delete global.thing; -// }); -// })(); - - -// describe('Thing test', () => { -// beforeEach(() => { -// global.testThing = new Thing(thing); -// }); - -// it('should have cloned metadata', () => { -// expect(testThing.name).to.equal('Light'); -// expect(testThing.id).to.equal('Light'); -// expect(testThing.username).to.equal('YourUsernameHere'); -// }); - -// describe('ACTIONS', () => { -// it('should register actions in the config object', () => { -// expect(_.allKeys(testThing.actions).length).to.equal(3); -// }); - -// it('should return the right action object when given an action id.', () => { -// var action = testThing.getAction('light_data') -// expect(action.name).to.equal('Log light data'); -// }); - -// it('should be able to call a registered action.', () => { -// expect(testThing.call('turn_light_on')).to.equal('Light on.'); -// }); - -// it('should get an action property', () => { -// expect(testThing.get('name', 'turn_light_on')).to.equal('On'); -// }); - -// it('should set an action property', () => { -// testThing.set('name', 'Robert', 'turn_light_on'); -// expect(testThing.get('name', 'turn_light_on')).to.equal('Robert'); -// }); - -// it('should emit an event when an action is called', () => { -// var event = false; -// testThing.on('turn_light_on', () => { -// return event = true; -// }); -// testThing.call('turn_light_on'); -// expect(event).to.equal(true); -// }); -// }); - -// describe('EVENTS', () => { -// it('should register events in the config object', () => { -// expect(_.allKeys(testThing.events).length).to.equal(2); -// }); - -// it('should get an event property', () => { -// expect(testThing.get('name', 'dark')).to.equal('It\'s dark.'); -// }); - -// it('should set an event property', () => { -// testThing.set('name', 'Robert', 'dark'); -// expect(testThing.get('name', 'dark')).to.equal('Robert'); -// }); - -// it('should return the right event object when given an id.', () => { -// var component = testThing.getEvent('dark'); -// expect(component.name).to.equal('It\'s dark.'); -// }); -// }); - -// describe('PROPERTIES', () => { -// it('should initialize correctly', () => { -// expect(testThing.get('lightconditions')).to.equal('unset'); -// }); - -// it('should set a property', () => { -// testThing.set('lightconditions', 'dark'); -// expect(testThing.get('lightconditions')).to.equal('dark'); -// }); - -// it('should emit an event when a property is set', () => { -// var event = false; -// testThing.on('property-updated', () => { -// return event = true; -// }); -// testThing.set('lightconditions', 'light'); -// expect(testThing.get('lightconditions')).to.equal('light'); -// expect(event).to.equal(true); -// }); - -// }); - -// afterEach(() => { -// delete global.testThing; -// }); -// }); From 4d521f997dc37479b313a9b12715410f6e47be8d Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 15:55:58 -0700 Subject: [PATCH 4/7] Update readme. --- README.md | 90 +++++++++++++++---------------------------------------- 1 file changed, 24 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index d921aa7..39ec547 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,59 @@ # Thing.js -Thing.js is meant to be an extremely light weight IoT-framework. Loosely inspired by [W3C web of things framework](https://github.com/w3c/web-of-things-framework), a thing is an object that has: +Thing.js is meant to be an *extremely light weight* IoT-framework. * Metadata * Properties -* Actions -* Events +* Methods -Thing.js exports a single class 'Thing,' which is an extension of the [Node.js EventEmitter Class](https://nodejs.org/api/events.html), and basic methods for: +Thing.js exports a single class 'Thing,' which is an extension of the [Node.js EventEmitter Class](https://nodejs.org/api/events.html) and basic methods for: * Updating properties -* Calling actions -* Emiting events -* Setting up event listeners +* Calling methods +* Emiting events for either of the above. [Full documentation available here](http://commongarden.github.io/Thing.js/docs/Thing.js.html). -For example of how this can be used in an IoT stack, checkout [Grow.js](https://github.com/CommonGarden/Grow.js) and [Grow-IoT](https://github.com/CommonGarden/Grow-IoT). +For example of how this can be used in an IoT stack, checkout [Grow.js](https://github.com/CommonGarden/Grow.js) which is used to connect devices (or purely software things) to a [Grow-IoT](https://github.com/CommonGarden/Grow-IoT) instance. ## Install ```bash npm install Thing.js ``` -### Example +### Usage ```javascript -var Thing = require('Thing.js'); +const Thing = require('Thing.js'); -var Light = new Thing({ +const Light = new Thing({ name: 'Light', desription: 'An LED light with a basic on/off api.', username: 'jakehart', + // These are setable and getable by the api. properties: { - state: 'off', - lightconditions: function () { - // Properties can be updated by the API. - // Note: property functions should return a value. - // When using actual hardware you might use this function to get the - // state of a pin. - return null; - } + state: null, }, - actions: { - turn_light_on: { - name: 'On', // Display name for the action - description: 'Turns the light on.', // Optional description - function: function () { - // The implementation of the action. - console.log('light on'); - Light.set('state', 'on'); - } - }, - turn_light_off: { - name: 'off', - function: function () { - console.log('light off'); - Light.set('state', 'off'); - } - }, - light_data: { - name: 'Log light data', - type: 'light', - template: 'sensor', - function: function () { - console.log("Log light data.") - } - } + start: function () { + console.log('Thing initialized, this code runs first'); }, - events: { - check_light_data: { - name: 'Check light data', - on: 'turn_light_on', // Adds Listener for action event. - function: function () { - console.log('this event listener is called when the light is turned on.'); - } - } - } -}, -function start () { - // Optional callback function. - return; + turn_light_on: function () { + console.log('light on'); + Light.set('state', 'on'); + }, + turn_light_off: function () { + console.log('light off'); + Light.set('state', 'off'); + } }); -console.log(Light.get(state)); -// logs 'off' +Light.on('turn_light_on', function() { + console.log('Light turned on.') +}); Light.call('turn_light_on'); -// logs 'Light on.' -// logs 'this event listener is called when the light is turned on.' - -console.log(Light.get(state)); -// logs 'on' ``` -Please open issues or PRs with thoughts || suggestions || proposals. - # Developing Code is written in ES6, and compiled using [rollup](https://github.com/rollup/rollup). [Full documentation is available here](http://commongarden.github.io/Thing.js/docs/Thing.js.html). From ac53a92409680a9628f91c0f02704ecbfa0b5165 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 18:43:24 -0700 Subject: [PATCH 5/7] Update readme. --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 39ec547..25e9aa8 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,5 @@ # Thing.js -Thing.js is meant to be an *extremely light weight* IoT-framework. - -* Metadata -* Properties -* Methods - Thing.js exports a single class 'Thing,' which is an extension of the [Node.js EventEmitter Class](https://nodejs.org/api/events.html) and basic methods for: * Updating properties From ee5be7710d3b2a1af93c00d076d5a77bc7f84f48 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Sat, 22 Oct 2016 18:44:52 -0700 Subject: [PATCH 6/7] Update docs. --- docs/Thing.js.html | 176 ++++----------------------------------------- docs/index.html | 94 ++++++------------------ 2 files changed, 35 insertions(+), 235 deletions(-) diff --git a/docs/Thing.js.html b/docs/Thing.js.html index cc6878e..6248c67 100644 --- a/docs/Thing.js.html +++ b/docs/Thing.js.html @@ -24,10 +24,6 @@

Create thing objects with properties, actions, and e