func (c *HomeCloud) PostConstruct() error {

	c.log = logger.GetLogger("HomeCloud")

	c.ExportRPCServices()
	c.ensureSiteExists()

	ledController := c.Conn.GetServiceClient("$home/led-controller")
	err := ledController.Call("enableControl", nil, nil, 0)
	if err != nil {
		c.log.Infof("Failed to enable control on LED controller: %s", err)
	}

	if syncEnabled {
		// We wait for at least one sync to happen, or fail
		<-c.StartSyncing(config.MustDuration("homecloud.sync.interval"))
	}

	// This is required to enable sphere-reset to clear out redis, then push this empty db to
	// cloud.
	if config.Bool(false, "clearcloud") {
		c.log.Infof("Just clearing cloud so exiting now!")
		os.Exit(0)
	}

	c.AutoStartModules()

	return nil
}
Example #2
0
func refreshMeshInfo() (*meshInfo, error) {

	nodes, err := getNodes()
	if err != nil {
		return nil, err
	}

	sites, err := getSites()
	if err != nil {
		return nil, err
	}

	node, ok := nodes[config.Serial()]
	if !ok {
		return nil, errors.New("Could not find our node in the cloud. (race condition?)")
	}

	site, ok := sites[node.SiteID]
	if !ok {
		return nil, errors.New("Could not find our node in the cloud. (race condition?)")
	}

	if config.Bool(false, "forceMaster") {
		site.MasterNodeID = config.Serial()
	}

	meshInfo := &meshInfo{
		SiteID:       site.ID,
		MasterNodeID: site.MasterNodeID,
		SiteUpdated:  int(time.Time(site.Updated).UnixNano() / int64(time.Second)),
	}

	return meshInfo, saveMeshInfo(meshInfo)
}
func main() {

	/*
		go func() {
			log.Printf("Starting pprof server")
			log.Println(http.ListenAndServe(":6060", nil))
		}()
		//*/

	log := logger.GetLogger("LED-controller")

	conn, err := ninja.Connect(drivername)

	if err != nil {
		log.FatalErrorf(err, "Failed to connect to mqtt")
	}

	controller, err := NewLedController(conn)

	if err != nil {
		log.FatalErrorf(err, "Failed to create led controller")
	}

	enableControl := config.Bool(false, "enableControl")

	controller.start(enableControl)

	blah := make(chan os.Signal, 1)
	signal.Notify(blah, os.Interrupt, os.Kill)

	// Block until a signal is received.
	x := <-blah
	log.Infof("Got signal:", x)

}
Example #4
0
// ExportDriver Exports a driver using the 'driver' protocol, and announces it
func (c *Connection) ExportDriver(driver Driver) error {

	time.Sleep(config.Duration(time.Second*3, "drivers.startUpDelay"))

	topic := fmt.Sprintf("$node/%s/driver/%s", config.Serial(), driver.GetModuleInfo().ID)

	announcement := driver.GetModuleInfo()

	announcement.ServiceAnnouncement = model.ServiceAnnouncement{
		Schema: "http://schema.ninjablocks.com/service/driver",
	}

	_, err := c.exportService(driver, topic, announcement)

	if err != nil {
		return err
	}

	if config.Bool(false, "autostart") {
		err := c.GetServiceClient(topic).Call("start", struct{}{}, nil, time.Second*20)
		if err != nil {
			c.log.Fatalf("Failed to autostart driver: %s", err)
		}
	}

	return nil
}
Example #5
0
// ExportApp Exports an app using the 'app' protocol, and announces it
func (c *Connection) ExportApp(app App) error {

	if app.GetModuleInfo().ID == "" {
		panic("You must provide an ID in the package.json")
	}
	topic := fmt.Sprintf("$node/%s/app/%s", config.Serial(), app.GetModuleInfo().ID)

	announcement := app.GetModuleInfo()

	announcement.ServiceAnnouncement = model.ServiceAnnouncement{
		Schema: "http://schema.ninjablocks.com/service/app",
	}

	_, err := c.exportService(app, topic, announcement)

	if err != nil {
		return err
	}

	if config.Bool(false, "autostart") {
		err := c.GetServiceClient(topic).Call("start", struct{}{}, nil, time.Second*20)
		if err != nil {
			c.log.Fatalf("Failed to autostart app: %s", err)
		}
	}

	return nil
}
Example #6
0
func getClient() *http.Client {
	client := &http.Client{}

	if config.Bool(false, "cloud", "allowSelfSigned") {
		log.Warningf("Allowing self-signed cerificate (should only be used to connect to development cloud)")
		client.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
	}

	return client
}
Example #7
0
func req(url string, data interface{}) error {

	client := &http.Client{
		Timeout: time.Second * 30,
	}

	if config.Bool(false, "cloud", "allowSelfSigned") {
		log.Warningf("Allowing self-signed cerificate (should only be used to connect to development cloud)")
		client.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
	}

	resp, err := client.Get(fmt.Sprintf(url, config.MustString("token")))
	if err != nil {
		return err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var response restResponse

	err = json.Unmarshal(body, &response)
	if err != nil {
		return err
	}

	if resp.StatusCode != http.StatusOK || response.Type == "error" {
		var data restError
		err = json.Unmarshal(response.Data, &data)

		if data.Type == "authentication_invalid_token" {
			return errorUnauthorised
		}

		if err != nil {
			return err
		}

		return fmt.Errorf("Error from cloud: %s (%s)", data.Message, data.Type)
	}

	return json.Unmarshal(response.Data, data)
}
Example #8
0
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)
}
package ui

