func NewLedController(conn *ninja.Connection) (*LedController, error) {

	s, err := util.GetLEDConnection()

	if err != nil {
		log.Fatalf("Failed to get connection to LED matrix: %s", err)
	}

	// Send a blank image to the led matrix
	util.WriteLEDMatrix(image.NewRGBA(image.Rect(0, 0, 16, 16)), s)

	controller := &LedController{
		conn:          conn,
		pairingLayout: ui.NewPairingLayout(),
		serial:        s,
		waiting:       make(chan bool),
	}

	conn.MustExportService(controller, "$node/"+config.Serial()+"/led-controller", &model.ServiceAnnouncement{
		Schema: "/service/led-controller",
	})

	conn.MustExportService(controller, "$home/led-controller", &model.ServiceAnnouncement{
		Schema: "/service/led-controller",
	})

	if config.HasString("siteId") {
		log.Infof("Have a siteId, checking if homecloud is running")
		// If we have just started, and we have a site, and homecloud is running... enable control!
		go func() {
			siteModel := conn.GetServiceClient("$home/services/SiteModel")
			for {

				if controller.commandReceived {
					log.Infof("Command has been received, stopping search for homecloud.")
					break
				}

				err := siteModel.Call("fetch", config.MustString("siteId"), nil, time.Second*5)

				if err != nil {
					log.Infof("Fetched site to enableControl. Got err: %s", err)
				} else if err == nil && !controller.commandReceived {
					controller.EnableControl()
					break
				}
				time.Sleep(time.Second * 5)
			}
		}()
	}

	return controller, nil
}
func (c *LedController) start(enableControl bool) {
	c.controlRequested = enableControl

	frameWritten := make(chan bool)

	go func() {
		fps.start()

		for {
			fps.tick()

			if c.controlEnabled {
				// Good to go

				image, wake, err := c.controlLayout.Render()
				if err != nil {
					log.Fatalf("Unable to render()", err)
				}

				go func() {
					util.WriteLEDMatrix(image, c.serial)
					frameWritten <- true
				}()

				select {
				case <-frameWritten:
					// All good.
				case <-time.After(10 * time.Second):
					log.Infof("Timeout writing to LED matrix. Quitting.")
					os.Exit(1)
				}

				if wake != nil {
					log.Infof("Waiting as the UI is asleep")
					select {
					case <-wake:
						log.Infof("UI woke up!")
					case <-c.waiting:
						log.Infof("Got a command from rpc...")
					}
				}

			} else if c.controlRequested && !c.controlRendering {

				// We want to display controls, so lets render the pane

				c.controlRendering = true
				go func() {

					log.Infof("Starting control layout")
					c.controlLayout = getPaneLayout(c.conn)
					c.controlRendering = false
					c.controlEnabled = true
					log.Infof("Finished control layout")

				}()
			}

			if c.controlRendering || !c.controlEnabled {
				// We're either already controlling, or waiting for the pane to render

				image, err := c.pairingLayout.Render()
				if err != nil {
					log.Fatalf("Unable to render()", err)
				}
				util.WriteLEDMatrix(image, c.serial)

			}
		}

	}()
}