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 *client) pair() error { var boardType string if config.HasString("boardType") { boardType = config.MustString("boardType") } else { boardType = fmt.Sprintf("custom-%s-%s", runtime.GOOS, runtime.GOARCH) } log.Debugf("Board type: %s", boardType) client := &http.Client{ Timeout: time.Second * 60, // It's 20sec on the server so this *should* be ok } if config.Bool(false, "cloud", "allowSelfSigned") { log.Warningf("Allowing self-signed certificate (should only be used to connect to development cloud)") client.Transport = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } var creds *credentials for { url := fmt.Sprintf(config.MustString("cloud", "activation"), config.Serial(), getLocalIP(), boardType) log.Debugf("Activating at URL: %s", url) var err error creds, err = activate(client, url) if err != nil { log.Warningf("Activation error : %s", err) log.Warningf("Sleeping for 3sec") time.Sleep(time.Second * 3) } else if creds != nil { break } } log.Infof("Got credentials. User: %s", creds.UserID) return saveCreds(creds) }
func (c *client) start() { if !config.IsPaired() { log.Infof("Client is unpaired. Attempting to pair.") if err := c.pair(); err != nil { log.Fatalf("An error occurred while pairing. Restarting. error: %s", err) } log.Infof("Pairing was successful.") // We reload the config so the creds can be picked up config.MustRefresh() if !config.IsPaired() { log.Fatalf("Pairing appeared successful, but I did not get the credentials. Restarting.") } } log.Infof("Client is paired. User: %s", config.MustString("userId")) if !config.NoCloud() { mesh, err := refreshMeshInfo() if err == errorUnauthorised { log.Warningf("UNAUTHORISED! Unpairing.") c.unpair() return } if err != nil { log.Warningf("Failed to refresh mesh info: %s", err) } else { log.Debugf("Got mesh info: %+v", mesh) } config.MustRefresh() if !config.HasString("masterNodeId") { log.Warningf("We don't have any mesh information. Which is unlikely. But we can't do anything without it, so restarting client.") time.Sleep(time.Second * 10) os.Exit(0) } } if config.MustString("masterNodeId") == config.Serial() { log.Infof("I am the master, starting HomeCloud.") cmd := exec.Command("start", "sphere-homecloud") cmd.Output() go c.exportNodeDevice() c.master = true } else { log.Infof("I am a slave. The master is %s", config.MustString("masterNodeId")) // TODO: Remove this when we are running drivers on slaves cmd := exec.Command("stop", "sphere-director") cmd.Output() c.masterReceiveTimeout = time.AfterFunc(orphanTimeout, func() { c.setOrphaned() }) } go func() { log.Infof("Starting search for peers") for { c.findPeers() time.Sleep(time.Second * 30) } }() }
func NewPaneLayout(fakeGestures bool, conn *ninja.Connection) (*PaneLayout, chan (bool)) { // Wait till we're paired and have a site for { config.MustRefresh() if config.HasString("siteId") { break } time.Sleep(time.Second * 2) } go startSearchTasks(conn) pane := &PaneLayout{ gestures: &Tick{ name: "Gestures/sec", }, wake: make(chan bool), log: logger.GetLogger("PaneLayout"), } pane.gestures.start() if !fakeGestures { g, err := gestic.Open() if err != nil { pane.log.Warningf("Error enabling gestures: %s\n", err) } else { //defer g.Close() pane.log.Infof("Succesfully connected to GestIC device") gestures := g.DataStream() go func() { for gesture := range gestures { //pane.log.Debugf("Gesture latency: %s", time.Since(gesture.Time).String()) go pane.OnGesture(&gesture) } }() } } // Check for sleep timeout go func() { for { time.Sleep(time.Millisecond * 50) if pane.awake && time.Since(pane.lastGesture) > sleepTimeout { pane.Sleep() } } }() /*if fakeGestures { go func() { for { time.Sleep(time.Millisecond * 5000) gesture := gestic.NewGestureData() gesture.Gesture.GestureVal = 2 pane.OnGesture(gesture) } }() go func() { for { time.Sleep(time.Millisecond * 10) gesture := gestic.NewGestureData() gesture.Coordinates.X = 100 gesture.Coordinates.Y = 100 gesture.Coordinates.Z = 100 pane.OnGesture(gesture) } }() }*/ return pane, pane.wake }