User Interface

Every Thing has an User Interface (UI) served up by Thing's web server over HTTP, and optionally HTTPS. Thing's UI is a Single Page Application (SPA), a single HTML page. (SPA are a great way to have a native mobile application feel without having to write a native mobile application...just need a client browser to view your Thing).


Assets

Thing UI assets are all the things needed to construct the SPA: HTML, JavaScript, CSS, images, etc.

Thing UI assets are specified by implementing the Assets() function of the Thinger interface.


func (t *thing) Assets() *merle.ThingAssets {

return &merle.ThingAssets{

AssetsDir: "thing/assets",

HtmlTemplate: "templates/thing.html",

}

}

Here we specify where Thing assets are located (AssetsDir) and the location of the single HTML page. We can inline the HTML using HtmlTemplateText instead of HtmlTemplate:


func (t *thing) Assets() *merle.ThingAssets {

return &merle.ThingAssets{

AssetsDir: "thing/assets",

HtmlTemplateText: "Hello, world!",

}

}

Template Parameters

Some items are passed into Thing's HTML template page, from Thing itself. These items can be used for string substitutions in the HTML or JavaScript.

{{.Host}}

This is set to the remote (mother) host

{{.Id}}

Thing's ID

{{.Model}}

Thing model type

{{.Name}}

Thing's name

{{.AssetDir}}

Thing's asset directory

{{.WebSocket}}

Thing's WebSocket address. Always use this when opening a WebSocket back to Thing. For example:


conn = new WebSocket("{{.WebSocket}}")

Enable/Disable UI

Thing's UI is disabled if there are no assets. A client browser request will fail when the UI is disabled:

Thing's UI is also disabled if thing.Cfg.PortPublic is zero. Enable Thing's UI (assuming it has assets) by setting thing.Cfg.PortPublic to a non-zero port number. Port :80 is the standard HTTP server port.

thing.Cfg.PortPublic = 80

To enable HTTPS in addition to HTTP, set thing.Cfg.PortPublicTls to a non-zero port number. Port :443 is the standard HTTPS server port.

thing.Cfg.PortPublicTls = 443

WebSockets

Thing UI can open a WebSocket back to Thing. The WebSocket connects to Thing message bus, giving the UI access to Thing state. Use the HTML template parameter {{.WebSocket}} for Thing's WebSocket address. {{.WebSocket}} encodes the protocol (ws:// or wss://) and Thing's host address. For example:

HTTP access:

{{.WebSocket}} = ws://192.168.1.125/ws/dc_a6_32_7a_a6_d0

HTTPS access:

{{.WebSocket}} = wss://linode.merliot.org/ws/dc_a6_32_7a_a6_d0

Thing ID is the last term in {{.WebSocket}}, e.g. dc_a6_32_7a_a6_d0

Example JavaScript to open WebSocket. On open, send a GetState message. On message receipt, handle the message. For ReplyState, we'll save Thing state in the UI, either using state variables or in the HTML DOM itself.


<script>

conn = new WebSocket("{{.WebSocket}}")


conn.onopen = function(evt) {

conn.send(JSON.stringify({Msg: "_GetState"}))

}


conn.onmessage = function(evt) {

msg = JSON.parse(evt.data)


switch(msg.Msg) {

case "_ReplyState":

// save Thing state

break

case "myMsg":

// do something with msg

break

// handle more messages...

}

}

</script>

Allow HTTP/HTTPS traffic

If Thing UI is enabled, we need to allow HTTP or HTTP and HTTPS port traffic (typically ports 80 and 443, respectively). Some environments allow these ports by default; others deny these ports. If Thing runs on a VM, check the VM settings. For example, on Google Cloud Platform, these ports are not enabled by default on a new VM instance.