joshuar-go-hass-agent/internal/linux/net/wifiSensor.go

155 lines
3.9 KiB
Go

// Copyright (c) 2024 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
package net
import (
"log/slog"
"github.com/joshuar/go-hass-agent/internal/hass/sensor"
"github.com/joshuar/go-hass-agent/internal/hass/sensor/types"
"github.com/joshuar/go-hass-agent/internal/linux"
"github.com/joshuar/go-hass-agent/pkg/linux/dbusx"
)
const (
accessPointInterface = dBusNMObj + ".AccessPoint"
activeAccessPointProp = dBusNMObj + ".Device.Wireless.ActiveAccessPoint"
ssidPropName = "Ssid"
hwAddrPropName = "HwAddress"
maxBitRatePropName = "MaxBitrate"
freqPropName = "Frequency"
strPropName = "Strength"
bandwidthPropName = "Bandwidth"
)
var apPropList = []string{ssidPropName, hwAddrPropName, maxBitRatePropName, freqPropName, strPropName, bandwidthPropName}
type wifiSensor struct {
prop string
linux.Sensor
}
func (w *wifiSensor) State() any {
switch w.prop {
case ssidPropName:
if value, ok := w.Value.([]uint8); ok {
return string(value)
} else {
return sensor.StateUnknown
}
case hwAddrPropName:
if value, ok := w.Value.(string); ok {
return value
} else {
return sensor.StateUnknown
}
case freqPropName, maxBitRatePropName, bandwidthPropName:
if value, ok := w.Value.(uint32); ok {
return value
} else {
return sensor.StateUnknown
}
case strPropName:
if value, ok := w.Value.(uint8); ok {
return value
} else {
return sensor.StateUnknown
}
default:
return sensor.StateUnknown
}
}
//nolint:mnd
func (w *wifiSensor) Icon() string {
switch w.prop {
case ssidPropName, hwAddrPropName, freqPropName, maxBitRatePropName, bandwidthPropName:
return "mdi:wifi"
case strPropName:
value, ok := w.Value.(uint8)
if !ok {
return "mdi:wifi-strength-alert-outline"
}
switch {
case value <= 25:
return "mdi:wifi-strength-1"
case value > 25 && value <= 50:
return "mdi:wifi-strength-2"
case value > 50 && value <= 75:
return "mdi:wifi-strength-3"
case value > 75:
return "mdi:wifi-strength-4"
}
}
return "mdi:network"
}
func newWifiSensor(prop string, value any) *wifiSensor {
wifiSensor := &wifiSensor{
prop: prop,
Sensor: linux.Sensor{
IsDiagnostic: true,
Value: value,
},
}
switch prop {
case ssidPropName:
wifiSensor.DisplayName = "Wi-Fi SSID"
wifiSensor.UniqueID = "wi_fi_ssid"
case hwAddrPropName:
wifiSensor.DisplayName = "Wi-Fi BSSID"
wifiSensor.UniqueID = "wi_fi_bssid"
case maxBitRatePropName:
wifiSensor.DisplayName = "Wi-Fi Link Speed"
wifiSensor.UniqueID = "wi_fi_link_speed"
wifiSensor.UnitsString = "kB/s"
wifiSensor.DeviceClassValue = types.DeviceClassDataRate
wifiSensor.StateClassValue = types.StateClassMeasurement
case freqPropName:
wifiSensor.DisplayName = "Wi-Fi Frequency"
wifiSensor.UniqueID = "wi_fi_frequency"
wifiSensor.UnitsString = "MHz"
wifiSensor.DeviceClassValue = types.DeviceClassFrequency
wifiSensor.StateClassValue = types.StateClassMeasurement
case bandwidthPropName:
wifiSensor.DisplayName = "Wi-Fi Bandwidth"
wifiSensor.UniqueID = "wi_fi_bandwidth"
wifiSensor.UnitsString = "MHz"
wifiSensor.DeviceClassValue = types.DeviceClassFrequency
wifiSensor.StateClassValue = types.StateClassMeasurement
case strPropName:
wifiSensor.DisplayName = "Wi-Fi Signal Strength"
wifiSensor.UniqueID = "wi_fi_signal_strength"
wifiSensor.UnitsString = "%"
wifiSensor.StateClassValue = types.StateClassMeasurement
}
return wifiSensor
}
func getWifiSensors(bus *dbusx.Bus, apPath string) []*wifiSensor {
sensors := make([]*wifiSensor, 0, len(apPropList))
for _, prop := range apPropList {
value, err := dbusx.NewProperty[any](bus, apPath, dBusNMObj, accessPointInterface+"."+prop).Get()
if err != nil {
slog.Debug("Could not retrieve access point property.",
slog.String("prop", prop),
slog.Any("error", err))
continue
}
sensors = append(sensors, newWifiSensor(prop, value))
}
return sensors
}