Skip to content

Commit

Permalink
feat(linux): rewrite D-Bus logic
Browse files Browse the repository at this point in the history
- D-Bus API now passed through context value
- all sensors check update response for error
- code logic clean-ups and spelling corrections
  • Loading branch information
joshuar committed Oct 1, 2023
1 parent e616b63 commit fa0e5bc
Show file tree
Hide file tree
Showing 20 changed files with 211 additions and 825 deletions.
4 changes: 3 additions & 1 deletion internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ func (agent *Agent) SensorValue(id string) (tracker.Sensor, error) {
func (agent *Agent) startWorkers(ctx context.Context) {
wokerFuncs := sensorWorkers()
wokerFuncs = append(wokerFuncs, device.ExternalIPUpdater)
d := newDevice(ctx)
workerCtx := d.Setup(ctx)

workerCh := make(chan func(context.Context, device.SensorTracker), len(wokerFuncs))

Expand All @@ -288,7 +290,7 @@ func (agent *Agent) startWorkers(ctx context.Context) {
wg.Add(1)
go func(workerFunc func(context.Context, device.SensorTracker)) {
defer wg.Done()
workerFunc(ctx, agent.sensors)
workerFunc(workerCtx, agent.sensors)
}(workerFunc)
}

Expand Down
1 change: 1 addition & 0 deletions internal/agent/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ type AgentUI interface {
type Device interface {
DeviceName() string
DeviceID() string
Setup(context.Context) context.Context
}
12 changes: 8 additions & 4 deletions internal/linux/appSensor.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ func AppUpdater(ctx context.Context, tracker device.SensorTracker) {
}
}()

err := NewBusRequest(SessionBus).
err := NewBusRequest(ctx, SessionBus).
Path(appStateDBusPath).
Match([]dbus.MatchOption{
dbus.WithMatchObjectPath(appStateDBusPath),
dbus.WithMatchInterface(appStateDBusInterface),
}).
Event(appStateDBusEvent).
Handler(func(_ *dbus.Signal) {
if activeAppList := NewBusRequest(SessionBus).
if activeAppList := NewBusRequest(ctx, SessionBus).
Path(appStateDBusPath).
Destination(portalDest).
GetData(appStateDBusMethod).AsVariantMap(); activeAppList != nil {
Expand All @@ -164,13 +164,17 @@ func AppUpdater(ctx context.Context, tracker device.SensorTracker) {
if count, ok := newAppCount.State().(int); ok {
if count != appStateTracker.appCount {
appStateTracker.countCh <- count
tracker.UpdateSensors(ctx, newAppCount)
if err := tracker.UpdateSensors(ctx, newAppCount); err != nil {
log.Error().Err(err).Msg("Could not update active app count.")
}
}
}
if app, ok := newApp.State().(string); ok {
if app != appStateTracker.currentApp {
appStateTracker.appChan <- app
tracker.UpdateSensors(ctx, newApp)
if err := tracker.UpdateSensors(ctx, newApp); err != nil {
log.Error().Err(err).Msg("Could not update active app.")
}
}
}
} else {
Expand Down
44 changes: 18 additions & 26 deletions internal/linux/batterySensor.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (b *upowerBattery) updateProp(ctx context.Context, t sensorType) {
case battModel:
p = "Model"
}
propValue, err := NewBusRequest(SystemBus).
propValue, err := NewBusRequest(ctx, SystemBus).
Path(b.dBusPath).
Destination(upowerDBusDest).
GetProp("org.freedesktop.UPower.Device." + p)
Expand All @@ -70,7 +70,6 @@ func (b *upowerBattery) getProp(t sensorType) interface{} {
}

func (b *upowerBattery) marshalBatteryStateUpdate(ctx context.Context, t sensorType) *upowerBatteryState {
// log.Debug().Caller().Msgf("Marshalling update for %v for battery %v", prop.String(), b.getProp(NativePath).(string))
state := &upowerBatteryState{
batteryID: b.getProp(battNativePath).(string),
model: b.getProp(battModel).(string),
Expand All @@ -92,9 +91,7 @@ func (b *upowerBattery) marshalBatteryStateUpdate(ctx context.Context, t sensorT
Energy: b.getProp(battEnergy).(float64),
DataSource: srcDbus,
}
case battPercentage:
fallthrough
case battLevel:
case battPercentage, battLevel:
state.attributes = &struct {
Type string `json:"Battery Type"`
DataSource string `json:"Data Source"`
Expand Down Expand Up @@ -166,11 +163,7 @@ func (state *upowerBatteryState) DeviceClass() sensor.SensorDeviceClass {

func (state *upowerBatteryState) StateClass() sensor.SensorStateClass {
switch state.prop.name {
case battPercentage:
fallthrough
case battTemp:
fallthrough
case battEnergyRate:
case battPercentage, battTemp, battEnergyRate:
return sensor.StateMeasurement
default:
return 0
Expand All @@ -179,15 +172,7 @@ func (state *upowerBatteryState) StateClass() sensor.SensorStateClass {

func (state *upowerBatteryState) State() interface{} {
switch state.prop.name {
case battVoltage:
fallthrough
case battTemp:
fallthrough
case battEnergy:
fallthrough
case battEnergyRate:
fallthrough
case battPercentage:
case battVoltage, battTemp, battEnergy, battEnergyRate, battPercentage:
return state.prop.value.(float64)
case battState:
return stringState(state.prop.value.(uint32))
Expand Down Expand Up @@ -285,7 +270,7 @@ func stringLevel(l uint32) string {
}

func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {
batteryList := NewBusRequest(SystemBus).
batteryList := NewBusRequest(ctx, SystemBus).
Path(upowerDBusPath).
Destination(upowerDBusDest).
GetData(upowerGetDevicesMethod).AsObjectPathList()
Expand All @@ -297,7 +282,6 @@ func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {

batteryTracker := make(map[string]*upowerBattery)
for _, v := range batteryList {

// Track this battery in batteryTracker.
batteryID := string(v)
batteryTracker[batteryID] = &upowerBattery{
Expand All @@ -313,7 +297,9 @@ func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {
batteryTracker[batteryID].updateProp(ctx, prop)
stateUpdate := batteryTracker[batteryID].marshalBatteryStateUpdate(ctx, prop)
if stateUpdate != nil {
tracker.UpdateSensors(ctx, stateUpdate)
if err := tracker.UpdateSensors(ctx, stateUpdate); err != nil {
log.Error().Err(err).Msg("Could not update battery sensor.")
}
}
}

Expand All @@ -323,15 +309,19 @@ func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {
batteryTracker[batteryID].updateProp(ctx, prop)
stateUpdate := batteryTracker[batteryID].marshalBatteryStateUpdate(ctx, prop)
if stateUpdate != nil {
tracker.UpdateSensors(ctx, stateUpdate)
if err := tracker.UpdateSensors(ctx, stateUpdate); err != nil {
log.Error().Err(err).Msg("Could not update battery sensor.")
}
}
}
} else {
batteryTracker[batteryID].updateProp(ctx, battLevel)
if batteryTracker[batteryID].getProp(battLevel).(uint32) != 1 {
stateUpdate := batteryTracker[batteryID].marshalBatteryStateUpdate(ctx, battLevel)
if stateUpdate != nil {
tracker.UpdateSensors(ctx, stateUpdate)
if err := tracker.UpdateSensors(ctx, stateUpdate); err != nil {
log.Error().Err(err).Msg("Could not update battery sensor.")
}
}
}
}
Expand All @@ -340,7 +330,7 @@ func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {
// battery. If a property changes, check it is one we want to track and
// if so, update the battery's state in batteryTracker and send the
// update back to Home Assistant.
err := NewBusRequest(SystemBus).
err := NewBusRequest(ctx, SystemBus).
Path(v).
Match([]dbus.MatchOption{
dbus.WithMatchObjectPath(v),
Expand All @@ -365,7 +355,9 @@ func BatteryUpdater(ctx context.Context, tracker device.SensorTracker) {
}
}
if len(sensors) > 0 {
tracker.UpdateSensors(ctx, sensors...)
if err := tracker.UpdateSensors(ctx, sensors...); err != nil {
log.Error().Err(err).Msg("Could not update battery sensor.")
}
}
}).
AddWatch(ctx)
Expand Down
17 changes: 10 additions & 7 deletions internal/linux/dbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,13 @@ type busRequest struct {
match []dbus.MatchOption
}

func NewBusRequest(busType dbusType) *busRequest {
b := dbusAPI.EndPoint(busType)
return &busRequest{
bus: b,
func NewBusRequest(ctx context.Context, busType dbusType) *busRequest {
if bus, ok := getBus(ctx, busType); !ok {
return &busRequest{}
} else {
return &busRequest{
bus: bus,
}
}
}

Expand Down Expand Up @@ -287,7 +290,7 @@ func findPortal() string {
// that, it will default to using "localhost"
func GetHostname(ctx context.Context) string {
var dBusDest = "org.freedesktop.hostname1"
hostnameFromDBus, err := NewBusRequest(SystemBus).
hostnameFromDBus, err := NewBusRequest(ctx, SystemBus).
Path(dbus.ObjectPath("/org/freedesktop/hostname1")).
Destination(dBusDest).
GetProp(dBusDest + ".Hostname")
Expand All @@ -305,7 +308,7 @@ func GetHardwareDetails(ctx context.Context) (string, string) {
var vendor, model string
var dBusDest = "org.freedesktop.hostname1"
var dBusPath = "/org/freedesktop/hostname1"
hwVendorFromDBus, err := NewBusRequest(SystemBus).
hwVendorFromDBus, err := NewBusRequest(ctx, SystemBus).
Path(dbus.ObjectPath(dBusPath)).
Destination(dBusDest).
GetProp(dBusDest + ".HardwareVendor")
Expand All @@ -319,7 +322,7 @@ func GetHardwareDetails(ctx context.Context) (string, string) {
} else {
vendor = string(variantToValue[[]uint8](hwVendorFromDBus))
}
hwModelFromDBus, err := NewBusRequest(SystemBus).
hwModelFromDBus, err := NewBusRequest(ctx, SystemBus).
Path(dbus.ObjectPath(dBusPath)).
Destination(dBusDest).
GetProp(dBusDest + ".HardwareVendor")
Expand Down
Loading

0 comments on commit fa0e5bc

Please sign in to comment.