Properly shut down EEBUS mdns entry (#2493)
This commit is contained in:
parent
518f937055
commit
10ac20f7e0
9 changed files with 119 additions and 22 deletions
|
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/cmd/shutdown"
|
||||
"github.com/evcc-io/evcc/server"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
@ -38,6 +39,9 @@ func runCharger(cmd *cobra.Command, args []string) {
|
|||
log.FATAL.Fatal(err)
|
||||
}
|
||||
|
||||
stopC := make(chan struct{})
|
||||
go shutdown.Run(stopC)
|
||||
|
||||
chargers := cp.chargers
|
||||
if len(args) == 1 {
|
||||
arg := args[0]
|
||||
|
|
@ -48,4 +52,7 @@ func runCharger(cmd *cobra.Command, args []string) {
|
|||
for name, v := range chargers {
|
||||
d.DumpWithHeader(name, v)
|
||||
}
|
||||
|
||||
close(stopC)
|
||||
<-shutdown.Done()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ package cmd
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/evcc-io/evcc/cmd/configure"
|
||||
"github.com/evcc-io/evcc/cmd/shutdown"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
|
@ -43,5 +47,24 @@ func runConfigure(cmd *cobra.Command, args []string) {
|
|||
|
||||
util.LogLevel(viper.GetString("log"), nil)
|
||||
|
||||
stopC := make(chan struct{})
|
||||
go shutdown.Run(stopC)
|
||||
|
||||
// catch signals
|
||||
go func() {
|
||||
signalC := make(chan os.Signal, 1)
|
||||
signal.Notify(signalC, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
<-signalC // wait for signal
|
||||
close(stopC) // signal loop to end
|
||||
|
||||
<-shutdown.Done()
|
||||
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
impl.Run(log, lang, advanced, expand)
|
||||
|
||||
close(stopC)
|
||||
<-shutdown.Done()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
certhelper "github.com/evcc-io/eebus/cert"
|
||||
"github.com/evcc-io/evcc/cmd/shutdown"
|
||||
"github.com/evcc-io/evcc/server"
|
||||
)
|
||||
|
||||
|
|
@ -13,13 +14,13 @@ func (c *CmdConfigure) configureEEBus(conf map[string]interface{}) error {
|
|||
var err error
|
||||
if server.EEBusInstance, err = server.NewEEBus(conf); err == nil {
|
||||
go server.EEBusInstance.Run()
|
||||
shutdown.Register(server.EEBusInstance.Shutdown)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// eebusCertificate setup EEBUS certificate
|
||||
// returns privagte key, public key and error
|
||||
// eebusCertificate creates EEBUS certificate and returns private/public key
|
||||
func (c *CmdConfigure) eebusCertificate() (map[string]interface{}, error) {
|
||||
details := server.EEBUSDetails
|
||||
|
||||
|
|
|
|||
|
|
@ -161,8 +161,7 @@ func (c *CmdConfigure) processDeviceRequirements(templateItem templates.Template
|
|||
return fmt.Errorf("%s: %s", c.localizedString("Requirements_EEBUS_Cert_Error", nil), err)
|
||||
}
|
||||
|
||||
err = c.configureEEBus(eebusConfig)
|
||||
if err != nil {
|
||||
if err := c.configureEEBus(eebusConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +169,7 @@ func (c *CmdConfigure) processDeviceRequirements(templateItem templates.Template
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.configuration.config.EEBUS = string(eebusYaml)
|
||||
fmt.Println()
|
||||
fmt.Println("--------------------------------------------")
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (c *CmdConfigure) askConfigFailureNextStep() bool {
|
|||
}
|
||||
|
||||
// select item from list
|
||||
func (c *CmdConfigure) askSelection(message string, items []string) (error, string, int) {
|
||||
func (c *CmdConfigure) askSelection(message string, items []string) (string, int, error) {
|
||||
selection := ""
|
||||
prompt := &survey.Select{
|
||||
Message: message,
|
||||
|
|
@ -47,19 +47,11 @@ func (c *CmdConfigure) askSelection(message string, items []string) (error, stri
|
|||
}
|
||||
|
||||
err := c.surveyAskOne(prompt, &selection)
|
||||
if err != nil {
|
||||
return err, "", 0
|
||||
if err == nil {
|
||||
return selection, funk.IndexOf(items, selection), nil
|
||||
}
|
||||
|
||||
var selectedIndex int
|
||||
for index, item := range items {
|
||||
if item == selection {
|
||||
selectedIndex = index
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err, selection, selectedIndex
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
// selectItem selects item from list
|
||||
|
|
@ -78,7 +70,7 @@ func (c *CmdConfigure) selectItem(deviceCategory DeviceCategory) templates.Templ
|
|||
}
|
||||
|
||||
text := fmt.Sprintf("%s %s %s:", c.localizedString("Choose", nil), DeviceCategories[deviceCategory].article, DeviceCategories[deviceCategory].title)
|
||||
err, _, selected := c.askSelection(text, items)
|
||||
_, selected, err := c.askSelection(text, items)
|
||||
if err != nil {
|
||||
c.log.FATAL.Fatal(err)
|
||||
}
|
||||
|
|
@ -88,7 +80,7 @@ func (c *CmdConfigure) selectItem(deviceCategory DeviceCategory) templates.Templ
|
|||
|
||||
// askChoice selects item from list
|
||||
func (c *CmdConfigure) askChoice(label string, choices []string) (int, string) {
|
||||
err, selection, index := c.askSelection(label, choices)
|
||||
selection, index, err := c.askSelection(label, choices)
|
||||
if err != nil {
|
||||
c.log.FATAL.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
18
cmd/root.go
18
cmd/root.go
|
|
@ -6,9 +6,11 @@ import (
|
|||
_ "net/http/pprof" // pprof handler
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/cmd/shutdown"
|
||||
"github.com/evcc-io/evcc/server"
|
||||
"github.com/evcc-io/evcc/server/updater"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
|
|
@ -233,15 +235,16 @@ func run(cmd *cobra.Command, args []string) {
|
|||
site.Prepare(valueChan, pushChan)
|
||||
|
||||
stopC := make(chan struct{})
|
||||
exitC := make(chan struct{})
|
||||
go shutdown.Run(stopC)
|
||||
|
||||
siteC := make(chan struct{})
|
||||
go func() {
|
||||
site.Run(stopC, conf.Interval)
|
||||
close(exitC)
|
||||
close(siteC)
|
||||
}()
|
||||
|
||||
// uds health check listener
|
||||
go server.HealthListener(site, exitC)
|
||||
go server.HealthListener(site, siteC)
|
||||
|
||||
// catch signals
|
||||
go func() {
|
||||
|
|
@ -251,6 +254,15 @@ func run(cmd *cobra.Command, args []string) {
|
|||
<-signalC // wait for signal
|
||||
close(stopC) // signal loop to end
|
||||
|
||||
exitC := make(chan struct{})
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(2)
|
||||
|
||||
// wait for main loop and shutdown functions to finish
|
||||
go func() { <-shutdown.Done(conf.Interval); wg.Done() }()
|
||||
go func() { <-siteC; wg.Done() }()
|
||||
go func() { wg.Wait(); close(exitC) }()
|
||||
|
||||
select {
|
||||
case <-exitC: // wait for loop to end
|
||||
case <-time.NewTimer(conf.Interval).C: // wait max 1 period
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
paho "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/api/proto/pb"
|
||||
"github.com/evcc-io/evcc/cmd/shutdown"
|
||||
"github.com/evcc-io/evcc/core"
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/evcc-io/evcc/hems"
|
||||
|
|
@ -164,6 +165,7 @@ func configureEEBus(conf map[string]interface{}) error {
|
|||
var err error
|
||||
if server.EEBusInstance, err = server.NewEEBus(conf); err == nil {
|
||||
go server.EEBusInstance.Run()
|
||||
shutdown.Register(server.EEBusInstance.Shutdown)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
53
cmd/shutdown/shutdown.go
Normal file
53
cmd/shutdown/shutdown.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package shutdown
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
handlers = make([]func(), 0)
|
||||
exitC = make(chan struct{})
|
||||
)
|
||||
|
||||
func Register(cb func()) {
|
||||
mu.Lock()
|
||||
handlers = append(handlers, cb)
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
func Run(stopC <-chan struct{}) {
|
||||
<-stopC
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
mu.Lock()
|
||||
for _, cb := range handlers {
|
||||
wg.Add(1)
|
||||
|
||||
go func(cb func()) {
|
||||
cb()
|
||||
wg.Done()
|
||||
}(cb)
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
wg.Wait()
|
||||
close(exitC)
|
||||
}
|
||||
|
||||
func Done(timeout ...time.Duration) <-chan struct{} {
|
||||
to := time.Second
|
||||
if len(timeout) == 1 {
|
||||
to = timeout[0]
|
||||
}
|
||||
|
||||
select {
|
||||
case <-exitC:
|
||||
return exitC
|
||||
case <-time.After(to):
|
||||
exitC := make(chan struct{})
|
||||
close(exitC)
|
||||
return exitC
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ type EEBus struct {
|
|||
log *util.Logger
|
||||
srv *server.Server
|
||||
id string
|
||||
zc *zeroconf.Server
|
||||
clients map[string]EEBusClientCBs
|
||||
connectedClients map[string]ship.Conn
|
||||
discoveredClients map[string]*zeroconf.ServiceEntry
|
||||
|
|
@ -90,11 +91,13 @@ func NewEEBus(other map[string]interface{}) (*EEBus, error) {
|
|||
Register: true,
|
||||
}
|
||||
|
||||
if _, err = srv.Announce(); err != nil {
|
||||
zc, err := srv.Announce()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &EEBus{
|
||||
zc: zc,
|
||||
log: log,
|
||||
srv: srv,
|
||||
id: id,
|
||||
|
|
@ -152,6 +155,10 @@ func (c *EEBus) Run() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *EEBus) Shutdown() {
|
||||
c.zc.Shutdown()
|
||||
}
|
||||
|
||||
func (c *EEBus) addDisoveredEntry(entry *zeroconf.ServiceEntry) {
|
||||
// we need to get the SKI only
|
||||
svc, err := mdns.NewFromDNSEntry(entry)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue