fix(pkg/rgb-led): complete rgb-led pkg

This commit is contained in:
Markus Pesch 2019-06-16 20:11:10 +02:00
parent 49d66cfcbb
commit 3436d6c91f
Signed by: volker.raschek
GPG Key ID: 852BCC170D81A982
11 changed files with 527 additions and 103 deletions

View File

@ -10,7 +10,7 @@ import (
) )
var enabled bool var enabled bool
var location, wireID, wirePath string var location string
var addRgbLedCmd = &cobra.Command{ var addRgbLedCmd = &cobra.Command{
Use: "add", Use: "add",
@ -27,7 +27,7 @@ flucky rgb-led add my-led GPIO13 GPIO17 GPIO26`),
} }
// determine gpio port // determine gpio port
gpioRed, err := types.StringToGPIO(args[1]) gpioBlue, err := types.StringToGPIO(args[1])
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
@ -37,7 +37,7 @@ flucky rgb-led add my-led GPIO13 GPIO17 GPIO26`),
log.Fatalln(err) log.Fatalln(err)
} }
gpioBlue, err := types.StringToGPIO(args[3]) gpioRed, err := types.StringToGPIO(args[3])
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
@ -47,10 +47,10 @@ flucky rgb-led add my-led GPIO13 GPIO17 GPIO26`),
RGBLEDName: args[0], RGBLEDName: args[0],
RGBLEDLocation: location, RGBLEDLocation: location,
RGBLEDEnabled: enabled, RGBLEDEnabled: enabled,
RGBLEDColorToGPIO: map[types.RGBColor]*types.GPIO{ BaseColorsToGPIO: map[types.BaseColor]*types.GPIO{
types.RGBLEDBlue: &gpioBlue, types.BaseColorBlue: &gpioBlue,
types.RGBLEDGreen: &gpioGreen, types.BaseColorGreen: &gpioGreen,
types.RGBLEDRed: &gpioRed, types.BaseColorRed: &gpioRed,
}, },
} }
@ -73,6 +73,4 @@ func init() {
addRgbLedCmd.Flags().BoolVarP(&enabled, "enabled", "e", true, "Enable Sensor") addRgbLedCmd.Flags().BoolVarP(&enabled, "enabled", "e", true, "Enable Sensor")
addRgbLedCmd.Flags().StringVarP(&location, "location", "l", "", "Sensor location") addRgbLedCmd.Flags().StringVarP(&location, "location", "l", "", "Sensor location")
addRgbLedCmd.Flags().StringVarP(&wireID, "wire-id", "i", "", "Wire-ID")
addRgbLedCmd.Flags().StringVarP(&wirePath, "wire-path", "w", "/sys/bus/w1/devices", "Wire device path")
} }

41
cmd/rgbled/off.go Normal file
View File

@ -0,0 +1,41 @@
package rgbled
import (
"log"
"github.com/go-flucky/flucky/pkg/config"
"github.com/go-flucky/flucky/pkg/rgbled"
"github.com/spf13/cobra"
)
var offRgbLedCmd = &cobra.Command{
Use: "off",
Short: "Turn a RGB-LED color off",
Example: `flucky rgb-led off <name/uuid> <blue>
flucky rgb-led off my-led`,
Run: func(cmd *cobra.Command, args []string) {
// read configuration
cnf, err := config.Read(configFile)
if err != nil {
log.Fatalln(err)
}
rgbLEDs := make([]rgbled.RGBLED, 0)
if len(args) != 0 {
rgbLEDs = cnf.GetRGBLEDsByName(args)
} else {
rgbLEDs = cnf.GetRGBLEDs(config.ENABLED)
}
err = rgbled.Off(rgbLEDs)
if err != nil {
log.Fatalln(err)
}
},
}
func init() {
rgbLedCmd.AddCommand(offRgbLedCmd)
}

50
cmd/rgbled/on.go Normal file
View File

@ -0,0 +1,50 @@
package rgbled
import (
"log"
"github.com/go-flucky/flucky/pkg/config"
"github.com/go-flucky/flucky/pkg/rgbled"
"github.com/go-flucky/flucky/pkg/types"
"github.com/spf13/cobra"
)
var onRgbLedCmd = &cobra.Command{
Use: "on",
Short: "Turn a RGB-LED color on",
Example: `flucky rgb-led on <names/uuids> <blue/green/purple/red/turquoise/white/yellow>
flucky rgb-led on my-led blue
flucky rgb-led on my-led my-sweet-led white
flucky rgb-led on 1c5b9424-f6e9-4a37-be5c-77e531e94aab red`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
// read configuration
cnf, err := config.Read(configFile)
if err != nil {
log.Fatalln(err)
}
rgbLEDs := make([]rgbled.RGBLED, 0)
if len(args) > 1 {
rgbLEDs = cnf.GetRGBLEDsByName(args[0 : len(args)-1])
} else {
rgbLEDs = cnf.GetRGBLEDs(config.ENABLED)
}
color, err := types.StrintToLEDColor(args[len(args)-1])
if err != nil {
log.Fatalln(err)
}
err = rgbled.CustomColor(rgbLEDs, color)
if err != nil {
log.Fatalln(err)
}
},
}
func init() {
rgbLedCmd.AddCommand(onRgbLedCmd)
}

View File

@ -77,7 +77,7 @@ func PrintRGBLEDs(cnf *config.Configuration, w io.Writer) {
fmt.Fprintln(tw, "name\tlocation\tblue\tgreen\tred\tenabled") fmt.Fprintln(tw, "name\tlocation\tblue\tgreen\tred\tenabled")
for _, rgbled := range cnf.RGBLEDs { for _, rgbled := range cnf.RGBLEDs {
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\n", rgbled.RGBLEDName, rgbled.RGBLEDLocation, *rgbled.RGBLEDColorToGPIO[types.RGBLEDBlue], *rgbled.RGBLEDColorToGPIO[types.RGBLEDGreen], *rgbled.RGBLEDColorToGPIO[types.RGBLEDRed], rgbled.RGBLEDEnabled) fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\n", rgbled.RGBLEDName, rgbled.RGBLEDLocation, *rgbled.BaseColorsToGPIO[types.BaseColorBlue], *rgbled.BaseColorsToGPIO[types.BaseColorGreen], *rgbled.BaseColorsToGPIO[types.BaseColorRed], rgbled.RGBLEDEnabled)
} }
tw.Flush() tw.Flush()

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/go-flucky/flucky/pkg/rgbled"
"github.com/go-flucky/flucky/pkg/sensor" "github.com/go-flucky/flucky/pkg/sensor"
"github.com/go-flucky/flucky/pkg/types" "github.com/go-flucky/flucky/pkg/types"
@ -308,6 +309,51 @@ func (c *Configuration) GetHumiditySensorsByName(names []string) []sensor.Humidi
return c.convertHumiditySensors(humiditySensors) return c.convertHumiditySensors(humiditySensors)
} }
func (c *Configuration) GetRGBLEDs(option Option) []rgbled.RGBLED {
rgbLEDs := c.RGBLEDs
switch option {
case ENABLED:
for i, rgbLED := range c.RGBLEDs {
if !rgbLED.RGBLEDEnabled {
rgbLEDs = append(rgbLEDs[:i], rgbLEDs[i+1:]...)
}
}
return c.convertRGBLEDs(rgbLEDs)
case DISABLED:
for i, rgbLED := range c.RGBLEDs {
if rgbLED.RGBLEDEnabled {
rgbLEDs = append(rgbLEDs[:i], rgbLEDs[i+1:]...)
}
}
return c.convertRGBLEDs(rgbLEDs)
default:
return c.convertRGBLEDs(rgbLEDs)
}
}
func (c *Configuration) GetRGBLEDsByName(names []string) []rgbled.RGBLED {
configRGBLEDs := make(map[string]*types.RGBLED, 0)
for _, name := range names {
for _, led := range c.RGBLEDs {
switch name {
case led.RGBLEDID:
configRGBLEDs[led.RGBLEDID] = led
case led.RGBLEDName:
configRGBLEDs[led.RGBLEDID] = led
}
}
}
rgbLEDs := make([]*types.RGBLED, 0)
for _, rgbLED := range configRGBLEDs {
rgbLEDs = append(rgbLEDs, rgbLED)
}
return c.convertRGBLEDs(rgbLEDs)
}
// GetTemperatureSensors returns a list of temperature sensors // GetTemperatureSensors returns a list of temperature sensors
func (c *Configuration) GetTemperatureSensors(option Option) []sensor.TemperatureSensor { func (c *Configuration) GetTemperatureSensors(option Option) []sensor.TemperatureSensor {
temperatureSensors := c.getTemperatureSensors() temperatureSensors := c.getTemperatureSensors()
@ -457,6 +503,18 @@ func (c *Configuration) convertHumiditySensors(sensors []*types.Sensor) []sensor
return humiditySensors return humiditySensors
} }
func (c *Configuration) convertRGBLEDs(rgbLEDs []*types.RGBLED) []rgbled.RGBLED {
leds := make([]rgbled.RGBLED, 0)
for _, rgbLED := range rgbLEDs {
leds = append(leds, &rgbled.LED{
RGBLED: rgbLED,
})
}
return leds
}
func (c *Configuration) convertTemperatureSensors(sensors []*types.Sensor) []sensor.TemperatureSensor { func (c *Configuration) convertTemperatureSensors(sensors []*types.Sensor) []sensor.TemperatureSensor {
temperatureSensors := make([]sensor.TemperatureSensor, 0) temperatureSensors := make([]sensor.TemperatureSensor, 0)

View File

@ -1,71 +0,0 @@
package led
import (
"fmt"
"github.com/go-flucky/flucky/pkg/types"
"github.com/stianeikeland/go-rpio"
)
type LED interface {
On() error
Off() error
Toggel() error
}
type RGBLED struct {
*types.LED
}
func (l *RGBLED) On() error {
if err := rpio.Open(); err != nil {
return fmt.Errorf("Can not open rpio: %v", err)
}
defer rpio.Close()
gpio, err := types.GPIOToInt(*l.GPIONumber)
if err != nil {
return fmt.Errorf("Can not determine %v into integer: %v", l.GPIONumber, err)
}
pin := rpio.Pin(gpio)
pin.High()
return nil
}
func (l *RGBLED) Off() error {
if err := rpio.Open(); err != nil {
return fmt.Errorf("Can not open rpio: %v", err)
}
defer rpio.Close()
gpio, err := types.GPIOToInt(*l.GPIONumber)
if err != nil {
return fmt.Errorf("Can not determine %v into integer: %v", l.GPIONumber, err)
}
pin := rpio.Pin(gpio)
pin.Low()
return nil
}
func (l *RGBLED) Toggel() error {
if err := rpio.Open(); err != nil {
return fmt.Errorf("Can not open rpio: %v", err)
}
defer rpio.Close()
gpio, err := types.GPIOToInt(*l.GPIONumber)
if err != nil {
return fmt.Errorf("Can not determine %v into integer: %v", l.GPIONumber, err)
}
pin := rpio.Pin(gpio)
pin.Toggle()
return nil
}

12
pkg/rgbled/interfaces.go Normal file
View File

@ -0,0 +1,12 @@
package rgbled
type RGBLED interface {
Blue(on bool) error
Green(on bool) error
Off() error
Purple(on bool) error
Red(on bool) error
Turquoise(on bool) error
White(on bool) error
Yellow(on bool) error
}

169
pkg/rgbled/led.go Normal file
View File

@ -0,0 +1,169 @@
package rgbled
import (
"fmt"
"github.com/go-flucky/flucky/pkg/types"
"github.com/stianeikeland/go-rpio"
)
type LED struct {
*types.RGBLED
}
func (l *LED) Blue(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorBlue],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) Green(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorGreen],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) Off() error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorBlue],
l.BaseColorsToGPIO[types.BaseColorGreen],
l.BaseColorsToGPIO[types.BaseColorRed],
}
if err := l.operate(gpios, false); err != nil {
return fmt.Errorf("Can not turn GPIOs off: %v", err)
}
return nil
}
func (l *LED) Purple(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorBlue],
l.BaseColorsToGPIO[types.BaseColorRed],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) Red(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorRed],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) Turquoise(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorBlue],
l.BaseColorsToGPIO[types.BaseColorGreen],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) White(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorBlue],
l.BaseColorsToGPIO[types.BaseColorGreen],
l.BaseColorsToGPIO[types.BaseColorRed],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) Yellow(on bool) error {
gpios := []*types.GPIO{
l.BaseColorsToGPIO[types.BaseColorGreen],
l.BaseColorsToGPIO[types.BaseColorRed],
}
if err := l.Off(); err != nil {
return err
}
if err := l.operate(gpios, on); err != nil {
return fmt.Errorf("Can not operate with GPIOs: %v", err)
}
return nil
}
func (l *LED) operate(gpios []*types.GPIO, on bool) error {
if err := rpio.Open(); err != nil {
return fmt.Errorf("Cam not open rpio connection: %v", err)
}
defer rpio.Close()
for _, gpio := range gpios {
gpioInt, err := types.GPIOToInt(*gpio)
if err != nil {
return fmt.Errorf("Can not determine %v into integer: %v", gpio, err)
}
pin := rpio.Pin(gpioInt)
if on {
pin.High()
} else {
pin.Low()
}
}
return nil
}

129
pkg/rgbled/rgbled.go Normal file
View File

@ -0,0 +1,129 @@
package rgbled
import (
"sync"
"github.com/go-flucky/flucky/pkg/internal/collect"
"github.com/go-flucky/flucky/pkg/internal/prittyprint"
"github.com/go-flucky/flucky/pkg/types"
)
func Blue(rgbLEDs []RGBLED) error {
color := types.LEDColorBlue
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func CustomColor(rgbLEDs []RGBLED, color types.LEDColor) error {
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func Green(rgbLEDs []RGBLED) error {
color := types.LEDColorGreen
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func Off(rgbLEDs []RGBLED) error {
color := types.LEDColorNone
if err := operate(rgbLEDs, false, color); err != nil {
return err
}
return nil
}
func Purple(rgbLEDs []RGBLED) error {
color := types.LEDColorPurple
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func Red(rgbLEDs []RGBLED) error {
color := types.LEDColorRed
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func Turquoise(rgbLEDs []RGBLED) error {
color := types.LEDColorTurquoise
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func White(rgbLEDs []RGBLED) error {
color := types.LEDColorWhite
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func Yellow(rgbLEDs []RGBLED) error {
color := types.LEDColorYellow
if err := operate(rgbLEDs, true, color); err != nil {
return err
}
return nil
}
func operate(rgbLEDs []RGBLED, on bool, color types.LEDColor) error {
errorChannel := make(chan error, len(rgbLEDs))
wg := new(sync.WaitGroup)
wg.Add(len(rgbLEDs))
for _, rgbLED := range rgbLEDs {
go func(rgbLED RGBLED, color types.LEDColor, on bool, errorChannel chan<- error, wg *sync.WaitGroup) {
defer wg.Done()
var err error
switch color {
case types.LEDColorBlue:
err = rgbLED.Blue(on)
case types.LEDColorGreen:
err = rgbLED.Green(on)
case types.LEDColorPurple:
err = rgbLED.Purple(on)
case types.LEDColorNone:
err = rgbLED.Off()
case types.LEDColorRed:
err = rgbLED.Red(on)
case types.LEDColorTurquoise:
err = rgbLED.Turquoise(on)
case types.LEDColorWhite:
err = rgbLED.White(on)
case types.LEDColorYellow:
err = rgbLED.Yellow(on)
default:
err = rgbLED.Off()
}
if err != nil {
errorChannel <- err
}
}(rgbLED, color, on, errorChannel, wg)
}
wg.Wait()
errors := collect.Errors(errorChannel)
if len(errors) > 0 {
return prittyprint.FormatErrors(errors)
}
return nil
}

View File

@ -1,6 +1,9 @@
package types package types
import "time" import (
"fmt"
"time"
)
type LED struct { type LED struct {
LEDID string `json:"led_id"` LEDID string `json:"led_id"`
@ -14,39 +17,74 @@ type LED struct {
} }
type RGBLED struct { type RGBLED struct {
RGBLEDID string `json:"rgbled_id"` RGBLEDID string `json:"rgbled_id"`
RGBLEDName string `json:"rgbled_name"` RGBLEDName string `json:"rgbled_name"`
RGBLEDLocation string `json:"rgbled_location"` RGBLEDLocation string `json:"rgbled_location"`
RGBLEDColorToGPIO map[RGBColor]*GPIO `json:"color_to_gpio"` BaseColorsToGPIO map[BaseColor]*GPIO `json:"color_to_gpio"`
RGBLEDEnabled bool `json:"rgbled_enabled"` ActionMapping map[LEDOption]LEDColor `json:"action_mapping"`
DeviceID string `json:"device_id"` RGBLEDEnabled bool `json:"rgbled_enabled"`
CreationDate time.Time `json:"creation_date"` DeviceID string `json:"device_id"`
CreationDate time.Time `json:"creation_date"`
} }
type RGBColor string type BaseColor string
const ( const (
RGBLEDBlue RGBColor = "blue" BaseColorBlue BaseColor = "blue"
RGBLEDRed = "red" BaseColorRed BaseColor = "red"
RGBLEDGreen = "green" BaseColorGreen BaseColor = "green"
) )
type LEDColor string type LEDColor string
const ( const (
LEDBlue LEDColor = "blue" LEDColorBlue LEDColor = "blue"
LEDRed = "red" LEDColorGreen LEDColor = "green"
LEDGreen = "green" LEDColorNone LEDColor = "none"
LEDPurple = "purple" LEDColorPurple LEDColor = "purple"
LEDTurquoiseGravel = "turquoise gravel" LEDColorRed LEDColor = "red"
LEDYellow = "yellow" LEDColorTurquoise LEDColor = "turquoise"
LEDWhite = "white" LEDColorYellow LEDColor = "yellow"
LEDColorWhite LEDColor = "white"
) )
func StrintToLEDColor(color string) (LEDColor, error) {
switch color {
case "blue":
return LEDColorBlue, nil
case "red":
return LEDColorRed, nil
case "green":
return LEDColorGreen, nil
case "none":
return LEDColorNone, nil
case "purple":
return LEDColorPurple, nil
case "turquoise":
return LEDColorTurquoise, nil
case "yellow":
return LEDColorYellow, nil
case "white":
return LEDColorWhite, nil
default:
return LEDColorNone, fmt.Errorf("Can not convert color to const")
}
}
type LEDOption string type LEDOption string
const ( const (
LEDError LEDOption = "error" LEDError LEDOption = "error"
LEDWarn = "warn" LEDWarn = "warn"
LEDOk = "ok" LEDOk = "ok"
LEDSync = "sync"
LEDLogfile = "logfile"
) )
var DefaultActionMapping = map[LEDOption]LEDColor{
LEDError: LEDColorRed,
LEDWarn: LEDColorYellow,
LEDOk: LEDColorGreen,
LEDSync: LEDColorTurquoise,
LEDLogfile: LEDColorBlue,
}