Example #1
0
func TestConnect(t *testing.T) {
	b := New()

	response := testProtocolResponse()

	go func() {
		for {
			testReadData = append(testReadData, response...)
			<-time.After(100 * time.Millisecond)
		}
	}()

	gobot.Once(b.Event("ProtocolVersion"), func(data interface{}) {
		response = testFirmwareResponse()
	})

	gobot.Once(b.Event("FirmwareQuery"), func(data interface{}) {
		response = testCapabilitiesResponse()
	})

	gobot.Once(b.Event("CapabilityQuery"), func(data interface{}) {
		response = testAnalogMappingResponse()
	})

	gobot.Once(b.Event("AnalogMappingQuery"), func(data interface{}) {
		response = testProtocolResponse()
	})

	gobot.Assert(t, b.Connect(readWriteCloser{}), nil)
}
func TestSparkCoreAdaptorEventStream(t *testing.T) {
	a := initTestSparkCoreAdaptor()
	var url string
	eventSource = func(u string) (chan eventsource.Event, chan error, error) {
		url = u
		return nil, nil, nil
	}
	a.EventStream("all", "ping")
	gobot.Assert(t, url, "https://api.spark.io/v1/events/ping?access_token=token")
	a.EventStream("devices", "ping")
	gobot.Assert(t, url, "https://api.spark.io/v1/devices/events/ping?access_token=token")
	a.EventStream("device", "ping")
	gobot.Assert(t, url, "https://api.spark.io/v1/devices/myDevice/events/ping?access_token=token")
	_, err := a.EventStream("nothing", "ping")
	gobot.Assert(t, err.Error(), "source param should be: all, devices or device")

	eventSource = func(u string) (chan eventsource.Event, chan error, error) {
		return nil, nil, errors.New("error connecting sse")
	}

	_, err = a.EventStream("devices", "")
	gobot.Assert(t, err.Error(), "error connecting sse")

	eventChan := make(chan eventsource.Event, 0)
	errorChan := make(chan error, 0)

	eventSource = func(u string) (chan eventsource.Event, chan error, error) {
		return eventChan, errorChan, nil
	}

	sem := make(chan bool, 0)
	stream, err := a.EventStream("devices", "")
	gobot.Assert(t, err, nil)

	eventChan <- testEventSource{event: "event", data: "sse event"}

	gobot.Once(stream, func(data interface{}) {
		e := data.(Event)
		gobot.Assert(t, e.Name, "event")
		gobot.Assert(t, e.Data, "sse event")
		gobot.Assert(t, e.Error, nil)
		sem <- true
	})

	<-sem

	errorChan <- errors.New("stream error")

	gobot.Once(stream, func(data interface{}) {
		e := data.(Event)
		gobot.Assert(t, e.Name, "")
		gobot.Assert(t, e.Data, "")
		gobot.Assert(t, e.Error.Error(), "stream error")
		sem <- true
	})

	<-sem

}
func TestAnalogSensorDriverStart(t *testing.T) {
	sem := make(chan bool, 1)

	d := NewAnalogSensorDriver(newGpioTestAdaptor("adaptor"), "bot", "1")

	gobot.Assert(t, len(d.Start()), 0)

	gobot.Once(d.Event(Data), func(data interface{}) {
		gobot.Assert(t, data.(int), 100)
		sem <- true
	})

	testAdaptorAnalogRead = func() (val int, err error) {
		val = 100
		return
	}

	select {
	case <-sem:
	case <-time.After(15 * time.Millisecond):
		t.Errorf("AnalogSensor Event \"Data\" was not published")
	}

	gobot.Once(d.Event(Error), func(data interface{}) {
		gobot.Assert(t, data.(error).Error(), "read error")
		sem <- true
	})

	testAdaptorAnalogRead = func() (val int, err error) {
		err = errors.New("read error")
		return
	}

	select {
	case <-sem:
	case <-time.After(15 * time.Millisecond):
		t.Errorf("AnalogSensor Event \"Error\" was not published")
	}

	gobot.Once(d.Event(Data), func(data interface{}) {
		sem <- true
	})

	testAdaptorAnalogRead = func() (val int, err error) {
		val = 200
		return
	}

	d.halt <- true

	select {
	case <-sem:
		t.Errorf("AnalogSensor Event should not published")
	case <-time.After(30 * time.Millisecond):
	}
}
Example #4
0
// Connect connects to the Client given conn. It first resets the firmata board
// then continuously polls the firmata board for new information when it's
// available.
func (b *Client) Connect(conn io.ReadWriteCloser) (err error) {
	if b.connected {
		return ErrConnected
	}

	b.connection = conn
	b.Reset()

	initFunc := b.ProtocolVersionQuery

	gobot.Once(b.Event("ProtocolVersion"), func(data interface{}) {
		initFunc = b.FirmwareQuery
	})

	gobot.Once(b.Event("FirmwareQuery"), func(data interface{}) {
		initFunc = b.CapabilitiesQuery
	})

	gobot.Once(b.Event("CapabilityQuery"), func(data interface{}) {
		initFunc = b.AnalogMappingQuery
	})

	gobot.Once(b.Event("AnalogMappingQuery"), func(data interface{}) {
		initFunc = func() error { return nil }
		b.ReportDigital(0, 1)
		b.ReportDigital(1, 1)
		b.connected = true
	})

	for {
		if err := initFunc(); err != nil {
			return err
		}
		if err := b.process(); err != nil {
			return err
		}
		if b.connected {
			go func() {
				for {
					if !b.connected {
						break
					}

					if err := b.process(); err != nil {
						gobot.Publish(b.Event("Error"), err)
					}
				}
			}()
			break
		}
	}
	return
}
Example #5
0
func TestMavlinkDriverStart(t *testing.T) {
	d := initTestMavlinkDriver()
	err := make(chan error, 0)
	packet := make(chan *common.MAVLinkPacket, 0)
	message := make(chan common.MAVLinkMessage, 0)

	gobot.Once(d.Event("packet"), func(data interface{}) {
		packet <- data.(*common.MAVLinkPacket)
	})

	gobot.Once(d.Event("message"), func(data interface{}) {
		message <- data.(common.MAVLinkMessage)
	})
	gobot.Once(d.Event("errorIO"), func(data interface{}) {
		err <- data.(error)
	})
	gobot.Once(d.Event("errorMAVLink"), func(data interface{}) {
		err <- data.(error)
	})

	gobottest.Assert(t, len(d.Start()), 0)

	select {
	case p := <-packet:
		gobottest.Assert(t, d.SendPacket(p), nil)

	case <-time.After(100 * time.Millisecond):
		t.Errorf("packet was not emitted")
	}
	select {
	case <-message:
	case <-time.After(100 * time.Millisecond):
		t.Errorf("message was not emitted")
	}
	select {
	case <-err:
	case <-time.After(100 * time.Millisecond):
		t.Errorf("error was not emitted")
	}

	payload = []byte{0xFE, 0x09, 0x4E, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x51, 0x04, 0x03, 0x1C, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	select {
	case e := <-err:
		gobottest.Assert(t, e, errors.New("Unknown Message ID: 255"))
	case <-time.After(100 * time.Millisecond):
		t.Errorf("error was not emitted")
	}

}
Example #6
0
// initBoard initializes board by listening for "firware_query", "capability_query"
// and "analog_mapping_query" events
func (b *board) initBoard() {
	gobot.Once(b.events["firmware_query"], func(data interface{}) {
		b.queryCapabilities()
	})

	gobot.Once(b.events["capability_query"], func(data interface{}) {
		b.queryAnalogMapping()
	})

	gobot.Once(b.events["analog_mapping_query"], func(data interface{}) {
		b.togglePinReporting(0, high, reportDigital)
		b.togglePinReporting(1, high, reportDigital)
		b.connected = true
	})
}
Example #7
0
// AnalogRead retrieves value from analog pin.
// Returns -1 if the response from the board has timed out
func (f *FirmataAdaptor) AnalogRead(pin string) (val int, err error) {
	ret := make(chan int)

	p, err := strconv.Atoi(pin)
	if err != nil {
		return
	}
	// NOTE pins are numbered A0-A5, which translate to digital pins 14-19
	p = f.digitalPin(p)
	if err = f.board.setPinMode(byte(p), analog); err != nil {
		return
	}

	if err = f.board.togglePinReporting(byte(p), high, reportAnalog); err != nil {
		return
	}

	if err = f.board.readAndProcess(); err != nil {
		return
	}

	gobot.Once(f.board.events[fmt.Sprintf("analog_read_%v", pin)], func(data interface{}) {
		b := data.([]byte)
		ret <- int(uint(b[0])<<24 | uint(b[1])<<16 | uint(b[2])<<8 | uint(b[3]))
	})

	select {
	case data := <-ret:
		return data, nil
	case <-time.After(10 * time.Millisecond):
	}
	return -1, nil
}
Example #8
0
// DigitalRead retrieves digital value from specified pin.
// Returns -1 if the response from the board has timed out
func (f *FirmataAdaptor) DigitalRead(pin string) (val int, err error) {
	ret := make(chan int)

	p, err := strconv.Atoi(pin)
	if err != nil {
		return
	}
	if err = f.board.setPinMode(byte(p), input); err != nil {
		return
	}
	if err = f.board.togglePinReporting(byte(p), high, reportDigital); err != nil {
		return
	}
	if err = f.board.readAndProcess(); err != nil {
		return
	}

	gobot.Once(f.board.events[fmt.Sprintf("digital_read_%v", pin)], func(data interface{}) {
		ret <- int(data.([]byte)[0])
	})

	select {
	case data := <-ret:
		return data, nil
	case <-time.After(10 * time.Millisecond):
	}
	return -1, nil
}
Example #9
0
func ExampleOnce() {
	e := gobot.NewEvent()
	gobot.Once(e, func(s interface{}) {
		fmt.Println(s)
		fmt.Println("I will no longer respond to events")
	})
	gobot.Publish(e, 100)
	gobot.Publish(e, 200)
}
Example #10
0
// I2cRead returns size bytes from the i2c device
// Returns an empty array if the response from the board has timed out
func (f *FirmataAdaptor) I2cRead(address int, size int) (data []byte, err error) {
	ret := make(chan []byte)

	if err = f.board.I2cRead(address, size); err != nil {
		return
	}

	gobot.Once(f.board.Event("I2cReply"), func(data interface{}) {
		ret <- data.(client.I2cReply).Data
	})

	data = <-ret

	return
}
Example #11
0
func main() {
	gbot := gobot.NewGobot()

	adaptor := mavlink.NewMavlinkAdaptor("iris", "/dev/ttyACM0")
	iris := mavlink.NewMavlinkDriver(adaptor, "iris")

	work := func() {
		gobot.Once(iris.Event("packet"), func(data interface{}) {
			packet := data.(*common.MAVLinkPacket)

			dataStream := common.NewRequestDataStream(100,
				packet.SystemID,
				packet.ComponentID,
				4,
				1,
			)
			iris.SendPacket(common.CraftMAVLinkPacket(packet.SystemID,
				packet.ComponentID,
				dataStream,
			))
		})

		gobot.On(iris.Event("message"), func(data interface{}) {
			if data.(common.MAVLinkMessage).Id() == 30 {
				message := data.(*common.Attitude)
				fmt.Println("Attitude")
				fmt.Println("TIME_BOOT_MS", message.TIME_BOOT_MS)
				fmt.Println("ROLL", message.ROLL)
				fmt.Println("PITCH", message.PITCH)
				fmt.Println("YAW", message.YAW)
				fmt.Println("ROLLSPEED", message.ROLLSPEED)
				fmt.Println("PITCHSPEED", message.PITCHSPEED)
				fmt.Println("YAWSPEED", message.YAWSPEED)
				fmt.Println("")
			}
		})
	}

	robot := gobot.NewRobot("mavBot",
		[]gobot.Connection{adaptor},
		[]gobot.Device{iris},
		work,
	)

	gbot.AddRobot(robot)

	gbot.Start()
}
Example #12
0
// I2cRead returns size bytes from the i2c device
// Returns an empty array if the response from the board has timed out
func (f *FirmataAdaptor) I2cRead(size uint) (data []byte, err error) {
	ret := make(chan []byte)
	if err = f.board.i2cReadRequest(f.i2cAddress, size); err != nil {
		return
	}

	if err = f.board.readAndProcess(); err != nil {
		return
	}

	gobot.Once(f.board.events["i2c_reply"], func(data interface{}) {
		ret <- data.(map[string][]byte)["data"]
	})

	select {
	case data := <-ret:
		return data, nil
	case <-time.After(10 * time.Millisecond):
	}
	return []byte{}, nil
}
Example #13
0
func TestNeuroskyDriverStart(t *testing.T) {
	sem := make(chan bool, 0)
	d := initTestNeuroskyDriver()
	gobot.Once(d.Event("error"), func(data interface{}) {
		gobottest.Assert(t, data.(error), errors.New("read error"))
		sem <- true
	})

	gobottest.Assert(t, len(d.Start()), 0)

	<-time.After(50 * time.Millisecond)
	readError = errors.New("read error")

	select {
	case <-sem:
	case <-time.After(100 * time.Millisecond):
		{
			t.Errorf("error was not emitted")
		}

	}
}
Example #14
0
func TestButtonDriverStart(t *testing.T) {
	sem := make(chan bool, 0)
	d := initTestButtonDriver()
	gobot.Assert(t, len(d.Start()), 0)

	testAdaptorDigitalRead = func() (val int, err error) {
		val = 1
		return
	}

	gobot.Once(d.Event(Push), func(data interface{}) {
		gobot.Assert(t, d.Active, true)
		sem <- true
	})

	select {
	case <-sem:
	case <-time.After(15 * time.Millisecond):
		t.Errorf("Button Event \"Push\" was not published")
	}

	testAdaptorDigitalRead = func() (val int, err error) {
		val = 0
		return
	}

	gobot.Once(d.Event(Release), func(data interface{}) {
		gobot.Assert(t, d.Active, false)
		sem <- true
	})

	select {
	case <-sem:
	case <-time.After(15 * time.Millisecond):
		t.Errorf("Button Event \"Release\" was not published")
	}

	testAdaptorDigitalRead = func() (val int, err error) {
		err = errors.New("digital read error")
		return
	}

	gobot.Once(d.Event(Error), func(data interface{}) {
		sem <- true
	})

	select {
	case <-sem:
	case <-time.After(15 * time.Millisecond):
		t.Errorf("Button Event \"Error\" was not published")
	}

	testAdaptorDigitalRead = func() (val int, err error) {
		val = 1
		return
	}

	gobot.Once(d.Event(Push), func(data interface{}) {
		sem <- true
	})

	d.halt <- true

	select {
	case <-sem:
		t.Errorf("Button Event \"Press\" should not published")
	case <-time.After(15 * time.Millisecond):
	}

}
Example #15
0
func TestProcess(t *testing.T) {
	sem := make(chan bool)
	b := initTestFirmata()

	tests := []struct {
		event    string
		data     []byte
		expected interface{}
		init     func()
	}{
		{
			event:    "ProtocolVersion",
			data:     []byte{249, 2, 3},
			expected: "2.3",
			init:     func() {},
		},
		{
			event:    "AnalogRead0",
			data:     []byte{0xE0, 0x23, 0x05},
			expected: 675,
			init:     func() {},
		},
		{
			event:    "AnalogRead1",
			data:     []byte{0xE1, 0x23, 0x06},
			expected: 803,
			init:     func() {},
		},
		{
			event:    "DigitalRead2",
			data:     []byte{0x90, 0x04, 0x00},
			expected: 1,
			init:     func() { b.pins[2].Mode = Input },
		},
		{
			event:    "DigitalRead4",
			data:     []byte{0x90, 0x16, 0x00},
			expected: 1,
			init:     func() { b.pins[4].Mode = Input },
		},
		{
			event:    "PinState13",
			data:     []byte{240, 110, 13, 1, 1, 247},
			expected: Pin{[]int{0, 1, 4}, 1, 0, 1, 127},
			init:     func() {},
		},
		{
			event: "I2cReply",
			data:  []byte{240, 119, 9, 0, 0, 0, 24, 1, 1, 0, 26, 1, 247},
			expected: I2cReply{
				Address:  9,
				Register: 0,
				Data:     []byte{152, 1, 154},
			},
			init: func() {},
		},
		{
			event: "FirmwareQuery",
			data: []byte{240, 121, 2, 3, 83, 0, 116, 0, 97, 0, 110, 0, 100, 0, 97,
				0, 114, 0, 100, 0, 70, 0, 105, 0, 114, 0, 109, 0, 97, 0, 116, 0, 97, 0, 46,
				0, 105, 0, 110, 0, 111, 0, 247},
			expected: "StandardFirmata.ino",
			init:     func() {},
		},
		{
			event:    "StringData",
			data:     append([]byte{240, 0x71}, append([]byte("Hello Firmata!"), 247)...),
			expected: "Hello Firmata!",
			init:     func() {},
		},
	}

	for _, test := range tests {
		test.init()
		gobot.Once(b.Event(test.event), func(data interface{}) {
			gobot.Assert(t, data, test.expected)
			sem <- true
		})

		testReadData = test.data
		go b.process()

		select {
		case <-sem:
		case <-time.After(10 * time.Millisecond):
			t.Errorf("%v was not published", test.event)
		}
	}
}
Example #16
0
func main() {
	if gobot.Version() != "0.7.dev" {
		panic("this requires the dev branch!")
	}

	summary := &telemetry{Status: "STANDBY"}
	gbot := gobot.NewGobot()

	a := api.NewAPI(gbot)

	a.Get("/mavlink/:a", func(res http.ResponseWriter, req *http.Request) {
		path := req.URL.Path
		t := strings.Split(path, "/")
		buf, err := Asset("assets/" + t[2])
		if err != nil {
			http.Error(res, err.Error(), http.StatusNotFound)
			return
		}
		t = strings.Split(path, ".")
		if t[len(t)-1] == "js" {
			res.Header().Set("Content-Type", "text/javascript; charset=utf-8")
		} else if t[len(t)-1] == "css" {
			res.Header().Set("Content-Type", "text/css; charset=utf-8")
		}
		res.Write(buf)
	})

	adaptor := mavlink.NewMavlinkAdaptor("iris", "/dev/ttyACM0")
	iris := mavlink.NewMavlinkDriver(adaptor, "iris")

	work := func() {

		iris.AddEvent("telemetry")

		gobot.Once(iris.Event("packet"), func(data interface{}) {
			fmt.Println(data)
			packet := data.(*common.MAVLinkPacket)

			dataStream := common.NewRequestDataStream(10,
				packet.SystemID,
				packet.ComponentID,
				0,
				1,
			)
			iris.SendPacket(common.CraftMAVLinkPacket(packet.SystemID,
				packet.ComponentID,
				dataStream,
			))
		})

		gobot.On(iris.Event("message"), func(data interface{}) {

			fmt.Println("message: ", data.(common.MAVLinkMessage).Id())
			if data.(common.MAVLinkMessage).Id() == 0 {
				statusCodes := map[uint8]string{
					1: "BOOT",
					2: "CALIBRATING",
					3: "STANDBY",
					4: "ACTIVE",
					5: "CRITICAL",
					6: "EMERGENCY",
					7: "POWEROFF",
					8: "ENUM_END",
				}
				summary.Status = statusCodes[data.(*common.Heartbeat).SYSTEM_STATUS]
				if summary.Status != "" {
					gobot.Publish(iris.Event("telemetry"), summary)
				}
			}

			if data.(common.MAVLinkMessage).Id() == 30 {
				roll := data.(*common.Attitude).ROLL
				pitch := data.(*common.Attitude).PITCH
				yaw := data.(*common.Attitude).YAW

				if roll < 4 || roll > -4 {
					summary.Roll = (roll * 180 / 3.14)
				}
				if yaw < 4 || roll > -4 {
					summary.Yaw = (yaw * 180 / 3.14)
				}
				if pitch < 4 || roll > -4 {
					summary.Pitch = (pitch * 180 / 3.14)
				}
				gobot.Publish(iris.Event("telemetry"), summary)
			}

			if data.(common.MAVLinkMessage).Id() == 33 {
				summary.Latitude = float32(data.(*common.GlobalPositionInt).LAT) / 10000000.0
				summary.Longitude = float32(data.(*common.GlobalPositionInt).LON) / 10000000.0
				summary.Altitude = data.(*common.GlobalPositionInt).ALT
				summary.Heading = float32(data.(*common.GlobalPositionInt).HDG) / 100
				gobot.Publish(iris.Event("telemetry"), summary)
			}
		})
	}

	gbot.AddRobot(gobot.NewRobot("irisBot",
		[]gobot.Connection{adaptor},
		[]gobot.Device{iris},
		work,
	))

	a.Start()
	gbot.Start()
}