rotonde
makes IoT development accessible to every developers.- just pick your favorite language and start coding on your favorite platform.
- with
rotonde
you use the best libraries available, not just the one available for your favorite language. - and it's as easy to use as a web
API
:)
- Go through the setup guide.
- Install this module.
- Run both of them, on your raspberry PI for example, but these two can work on you laptop too, not sure about Windows tho...
- Install this chrome extension.
TODO: make install+run script
Now from the extension connect to rotonde on your board's IP:
ws://[ip address]:4224/
Click open
, you are now connected to rotonde.
In the extension's console you should have something like this (stripped most of them for clarity):
[...]
{
"type":"def",
"payload":{
"identifier":"SERIAL_PORTMESSAGE",
"type":"event",
"fields":[
{
"name":"P",
"type":"",
"units":""
},
{
"name":"D",
"type":"",
"units":""
}
]
}
}
{
"type":"def",
"payload":{
"identifier":"SERIAL_OPEN",
"type":"action",
"fields":[
{
"name":"port",
"type":"string",
"units":""
},
{
"name":"baudrate",
"type":"number",
"units":""
},
{
"name":"buffer",
"type":"string",
"units":""
}
]
}
}
[...]
These are the available events and actions. All those starting with
SERIAL_
are from our serial module.
We are going to use it and open a serial port on the system by
sending a SERIAL_OPEN
action.
Clear the websocket output and copy-paste this JSON object into to the websocket extension:
{
"type":"action",
"payload":{
"identifier":"SERIAL_OPEN",
"data":{
"port":"/dev/ttyAMA0", // internal serial port on raspberry PI
"baudrate":9600
}
}
}
hit ctrl+enter to send it to rotonde.
If your serial port is opened you can now listen to it by subsribing to
the SERIAL_PORTMESSAGE
by sending this packet:
{
"type":"sub",
"payload":{
"identifier":"SERIAL_PORTMESSAGE"
}
}
And that's it, you just opened a serial port on you raspberry PI, that's as easy as that with rotonde.
When you code with rotonde
you have to think in term of modules.
Each module is connected to rotonde
, and communicate with each other
though rotonde
.
In rotonde
each module exposes its API through events
and actions
.
Events
and actions
have similarities in their behavior, but they
represent two different concepts.
- Events:
- sent by modules to notify the rest of the system
- other modules can
subscribe
to them
- Actions:
- the
API
of the available modules - sent by modules to call features from other modules
- the
Modules first have to declare their events and actions to rotonde.
Declaring an event
or action
to rotonde is achieved by sending a def
packet, please see the def
section below.
When a module exposes an action
or event
to rotonde, it has to specify an
identifier and a list of fields.
The first thing that a module receives when connecting to rotonde
is the list
of all events
and actions
that have been defined on rotonde by other
modules.
This gives modules the opportunity to check that the system they are connected to has the required features available.
Internally rotonde works like some kind of a router or dispatcher. The routing rules are slightly different for actions and events.
When rotonde receives an action from a module, it looks at all modules that exposed this actions, and dispatches the action to them.
When rotonde receives an event
from a module, it only dispatches it to
the modules that subscribed to this event
.
- some unix os (tested with success on Linux and OSX so far)
- Golang (1.5.1, please tell us if you got it working on previous versions, we didn't test them yet)
- Godep
Assuming Golang had been installed, if it's not already done a workspace can be set with
export GOPATH=$HOME/go
mkdir $GOPATH
go get github.com/HackerLoop/rotonde && go get github.com/tools/godep
cd $GOPATH/src/github.com/HackerLoop/rotonde
godep restore
go build
go build
will compile an executable called rotonde
in the project
folder ($GOPATH/src/HackerLoop/rotonde
).
If something goes wrong during compilation, please open up an issue with your os/distribution infos and compilation output.
./rotonde
Rotonde will start serving on port 4224 by default, add option -port
to specify another one.
In most case, rotonde is used through its websocket (other interfaces are foreseen), by sending and receiving JSON objects.
All objects received or sent from/to rotonde have this structure:
{
type: "",
payload: {
// mixed, based on type
}
}
There a five possible values for the type
field, event
, action
, def
, sub
or unsub
,
the content of the payload
field varies based on the type.
The different possible structures of the payload are described below.
When a module connects to rotonde, it has to detail its API to rotonde.
It does so by sending definition
objects, rotonde routes all received
definitions to all connected modules. And when you connect to rotonde,
you receive all the available definitions.
Knowing that everything is either an action or an event in rotonde,
there are two types of definitions, either action
or event
.
Each definitions contain a set of fields describing its structure. This is mainly to ensure that the action or event is present with a predictable structure.
In a typical scenario, a module that connects to rotonde starts by waiting for all the events and actions it requires to work properly. Definitions are a sort of description of what is available on the system.
This way of doing things gives you the ability to create a modular system where some module would only start when a given capability is present.
{
"identifier": "",
"type": "",
"fields":[
{
"name": "",
"type": "", // optional
"unit": "", // optional
},
{
... other fields ...
}
]
}
In rotonde, everything is either an action or an event, they are the only way for the modules to exchange data with the external world.
Actions are the APIs of the modules, each action has an identifier; when
a module declares an action through the mean of a definition
object,
it will receive all actions matching this identifier sent to rotonde.
If multiple modules declare the same action, they will all receive it.
Actions are typically sent by user interface modules, for example, when
a user presses a button, the controller of the button will send an action,
that will be handled by one or multiple modules.
For example, if the button is meant to switch a light on, the action
identifier would be TURN_LIGHT_ON
, this could totally trigger the
light control module, but if we want to play a music when this happens,
just do another module that also exposes the TURN_LIGHT_ON
action, and
starts the music when it receives the action.
An action generally comes with some data, this data can be of any form, its structure should be described by the definitions.
An action payload contains the following fields:
{
"identifier":"",
"data": {
... data fields of the action ...
}
}
Actions can be seen as the input of modules.
Modules will often have things to say, whether they want to tell what there sensor is sensing, or whether they want to report a status.
This is what events are made for. Modules have the ability to send events through rotonde, these events will be routed to the concerned modules.
An event generally comes with some data, this data can be of any form, its structure should be described by the definitions.
An event payload contains the following fields:
{
"identifier":"",
"data": {
... data fields of the event ...
}
}
Events can be seen as the output of modules.
When you connect to rotonde nothing will be received except definitions, you have to subscribe to a given event in order to start receiving it.
{
"type": "sub",
"payload": {
"identifier": ""
}
}
and you can unsubscribe from this identifier with:
{
"type": "unsub",
"payload": {
"identifier": ""
}
}
Rotonde can be used as-is but having an abstraction above the websocket, makes it much more efficient.
This is a list (in progress) of the available abstractions:
The number of available modules is crucial for rotonde, the good news is that it is actually quite easy to take a library and make its API available to rotonde modules.
Here is a list of libraries that are ported, or will be ported:
- Serial:
- rotonde serial module exposes the features of serial-port-json-server(SPJS)
- serial devices listing
- advanced serial communication
- flashing of an arduino from an url :) this one is crazy haha.
- please see his README first
- rotonde serial module exposes the features of serial-port-json-server(SPJS)
- Gobot:
-
This is a work in progress and a huge gain for rotonde, gobot already has the ability to make programs that expose features through a REST API, and because it is written in Go, it is really easy to just swap REST to websocket.
The plan here is to generate tons of modules for all of gobot drivers, in all supported plateforms.
A skeleton project is on its way to ease the work.
-
- TODO: expand list
Yes please.