first commit
This commit is contained in:
commit
a5a0434432
1126 changed files with 439481 additions and 0 deletions
23
Software/flogo/LICENSE
Normal file
23
Software/flogo/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2018 Jörg Grote
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
50
Software/flogo/README.md
Normal file
50
Software/flogo/README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Flogo.io library for GrovePi
|
||||
Details about TIBCO Flogo can be found on (http://flogo.io)
|
||||
|
||||
## Introduction
|
||||
This first two Activity can be used easily in any graphically defined Flogo Flow to execute a Digital Write or Read Temperature and Humidity on GrovePi Board.
|
||||
|
||||

|
||||
|
||||
## Install
|
||||
All you need to install the new Activity into your Flogo WebUI Environment is the GitHub Path to the Extension: e.g. github.com/DexterInd/GrovePi/Software/flogo/activities/grovepiDigitalWrite
|
||||
|
||||
Basically this needs match with the 'ref' in the Activity 'JSON'
|
||||
|
||||

|
||||
|
||||
select 'add new Activity'
|
||||
|
||||

|
||||
|
||||
This is visible in the Flow WebUI Server Console, but after a little while you will see the 'success' message within the WebUI.
|
||||
And you can start working with the new Activity.
|
||||
|
||||

|
||||
|
||||
## Activity Interfaces
|
||||
|
||||
### Digital Write
|
||||
|
||||
Input
|
||||
- pin integer pin number
|
||||
- value boolean true/false
|
||||
|
||||
Output
|
||||
- success boolean true/false
|
||||
|
||||
### DHT Read
|
||||
|
||||
Input
|
||||
- pin integer pin number
|
||||
|
||||
Output
|
||||
- temperature string
|
||||
- humidity string
|
||||
|
||||
## Remarks
|
||||
Based on the GOlang GrovePi Implemenation from Falco Tomasetti and [didrocks](https://github.com/didrocks)
|
||||
|
||||
You will need to install mrmorphic hwio library:
|
||||
go get github.com/mrmorphic/hwio
|
||||
|
||||
121
Software/flogo/activities/grovepiDHT/activity.go
Normal file
121
Software/flogo/activities/grovepiDHT/activity.go
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
package grovepiDHT
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/TIBCOSoftware/flogo-lib/core/activity"
|
||||
"github.com/TIBCOSoftware/flogo-lib/logger"
|
||||
"github.com/mrmorphic/hwio"
|
||||
)
|
||||
|
||||
// log is the default package logger
|
||||
var log = logger.GetLogger("activity-tibco-GrovePiDHT")
|
||||
|
||||
const (
|
||||
ivPin = "pin"
|
||||
ovTemperature = "temperature"
|
||||
ovHumidity = "humidity"
|
||||
|
||||
//Cmd format
|
||||
DHT_READ = 40
|
||||
)
|
||||
|
||||
type GrovePi struct {
|
||||
i2cmodule hwio.I2CModule
|
||||
i2cDevice hwio.I2CDevice
|
||||
}
|
||||
|
||||
// Activity is a Activity implementation
|
||||
type grovePiDWActivity struct {
|
||||
sync.Mutex
|
||||
metadata *activity.Metadata
|
||||
}
|
||||
|
||||
// NewActivity creates a new Activity
|
||||
func NewActivity(metadata *activity.Metadata) activity.Activity {
|
||||
return &grovePiDWActivity{metadata: metadata}
|
||||
}
|
||||
|
||||
// Metadata implements activity.Activity.Metadata
|
||||
func (a *grovePiDWActivity) Metadata() *activity.Metadata {
|
||||
return a.metadata
|
||||
}
|
||||
|
||||
// Eval implements activity.Activity.Eval
|
||||
func (a *grovePiDWActivity) Eval(context activity.Context) (done bool, err error) {
|
||||
|
||||
var pin byte
|
||||
|
||||
log.Debug("Starting Pin DHT read")
|
||||
if context.GetInput(ivPin) != nil {
|
||||
pin = byte(context.GetInput(ivPin).(int))
|
||||
}
|
||||
|
||||
var g *GrovePi
|
||||
g = InitGrovePi(0x04)
|
||||
defer g.CloseDevice()
|
||||
|
||||
t, h, err := g.ReadDHT(pin)
|
||||
if err != nil {
|
||||
log.Error("GrovePi ReadDHT Issue: ", err)
|
||||
}
|
||||
|
||||
context.SetOutput(ovTemperature, t)
|
||||
context.SetOutput(ovHumidity, h)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func InitGrovePi(address int) *GrovePi {
|
||||
grovePi := new(GrovePi)
|
||||
m, err := hwio.GetModule("i2c")
|
||||
if err != nil {
|
||||
log.Error("GrovePi :: could not get i2c module Error", err)
|
||||
//fmt.Printf("could not get i2c module: %s\n", err)
|
||||
return nil
|
||||
}
|
||||
grovePi.i2cmodule = m.(hwio.I2CModule)
|
||||
grovePi.i2cmodule.Enable()
|
||||
|
||||
grovePi.i2cDevice = grovePi.i2cmodule.GetDevice(address)
|
||||
return grovePi
|
||||
}
|
||||
|
||||
func (grovePi GrovePi) CloseDevice() {
|
||||
grovePi.i2cmodule.Disable()
|
||||
}
|
||||
|
||||
func (grovePi *GrovePi) ReadDHT(pin byte) (float32, float32, error) {
|
||||
b := []byte{DHT_READ, pin, 0, 0}
|
||||
rawdata, err := grovePi.readDHTRawData(b)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
temperatureData := rawdata[1:5]
|
||||
|
||||
tInt := int32(temperatureData[0]) | int32(temperatureData[1])<<8 | int32(temperatureData[2])<<16 | int32(temperatureData[3])<<24
|
||||
t := (*(*float32)(unsafe.Pointer(&tInt)))
|
||||
|
||||
humidityData := rawdata[5:9]
|
||||
humInt := int32(humidityData[0]) | int32(humidityData[1])<<8 | int32(humidityData[2])<<16 | int32(humidityData[3])<<24
|
||||
h := (*(*float32)(unsafe.Pointer(&humInt)))
|
||||
return t, h, nil
|
||||
}
|
||||
|
||||
func (grovePi *GrovePi) readDHTRawData(cmd []byte) ([]byte, error) {
|
||||
|
||||
err := grovePi.i2cDevice.Write(1, cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
time.Sleep(600 * time.Millisecond)
|
||||
grovePi.i2cDevice.ReadByte(1)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
raw, err := grovePi.i2cDevice.Read(1, 9)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
26
Software/flogo/activities/grovepiDHT/activity.json
Normal file
26
Software/flogo/activities/grovepiDHT/activity.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "grovepiDHT",
|
||||
"type": "flogo:activity",
|
||||
"ref": "github.com/DexterInd/GrovePi/Software/flogo/activities/grovepiDHT",
|
||||
"version": "0.0.1",
|
||||
"title": "grovepi DHT",
|
||||
"description": "DHT Activity for GrovePi to read current temperature and humidity",
|
||||
"homepage": "https://github.com/DexterInd/GrovePi/Software/flogo/",
|
||||
"inputs":[
|
||||
{
|
||||
"name": "pin",
|
||||
"type": "integer",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "temperature",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "humidity",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
67
Software/flogo/activities/grovepiDHT/activity_test.go
Normal file
67
Software/flogo/activities/grovepiDHT/activity_test.go
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
package grovepiDHT
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/TIBCOSoftware/flogo-contrib/action/flow/test"
|
||||
"github.com/TIBCOSoftware/flogo-lib/core/activity"
|
||||
)
|
||||
|
||||
var activityMetadata *activity.Metadata
|
||||
|
||||
func getActivityMetadata() *activity.Metadata {
|
||||
|
||||
if activityMetadata == nil {
|
||||
jsonMetadataBytes, err := ioutil.ReadFile("activity.json")
|
||||
if err != nil {
|
||||
panic("No Json Metadata found for activity.json path")
|
||||
}
|
||||
|
||||
activityMetadata = activity.NewMetadata(string(jsonMetadataBytes))
|
||||
}
|
||||
|
||||
return activityMetadata
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
|
||||
act := NewActivity(getActivityMetadata())
|
||||
|
||||
if act == nil {
|
||||
t.Error("Activity Not Created")
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestGrovePiDHT(t *testing.T) {
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Failed()
|
||||
t.Errorf("panic during execution: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
act := NewActivity(getActivityMetadata())
|
||||
tc := test.NewTestActivityContext(getActivityMetadata())
|
||||
|
||||
//setup attrs GrovePi Tester, using Pin 4
|
||||
tc.SetInput(ivPin, 4)
|
||||
|
||||
act.Eval(tc)
|
||||
|
||||
temp := tc.GetOutput(ovTemperature).(string)
|
||||
humi := tc.GetOutput(ovHumidity).(string)
|
||||
|
||||
assert.NotNil(t, temp)
|
||||
assert.NotNil(t, humi)
|
||||
|
||||
fmt.Printf("Temperature: %f - Humidity: %f\n", temp, humi)
|
||||
|
||||
}
|
||||
123
Software/flogo/activities/grovepiDigitalWrite/activity.go
Normal file
123
Software/flogo/activities/grovepiDigitalWrite/activity.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package grovepiDigitalWrite
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/TIBCOSoftware/flogo-lib/core/activity"
|
||||
"github.com/TIBCOSoftware/flogo-lib/logger"
|
||||
"github.com/mrmorphic/hwio"
|
||||
)
|
||||
|
||||
// log is the default package logger
|
||||
var log = logger.GetLogger("activity-tibco-GrovePi")
|
||||
|
||||
const (
|
||||
ivPin = "pin"
|
||||
ivValue = "value"
|
||||
ovSuccess = "success"
|
||||
|
||||
//Cmd format
|
||||
DIGITAL_WRITE = 2
|
||||
PIN_MODE = 5
|
||||
)
|
||||
|
||||
type GrovePi struct {
|
||||
i2cmodule hwio.I2CModule
|
||||
i2cDevice hwio.I2CDevice
|
||||
}
|
||||
|
||||
// Activity is a Activity implementation
|
||||
type grovePiDWActivity struct {
|
||||
sync.Mutex
|
||||
metadata *activity.Metadata
|
||||
}
|
||||
|
||||
// NewActivity creates a new Activity
|
||||
func NewActivity(metadata *activity.Metadata) activity.Activity {
|
||||
return &grovePiDWActivity{metadata: metadata}
|
||||
}
|
||||
|
||||
// Metadata implements activity.Activity.Metadata
|
||||
func (a *grovePiDWActivity) Metadata() *activity.Metadata {
|
||||
return a.metadata
|
||||
}
|
||||
|
||||
// Eval implements activity.Activity.Eval
|
||||
func (a *grovePiDWActivity) Eval(context activity.Context) (done bool, err error) {
|
||||
|
||||
var pin byte
|
||||
var value bool
|
||||
|
||||
log.Debug("Starting Pin Write")
|
||||
if context.GetInput(ivPin) != nil {
|
||||
pin = byte(context.GetInput(ivPin).(int))
|
||||
}
|
||||
if context.GetInput(ivValue) != nil {
|
||||
value = context.GetInput(ivValue).(bool)
|
||||
}
|
||||
|
||||
var g *GrovePi
|
||||
g = InitGrovePi(0x04)
|
||||
err = g.PinMode(pin, "output")
|
||||
if err != nil {
|
||||
log.Error("GrovePi :: Set PinMode Error", err)
|
||||
}
|
||||
|
||||
//write to GrovePi
|
||||
if value {
|
||||
g.DigitalWrite(pin, 1)
|
||||
} else {
|
||||
g.DigitalWrite(pin, 0)
|
||||
}
|
||||
|
||||
context.SetOutput(ovSuccess, true)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func InitGrovePi(address int) *GrovePi {
|
||||
grovePi := new(GrovePi)
|
||||
m, err := hwio.GetModule("i2c")
|
||||
if err != nil {
|
||||
log.Error("GrovePi :: could not get i2c module Error", err)
|
||||
//fmt.Printf("could not get i2c module: %s\n", err)
|
||||
return nil
|
||||
}
|
||||
grovePi.i2cmodule = m.(hwio.I2CModule)
|
||||
grovePi.i2cmodule.Enable()
|
||||
|
||||
grovePi.i2cDevice = grovePi.i2cmodule.GetDevice(address)
|
||||
return grovePi
|
||||
}
|
||||
|
||||
func (grovePi GrovePi) CloseDevice() {
|
||||
grovePi.i2cmodule.Disable()
|
||||
}
|
||||
|
||||
func (grovePi GrovePi) DigitalWrite(pin byte, val byte) error {
|
||||
b := []byte{DIGITAL_WRITE, pin, val, 0}
|
||||
err := grovePi.i2cDevice.Write(1, b)
|
||||
if err != nil {
|
||||
log.Error("GrovePi :: DigitalWrite Error", err)
|
||||
return err
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (grovePi GrovePi) PinMode(pin byte, mode string) error {
|
||||
var b []byte
|
||||
if mode == "output" {
|
||||
b = []byte{PIN_MODE, pin, 1, 0}
|
||||
} else {
|
||||
b = []byte{PIN_MODE, pin, 0, 0}
|
||||
}
|
||||
err := grovePi.i2cDevice.Write(1, b)
|
||||
if err != nil {
|
||||
log.Error("GrovePi :: i2cDevice.Write Error", err)
|
||||
return err
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
return nil
|
||||
}
|
||||
27
Software/flogo/activities/grovepiDigitalWrite/activity.json
Normal file
27
Software/flogo/activities/grovepiDigitalWrite/activity.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "grovepiDigitalWrite",
|
||||
"type": "flogo:activity",
|
||||
"ref": "github.com/DexterInd/GrovePi/Software/flogo/activities/grovepiDigitalWrite",
|
||||
"version": "0.0.1",
|
||||
"title": "grovepi Digital Write",
|
||||
"description": "Digital Write Activity for GrovePi",
|
||||
"homepage": "https://github.com/DexterInd/GrovePi/Software/flogo/",
|
||||
"inputs":[
|
||||
{
|
||||
"name": "pin",
|
||||
"type": "integer",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "boolean",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package grovepiDigitalWrite
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/TIBCOSoftware/flogo-contrib/action/flow/test"
|
||||
"github.com/TIBCOSoftware/flogo-lib/core/activity"
|
||||
)
|
||||
|
||||
var activityMetadata *activity.Metadata
|
||||
|
||||
func getActivityMetadata() *activity.Metadata {
|
||||
|
||||
if activityMetadata == nil {
|
||||
jsonMetadataBytes, err := ioutil.ReadFile("activity.json")
|
||||
if err != nil {
|
||||
panic("No Json Metadata found for activity.json path")
|
||||
}
|
||||
|
||||
activityMetadata = activity.NewMetadata(string(jsonMetadataBytes))
|
||||
}
|
||||
|
||||
return activityMetadata
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
|
||||
act := NewActivity(getActivityMetadata())
|
||||
|
||||
if act == nil {
|
||||
t.Error("Activity Not Created")
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestGrovePiDW(t *testing.T) {
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Failed()
|
||||
t.Errorf("panic during execution: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
act := NewActivity(getActivityMetadata())
|
||||
tc := test.NewTestActivityContext(getActivityMetadata())
|
||||
|
||||
//setup attrs GrovePi Tester, using Pin 3
|
||||
tc.SetInput(ivPin, 3)
|
||||
tc.SetInput(ivValue, false)
|
||||
|
||||
act.Eval(tc)
|
||||
|
||||
success := tc.GetOutput(ovSuccess).(bool)
|
||||
|
||||
if success != true {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
BIN
Software/flogo/screenshots/Flogo-GrovePi-Flow.png
Normal file
BIN
Software/flogo/screenshots/Flogo-GrovePi-Flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
Software/flogo/screenshots/Flogo-add-Activity.png
Normal file
BIN
Software/flogo/screenshots/Flogo-add-Activity.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
Software/flogo/screenshots/GrovePi-Extension-Install.png
Normal file
BIN
Software/flogo/screenshots/GrovePi-Extension-Install.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
Software/flogo/screenshots/GrovePi-Extension-Success.png
Normal file
BIN
Software/flogo/screenshots/GrovePi-Extension-Success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Loading…
Add table
Add a link
Reference in a new issue