Skip to content

Commit

Permalink
refactor(linux): 🔥 remove busRequest concept
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuar committed May 20, 2024
1 parent 2af72ae commit eafb883
Show file tree
Hide file tree
Showing 16 changed files with 93 additions and 232 deletions.
5 changes: 1 addition & 4 deletions internal/linux/apps/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,13 @@ func Updater(ctx context.Context) chan sensor.Details {
defer close(sensorCh)
activeApp := newActiveAppSensor()
runningApps := newRunningAppsSensor()
appListReq := dbusx.NewBusRequest(ctx, dbusx.SessionBus).
Path(appStateDBusPath).
Destination(portalDest)
for {
select {
case <-ctx.Done():
log.Debug().Msg("Stopped app sensor.")
return
case <-eventCh:
appList, err := dbusx.GetData[map[string]dbus.Variant](appListReq, appStateDBusMethod)
appList, err := dbusx.GetData[map[string]dbus.Variant](ctx, dbusx.SessionBus, appStateDBusPath, portalDest, appStateDBusMethod)
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve app list from D-Bus.")
}
Expand Down
11 changes: 2 additions & 9 deletions internal/linux/battery/battery.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,7 @@ func (b *upowerBattery) getProp(ctx context.Context, t linux.SensorTypeValue) (d
if !b.dBusPath.IsValid() {
return dbus.MakeVariant(""), errors.New("invalid battery path")
}
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(b.dBusPath).
Destination(upowerDBusDest)
return dbusx.GetProp[dbus.Variant](req, dBusSensorToProps[t])
return dbusx.GetProp[dbus.Variant](ctx, dbusx.SystemBus, string(b.dBusPath), upowerDBusDest, dBusSensorToProps[t])
}

// getSensors retrieves the sensors passed in for a given battery.
Expand All @@ -101,7 +98,6 @@ func newBattery(ctx context.Context, path dbus.ObjectPath) (*upowerBattery, erro
dBusPath: path,
}


// Get the battery type. Depending on the value, additional sensors will be added.
battType, err := b.getProp(ctx, linux.SensorBattType)
if err != nil {
Expand Down Expand Up @@ -337,10 +333,7 @@ func Updater(ctx context.Context) chan sensor.Details {
// getBatteries is a helper function to retrieve all of the known batteries
// connected to the system.
func getBatteries(ctx context.Context) ([]dbus.ObjectPath, error) {
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(upowerDBusPath).
Destination(upowerDBusDest)
batteryList, err := dbusx.GetData[[]dbus.ObjectPath](req, upowerGetDevicesMethod)
batteryList, err := dbusx.GetData[[]dbus.ObjectPath](ctx, dbusx.SystemBus, upowerDBusPath, upowerDBusDest, upowerGetDevicesMethod)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/linux/desktop/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ func newColorSchemeSensor(ctx context.Context, scheme string) *desktopSettingSen
func getProp(ctx context.Context, prop string) string {
var value dbus.Variant
var err error
settingsReq := dbusx.NewBusRequest(ctx, dbusx.SessionBus).
Path(desktopPortalPath).
Destination(desktopPortalInterface)
if value, err = dbusx.GetData[dbus.Variant](settingsReq,
if value, err = dbusx.GetData[dbus.Variant](ctx,
dbusx.SessionBus,
desktopPortalPath,
desktopPortalInterface,
settingsPortalInterface+".Read",
"org.freedesktop.appearance",
prop); err != nil {
Expand Down
24 changes: 7 additions & 17 deletions internal/linux/location/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,34 @@ func Updater(ctx context.Context) chan *hass.LocationData {

// The process to watch for location updates via D-Bus is tedious...

// Get a new client for setting up a location watch.
clientReq := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(managerPath).
Destination(geoclueInterface)

var clientPath dbus.ObjectPath
var err error
clientPath, err = dbusx.GetData[dbus.ObjectPath](clientReq, getClientCall)
clientPath, err = dbusx.GetData[dbus.ObjectPath](ctx, dbusx.SystemBus, managerPath, geoclueInterface, getClientCall)
if !clientPath.IsValid() || err != nil {
log.Error().Err(err).Msg("Could not set up a geoclue client.")
close(sensorCh)
return sensorCh
}
// Create a reusable busRequest for the remaining setup steps.
locationRequest := dbusx.NewBusRequest(ctx, dbusx.SystemBus).Path(clientPath).Destination(geoclueInterface)

// Set our client ID.
if err = dbusx.SetProp(locationRequest, desktopIDProp, preferences.AppID); err != nil {
if err = dbusx.SetProp(ctx, dbusx.SystemBus, string(clientPath), geoclueInterface, desktopIDProp, preferences.AppID); err != nil {
log.Error().Err(err).Msg("Could not set a geoclue client id.")
close(sensorCh)
return sensorCh
}

// Set a distance threshold.
if err = dbusx.SetProp(locationRequest, distanceThresholdProp, uint32(0)); err != nil {
if err = dbusx.SetProp(ctx, dbusx.SystemBus, string(clientPath), geoclueInterface, distanceThresholdProp, uint32(0)); err != nil {
log.Warn().Err(err).Msg("Could not set distance threshold for geoclue requests.")
}

// Set a time threshold.
if err = dbusx.SetProp(locationRequest, timeThresholdProp, uint32(0)); err != nil {
if err = dbusx.SetProp(ctx, dbusx.SystemBus, string(clientPath), geoclueInterface, timeThresholdProp, uint32(0)); err != nil {
log.Warn().Err(err).Msg("Could not set time threshold for geoclue requests.")
}

// Request to start tracking location updates.
if err = locationRequest.Call(startCall); err != nil {
if err = dbusx.Call(ctx, dbusx.SystemBus, string(clientPath), geoclueInterface, startCall); err != nil {
log.Warn().Err(err).Msg("Could not start geoclue client.")
close(sensorCh)
return sensorCh
Expand All @@ -97,7 +90,7 @@ func Updater(ctx context.Context) chan *hass.LocationData {
for {
select {
case <-ctx.Done():
err := locationRequest.Call(stopCall)
err := dbusx.Call(ctx, dbusx.SystemBus, string(clientPath), geoclueInterface, stopCall)
if err != nil {
log.Debug().Caller().Err(err).Msg("Failed to stop location updater.")
return
Expand All @@ -117,10 +110,7 @@ func Updater(ctx context.Context) chan *hass.LocationData {

func newLocation(ctx context.Context, locationPath dbus.ObjectPath) *hass.LocationData {
getProp := func(prop string) float64 {
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(locationPath).
Destination(geoclueInterface)
value, err := dbusx.GetProp[float64](req, locationInterface+"."+prop)
value, err := dbusx.GetProp[float64](ctx, dbusx.SystemBus, string(locationPath), geoclueInterface, locationInterface+"."+prop)
if err != nil {
log.Debug().Caller().Err(err).
Msgf("Could not retrieve %s.", prop)
Expand Down
23 changes: 7 additions & 16 deletions internal/linux/net/networkConnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,28 +102,25 @@ func newConnection(ctx context.Context, path dbus.ObjectPath) *connection {
}

// fetch properties for the connection
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(path).
Destination(dBusNMObj)
var err error
c.name, err = dbusx.GetProp[string](req, dbusNMActiveConnIntr+".Id")
c.name, err = dbusx.GetProp[string](ctx, dbusx.SystemBus, string(path), dBusNMObj, dbusNMActiveConnIntr+".Id")
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve connection ID.")
}
c.state, err = dbusx.GetProp[connState](req, dbusNMActiveConnIntr+".State")
c.state, err = dbusx.GetProp[connState](ctx, dbusx.SystemBus, string(path), dBusNMObj, dbusNMActiveConnIntr+".State")
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve connection state.")
}
c.attrs.ConnectionType, err = dbusx.GetProp[string](req, dbusNMActiveConnIntr+".Type")
c.attrs.ConnectionType, err = dbusx.GetProp[string](ctx, dbusx.SystemBus, string(path), dBusNMObj, dbusNMActiveConnIntr+".Type")
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve connection type.")
}
ip4ConfigPath, err := dbusx.GetProp[dbus.ObjectPath](req, dbusNMActiveConnIntr+".Ip4Config")
ip4ConfigPath, err := dbusx.GetProp[dbus.ObjectPath](ctx, dbusx.SystemBus, string(path), dBusNMObj, dbusNMActiveConnIntr+".Ip4Config")
if err != nil {
log.Warn().Err(err).Str("connection", c.name).Msg("Could not fetch IPv4 address.")
}
c.attrs.Ipv4, c.attrs.IPv4Mask = getAddr(ctx, 4, ip4ConfigPath)
ip6ConfigPath, err := dbusx.GetProp[dbus.ObjectPath](req, dbusNMActiveConnIntr+".Ip6Config")
ip6ConfigPath, err := dbusx.GetProp[dbus.ObjectPath](ctx, dbusx.SystemBus, string(path), dBusNMObj, dbusNMActiveConnIntr+".Ip6Config")
if err != nil {
log.Warn().Err(err).Str("connection", c.name).Msg("Could not fetch IPv4 address.")
}
Expand Down Expand Up @@ -314,10 +311,7 @@ func getAddr(ctx context.Context, ver int, path dbus.ObjectPath) (addr string, m
case 6:
connProp = dBusNMObj + ".IP6Config"
}
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(path).
Destination(dBusNMObj)
addrDetails, err := dbusx.GetProp[[]map[string]dbus.Variant](req, connProp+".AddressData")
addrDetails, err := dbusx.GetProp[[]map[string]dbus.Variant](ctx, dbusx.SystemBus, string(path), dBusNMObj, connProp+".AddressData")
if err != nil {
return "", 0
}
Expand All @@ -333,10 +327,7 @@ func getAddr(ctx context.Context, ver int, path dbus.ObjectPath) (addr string, m
}

func getActiveConnections(ctx context.Context) []dbus.ObjectPath {
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(dBusNMPath).
Destination(dBusNMObj)
v, err := dbusx.GetProp[[]dbus.ObjectPath](req, dBusNMObj+".ActiveConnections")
v, err := dbusx.GetProp[[]dbus.ObjectPath](ctx, dbusx.SystemBus, dBusNMPath, dBusNMObj, dBusNMObj+".ActiveConnections")
if err != nil {
log.Debug().Err(err).
Msg("Could not retrieve active connection list.")
Expand Down
9 changes: 3 additions & 6 deletions internal/linux/net/wifiProps.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,25 +142,22 @@ func newWifiSensor(sensorType string) *wifiSensor {
// relevant WiFi properties that are to be represented as sensors.
func monitorWifi(ctx context.Context, p dbus.ObjectPath) <-chan sensor.Details {
outCh := make(chan sensor.Details)
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(p).
Destination(dBusNMObj)
// get the devices associated with this connection
wifiDevices, err := dbusx.GetProp[[]dbus.ObjectPath](req, dbusNMActiveConnIntr+".Devices")
wifiDevices, err := dbusx.GetProp[[]dbus.ObjectPath](ctx, dbusx.SystemBus, string(p), dBusNMObj, dbusNMActiveConnIntr+".Devices")
if err != nil {
log.Warn().Err(err).Msg("Could not retrieve active wireless devices.")
return nil
}
for _, d := range wifiDevices {
// for each device, get the access point it is currently associated with
ap, err := dbusx.GetProp[dbus.ObjectPath](req.Path(d), accessPointProp)
ap, err := dbusx.GetProp[dbus.ObjectPath](ctx, dbusx.SystemBus, string(d), dBusNMObj, accessPointProp)
if err != nil {
log.Warn().Err(err).Msg("Could not ascertain access point.")
continue
}
for _, prop := range wifiPropList {
// for the associated access point, get the wifi properties as sensors
value, err := dbusx.GetProp[any](req.Path(ap), accessPointInterface+"."+prop)
value, err := dbusx.GetProp[any](ctx, dbusx.SystemBus, string(ap), dBusNMObj, accessPointInterface+"."+prop)
if err != nil {
log.Warn().Err(err).Str("prop", prop).Msg("Could not get Wi-Fi property %s.")
continue
Expand Down
7 changes: 2 additions & 5 deletions internal/linux/power/idle.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,12 @@ func newIdleSensor(ctx context.Context) *idleSensor {
var idleState bool
var idleTime int64
var err error
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(loginBasePath).
Destination(loginBaseInterface)
if idleState, err = dbusx.GetProp[bool](req, idleProp); err != nil {
if idleState, err = dbusx.GetProp[bool](ctx, dbusx.SystemBus, loginBasePath, loginBaseInterface, idleProp); err != nil {
log.Debug().Err(err).Str("prop", filepath.Ext(idleProp)).Msg("Could not retrieve property from D-Bus.")
return nil
}
s.Value = idleState
idleTime, _ = dbusx.GetProp[int64](req, idleTimeProp)
idleTime, _ = dbusx.GetProp[int64](ctx, dbusx.SystemBus, loginBasePath, loginBaseInterface, idleTimeProp)
s.idleTime = idleTime
return s
}
Expand Down
5 changes: 1 addition & 4 deletions internal/linux/power/laptop.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,7 @@ func LaptopUpdater(ctx context.Context) chan sensor.Details {
func sendLaptopPropState(ctx context.Context, prop string, outCh chan sensor.Details) {
var state bool
var err error
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(loginBasePath).
Destination(loginBaseInterface)
if state, err = dbusx.GetProp[bool](req, prop); err != nil {
if state, err = dbusx.GetProp[bool](ctx, dbusx.SystemBus, loginBasePath, loginBaseInterface, prop); err != nil {
log.Debug().Err(err).Str("prop", filepath.Ext(prop)).Msg("Could not retrieve laptop property from D-Bus.")
return
}
Expand Down
22 changes: 7 additions & 15 deletions internal/linux/power/powerControl.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"context"

"github.com/eclipse/paho.golang/paho"
"github.com/godbus/dbus/v5"
mqtthass "github.com/joshuar/go-hass-anything/v9/pkg/hass"
"github.com/rs/zerolog/log"

Expand All @@ -30,7 +29,7 @@ const (
type commandConfig struct {
name string
icon string
path dbus.ObjectPath
path string
method string
}

Expand All @@ -48,25 +47,25 @@ var commands = map[string]commandConfig{
"reboot": {
name: "Reboot",
icon: "mdi:restart",
path: dbus.ObjectPath(loginBasePath),
path: loginBasePath,
method: dbusSessionRebootMethod,
},
"suspend": {
name: "Suspend",
icon: "mdi:power-sleep",
path: dbus.ObjectPath(loginBasePath),
path: loginBasePath,
method: dbusSessionSuspendMethod,
},
"hibernate": {
name: "Hibernate",
icon: "mdi:power-sleep",
path: dbus.ObjectPath(loginBasePath),
path: loginBasePath,
method: dbusSessionHibernateMethod,
},
"power_off": {
name: "Power Off",
icon: "mdi:power",
path: dbus.ObjectPath(loginBasePath),
path: loginBasePath,
method: dbusSessionPowerOffMethod,
},
}
Expand All @@ -80,14 +79,14 @@ func NewPowerControl(ctx context.Context) []*mqtthass.ButtonEntity {
var callback func(p *paho.Publish)
if v.path == "" {
callback = func(_ *paho.Publish) {
err := systemDBusCall(ctx, sessionPath, loginBaseInterface, v.method)
err := dbusx.Call(ctx, dbusx.SystemBus, string(sessionPath), loginBaseInterface, v.method)
if err != nil {
log.Warn().Err(err).Msgf("Could not %s session.", v.name)
}
}
} else {
callback = func(_ *paho.Publish) {
err := systemDBusCall(ctx, v.path, loginBaseInterface, v.method, true)
err := dbusx.Call(ctx, dbusx.SystemBus, v.path, loginBaseInterface, v.method, true)
if err != nil {
log.Warn().Err(err).Msg("Could not power off session.")
}
Expand All @@ -103,10 +102,3 @@ func NewPowerControl(ctx context.Context) []*mqtthass.ButtonEntity {
}
return entities
}

func systemDBusCall(ctx context.Context, path dbus.ObjectPath, dest, method string, args ...any) error {
return dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(path).
Destination(dest).
Call(method, args...)
}
5 changes: 1 addition & 4 deletions internal/linux/power/powerProfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ func newPowerSensor(t linux.SensorTypeValue, v dbus.Variant) *powerSensor {

func (s *sensors) Sensors(ctx context.Context) []sensor.Details {
var sensors []sensor.Details
req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(powerProfilesPath).
Destination(powerProfilesDest)
profile, err := dbusx.GetProp[dbus.Variant](req, powerProfilesDest+"."+activeProfileProp)
profile, err := dbusx.GetProp[dbus.Variant](ctx, dbusx.SystemBus, powerProfilesPath, powerProfilesDest, powerProfilesDest+"."+activeProfileProp)
if err != nil {
log.Debug().Err(err).Msg("Cannot retrieve a power profile from D-Bus.")
return nil
Expand Down
12 changes: 2 additions & 10 deletions internal/linux/power/screenLockControl.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strings"

"github.com/eclipse/paho.golang/paho"
"github.com/godbus/dbus/v5"
mqtthass "github.com/joshuar/go-hass-anything/v9/pkg/hass"

"github.com/joshuar/go-hass-agent/internal/linux"
Expand All @@ -37,9 +36,9 @@ func NewScreenLockControl(ctx context.Context) *mqtthass.ButtonEntity {
}
var err error
if dbusScreensaverMsg != nil {
err = sessionDBusCall(ctx, dbus.ObjectPath(dbusScreensaverPath), dbusScreensaverDest, dbusScreensaverLockMethod, dbusScreensaverMsg)
err = dbusx.Call(ctx, dbusx.SessionBus, dbusScreensaverPath, dbusScreensaverDest, dbusScreensaverLockMethod, dbusScreensaverMsg)
} else {
err = sessionDBusCall(ctx, dbus.ObjectPath(dbusScreensaverPath), dbusScreensaverDest, dbusScreensaverLockMethod)
err = dbusx.Call(ctx, dbusx.SessionBus, dbusScreensaverPath, dbusScreensaverDest, dbusScreensaverLockMethod)
}
if err != nil {
log.Warn().Err(err).Msg("Could not lock screensaver.")
Expand All @@ -64,10 +63,3 @@ func getDesktopEnvScreensaverConfig() (dest, path string, msg *string) {
return "", "", nil
}
}

func sessionDBusCall(ctx context.Context, path dbus.ObjectPath, dest, method string, args ...any) error {
return dbusx.NewBusRequest(ctx, dbusx.SessionBus).
Path(path).
Destination(dest).
Call(method, args...)
}
12 changes: 6 additions & 6 deletions internal/linux/problems/problems.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ func Updater(ctx context.Context) chan sensor.Details {
problems.UnitsString = "problems"
problems.StateClassValue = types.StateClassMeasurement

req := dbusx.NewBusRequest(ctx, dbusx.SystemBus).
Path(dBusProblemsDest).
Destination(dBusProblemIntr)

problemList, err := dbusx.GetData[[]string](req, dBusProblemIntr+".GetProblems")
problemList, err := dbusx.GetData[[]string](ctx, dbusx.SystemBus, dBusProblemsDest, dBusProblemIntr, dBusProblemIntr+".GetProblems")
if err != nil {
log.Debug().Err(err).Msg("Unable to retrieve list of ABRT problems.")
return
}

for _, p := range problemList {
problemDetails, err := dbusx.GetData[map[string]string](req, dBusProblemIntr+".GetInfo", p, []string{"time", "count", "package", "reason"})
problemDetails, err := dbusx.GetData[map[string]string](ctx,
dbusx.SystemBus,
dBusProblemsDest,
dBusProblemIntr,
dBusProblemIntr+".GetInfo", p, []string{"time", "count", "package", "reason"})
if problemDetails == nil || err != nil {
log.Debug().Msg("No problems retrieved.")
} else {
Expand Down
Loading

0 comments on commit eafb883

Please sign in to comment.