Thing represents a thing which is connected with the hub. It can provide several services for user/developers. For example, LED is a thing, and turn on, turn off, dim are services of the thing.
The connection between thing and hub can be wired, wireless, or builtin.
Each Thing is a directory, which is contained by the thingbundle folder and must has the thing.json.
For example, the thingbundle path is bundle/, and its tree graph is as follows:
bundle
|-- display
| `-- led
| `-- thing.json
|-- sensor
| |-- sensor0
| | `-- readme
| |-- sensor1
| | `-- thing.json
| `-- sensor2
| `-- thing.json
`-- doc
Then led, sensor1 and sensor2 are things, while sensor0, display, sensor and doc are NOT things because they don’t contain thing.json directly.
thing.jsonthing.json is the description JSON file of the thing. It has the following properties.
id: String. The unique id of the thing. Default: one created by the path and hub id.name: String. The thing name, which will be showed in the web IDE. Default: the name of the thing folder.description: String. The description of the thing.is_builtin: Boolean. If true, the thing and all its services cannot be changed and removed. Default: false.Service represents one service provided by a thing. For example, LED is a thing, and turn on, turn off, dim are services of the thing.
Each Service is a thing directory’s first-level subdirectory, which must have a service.json
For example, the thing directory is led/, and its tree graph is as follows.
led
|-- dim
| |-- service.json
| `-- a
| `--service.json
|-- b
|-- switch
| `-- service.json
`-- thing.json
service.json describes some properties of the service. Except for service.json, service directory should have the following JavaScript files.
service_init.js: initialize the serviceservice_destroy.js: destroy the servicestart.js: open and initialize the sessionresume.js: resume the sessionafter_resume.js: actions after the session resumedpause.js: pause the sessionstop.js: destroy and close the sessionIf any of above file is missing, the system will create a default one in memory (not in filesystem)
Besides, user can add any other files or subdirectories into the service directory.
In the workflow graph, each node represents a service. When the graph starts running, each node will create a new session to execute the service. It is designed to maintain node’s own state, because each session has a sandbox to isolate each other.
Note that if two nodes represent one service, they have two different sessions.
Service only has two status: initialized or not.
Not-initialized ------ service_init.js -------> initialized
^ |
| |
`------------------service_destroy.js--------------
Session has 3 status: idle, paused, working.
The following table shows the state transition rules.
| current state | start | resume | pause | stop |
|---|---|---|---|---|
idle |
paused |
invalid | invalid | invalid |
paused |
invalid | working |
invalid | idle |
working |
invalid | invalid | paused |
invalid |
Here, invalid means the action is illegal when session is in that status.
service.jsonid: String. The unique id of the service. Default: one created by service directory path and thing id.name: String. The name of the service. It will be showed in the web IDE.description: String. The description of the service.spec: Essential. String or Object. If the spec is string, it means the spec id which service links to. If the spec is object, it is service’s own spec.config: Object. The service’s config information.This sections shows how to write these JS service files. (service_init.js, start.js, …) ### Sandbox Each JS service file runs in a sandbox, and it make sure that the service codes in each file will not affect each other or affect the framework.
buffer, process, require, setTimeout, …child_processOther useful global variables are added into the sandbox.
sharedIt is a global object shared among one session. In one session, start.js, resume.js, after_resume.js, kernel.js, pause.js, stop.js will share the same object. For example, we set shared.num = 1 in start.js, and we can get the value in stop.js.
service_sharedIt is a global object shared among one service In one service directory, start.js, resume.js, after_resume.js, kernel.js, pause.js, stop.js, service_init.js, service_destroy.js will share the same object. Note that it can be shared between two different sessions which run same service.
hub_sharedIt is a global object shared among all service JS files in one hub. It is used for implicit cooperation between different services.
CONFIGIt is a global readonly object. All service JS files can access it. Its value is the config in service.json.
INIt is a global readonly object only used in kernel.js. The value is the session’s inports value, e.g. {in1: value1, in2: value2}.
done(value)and fail(err)They are global functions used in start.js, resume.js, pause.js, stop.js, service_init.js, service_destroy.js. All those files will cause the transition of service/session’s status.
done(value) is called when the action is done successfully. The value will be sent to the framework for logging.fail(err) is called when the action is failed. err can be any kinds of error message, which will be sent to the framework and showed in the web page.done or fail is called multiple times in one action, only the first one will be processed, and the remainings are ignored.fail(exception).sendOUT(out)and sendERR(err)They are global functions used in after_resume.jsand kernel.js. Only when the session is in working state, those two function are valid. Otherwise, they are ignored.
sendOUT(out) will send the out into the outports of the session. out is the key-value mapping of the outports, e.g. {o1: value1, o2: value2}, and o1,o2 is the name of the outports.sendERR(err)will send the err into the error port of the session. err can be any kinds of error message.sendERR(exception).If any service JS files are missing, the system will create default content in memory.
after_resume.js and kernel.js, the default content is empty.start.js, resume.js, pause.js, stop.js, service_init.js, service_destroy.js, the default content is done().start.js firstly. After all starts are done, they execute resume.js. After all resumes are done, all sessions execute after_resume.js.pause.js.resume.js. After all resumes are done, all sessions execute after_resume.js.When the workflow graph stops, If the graph’s status is working, all sessions execute paused.js firstly, then after all pauses are done successfully, all sessions execute stop.js. If the graph’s status is paused, all sessions execute stop.js.
kernel.js will be executed once the session is triggered.
When a session starts to run start.js, if the service is not initilized, it will execute service_init.js firstly.