Skip to content

Commit

Permalink
Pass context
Browse files Browse the repository at this point in the history
  • Loading branch information
claes committed Dec 14, 2024
1 parent cfc9ca6 commit 7d84fbc
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 38 deletions.
2 changes: 1 addition & 1 deletion internal/bridge-cec.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (l *CecBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config Confi
return nil
}

func (l *CecBridgeWrapper) Run() error {
func (l *CecBridgeWrapper) Run(context context.Context) error {
go cecBridgeMainLoop(l.mqttClient, l.topicPrefix)
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion internal/bridge-mpd.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"log/slog"

mpdmqtt "github.com/claes/mpd-mqtt/lib"
Expand Down Expand Up @@ -32,7 +33,7 @@ func (l *MpdBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config Confi
return nil
}

func (l *MpdBridgeWrapper) Run() error {
func (l *MpdBridgeWrapper) Run(context context.Context) error {
go func() {
l.bridge.DetectReconnectMPDClient(l.config.MpdServer, l.mpdPassword)
}()
Expand Down
3 changes: 2 additions & 1 deletion internal/bridge-pulseaudio.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"log/slog"

pulsemqtt "github.com/claes/pulseaudio-mqtt/lib"
Expand All @@ -21,7 +22,7 @@ func (l *PulseaudioBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, confi
return nil
}

func (l *PulseaudioBridgeWrapper) Run() error {
func (l *PulseaudioBridgeWrapper) Run(context context.Context) error {
go l.bridge.MainLoop()
slog.Info("Pulseaudio bridge started")
return nil
Expand Down
3 changes: 2 additions & 1 deletion internal/bridge-rotel.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"log/slog"

rotelmqtt "github.com/claes/rotel-mqtt/lib"
Expand All @@ -24,7 +25,7 @@ func (l *RotelBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config Con
return nil
}

func (l *RotelBridgeWrapper) Run() error {
func (l *RotelBridgeWrapper) Run(context context.Context) error {
slog.Debug("Starting rotel bridge", "bridge", l.bridge)
go l.bridge.SerialLoop()
slog.Debug("Rotel bridge started")
Expand Down
3 changes: 2 additions & 1 deletion internal/bridge-routeros.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"log/slog"

routerosmqtt "github.com/claes/routeros-mqtt/lib"
Expand Down Expand Up @@ -36,7 +37,7 @@ func (l *RouterOSBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config
return nil
}

func (l *RouterOSBridgeWrapper) Run() error {
func (l *RouterOSBridgeWrapper) Run(context context.Context) error {
slog.Debug("Starting RouterOS bridge", "bridge", l.bridge)
go l.bridge.MainLoop()
slog.Debug("RouterOS bridge started")
Expand Down
4 changes: 3 additions & 1 deletion internal/bridge-samsung.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package regelverk

import (
"context"

samsungmqtt "github.com/claes/samsung-mqtt/lib"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
Expand All @@ -14,7 +16,7 @@ func (l *SamsungBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config C
return nil
}

func (l *SamsungBridgeWrapper) Run() error {
func (l *SamsungBridgeWrapper) Run(context context.Context) error {
go l.bridge.MainLoop()
return nil
}
3 changes: 2 additions & 1 deletion internal/bridge-snapcast.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"log/slog"

snapcastmqtt "github.com/claes/snapcast-mqtt/lib"
Expand All @@ -22,7 +23,7 @@ func (l *SnapcastBridgeWrapper) InitializeBridge(mqttClient mqtt.Client, config
return nil
}

func (l *SnapcastBridgeWrapper) Run() error {
func (l *SnapcastBridgeWrapper) Run(context context.Context) error {
go l.bridge.MainLoop()
slog.Info("Snapcast bridge started")
return nil
Expand Down
7 changes: 4 additions & 3 deletions internal/bridges.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package regelverk

import (
"context"
"log/slog"

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

type BridgeWrapper interface {
InitializeBridge(mqttClient mqtt.Client, config Config) error
Run() error
Run(context context.Context) error
}

func initBridges(mqttClient mqtt.Client, config Config, bridgeWrappers *[]BridgeWrapper) {
func initBridges(context context.Context, mqttClient mqtt.Client, config Config, bridgeWrappers *[]BridgeWrapper) {

for _, bridgeWrapper := range *bridgeWrappers {
slog.Debug("Initializing bridge", "bridgeWrapper", bridgeWrapper)
Expand All @@ -20,7 +21,7 @@ func initBridges(mqttClient mqtt.Client, config Config, bridgeWrappers *[]Bridge
slog.Error("Could not initialize bridge", "error", err, "bridgeWrapper", bridgeWrapper)
} else {
slog.Debug("Starting bridge", "bridgeWrapper", bridgeWrapper)
err = bridgeWrapper.Run()
err = bridgeWrapper.Run(context)
if err != nil {
slog.Error("Error when starting bridge", "error", err, "bridgeWrapper", bridgeWrapper)
} else {
Expand Down
17 changes: 12 additions & 5 deletions internal/cmd.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package regelverk

import (
"context"
"flag"
"fmt"
"log"
"log/slog"
"os"
"os/signal"
"sync"
)

func ParseConfig() (Config, *bool, *bool) {
Expand Down Expand Up @@ -70,22 +72,27 @@ func printHelp() {

func StartRegelverk(config Config, loops []ControlLoop, bridgeWrappers *[]BridgeWrapper, controllers *[]Controller,
dryRun *bool, debug *bool) {

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
slog.Info("Initializing Regelverk", "config", config)
err := Regelverk(config, loops, bridgeWrappers, controllers, dryRun, debug)
err := runRegelverk(ctx, config, loops, bridgeWrappers, controllers, dryRun, debug)
if err != nil {
slog.Error("Error initializing regelverk", "error", err)
os.Exit(1)
} else {
slog.Info("Initialized regelverk")
}
}()

slog.Info("Starting regelverk")
<-c
cancel()
wg.Wait()
slog.Info("Shut down regelverk")
os.Exit(0)
}
34 changes: 17 additions & 17 deletions internal/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ func (c *BaseController) ProcessEvent(ev MQTTEvent) []MQTTPublish {
c.addEventsToPublish(eventHandler(ev))
}

slog.Info("Fire event", "name", c.name)
slog.Debug("Fire event", "name", c.name)
beforeState := c.stateMachine.MustState()
c.stateMachine.Fire("mqttEvent", ev)

eventsToPublish := c.getAndResetEventsToPublish()
slog.Info("Event fired", "fsm", c.name, "beforeState", beforeState,
slog.Debug("Event fired", "fsm", c.name, "beforeState", beforeState,
"afterState", c.stateMachine.MustState())
return eventsToPublish
}
Expand Down Expand Up @@ -141,71 +141,71 @@ func (masterController *MasterController) ProcessEvent(client mqtt.Client, ev MQ

func (l *MasterController) guardStateSnapcastOn(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrue("snapcast")
slog.Info("guardStateSnapcastOn", "check", check)
slog.Debug("guardStateSnapcastOn", "check", check)
return check
}

func (l *MasterController) guardStateSnapcastOff(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireFalse("snapcast")
slog.Info("guardStateSnapcastOff", "check", check)
slog.Debug("guardStateSnapcastOff", "check", check)
return check
}

func (l *MasterController) guardTurnOnLivingroomLamp(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrue("phonePresent") &&
l.stateValueMap.requireTrue("nighttime") &&
l.stateValueMap.requireTrueRecently("livingroomPresence", 10*time.Minute)
slog.Info("guardTurnOnLamp", "check", check)
slog.Debug("guardTurnOnLamp", "check", check)
return check
}

func (l *MasterController) guardTurnOffLivingroomLamp(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireFalse("phonePresent") ||
l.stateValueMap.requireFalse("nighttime") ||
l.stateValueMap.requireTrueNotRecently("livingroomPresence", 10*time.Minute)
slog.Info("guardTurnOffLamp", "check", check)
slog.Debug("guardTurnOffLamp", "check", check)
return check
}

func (l *MasterController) guardStateTvOn(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrue("tvpower")
slog.Info("guardStateTvOn", "check", check)
slog.Debug("guardStateTvOn", "check", check)
return check
}

func (l *MasterController) guardStateTvOff(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireFalse("tvpower")
slog.Info("guardStateTvOff", "check", check)
slog.Debug("guardStateTvOff", "check", check)
return check
}

func (l *MasterController) guardStateTvOffLong(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrueNotRecently("tvpower", 30*time.Minute)
slog.Info("guardStateTvOff", "check", check)
slog.Debug("guardStateTvOff", "check", check)
return check
}

func (l *MasterController) guardStateKitchenAmpOn(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrue("kitchenaudioplaying")
slog.Info("guardStateKitchenAmpOn", "check", check)
slog.Debug("guardStateKitchenAmpOn", "check", check)
return check
}

func (l *MasterController) guardStateKitchenAmpOff(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrueNotRecently("kitchenaudioplaying", 10*time.Minute)
slog.Info("guardStateKitchenAmpOn", "check", check)
slog.Debug("guardStateKitchenAmpOn", "check", check)
return check
}

func (l *MasterController) guardStateBedroomBlindsOpen(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireFalse("nighttime")
slog.Info("guardStateBedroomBlindsOpen", "check", check)
slog.Debug("guardStateBedroomBlindsOpen", "check", check)
return check
}

func (l *MasterController) guardStateBedroomBlindsClosed(_ context.Context, _ ...any) bool {
check := l.stateValueMap.requireTrue("nighttime")
slog.Info("guardStateBedroomBlindsClosed", "check", check)
slog.Debug("guardStateBedroomBlindsClosed", "check", check)
return check
}

Expand All @@ -217,7 +217,7 @@ func (l *MasterController) detectPhonePresent(ev MQTTEvent) {

err := json.Unmarshal(ev.Payload.([]byte), &wifiClients)
if err != nil {
slog.Info("Could not parse payload", "topic", "routeros/wificlients", "error", err)
slog.Error("Could not parse payload", "topic", "routeros/wificlients", "error", err)
return
}
found := false
Expand All @@ -227,7 +227,7 @@ func (l *MasterController) detectPhonePresent(ev MQTTEvent) {
break
}
}
slog.Info("detectPhonePresent", "phonePresent", found)
slog.Debug("detectPhonePresent", "phonePresent", found)
l.stateValueMap.setState("phonePresent", found)
}
}
Expand Down Expand Up @@ -261,7 +261,7 @@ func (l *MasterController) detectTVPower(ev MQTTEvent) {
if ev.Topic == "regelverk/state/tvpower" {
tvPower, err := strconv.ParseBool(string(ev.Payload.([]byte)))
if err != nil {
slog.Info("Could not parse payload", "topic", "regelverk/state/tvpower", "error", err)
slog.Error("Could not parse payload", "topic", "regelverk/state/tvpower", "error", err)
}
l.stateValueMap.setState("tvpower", tvPower)
}
Expand All @@ -286,7 +286,7 @@ func (l *MasterController) detectKitchenAudioPlaying(ev MQTTEvent) {
var pulseaudioState pulseaudiomqtt.PulseAudioState
err := json.Unmarshal(ev.Payload.([]byte), &pulseaudioState)
if err != nil {
slog.Info("Could not parse payload", "topic", "kitchen/pulseaudio/state", "error", err)
slog.Error("Could not parse payload", "topic", "kitchen/pulseaudio/state", "error", err)
return
}
l.stateValueMap.setState("kitchenaudioplaying", pulseaudioState.DefaultSink.State == 0)
Expand Down
16 changes: 10 additions & 6 deletions internal/regelverk.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regelverk

import (
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -67,7 +68,7 @@ type MQTTMessageHandler struct {
dryRun bool
client mqtt.Client
loops []ControlLoop
masterController MasterController
masterController *MasterController
}

func (h *MQTTMessageHandler) handle(_ mqtt.Client, m mqtt.Message) {
Expand Down Expand Up @@ -113,7 +114,7 @@ func (h *MQTTMessageHandler) handleEvent(ev MQTTEvent) {
}
}

func createMQTTMessageHandler(config Config, loops []ControlLoop, masterController MasterController, dryRun, debug *bool) (*MQTTMessageHandler, error) {
func createMQTTMessageHandler(config Config, loops []ControlLoop, masterController *MasterController, dryRun, debug *bool) (*MQTTMessageHandler, error) {
host, err := os.Hostname()
if err != nil {
return nil, err
Expand Down Expand Up @@ -184,19 +185,20 @@ func createMQTTMessageHandler(config Config, loops []ControlLoop, masterControll
// }()
// }

func Regelverk(config Config, loops []ControlLoop, bridgeWrappers *[]BridgeWrapper, controllers *[]Controller,
func runRegelverk(ctx context.Context, config Config,
loops []ControlLoop, bridgeWrappers *[]BridgeWrapper, controllers *[]Controller,
dryRun, debug *bool) error {

masterController := CreateMasterController()
masterController.controllers = controllers

mqttMessageHandler, err := createMQTTMessageHandler(config, loops, masterController, dryRun, debug)
mqttMessageHandler, err := createMQTTMessageHandler(config, loops, &masterController, dryRun, debug)
if err != nil {
return err
}

slog.Info("Initializing bridges")
initBridges(mqttMessageHandler.client, config, bridgeWrappers)
initBridges(ctx, mqttMessageHandler.client, config, bridgeWrappers)

slog.Info("Initializing loops")
for _, l := range loops {
Expand All @@ -219,7 +221,9 @@ func Regelverk(config Config, loops []ControlLoop, bridgeWrappers *[]BridgeWrapp
}()

slog.Info("Started regelverk")
select {} // loop forever
<-ctx.Done()
slog.Info("Finishing regelverk")
return nil
}

func fileToString(filePath string) (string, error) {
Expand Down

0 comments on commit 7d84fbc

Please sign in to comment.