summaryrefslogtreecommitdiff
path: root/lib/sway/device.vala
diff options
context:
space:
mode:
authornoname <[email protected]>2025-02-27 15:08:15 +1100
committernoname <[email protected]>2025-03-03 22:06:48 +1100
commitbfceeb515a928de6ad901a1435b8e5bbc26eb64d (patch)
treec8513f519ec15345c3dd95dca9be873da43248f6 /lib/sway/device.vala
parent4b283b0045c0752c36c6e8306fc137f2c9f244a4 (diff)
test
Diffstat (limited to 'lib/sway/device.vala')
-rw-r--r--lib/sway/device.vala458
1 files changed, 458 insertions, 0 deletions
diff --git a/lib/sway/device.vala b/lib/sway/device.vala
new file mode 100644
index 0000000..db69574
--- /dev/null
+++ b/lib/sway/device.vala
@@ -0,0 +1,458 @@
+namespace AstalBattery {
+ /** Get the DisplayDevice. */
+ public Device get_default() {
+ return Device.get_default();
+ }
+}
+
+/**
+ * Client for a UPower [[https://upower.freedesktop.org/docs/Device.html|device]].
+ */
+public class AstalBattery.Device : Object {
+ private static Device display_device;
+
+ /** Get the DisplayDevice. */
+ public static Device? get_default() {
+ if (display_device != null) {
+ return display_device;
+ }
+
+ try {
+ display_device = new Device((ObjectPath)"/org/freedesktop/UPower/devices/DisplayDevice");
+ return display_device;
+ } catch (Error error) {
+ critical(error.message);
+ }
+
+ return null;
+ }
+
+ private IUPowerDevice proxy;
+
+ public Device(ObjectPath path) throws Error {
+ proxy = Bus.get_proxy_sync(BusType.SYSTEM, "org.freedesktop.UPower", path);
+ proxy.g_properties_changed.connect(sync);
+ sync();
+ }
+
+ /**
+ * If it is [[email protected]], you will need to verify that the
+ * property power-supply has the value `true` before considering it as a laptop battery.
+ * Otherwise it will likely be the battery for a device of an unknown type.
+ */
+ public Type device_type { get; private set; }
+
+ /**
+ * Native path of the power source. This is the sysfs path,
+ * for example /sys/devices/LNXSYSTM:00/device:00/PNP0C0A:00/power_supply/BAT0.
+ * It is blank if the device is being driven by a user space driver.
+ */
+ public string native_path { owned get; private set; }
+
+ /** Name of the vendor of the battery. */
+ public string vendor { owned get; private set; }
+
+ /** Name of the model of this battery. */
+ public string model { owned get; private set; }
+
+ /** Unique serial number of the battery. */
+ public string serial { owned get; private set; }
+
+ /**
+ * The point in time (seconds since the Epoch)
+ * that data was read from the power source.
+ */
+ public uint64 update_time { get; private set; }
+
+ /**
+ * If the power device is used to supply the system.
+ * This would be set `true` for laptop batteries and UPS devices,
+ * but set to `false` for wireless mice or PDAs.
+ */
+ public bool power_supply { get; private set; }
+
+ /** If the power device has history. */
+ // TODO: public bool has_history { get; private set; }
+
+ /** If the power device has statistics. */
+ // TODO: public bool has_statistics { get; private set; }
+
+ /**
+ * Whether power is currently being provided through line power.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]_POWER].
+ */
+ public bool online { get; private set; }
+
+ /**
+ * Amount of energy (measured in Wh) currently available in the power source.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double energy { get; private set; }
+
+ /**
+ * Amount of energy (measured in Wh) in the power source when it's considered to be empty.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double energy_empty { get; private set; }
+
+ /**
+ * Amount of energy (measured in Wh) in the power source when it's considered full.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double energy_full { get; private set; }
+
+ /**
+ * Amount of energy (measured in Wh) the power source is designed to hold when it's considered full.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double energy_full_design { get; private set; }
+
+ /**
+ * Amount of energy being drained from the source, measured in W.
+ * If positive, the source is being discharged, if negative it's being charged.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double energy_rate { get; private set; }
+
+ /** Voltage in the Cell or being recorded by the meter. */
+ public double voltage { get; private set; }
+
+ /**
+ * The number of charge cycles as defined by the TCO certification,
+ * or -1 if that value is unknown or not applicable.
+ */
+ public int charge_cycles { get; private set; }
+
+ /** Luminosity being recorded by the meter. */
+ public double luminosity { get; private set; }
+
+ /**
+ * Number of seconds until the power source is considered empty. Is set to 0 if unknown.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public int64 time_to_empty { get; private set; }
+
+ /**
+ * Number of seconds until the power source is considered full. Is set to 0 if unknown.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public int64 time_to_full { get; private set;}
+
+ /**
+ * The amount of energy left in the power source expressed as a percentage between 0 and 1.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ * The percentage will be an approximation if [[email protected]:battery_level]
+ * is set to something other than None.
+ */
+ public double percentage { get; private set; }
+
+ /**
+ * The temperature of the device in degrees Celsius.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double temperature { get; private set; }
+
+ /**
+ * If the power source is present in the bay.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public bool is_present { get; private set; }
+
+ /**
+ * The battery power state.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public State state { get; private set; }
+
+ /**
+ * If the power source is rechargeable.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public bool is_rechargable { get; private set; }
+
+ /**
+ * The capacity of the power source expressed as a percentage between 0 and 1.
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public double capacity { get; private set; }
+
+ /**
+ * Technology used in the battery:
+ *
+ * This property is only valid if [[email protected]:device_type] is [[email protected]].
+ */
+ public Technology technology { get; private set; }
+
+ /** Warning level of the battery. */
+ public WarningLevel warning_level { get; private set; }
+
+ /**
+ * The level of the battery for devices which do not report a percentage
+ * but rather a coarse battery level. If the value is None.
+ * then the device does not support coarse battery reporting,
+ * and the [[email protected]:percentage] should be used instead.
+ */
+ public BatteryLevel battery_level { get; private set; }
+
+ /**
+ * An icon name representing this Device.
+ *
+ * NOTE: [[email protected]:battery_icon_name] might be a better fit
+ * as it is calculated from percentage.
+ */
+ public string icon_name { owned get; private set; }
+
+ /**
+ * Indicates if [[email protected]:state] is charging or fully charged.
+ */
+ public bool charging { get; private set; }
+
+ /**
+ * Indicates if [[email protected]:device_type] is not line power or unknown.
+ */
+ public bool is_battery { get; private set; }
+
+ /**
+ * An icon name in the form of "battery-level-$percentage-$state-symbolic".
+ */
+ public string battery_icon_name { get; private set; }
+
+ /**
+ * A string representation of this device's [[email protected]:device_type].
+ */
+ public string device_type_name { get; private set; }
+
+ /**
+ * An icon name that can be used to represent this device's [[email protected]:device_type].
+ */
+ public string device_type_icon { get; private set; }
+
+ // TODO: get_history
+ // TODO: get_statistics
+
+ private void sync() {
+ device_type = (Type)proxy.Type;
+ native_path = proxy.native_path;
+ vendor = proxy.vendor;
+ model = proxy.model;
+ serial = proxy.serial;
+ update_time = proxy.update_time;
+ power_supply = proxy.power_supply;
+ // TODO: has_history = proxy.has_history;
+ // TODO: has_statistics = proxy.has_statistics;
+ online = proxy.online;
+ energy = proxy.energy;
+ energy_empty = proxy.energy_empty;
+ energy_full = proxy.energy_full;
+ energy_full_design = proxy.energy_full_design;
+ energy_rate = proxy.energy_rate;
+ voltage = proxy.voltage;
+ charge_cycles = proxy.charge_cycles;
+ luminosity = proxy.luminosity;
+ time_to_empty = proxy.time_to_empty;
+ time_to_full = proxy.time_to_full;
+ percentage = proxy.percentage / 100;
+ temperature = proxy.temperature;
+ is_present = proxy.is_present;
+ state = (State)proxy.state;
+ is_rechargable = proxy.is_rechargable;
+ capacity = proxy.capacity / 100;
+ technology = (Technology)proxy.technology;
+ warning_level = (WarningLevel)proxy.warning_level;
+ battery_level = (BatteryLevel)proxy.battery_level;
+ icon_name = proxy.icon_name;
+
+ charging = state == State.FULLY_CHARGED || state == State.CHARGING;
+ is_battery = device_type != Type.UNKNOWN && device_type != Type.LINE_POWER;
+
+ if (!is_battery) {
+ battery_icon_name = "battery-missing-symbolic";
+ } else if (percentage >= 0.95 && charging) {
+ battery_icon_name = "battery-level-100-charged-symbolic";
+ } else {
+ var state = charging ? "-charging" : "";
+ var level = (int)Math.round(percentage * 10)*10;
+ battery_icon_name = @"battery-level-$level$state-symbolic";
+ }
+
+ device_type_name = device_type.get_name();
+ device_type_icon = device_type.get_icon_name();
+ }
+}
+
+[CCode (type_signature = "u")]
+public enum AstalBattery.State {
+ UNKNOWN,
+ CHARGING,
+ DISCHARGING,
+ EMPTY,
+ FULLY_CHARGED,
+ PENDING_CHARGE,
+ PENDING_DISCHARGE,
+}
+
+[CCode (type_signature = "u")]
+public enum AstalBattery.Technology {
+ UNKNOWN,
+ LITHIUM_ION,
+ LITHIUM_POLYMER,
+ LITHIUM_IRON_PHOSPHATE,
+ LEAD_ACID,
+ NICKEL_CADMIUM,
+ NICKEL_METAL_HYDRIDE,
+}
+
+[CCode (type_signature = "u")]
+public enum AstalBattery.WarningLevel {
+ UNKNOWN,
+ NONE,
+ DISCHARGING,
+ LOW,
+ CRITICIAL,
+ ACTION,
+}
+
+[CCode (type_signature = "u")]
+public enum AstalBattery.BatteryLevel {
+ UNKNOWN,
+ NONE,
+ LOW,
+ CRITICIAL,
+ NORMAL,
+ HIGH,
+ FULL,
+}
+
+[CCode (type_signature = "u")]
+public enum AstalBattery.Type {
+ UNKNOWN,
+ LINE_POWER,
+ BATTERY,
+ UPS,
+ MONITOR,
+ MOUSE,
+ KEYBOARD,
+ PDA,
+ PHONE,
+ MEDIA_PLAYER,
+ TABLET,
+ COMPUTER,
+ GAMING_INPUT,
+ PEN,
+ TOUCHPAD,
+ MODEM,
+ NETWORK,
+ HEADSET,
+ SPEAKERS,
+ HEADPHONES,
+ VIDEO,
+ OTHER_AUDIO,
+ REMOVE_CONTROL,
+ PRINTER,
+ SCANNER,
+ CAMERA,
+ WEARABLE,
+ TOY,
+ BLUETOOTH_GENERIC;
+
+ // TODO: add more icon names
+ internal string? get_icon_name () {
+ switch (this) {
+ case UPS:
+ return "uninterruptible-power-supply";
+ case MOUSE:
+ return "input-mouse";
+ case KEYBOARD:
+ return "input-keyboard";
+ case PDA:
+ case PHONE:
+ return "phone";
+ case MEDIA_PLAYER:
+ return "multimedia-player";
+ case TABLET:
+ case PEN:
+ return "input-tablet";
+ case GAMING_INPUT:
+ return "input-gaming";
+ default:
+ return null;
+ }
+ }
+
+ internal unowned string? get_name () {
+ switch (this) {
+ case LINE_POWER:
+ return "Plugged In";
+ case BATTERY:
+ return "Battery";
+ case UPS:
+ return "UPS";
+ case MONITOR:
+ return "Display";
+ case MOUSE:
+ return "Mouse";
+ case KEYBOARD:
+ return "Keyboard";
+ case PDA:
+ return "PDA";
+ case PHONE:
+ return "Phone";
+ case MEDIA_PLAYER:
+ return "Media Player";
+ case TABLET:
+ return "Tablet";
+ case COMPUTER:
+ return "Computer";
+ case GAMING_INPUT:
+ return "Controller";
+ case PEN:
+ return "Pen";
+ case TOUCHPAD:
+ return "Touchpad";
+ case MODEM:
+ return "Modem";
+ case NETWORK:
+ return "Network";
+ case HEADSET:
+ return "Headset";
+ case SPEAKERS:
+ return "Speakers";
+ case HEADPHONES:
+ return "Headphones";
+ case VIDEO:
+ return "Video";
+ case OTHER_AUDIO:
+ return "Other Audio";
+ case REMOVE_CONTROL:
+ return "Remove Control";
+ case PRINTER:
+ return "Printer";
+ case SCANNER:
+ return "Scanner";
+ case CAMERA:
+ return "Camera";
+ case WEARABLE:
+ return "Wearable";
+ case TOY:
+ return "Toy";
+ case BLUETOOTH_GENERIC:
+ return "Bluetooth Generic";
+ default:
+ return "Unknown";
+ }
+ }
+}