node package manager

filament-sty

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:

  1. All Connected Taps (Main Mode)
  2. 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 within sty.

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 current sty 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:

    1. We don't invent another protocol
    1. see #1
    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
    1. 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
    1. 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)