Skip to content

Commit

Permalink
Implemented DI
Browse files Browse the repository at this point in the history
  • Loading branch information
mannkind committed Nov 20, 2018
1 parent 676bdbb commit 90064a2
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 177 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -27,7 +27,7 @@ build: format
$(GOBUILD) $(BINARY_VERSION_FLAGS) -o $(BINARY_NAME) -v
run: build
./$(BINARY_NAME)
docker:
docker: clean
{ \
set -e ;\
for arch in $(DOCKER_ARCHS); do \
Expand Down
17 changes: 8 additions & 9 deletions README.md
Expand Up @@ -12,31 +12,30 @@ A Firmware Uploading Tool for the MYSBootloader via MQTT

## Via Docker
```
docker run -d --name="mysb" -v /the/path/to/config_folder:/config -v /etc/localtime:/etc/localtime:ro mannkind/mysb
docker run -d --name="mysb" -v /etc/localtime:/etc/localtime:ro mannkind/mysb
```

## Via Make
```
git clone https://github.com/mannkind/mysb
cd mysb
make
MYSB_CONFIGFILE="config.yaml" ./mysb
./mysb
```

# Configuration

Configuration happens via environmental variables

```
MYSB_AUTOID - The flag that indicates Mysb should handle ID requests, defaults to false
MYSB_NEXTID - The number on which to base the next id, defaults to 1
MYSB_FIRMWAREBASEPATH - The path to the firmware files, defaults to "/config/firmware"
MYSB_CONFIG - The yaml config that contains control variables for Mysb
MYSB_NODES - The nodes configuration (see below)
MYSB_SUBTOPIC - [OPTIONAL] The MQTT topic on which to subscribe, defaults to "mysensors_rx"
MYSB_PUBTOPIC - [OPTIONAL] The MQTT topic on which to publish, defaults to "mysensors_tx"
MYSB_AUTOID - [OPTIONAL] The flag that indicates Mysb should handle ID requests, defaults to false
MYSB_NEXTID - [OPTIONAL] The number on which to base the next id, defaults to 1
MYSB_FIRMWAREBASEPATH - [OPTIONAL] The path to the firmware files, defaults to "/config/firmware"
MYSB_NODES - [OPTIONAL] The nodes configuration (see below)
MQTT_CLIENTID - [OPTIONAL] The clientId, defaults to "DefaultMysbClientID"
MQTT_BROKER - [OPTIONAL] The MQTT broker, defaults to "tcp://mosquitto.org:1883"
MQTT_SUBTOPIC - [OPTIONAL] The MQTT topic on which to subscribe, defaults to "mysensors_rx"
MQTT_PUBTOPIC - [OPTIONAL] The MQTT topic on which to publish, defaults to "mysensors_tx"
MQTT_USERNAME - [OPTIONAL] The MQTT username, default to ""
MQTT_PASSWORD - [OPTIONAL] The MQTT password, default to ""
```
Expand Down
62 changes: 62 additions & 0 deletions config.go
@@ -0,0 +1,62 @@
package main

import (
"log"
"reflect"

"github.com/caarlos0/env"
"gopkg.in/yaml.v2"
)

// Config - Structured configuration for the application.
type Config struct {
ClientID string `env:"MQTT_CLIENTID" envDefault:"DefaultMysbClientID"`
Broker string `env:"MQTT_BROKER" envDefault:"tcp://mosquitto.org:1883"`
Username string `env:"MQTT_USERNAME"`
Password string `env:"MQTT_PASSWORD"`
SubTopic string `env:"MYSB_SUBTOPIC" envDefault:"mysensors_rx"`
PubTopic string `env:"MYSB_PUBTOPIC" envDefault:"mysensors_tx"`
AutoIDEnabled bool `env:"MYSB_AUTOID" envDefault:"false"`
NextID uint `env:"MYSB_NEXTID" envDefault:"1"`
FirmwareBasePath string `env:"MYSB_FIRMWAREBASEPATH" envDefault:"/config/firmware"`
Nodes nodeSettingsMap `env:"MYSB_NODES"`
}

// NewConfig - Returns a new Config object with configuration from ENV variables.
func NewConfig() *Config {
c := Config{}

if err := env.ParseWithFuncs(&c, env.CustomParsers{
reflect.TypeOf(nodeSettingsMap{}): nodeSettingsParser,
}); err != nil {
log.Panicf("Error unmarshaling configuration: %s", err)
}

redactedPassword := ""
if len(c.Password) > 0 {
redactedPassword = "<REDACTED>"
}

log.Printf("Environmental Settings:")
log.Printf(" * ClientID : %s", c.ClientID)
log.Printf(" * Broker : %s", c.Broker)
log.Printf(" * SubTopic : %s", c.SubTopic)
log.Printf(" * PubTopic : %s", c.PubTopic)
log.Printf(" * Username : %s", c.Username)
log.Printf(" * Password : %s", redactedPassword)
log.Printf(" * AutoID : %t", c.AutoIDEnabled)
log.Printf(" * NextID : %d", c.NextID)
log.Printf(" * FirmwareBasePath: %s", c.FirmwareBasePath)
log.Printf(" * Nodes : %+v", c.Nodes)

return &c
}

func nodeSettingsParser(value string) (interface{}, error) {
c := make(nodeSettingsMap)
if err := yaml.Unmarshal([]byte(value), &c); err != nil {
log.Panicf("Error unmarshaling control configuration: %s", err)
}

return c, nil
}
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -4,6 +4,7 @@ require (
github.com/caarlos0/env v3.5.0+incompatible
github.com/eclipse/paho.mqtt.golang v1.1.1
github.com/kierdavis/ihex-go v0.0.0-20180105024510-bf28f2206797
go.uber.org/dig v1.6.0
golang.org/x/net v0.0.0-20181108082009-03003ca0c849 // indirect
gopkg.in/yaml.v2 v2.2.1
)
31 changes: 2 additions & 29 deletions go.sum
@@ -1,40 +1,13 @@
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eclipse/paho.mqtt.golang v1.1.1 h1:iPJYXJLaViCshRTW/PSqImSS6HJ2Rf671WR0bXZ2GIU=
github.com/eclipse/paho.mqtt.golang v1.1.1/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/kierdavis/ihex-go v0.0.0-20180105024510-bf28f2206797 h1:W3pEj5EglEQLUAMwE6PBm3Y1DZapp7AOsSeHeDZnTwI=
github.com/kierdavis/ihex-go v0.0.0-20180105024510-bf28f2206797/go.mod h1:XCg/J3R8D3GZvAYjJx0Q6R9OzF+fUgzYHu2exysdiIE=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.2.1 h1:bIcUwXqLseLF3BDAZduuNfekWG87ibtFxi59Bq+oI9M=
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
golang.org/x/net v0.0.0-20181107093936-a544f70c90f1 h1:SwqD3GJ9PsSBBVv1HlDeSwjjPSeZjUZQcAgGnwsWpyc=
golang.org/x/net v0.0.0-20181107093936-a544f70c90f1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
go.uber.org/dig v1.6.0 h1:SUxK4CpYs3SRlqTLku5uaXbiSmyycpSFZG6B/fJ8C+4=
go.uber.org/dig v1.6.0/go.mod h1:z+dSd2TP9Usi48jL8M3v63iSBVkiwtVyMKxMZYYauPg=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849 h1:FSqE2GGG7wzsYUsWiQ8MZrvEd1EOyU3NCF0AW3Wtltg=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg=
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
49 changes: 13 additions & 36 deletions main.go
Expand Up @@ -2,10 +2,8 @@ package main

import (
"log"
"reflect"

"github.com/caarlos0/env"
"gopkg.in/yaml.v2"
"go.uber.org/dig"
)

// Version - Set during compilation when using included Makefile
Expand All @@ -14,44 +12,23 @@ var Version = "X.X.X"
func main() {
log.Printf("Mysb Version: %s", Version)

log.Print("Stating Process")
controller := mysb{}
if err := env.ParseWithFuncs(&controller, env.CustomParsers{
reflect.TypeOf(nodeSettingsMap{}): nodeSettingsParser,
}); err != nil {
log.Panicf("Error unmarshaling configuration: %s", err)
}

redactedPassword := ""
if len(controller.Password) > 0 {
redactedPassword = "<REDACTED>"
}
c := buildContainer()
err := c.Invoke(func(m *Mysb) error {
return m.Run()
})

log.Printf("Environmental Settings:")
log.Printf(" * ClientID : %s", controller.ClientID)
log.Printf(" * Broker : %s", controller.Broker)
log.Printf(" * SubTopic : %s", controller.SubTopic)
log.Printf(" * PubTopic : %s", controller.PubTopic)
log.Printf(" * Username : %s", controller.Username)
log.Printf(" * Password : %s", redactedPassword)
log.Printf(" * AutoID : %t", controller.AutoIDEnabled)
log.Printf(" * NextID : %d", controller.NextID)
log.Printf(" * FirmwareBasePath: %s", controller.FirmwareBasePath)
log.Printf(" * Nodes : %+v", controller.Nodes)

if err := controller.start(); err != nil {
log.Panicf("Error starting mysb: %s", err)
if err != nil {
log.Panicf("Error starting mysb process: %s", err)
}

// log.Print("Ending Process")
select {}
}

func nodeSettingsParser(value string) (interface{}, error) {
control := make(nodeSettingsMap)
if err := yaml.Unmarshal([]byte(value), &control); err != nil {
log.Panicf("Error unmarshaling control configuration: %s", err)
}
func buildContainer() *dig.Container {
c := dig.New()
c.Provide(NewConfig)
c.Provide(NewMQTTFuncWrapper)
c.Provide(NewMysb)

return control, nil
return c
}
30 changes: 30 additions & 0 deletions mqtt.go
@@ -0,0 +1,30 @@
package main

import (
"github.com/eclipse/paho.mqtt.golang"
)

type newMqttClientOptsFunc func() *mqtt.ClientOptions
type newMqttClientFunc func(*mqtt.ClientOptions) mqtt.Client
type mqttDiscovery struct {
Name string `json:"name"`
StateTopic string `json:"state_topic"`
UniqueID string `json:"unique_id,omitempty"`
PayloadOn string `json:"payload_on,omitempty"`
PayloadOff string `json:"payload_off,omitempty"`
DeviceClass string `json:"device_class,omitempty"`
}

// MQTTFuncWrapper - Wraps the functions needed to create a new MQTT client.
type MQTTFuncWrapper struct {
clientOptsFunc newMqttClientOptsFunc
clientFunc newMqttClientFunc
}

// NewMQTTFuncWrapper - Returns a fancy new wrapper for the mqtt creation functions.
func NewMQTTFuncWrapper() *MQTTFuncWrapper {
return &MQTTFuncWrapper{
clientOptsFunc: mqtt.NewClientOptions,
clientFunc: mqtt.NewClient,
}
}

0 comments on commit 90064a2

Please sign in to comment.