This example Thing is a hub. A hub is a bridge that provides an aggregated UI to view any or all of the child user interfaces. The hub does not forward packets between children; it strictly provides an aggregated view into all connected children.

Consider these three Things. One running the GPS Locator example, one running the Relays example, and a third running the Temperature/Pressure example.

We can run a hub to view all three Thing in one UI.

We see a Thing icon for each child connected. Click on the Thing icon to view the child. The child's UI is shown in a HTML iframe element below the Thing icons. Notice the hub view of the child is synchronized with a standalone view of the child. If the user makes a stateful change in one view, all views are updated.

Carousel imageCarousel imageCarousel imageCarousel imageCarousel image

If a child disconnects, the hub shows the child offline. When the child comes back online, the hub will show the child online.

Hardware Setup

There is no hardware setup for the hub itself, other than the hosting system that runs the hub. The hub could run on a VM on the internet, or run locally on a private server on the local network. Regardless of where the hub runs, the child Things need to have a network path to the hub.

Software Setup

Files for this example are located in examples/hub.


├── assets // Hub UI assets

│ ├── css

│ │ └── hub.css

│ ├── images

│ │ ├── offline.jpg

│ │ └── online.jpg

│ ├── js

│ │ └── hub.js

│ └── templates

│ └── hub.html

├── cmd

│ └── hub

│ └── main.go // Hub application

└── hub.go // Hub Thing

This example hub allows only certain children to connect. Which children can connect is hard-coded in the hub's BridgeThingers() interface:

func (h *hub) BridgeThingers() merle.BridgeThingers {

return merle.BridgeThingers{

".*:relays:.*": func() merle.Thinger { return relays.NewRelays() },

".*:gps:.*": func() merle.Thinger { return gps.NewGps() },

".*:bmp180:.*": func() merle.Thinger { return bmp180.NewBmp180() },



In this case, the hub will allow any children with model = [relays | gps | bmp180]. Children models outside of [relays | gps | bmp180] will not be allowed to connect.


Build GPS Locator and Temperature/Pressure Sensor and Relays Things on their respective systems.

Build hub:

$ cd merle

$ ./build examples/hub


Run GPS Locator and Temperature/Pressure Sensor and Relays Things, specifying the hub as the mother:

// (On each Thing system)

$ cd merle

$ ~/go/bin/<thing> -rhost <hub address>

Run hub:

// (on hub)

$ cd merle

$ ~/go/bin/hub

Running Hub on the Internet

If running the hub on the Internet, SSH keys will need to be created and pushed from each child to the hub. Basically, on each child, push the key before running:

$ cd merle

$ ./scripts/key-push <user>@<hub address>

$ ~/go/bin/<thing> -rhost <hub address>