import (
	"image"
	"math"

	draw2d "github.com/ninjasphere/draw2d/draw2dimg"

	"github.com/lucasb-eyer/go-colorful"
	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/config"
)

var enableGesturePane = config.Bool(false, "led.gestures.testPane")

type GesturePane struct {
	last *gestic.GestureMessage
}

func NewGesturePane() *GesturePane {
	return &GesturePane{}
}

func (p *GesturePane) IsEnabled() bool {
	return enableGesturePane
}

func (p *GesturePane) KeepAwake() bool {
	return false
}
Example #10
0
	siteModel := NewSiteModel()
	thingModel := NewThingModel()

	return []interface{}{
		moduleModel, &moduleModel.baseModel,
		channelModel, &channelModel.baseModel,
		deviceModel, &deviceModel.baseModel,
		roomModel, &roomModel.baseModel,
		siteModel, &siteModel.baseModel,
		thingModel, &thingModel.baseModel,
	}
}

var fsSyncLog = logger.GetLogger("FS Sync")
var fsSyncInterval = config.Duration(time.Second, "homecloud.fsSync.minInterval")
var fsSyncEnabled = config.Bool(false, "homecloud.fsSync.enabled")
var fsSyncTask *time.Timer

func syncFS() {
	if fsSyncEnabled {
		if fsSyncTask == nil {
			fsSyncTask = time.AfterFunc(fsSyncInterval, func() {
				fsSyncLog.Debugf("Syncing filesystem...")
				exec.Command("sync").Output()
			})
		}

		fsSyncTask.Reset(fsSyncInterval)
	}
}
	"encoding/json"
	"fmt"

	"image"
	"image/color"
	"regexp"

	"github.com/davecgh/go-spew/spew"
	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/bus"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
)

var enableCertificationPane = config.Bool(false, "led.certification.enabled")

type CertPane struct {
	log       *logger.Logger
	waypoints int
	rssi      string
	tag       string
}

func NewCertPane(conn bus.Bus) *CertPane {

	log := logger.GetLogger("CertPane")

	pane := &CertPane{
		log: log,
	}
	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"

	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
)

const width = 16
const height = 16

var panDuration = config.MustDuration("led.panDuration")
var wakeTransitionDuration = config.MustDuration("led.wakeTransition")
var sleepTransitionDuration = config.MustDuration("led.sleepTransition")
var sleepTimeout = config.MustDuration("led.sleepTimeout")
var forceAllPanes = config.Bool(false, "led.forceAllPanes")

var logGestures = config.Bool(false, "led.gestures.log")
var enableGestures = config.Bool(true, "led.gestures.enable")

type PaneLayout struct {
	currentPane int
	targetPane  int
	panes       []Pane
	lastGesture time.Time

	panTween *Tween
	panLock  sync.Mutex

	renderLock sync.Mutex
Example #13
0
	"path/filepath"
	"reflect"
	"sync"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/redigo/redis"
	"github.com/ninjasphere/sphere-go-homecloud/models"
)

var log = logger.GetLogger("HomeCloud")

var syncEnabled = config.Bool(true, "homecloud.sync.enabled")
var syncTimeout = config.MustDuration("homecloud.sync.timeout")

type HomeCloud struct {
	Conn         *ninja.Connection    `inject:""`
	Pool         *redis.Pool          `inject:""`
	ThingModel   *models.ThingModel   `inject:""`
	DeviceModel  *models.DeviceModel  `inject:""`
	ChannelModel *models.ChannelModel `inject:""`
	RoomModel    *models.RoomModel    `inject:""`
	ModuleModel  *models.ModuleModel  `inject:""`
	SiteModel    *models.SiteModel    `inject:""`
	log          *logger.Logger
}

