Thing.js is an Agent Framework written in JavaScript for building Internet of Things applications. The Framework supports Node.js, Browsers (ES5+, Chrome, Safari, Firefox, Opera), Tessel 2, Phonegap/Cordova, JavaScriptCore and other Mobile Containers.
Features
- Abstractions, Inheritance and Interfaces
- Properties, Annotations and Templates
- Passivity and Singletons
- Simple, Series, Parallel, Queue, MapReduce and Waker Primitive Behaviours
- HRRN Scheduling, Micro-containers and Auditing
- Asynchronous Messaging, Selectors and Filters
- JSON-LD Ontologies and Message Translation
- WoT Descriptions and Actions
- MQTT Sensors, Actuators and Bridging
Installation
In the Browser
Node.js
npm install thingjs-agent
var agent = ;
Quick Example
; ;;; '^found' { console; ; } 'forNeo' ;// Outputs: "As you can see, we've had our eye on you for some time now, Mr. Anderson."// "As you can see, we've had our eye on you for some time now, Mr. Anderson."// "As you can see, we've had our eye on you for some time now, Mr. Anderson."
Usage
Declarations
Agent Declaration
;
Behaviour Declaration
;
Anonymous Declaration
// Nameless Agent or Behaviour
Abstraction
'abstract MyObject' // Agent or Behaviour // Abstraction called MyObject
Properties
Methods
'MyObject' // Agent or Behaviour { // Empty Method } { // Another Empty Method }
Ontology Terms
'MyObject' // Agent or Behaviour // JSON-LD Context name: 'http://schema.org/name' // Term url: 'https://schema.org/url' // Another Term
'MyObject' // Agent or Behaviour '@context': // JSON-LD Context name: 'http://schema.org/name' // Term url: 'https://schema.org/url' // Another Term
Inheritance
'MyBaseObject' // Agent or Behaviour { } 'MyObject extends MyBaseObject' // Agent or Behaviour // MyObject inherits Methods and Properties from MyBaseObject { this; // Call exampleMethod in MyBaseObject }
Agent Constructor and Destructor
;
Annotations
'@example annotation' // Declare Annotation '@annotation +' 'spanning +' 'multiple decorations' // Concat decorations with + operator 'MyObject' // Agent or Behaviour { console; // outputs: [ // 'example annotation', // 'annotation spanning multiple decorations' // ] }
Templates
var string = 'annotation' nameSuffix = 'Object' ; '@example $' string // Substitue $ for string '@$ +' string 'spanning +' 'multiple decorations' // Substitue $ for string '@the meaning of life is $(meaningOfLife)' 42 // Substitue $(meaningOfLife) for 42 and // Set this.$meaningOfLife = 42 'My$' nameSuffix // Add nameSuffix to the Name of the Agent or Behaviour { this console; // outputs: [ // 'example annotation', // 'annotation spanning multiple decorations', // 'the meaning of life is 42' // ] console; // outputs: 'MyObject' console; // outputs: 42 }
Messaging
'MyObject' // Agent or Behaviour { // Method with Callback Object Argument $cb console; ; // Callback } // Select Agent(s) and Behaviour(s) 'exampleMethod' // Call exampleMethod // with Empty Callback Object ;// Outputs: 'exampleMethod' // MyUndefinedObject doesn't exist 'exampleMethod' ;// No Output 'exampleMethod' 42 // Call exampleMethod with 1 Argument ;// No Output 'exampleMethod' // Stack Multiple Calls 'exampleMethod' 'exampleMethod' ;// Outputs: 'exampleMethod'// 'exampleMethod'// 'exampleMethod'
'MyObject' // Agent or Behaviour { // Method with meaningOfLife Argument // and Callback Object Argument $cb console; console; // Call callbackMethod in $cb // with an Empty Callback Object ; } 'exampleMethod' 42 // Callback Object created from Agent Declaration // Callback Objects may be Agent Declarations, // Instances or Selectors { console; ; } ;// Outputs: 'exampleMethod'// 42// 'callbackMethod'
'MyObject' // Agent or Behaviour { console; console; ; } '^callbackMethod' { // The ^ operator defines an inline method called callbackMethod console; ; } 'exampleMethod' 42 // Uses callbackMethod 'exampleMethod' 42 // Reuses callbackMethod ; // Outputs: 'exampleMethod'// 42// 'callbackMethod'// 'exampleMethod'// 42// 'callbackMethod'
Message Translation
this; var me = '@context': 'http://schema.org/' '@type': 'Person' 'name': 'Jane Doe' 'jobTitle': 'Professor' 'telephone': '(425) 123-4567' 'url': 'http://www.janedoe.com' ; 'hello' me; // Outputs: Hello Jane Doe
Selectors
;
Filters
;
Interfaces
'MyObject implements MyInterfaceA MyInterfaceB' // Agent or Behaviour // Accepts Messages to Interfaces MyInterfaceA and // MyInterfaceB { console; console; ; } 'exampleMethod' ;// Outputs: 'exampleMethod'// [ 'MyObject',// 'MyInterfaceA',// 'MyInterfaceB' ]
'MyObject implements MyInterfaceA MyInterfaceB' // Agent or Behaviour // Accepts Messages to Interfaces MyInterfaceA and // MyInterfaceB { console; ; } { console; ; } 'exampleMethod' ;// Outputs: 'MyInterfaceB.exampleMethod'
var myInterfaceB = 'MyInterfaceB' ; 'MyObject implements MyInterfaceA $(MyInterfaceB)' myInterfaceB // Agent or Behaviour // Accepts Messages to Interfaces MyInterfaceA and // MyInterfaceB { console; ; } { console; ; } 'exampleMethod' ;// Outputs: 'MyInterfaceB.exampleMethod'
'MyObject implements /MyInt/g' // Regular Expressions // Agent or Behaviour // Accepts Messages to any Interface matching the // Regular Expression Pattern /MyInt/g { console; ; } 'exampleMethod' ;// Outputs: 'exampleMethod'
Passivity
;
this;
Singletons
'@singleton' 'MyObject' // Only one instance of this Agent or // Behaviour will exist
; ; // Exists; // Doesn't exist 'exampleMethod' ;// Output: 'exampleMethod'
Simple Behaviour
this;
Waker Behaviour
this;// Outputs: 'wake'
Series Behaviour
this;// Outputs: 'method1'// 'method2'// 'method3'// 'method4'
Parallel Behaviour
this;// Outputs: 'method1'// 'method2'// 'method3'// 'method4'
Queue Behaviour
this; 'pause' // Pauses the Queue 'push' 42 'resume' // Un-pauses the Queue 'push' 43 'push' 44 ;// Outputs: 42// 43// 44 'push' 42 43 44 ;// Outputs: 42// 43// 44
MapReduce Behaviour
this; 'push' 0123 ; // Outputs: [0,2]// [1,3]
this; this; 'push' 0123 ; // Outputs: [0,2]// [1,3]
Micro-Container Framing
$thingframe { // Container Frame ; ; };
Micro-Container Auditing
;
Agent Descriptions
; '^data' { console; // output: // { // '@id': 'http://test.com/agent', // '@type': 'wot:thing', // // 'wot:author': ['The Author'], // 'wot:description': ['The Desc'], // 'wot:tag': ['tag1', 'tag2'], // // '@graph': [ // { // '@id': 'http://test.com/a', // '@type': 'wot:property', // 'wot:writable': false // // }, // { // '@id': 'http://test.com/act/behaviour', // '@type': 'wot:action', // 'wot:tag': ['actionTag'] // } // ] // } ; } 'get'
MQTT Usage
Sensor
;
Actuator
; 'push' 'MyMessage' // Send 'MyMessage' to the Actuator ; // Select the specific Actuator if you have multiple objects // implementing the MyTopic interface 'push' 'MyMessage' ;
Bridge
; ; // Queue and Bridge 'push' 'MyMessage' ; // Bridge only 'push' 'MyMessage' ; // Bridge only 'push' 'MyMessage' ;
FAQ
Why is my Agent taken down shortly after setup?
Agents should be declared @passive or have one or more behaviours. The framework is designed to automatically dereference objects not doing anything.
Contact
Creator
License - "MIT"
Copyright (c) 2015 Simon Cullen, http://github.com/cullens
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.