sty
Core tools for filament networks.
STY (secure tty) is the name for historical purposes, but has evolved to be a more wide spanning CLI tool for managing init scripts, mesh config, and sinks
sty Usage
Installation
To install sty
, make sure that npm
is already installed (see here for
installation options) and then run on the command line:
~$ npm install -g filament-sty
To check the currently installed version of sty
, run:
~$ npm list -g filament-sty
To update to the latest version of sty
, run:
~$ npm update -g filament-sty
Now run sty
from the command line:
~$ sty
sty~$
This enters into the sty
command line interface.
The rest of this document will refer to entering commands within this interface.
Tab Autocomplete
sty
has extensive tab autocomplete support throughout the interface. Hit tab to complete commands, file names, and even hashnames.
Modes
There are two modes for using sty
:
- All Connected Taps (Main Mode)
- Single Tap (Connect Mode)
Initially, sty
will send any command to all connected taps (Main Mode). This is useful for flashing Taps to new firmware,
setting initialization scripts, running test commands, and configuring various "global" settings for all of the Taps to which you are connected.
Which Mode Am I In?
If the command prompt is sty~$
, sty
is currently in Main Mode. If the command prompt shows a hashname like ted47s7e~$
,
then sty
is currently in Connect Mode and will only execute commands against this particular Tap (ted47s7e
in this example).
Entering Connect Mode
To enter Connect Mode, type connect <short-hashname>
. For example:
sty~$ connect ted47s7e
ted47s7e~$
Exiting Connect Mode
Type main
to return to Main Mode:
ted47s7e~$ main
sty~$
Command Reference
help
help
to see all of the commands available.help <command>
to see more details about each command.
scan
scan
lists all connected Taps and their short hashnames, which can be used with other commands withinsty
.
dfu
dfu -t <type> <file>
flashes Tap(s) to the<file>
specified.<type>
can be one of the following:patch
directive
tap
ble
bootloader
fallback
playbook
playbook <file>
starts running an Ansible-style playbook file against any Tap(s) connected.playbook -d <file>
runs the playbook in "daemon" mode and will keep running the playbook for newly connected Taps.
A few playbook files are provided in the firmware releases as examples. The purpose is to automate tasks in sty
.
For instance, here is the playbook file to update Tap(s) to the latest firmware set:
- hosts: 'all'
vars :
jer: '42'
tasks:
- name: flash patchos in patchos memory
command: dfu -t patch ./patchos.bin
- name: wait for reset
command: wait 20
- name: flash fallback in place
command: dfu -t fallback ./patchos-fallback.bin
- name: wait for reset
command: wait 20
- name: flash ble
command: dfu -t ble ./foible_application.bin
- name: wait for ble flashing
command: wait 20
- name: flash tap
command: dfu -t tap ./tapos.bin
- name: finished
command: wait 21
init
init <file>
sets the initialization script to the JavaScript contents of what is in<file>
.init -i '<JavaScript>'
sets the initialization script to the inline<JavaScript>
you place in the quotes.init()
returns the current initialization script.
The Tap will restart after the initialization is set.
Note that when using the inline command, quote and tick marks are very important to use correctly. Here's an example of a correct initialization:
init -i 'mesh_allow("xdmuf4cv");'
Note that there are known issues with nesting quotes and tick marks in inline mode.
It is recommended to use init() within the repl
command (see the repl
section below)
or use the init <file>
method for complicated initialization scripts.
run
run <file>
runs JavaScript that is in<file>
.run -i '<JavaScript>'
runs the inline JavaScript commands on the connected Tap(s).
Note that there are known issues with nesting quotes and tick marks in inline mode.
It is recommended to use repl
command (see the repl
section below) or use the init <file>
method.
repl
repl
mode enters into a direct command-line mode with the Tap(s). (repl
stands for "Read-Eval-Print Loop" which
is a common name for simple command-line programming environments. Read more here.)
After entering repl
mode, you can now run direct commands that the Tap(s) will evaluate.
For instance, here is an example of running init()
and netstat()
commands:
sty~$
sty~$ repl
sty~$ repl: init()
running command : init()
7fpcztr5 { from: 'r75r67yv',
c: 9,
end: true,
result: 'gw="xdmuf4cv";setInterval(function(){push(gw,"report",report(true));tapsleep(50)},60000);mesh_allow(gw);mesh(true)' }
[ undefined ]
sty~$ repl: netstat()
running command : netstat()
7fpcztr5 { from: 'r75r67yv',
c: 11,
end: true,
result: '[{"hn":"xdmuf4cv","rssi":"-83,-77,-86","stats":"27,0,7,0","wait":265,"link":true}]' }
[ undefined ]
sty~$ repl:
sty~$ repl: exit
sty~$
repl
can be run in both Main Mode and Connect Mode. Type exit
to go back to the normal sty
command line.
sinks
sinks
mode enters into a special command line that enables you to start up a particular endpoint type for sending data.
Type main
to return to the normal sty
command line.
The standard format for each sink is <sink> <options> <events>
where
<sink>
is the name of the sink type (e.g.,dweet
for dweet.io) that is supported by the currentsty
revision or your local installation.<options>
specify the particular configurations that the sink needs (e.g., server addresses or user credentials).<events>
are the type of events to forward to the sink.
MySQL Sink
Given a table created with the following structure:
CREATE TABLE `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`report` varchar(500) NOT NULL,
`hn` varchar(45) DEFAULT NULL,
`up` int(11) DEFAULT NULL,
`temp` float DEFAULT NULL,
`humidity` float DEFAULT NULL,
`lux` float DEFAULT NULL,
`move` varchar(45) DEFAULT NULL,
`dB` int(11) DEFAULT NULL,
`rssi` int(11) DEFAULT NULL,
`usb_cdc` varchar(100) DEFAULT NULL,
`gps_sentence` varchar(5) DEFAULT NULL,
`gps_type` varchar(5) DEFAULT NULL,
`gps_timestamp` varchar(10) DEFAULT NULL,
`gps_lat` varchar(45) DEFAULT NULL,
`gps_latPole` varchar(1) DEFAULT NULL,
`gps_lon` varchar(45) DEFAULT NULL,
`gps_lonPole` varchar(1) DEFAULT NULL,
`gps_fixType` varchar(5) DEFAULT NULL,
`gps_numSat` int(11) DEFAULT NULL,
`gps_horDilution` float DEFAULT NULL,
`gps_alt` float DEFAULT NULL,
`gps_altUnit` varchar(1) DEFAULT NULL,
`gps_geoidalSep` float DEFAULT NULL,
`gps_geoidalSepUnit` varchar(1) DEFAULT NULL,
`gps_differentialAge` int(11) DEFAULT NULL,
`gps_differentialRefStn` varchar(45) DEFAULT NULL,
`gps_talker_id` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
The following command in sty
will push reports to the table:
mysql -d <database> -u <user> -p <password> -h <server> -c *,-build,-reset,-type,-beat,-tup,-tmem,-usb_vid,-usb_pid,-mem,-seen,-name,-via,-tap -t <table> report
API?
The upside of a decentralized system is that there is no central point of failure or control. The downside, for many people, is that there is no central point of control, or at the very least, no central point of interface.
The question then, is how do we provide a network managment API that will make sense to developers, without compromising our promise of decentralization?
The constraints:
-
- We don't invent another protocol
-
- see #1
-
- The API must not provide any feature that is not fundamentally available on the low level devices
- 3a) customers should be able to forego a centralized API endpoint and still run a functioning network, with the caveat that it will take more effort to set up and monitor
-
- We don't host the API endpoint as part of our business model, because we are not a cloud company.
- 4a) We make freely available the software to host an API endpoint
-
- We don't enforce that our interface is the only interface. remain interoperaple with IoT managment platforms like Amazon, Google, Azure, Bluemix, Fusion, Thingspace etc.
- 5a) more of a reference implimentation and starting point for custom work.
High level Design, take 1
Layers, ascending
- Channel API: low level, firmware builtins. things like DFU, MQTT, interdevice event emitter, scripting.
- Script API: customer available functionality, event emitters in javascript (Network, buttons, sensors, duty cycles etc)
- MQTT API - requires central broker, and one or more gateways. manages changes of network state, init scripts, provisioning, grouping by topic conventions
- REST API - EITHER:
- a simple mapping between HTTP endpoints and MQTT pub/sub, written by Filament but hosted by you.
- the HTTP api provided by the big box cloud IoT solution of your choice, with our devices hooked into their MQTT broker via a gateway (written by Filament, hosted onsite)