func (c *HomeCloud) PostConstruct() error {
Example #14
0
package simtime

import (
	"container/heap"
	"runtime/debug"
	"time"

	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
)

var log = logger.GetLogger("simtime")

var enabled = config.Bool(false, "simtime.enable")
var startOffset = config.Duration(time.Hour*24*30, "simtime.startOffset")
var offset = config.Duration(0, "simtime.offset")
var allowFuture = config.Bool(false, "simtime.allowFuture")

var currentTime = time.Now()

var addQueue = make(chan *event)
var queue = eventQueue{}

var added = make(chan bool)
var tick = make(chan bool)
var start = make(chan bool)

func addQueuedEvents() {
	for {
		select {
		case e := <-addQueue:
package ui

import (
	"fmt"
	"image"
	"image/color"
	"strings"
	"time"

	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/clock"
)

var enableClockPane = config.Bool(true, "led.clock.enabled")
var enableAlarm = config.Bool(true, "led.clock.alarmEnabled")
var alarmFlashTimes = config.Int(2, "led.clock.alarmFlashTimes") * 2
var alarmFlashInterval = config.MustDuration("led.clock.alarmFlashInterval")

type ClockPane struct {
	alarm       *time.Time
	timer       *time.Timer
	tapThrottle *throttle
	lights      []*ninja.ServiceClient
	tickTock    bool
}

func NewClockPane() *ClockPane {
	var pane *ClockPane
	pane = &ClockPane{
Example #16
0
func main() {

	log.Infof("Welcome home, Ninja.")

	if config.Bool(true, "homecloud.waitForNTP") {
		waitForNTP()
	}

	// The MQTT Connection
	conn, err := ninja.Connect("sphere-go-homecloud")
	if err != nil {
		log.Fatalf("Failed to connect to sphere: %s", err)
	}

	// An MQTT Connection used for outbound syncing connections
	syncConn := &models.SyncConnection{}
	syncConn.Conn, err = ninja.Connect("sphere-go-homecloud.sync")
	if err != nil {
		log.Fatalf("Failed to connect to sphere (sync): %s", err)
	}

	// Our redis pool
	pool := &redis.Pool{
		MaxIdle:     config.MustInt("homecloud.redis.maxIdle"),
		MaxActive:   config.Int(10, "homecloud.redis.maxActive"),
		IdleTimeout: config.MustDuration("homecloud.redis.idleTimeout"),
		Wait:        true,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", config.String("", "homecloud.redis.host"), config.MustInt("homecloud.redis.port")))
			if err != nil {
				return nil, err
			}
			return c, err
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}

	// Not pretty.
	rpc.RedisPool = pool

	// Wait until we connect to redis successfully.
	for {
		c := pool.Get()

		if c.Err() == nil {
			c.Close()
			break
		}
		log.Warningf("Failed to connect to redis: %s", c.Err())
		time.Sleep(time.Second)
	}

	// Build the object graph using dependency injection
	injectables := []interface{}{}

	injectables = append(injectables, pool, conn, syncConn)
	injectables = append(injectables, &homecloud.HomeCloud{}, &homecloud.TimeSeriesManager{}, &homecloud.DeviceManager{}, &homecloud.ModuleManager{})
	injectables = append(injectables, state.NewStateManager())
	injectables = append(injectables, &rest.RestServer{})
	injectables = append(injectables, models.GetInjectables()...)

	err = inject.Populate(injectables...)

	if err != nil {
		log.Fatalf("Failed to construct the object graph: %s", err)
	}

	// Run PostConstruct on any objects that have it
	for _, node := range injectables {
		if n, ok := node.(postConstructable); ok {
			go func(c postConstructable) {
				if err := c.PostConstruct(); err != nil {
					log.Fatalf("Failed PostConstruct on object %s: %s", reflect.TypeOf(c).String(), err)
				}
			}(n)
		}
	}

	support.WaitUntilSignal()
	// So long, and thanks for all the fish.
}
Example #17
0
import (
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"sync"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/redigo/redis"
)

var enableSyncFromCloud = config.Bool(false, "homecloud.sync.fromCloud")
var deleteUnknownFromCloud = config.Bool(false, "homecloud.sync.deleteUnknownFromCloud")

var (
	RecordNotFound  = errors.New("Record Not Found")
	RecordUnchanged = errors.New("Record Unchanged")
)

// A wrapper for the connection type.
//
// We need two different connections but the dependency injection
// framework does not provide a way to support this requirement.
//
// So, we use a wrapper type here and inject the wrapper.
type SyncConnection struct {
	Conn *ninja.Connection
package service

import (
	"fmt"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/bus"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
)

var mocking = config.Bool(false, "mock")

// This isn't an example of good code. Fix it or ignore it, but don't copy it.

var lightsConfig map[string]SecurityLightConfig
var conn *ninja.Connection
var saveConfig func()
var thingModel *ninja.ServiceClient

var log = logger.GetLogger("service")
var lights = make(map[string]*securityLight)

var allThings []model.Thing

var started bool

var latitude, longitude float64
type Device struct {
	Name     string `json:"name"`
	ID       string `json:"id"`
	IDType   string `json:"idType"`
	Guid     string `json:"guid"`
	Channels []Channel
}

type Channel struct {
	Protocol string `json:"protocol"`
	Name     string `json:"channel"`
	ID       string `json:"id"`
}*/

var sameRoomOnly = config.Bool(true, "homecloud.sameRoomOnly")

var conn *ninja.Connection
var tasks []*request
var thingModel *ninja.ServiceClient

var log = logger.GetLogger("ui")

type request struct {
	thingType string
	protocol  string
	filter    func(thing *model.Thing) bool
	cb        func([]*ninja.ServiceClient, error)
}

var roomID *string
Example #20
0
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/gojsonschema"
	"github.com/xeipuuv/gojsonreference"
)

var log = logger.GetLogger("schemas")

var root = "http://schema.ninjablocks.com/"
var rootURL, _ = url.Parse(root)
var filePrefix = config.MustString("installDirectory") + "/sphere-schemas/"
var fileSuffix = ".json"

var schemaPool = gojsonschema.NewSchemaPool()
var validationEnabled = config.Bool(false, "validate")

func init() {
	schemaPool.FilePrefix = &filePrefix
	schemaPool.FileSuffix = &fileSuffix

	if validationEnabled {
		log.Infof("-------- VALIDATION ENABLED --------")
	}
}

func Validate(schema string, obj interface{}) (*string, error) {

	if !validationEnabled {
		return nil, nil
	}
	"time"

	"github.com/lucasb-eyer/go-colorful"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
	ledmodel "github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/ninjasphere/sphere-go-led-controller/remote"
	"github.com/ninjasphere/sphere-go-led-controller/ui"
	"github.com/ninjasphere/sphere-go-led-controller/util"
)

var log = logger.GetLogger("sphere-go-led-controller")

var enableRemotePanes = config.Bool(false, "led.remote.enabled")
var remotePort = config.Int(3115, "led.remote.port")

var fps Tick = Tick{
	name: "Pane FPS",
}

type LedController struct {
	controlEnabled   bool
	controlRequested bool
	controlRendering bool
	commandReceived  bool

	controlLayout *ui.PaneLayout
	pairingLayout *ui.PairingLayout
	conn          *ninja.Connection
package ui

import (
	"encoding/json"
	"image"
	"image/color"

	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
)

var systemPaneEnabled = config.Bool(false, "led.systempane.enabled")

var colors = map[string]*color.RGBA{
	"white":  &color.RGBA{255, 255, 255, 0},
	"black":  &color.RGBA{0, 0, 0, 0},
	"red":    &color.RGBA{255, 0, 0, 255},
	"green":  &color.RGBA{0, 255, 0, 255},
	"blue":   &color.RGBA{0, 0, 255, 255},
	"yellow": &color.RGBA{255, 255, 0, 255},
}

type SystemPane struct {
	log   *logger.Logger
	code  string
	color string
}
	"github.com/google/uuid"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/redigo/redis"
	"github.com/ninjasphere/sphere-go-homecloud/state"
)

type ThingModel struct {
	baseModel

	DeviceModel  *DeviceModel       `inject:""`
	RoomModel    *RoomModel         `inject:""`
	StateManager state.StateManager `inject:""`
}

var autoPromote = config.Bool(false, "homecloud.autopromote")

func toThing(obj interface{}) *model.Thing {
	var thing, ok = obj.(*model.Thing)
	if !ok {
		panic("Non-'Thing' passed to a ThingModel handler")
	}
	return thing
}

func NewThingModel() *ThingModel {

	thingModel := &ThingModel{
		baseModel: newBaseModel("thing", model.Thing{}),
	}
package ui

import (
	"bytes"
	"image"
	"math/rand"

	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/config"
)

var enableGameOfLifePane = config.Bool(false, "led.gameOfLife.enabled")

type GameOfLifePane struct {
	life *Life
}

func NewGameOfLifePane() *GameOfLifePane {
	pane := &GameOfLifePane{}
	pane.reset()
	return pane
}

func (p *GameOfLifePane) IsEnabled() bool {
	return enableGameOfLifePane
}

func (p *GameOfLifePane) KeepAwake() bool {
	return false
}