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) } } }() }