From e616b634b5cf2575b66ad21bbb695649223053e6 Mon Sep 17 00:00:00 2001 From: Joshua Rich Date: Sun, 1 Oct 2023 08:29:36 +0000 Subject: [PATCH] refactor(agent,device): merge code into agent to simplify logic --- internal/agent/agent.go | 40 ++++++++++++------ internal/agent/config.go | 8 ---- internal/agent/device_linux.go | 24 ++++++++++- internal/agent/interfaces.go | 41 +++++++++++++++++++ ...Config_test.go => mockAgentConfig_test.go} | 0 ...ck_AgentUI_test.go => mockAgentUI_test.go} | 0 internal/agent/register.go | 2 +- internal/config/config_linux.go | 33 --------------- internal/device/device.go | 41 ------------------- internal/device/interfaces.go | 16 ++++++++ 10 files changed, 108 insertions(+), 97 deletions(-) create mode 100644 internal/agent/interfaces.go rename internal/agent/{mock_agentConfig_test.go => mockAgentConfig_test.go} (100%) rename internal/agent/{mock_AgentUI_test.go => mockAgentUI_test.go} (100%) delete mode 100644 internal/config/config_linux.go delete mode 100644 internal/device/device.go create mode 100644 internal/device/interfaces.go diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 49cbfccfe..7916368c3 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -15,12 +15,11 @@ import ( "sync" "syscall" - deviceConfig "github.com/joshuar/go-hass-agent/internal/config" + "github.com/joshuar/go-hass-agent/internal/device" "github.com/joshuar/go-hass-agent/internal/hass/api" "github.com/joshuar/go-hass-agent/internal/agent/config" "github.com/joshuar/go-hass-agent/internal/agent/ui" - "github.com/joshuar/go-hass-agent/internal/device" "github.com/joshuar/go-hass-agent/internal/tracker" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -48,14 +47,6 @@ type Agent struct { headless bool } -//go:generate moq -out mock_AgentUI_test.go . AgentUI -type AgentUI interface { - DisplayNotification(string, string) - DisplayTrayIcon(context.Context, ui.Agent) - DisplayRegistrationWindow(context.Context, ui.Agent, chan struct{}) - Run() -} - // AgentOptions holds options taken from the command-line that was used to // invoke go-hass-agent that are relevant for agent functionality. type AgentOptions struct { @@ -114,9 +105,7 @@ func Run(options AgentOptions) { wg.Add(1) go func() { defer wg.Done() - sensorWorkers := deviceConfig.SensorWorkers() - sensorWorkers = append(sensorWorkers, device.ExternalIPUpdater) - device.StartWorkers(ctx, agent.sensors, sensorWorkers...) + agent.startWorkers(ctx) }() wg.Add(1) go func() { @@ -281,3 +270,28 @@ func (agent *Agent) SensorList() []string { func (agent *Agent) SensorValue(id string) (tracker.Sensor, error) { return agent.sensors.Get(id) } + +// StartWorkers will call all the sensor worker functions that have been defined +// for this device. +func (agent *Agent) startWorkers(ctx context.Context) { + wokerFuncs := sensorWorkers() + wokerFuncs = append(wokerFuncs, device.ExternalIPUpdater) + + workerCh := make(chan func(context.Context, device.SensorTracker), len(wokerFuncs)) + + for i := 0; i < len(workerCh); i++ { + workerCh <- wokerFuncs[i] + } + + var wg sync.WaitGroup + for _, workerFunc := range wokerFuncs { + wg.Add(1) + go func(workerFunc func(context.Context, device.SensorTracker)) { + defer wg.Done() + workerFunc(ctx, agent.sensors) + }(workerFunc) + } + + close(workerCh) + wg.Wait() +} diff --git a/internal/agent/config.go b/internal/agent/config.go index 0c3f4c5a1..4c8fd22ee 100644 --- a/internal/agent/config.go +++ b/internal/agent/config.go @@ -23,14 +23,6 @@ const ( webHookPath = "/api/webhook/" ) -//go:generate moq -out mock_agentConfig_test.go . AgentConfig -type AgentConfig interface { - Get(string, interface{}) error - Set(string, interface{}) error - Delete(string) error - StoragePath(string) (string, error) -} - // ValidateConfig takes an agentConfig and ensures that it meets the minimum // requirements for the agent to function correctly func ValidateConfig(c AgentConfig) error { diff --git a/internal/agent/device_linux.go b/internal/agent/device_linux.go index b4ad5e98b..378419441 100644 --- a/internal/agent/device_linux.go +++ b/internal/agent/device_linux.go @@ -8,9 +8,31 @@ package agent import ( "context" + "github.com/joshuar/go-hass-agent/internal/device" "github.com/joshuar/go-hass-agent/internal/linux" ) -func (agent *Agent) setupDevice(ctx context.Context) *linux.LinuxDevice { +func newDevice(ctx context.Context) *linux.LinuxDevice { return linux.NewDevice(ctx, name, version) } + +// sensorWorkers returns a list of functions to start to enable sensor tracking. +func sensorWorkers() []func(context.Context, device.SensorTracker) { + var workers []func(context.Context, device.SensorTracker) + workers = append(workers, + linux.LocationUpdater, + linux.BatteryUpdater, + linux.AppUpdater, + linux.NetworkConnectionsUpdater, + linux.NetworkStatsUpdater, + linux.PowerUpater, + linux.ProblemsUpdater, + linux.MemoryUpdater, + linux.LoadAvgUpdater, + linux.DiskUsageUpdater, + linux.TimeUpdater, + linux.ScreenLockUpdater, + linux.UsersUpdater, + linux.Versions) + return workers +} diff --git a/internal/agent/interfaces.go b/internal/agent/interfaces.go new file mode 100644 index 000000000..861eea7d4 --- /dev/null +++ b/internal/agent/interfaces.go @@ -0,0 +1,41 @@ +// Copyright (c) 2023 Joshua Rich +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +package agent + +import ( + "context" + + "github.com/joshuar/go-hass-agent/internal/agent/ui" +) + +// AgentConfig represents the methods that the agent uses to interact with +// its config. It is effectively a CRUD interface to wherever the configuration +// is stored. +// +//go:generate moq -out mockAgentConfig_test.go . AgentConfig +type AgentConfig interface { + Get(string, interface{}) error + Set(string, interface{}) error + Delete(string) error + StoragePath(string) (string, error) +} + +// AgentUI are the methods required for the agent to display its windows, tray +// and notifications +// +//go:generate moq -out mockAgentUI_test.go . AgentUI +type AgentUI interface { + DisplayNotification(string, string) + DisplayTrayIcon(context.Context, ui.Agent) + DisplayRegistrationWindow(context.Context, ui.Agent, chan struct{}) + Run() +} + +//go:generate moq -out mockDevice.go . Device +type Device interface { + DeviceName() string + DeviceID() string +} diff --git a/internal/agent/mock_agentConfig_test.go b/internal/agent/mockAgentConfig_test.go similarity index 100% rename from internal/agent/mock_agentConfig_test.go rename to internal/agent/mockAgentConfig_test.go diff --git a/internal/agent/mock_AgentUI_test.go b/internal/agent/mockAgentUI_test.go similarity index 100% rename from internal/agent/mock_AgentUI_test.go rename to internal/agent/mockAgentUI_test.go diff --git a/internal/agent/register.go b/internal/agent/register.go index c81a48171..55d374866 100644 --- a/internal/agent/register.go +++ b/internal/agent/register.go @@ -102,7 +102,7 @@ func (agent *Agent) registrationProcess(ctx context.Context, server, token strin } } - device := agent.setupDevice(ctx) + device := newDevice(ctx) if !headless { userInputDone := make(chan struct{}) agent.ui.DisplayRegistrationWindow(ctx, agent, userInputDone) diff --git a/internal/config/config_linux.go b/internal/config/config_linux.go deleted file mode 100644 index 1056d1623..000000000 --- a/internal/config/config_linux.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2023 Joshua Rich -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -package config - -import ( - "context" - - "github.com/joshuar/go-hass-agent/internal/device" - "github.com/joshuar/go-hass-agent/internal/linux" -) - -// SensorWorkers returns a list of functions to start to enable sensor tracking. -func SensorWorkers() []func(context.Context, device.SensorTracker) { - var workers []func(context.Context, device.SensorTracker) - workers = append(workers, linux.LocationUpdater) - workers = append(workers, linux.BatteryUpdater) - workers = append(workers, linux.AppUpdater) - workers = append(workers, linux.NetworkConnectionsUpdater) - workers = append(workers, linux.NetworkStatsUpdater) - workers = append(workers, linux.PowerUpater) - workers = append(workers, linux.ProblemsUpdater) - workers = append(workers, linux.MemoryUpdater) - workers = append(workers, linux.LoadAvgUpdater) - workers = append(workers, linux.DiskUsageUpdater) - workers = append(workers, linux.TimeUpdater) - workers = append(workers, linux.ScreenLockUpdater) - workers = append(workers, linux.UsersUpdater) - workers = append(workers, linux.Versions) - return workers -} diff --git a/internal/device/device.go b/internal/device/device.go deleted file mode 100644 index d6cedf137..000000000 --- a/internal/device/device.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2023 Joshua Rich -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -package device - -import ( - "context" - "sync" -) - -// SensorTracker is the interface through which a device can update its sensors. -type SensorTracker interface { - // UpdateSensors will take any number of sensor updates and pass them on to - // the sensor tracker, which will handle updating its internal database and - // Home Assistant. - UpdateSensors(context.Context, ...interface{}) error -} - -// StartWorkers will call all the sensor worker functions that have been defined -// for this device. -func StartWorkers(ctx context.Context, tracker SensorTracker, workers ...func(context.Context, SensorTracker)) { - workerCh := make(chan func(context.Context, SensorTracker), len(workers)) - - for i := 0; i < len(workerCh); i++ { - workerCh <- workers[i] - } - - var wg sync.WaitGroup - for _, workerFunc := range workers { - wg.Add(1) - go func(workerFunc func(context.Context, SensorTracker)) { - defer wg.Done() - workerFunc(ctx, tracker) - }(workerFunc) - } - - close(workerCh) - wg.Wait() -} diff --git a/internal/device/interfaces.go b/internal/device/interfaces.go new file mode 100644 index 000000000..86f363e58 --- /dev/null +++ b/internal/device/interfaces.go @@ -0,0 +1,16 @@ +// Copyright (c) 2023 Joshua Rich +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +package device + +import "context" + +// SensorTracker is the interface through which a device can update its sensors. +type SensorTracker interface { + // UpdateSensors will take any number of sensor updates and pass them on to + // the sensor tracker, which will handle updating its internal database and + // Home Assistant. + UpdateSensors(context.Context, ...interface{}) error +}