Skip to content

Commit

Permalink
Merge pull request #37 from CommonGarden/alpha
Browse files Browse the repository at this point in the history
v0.3
  • Loading branch information
JakeHartnell committed Dec 10, 2016
2 parents 68879f7 + d5fb273 commit 8c61719
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 593 deletions.
92 changes: 22 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,101 +1,53 @@
# 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:

* Metadata
* Properties
* Actions
* Events

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,
},
start: function () {
console.log('Thing initialized, this code runs first');
},
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.")
}
}
turn_light_on: function () {
console.log('light on');
Light.set('state', 'on');
},
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_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).
Expand Down
179 changes: 15 additions & 164 deletions docs/Thing.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ <h2 class="project-tagline">Create thing objects with properties, actions, and e
<ul class="nav nav-stacked">
<li><a href="#Thing"><i class="alert alert-success"></i><span>Thing</span></a>
</li>
<li><a href="#getAction"><i class="alert alert-info"></i><span>getAction</span></a>
</li>
<li><a href="#getEvent"><i class="alert alert-info"></i><span>getEvent</span></a>
</li>
<li><a href="#set"><i class="alert alert-info"></i><span>set</span></a>
</li>
<li><a href="#get"><i class="alert alert-info"></i><span>get</span></a>
Expand Down Expand Up @@ -82,117 +78,11 @@ <h5 class="subheader"></h5>
_.extend(this, config);
}

if (!_.isUndefined(this.events)) {
_.each(this.events, (event, key, list) =&gt; {
if (!_.isUndefined(event.on)) {
this.on(event.on, () =&gt; {
if (!_.isUndefined(event.rule)) {
if (event.rule.condition() === true) {
event.rule.consequence();
}
} else {
event.function();
}
});
}
});
}

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]()
}
}
}

// Callback is optional. May be used for a start function.
if (!_.isUndefined(callback)) {
callback();
// What would be other useful default methods?
if (!_.isUndefined(this.start)) {
this.start();
}
}</code></pre>
<section id="getAction">
<h1>getAction</h1>
<h5 class="subheader"></h5>
<p>
<div class="label label-info radius ctx-type">method</div><span>&nbsp;</span><span>Thing.prototype.getAction()</span><span>&nbsp;</span>
</p>
</section>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width:20%">Option name</th>
<th style="width:20%">Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>ID</td>
<td>String</td>
<td><p>The key of the action object you want.</p></td>
</tr>
</tbody>
</table>
<div class="description"><p>Get an action object by key</p></div>
<pre><code class="language-javascript">getAction (ID) {
let action = {};
_.each(this.actions, (value, key, list) =&gt; {
if (key === ID) {
return action = value;
} else if (this.actions[key].id === ID) {
return action = value;
}
});

if (_.isEmpty(action)) {
return false;
} else {
return action;
}
}</code></pre>
<section id="getEvent">
<h1>getEvent</h1>
<h5 class="subheader"></h5>
<p>
<div class="label label-info radius ctx-type">method</div><span>&nbsp;</span><span>Thing.prototype.getEvent()</span><span>&nbsp;</span>
</p>
</section>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width:20%">Option name</th>
<th style="width:20%">Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>ID</td>
<td>String</td>
<td><p>The key / id of the event object you want.</p></td>
</tr>
</tbody>
</table>
<div class="description"><p>Get event object by key</p></div>
<pre><code class="language-javascript">getEvent (ID) {
let event = {}
_.each(this.events, (value, key, list) =&gt; {
if (key === ID) {
return event = value;
} else if (this.events[key].id === ID) {
return event = value;
}
});

if (_.isEmpty(event)) {
return false;
} else {
return event;
}
}</code></pre>
<section id="set">
<h1>set</h1>
<h5 class="subheader"></h5>
Expand Down Expand Up @@ -227,22 +117,9 @@ <h5 class="subheader"></h5>
</tbody>
</table>
<div class="description"><p>Update a property based on a component ID.</p></div>
<pre><code class="language-javascript">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');
}
<pre><code class="language-javascript">set (key, value) {
this.properties[key] = value;
this.emit('property-updated', key);
}</code></pre>
<section id="get">
<h1>get</h1>
Expand All @@ -268,19 +145,8 @@ <h5 class="subheader"></h5>
</tbody>
</table>
<div class="description"><p>Get a property by key.</p></div>
<pre><code class="language-javascript">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];
}
}
<pre><code class="language-javascript">get (key) {
return this.properties[key];
}</code></pre>
<section id="call">
<h1>call</h1>
Expand Down Expand Up @@ -310,33 +176,18 @@ <h5 class="subheader"></h5>
</tr>
</tbody>
</table>
<div class="description"><p>Calls a registered action or event function, emits event if the the action has an &#39;event&#39;<br />property defined. </p></div>
<div class="description"><p>Calls a method, emits event<br />property defined. </p></div>
<pre><code class="language-javascript">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);
if (!_.isUndefined(options)) {
var output = this[key](options);
}

else if (event) {
if (!_.isUndefined(options)) {
var output = event.function(options);
}
else {
var output = event.function();
}
this.emit(key);
else {
var output = this[key]();
}
this.emit(key, options);

// We return any returns of called functions for testing.
// We return any returns of called functions.
if (!_.isUndefined(output)) {
return output;
}
Expand Down
Loading

0 comments on commit 8c61719

Please sign in to comment.