File indexing completed on 2024-05-26 04:05:33

0001 /*
0002     SPDX-FileCopyrightText: 2009 Harald Fernengel <harry@kdevelop.org>
0003     SPDX-FileCopyrightText: 2017 René J.V. Bertin <rjvbertin@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "iokitbattery.h"
0009 #include "iokitdevice.h"
0010 
0011 // TODO - emit the signals
0012 
0013 using namespace Solid::Backends::IOKit;
0014 
0015 Battery::Battery(IOKitDevice *device)
0016     : DeviceInterface(device)
0017 {
0018 }
0019 
0020 Battery::~Battery()
0021 {
0022 }
0023 
0024 // properties: QMap(("AdapterInfo", QVariant(int, 0))
0025 //     ("Amperage", QVariant(int, 0))
0026 //     ("AvgTimeToEmpty", QVariant(int, 65535))
0027 //     ("AvgTimeToFull", QVariant(int, 65535))
0028 //     ("BatteryInstalled", QVariant(bool, true))
0029 //     ("BatteryInvalidWakeSeconds", QVariant(int, 30))
0030 //     ("BatterySerialNumber", QVariant(QString, "W01286PEED3BA"))
0031 //     ("BootPathUpdated", QVariant(int, 1501532930))
0032 //     ("CellVoltage", QVariant(QVariantList, (QVariant(int, 4136), QVariant(int, 4134), QVariant(int, 4134), QVariant(int, 0))))
0033 //     ("CurrentCapacity", QVariant(int, 5552))
0034 //     ("CycleCount", QVariant(int, 16))
0035 //     ("DesignCapacity", QVariant(int, 5770))
0036 //     ("DesignCycleCount", QVariant(int, 1000))
0037 //     ("DeviceName", QVariant(QString, "bq20z451"))
0038 //     ("ExternalChargeCapable", QVariant(bool, true))
0039 //     ("ExternalConnected", QVariant(bool, true))
0040 //     ("FirmwareSerialNumber", QVariant(int, 48))
0041 //     ("FullPathUpdated", QVariant(int, 1502790621))
0042 //     ("FullyCharged", QVariant(bool, true))
0043 //     ("IOGeneralInterest", QVariant(QString, "IOCommand is not serializable"))
0044 //     ("InstantAmperage", QVariant(int, 0))
0045 //     ("InstantTimeToEmpty", QVariant(int, 65535))
0046 //     ("IsCharging", QVariant(bool, false))
0047 //     ("LegacyBatteryInfo", QVariant(QVariantMap, QMap(("Amperage", QVariant(int, 0))
0048 //         ("Capacity", QVariant(int, 5814))
0049 //         ("Current", QVariant(int, 5552))
0050 //         ("Cycle Count", QVariant(int, 16))
0051 //         ("Flags", QVariant(int, 5))
0052 //         ("Voltage", QVariant(int, 12403)))))
0053 //     ("Location", QVariant(int, 0))
0054 //     ("ManufactureDate", QVariant(int, 16106))
0055 //     ("Manufacturer", QVariant(QString, "SMP"))
0056 //     ("ManufacturerData", QVariant(QByteArray, "\x00\x00\x00\x00\x02\x01\x00\n\x01X\x00\x00\x02K6c\x03""00A\x03""ATL\x00\x12\x00\x00"))
0057 //     ("MaxCapacity", QVariant(int, 5814))
0058 //     ("MaxErr", QVariant(int, 1))
0059 //     ("OperationStatus", QVariant(int, 58435))
0060 //     ("PackReserve", QVariant(int, 200))
0061 //     ("PermanentFailureStatus", QVariant(int, 0))
0062 //     ("PostChargeWaitSeconds", QVariant(int, 120))
0063 //     ("PostDischargeWaitSeconds", QVariant(int, 120))
0064 //     ("Temperature", QVariant(int, 2965))
0065 //     ("TimeRemaining", QVariant(int, 0))
0066 //     ("UserVisiblePathUpdated", QVariant(int, 1502790679))
0067 //     ("Voltage", QVariant(int, 12403))
0068 //     ("className", QVariant(QString, "AppleSmartBattery")))
0069 
0070 qlonglong Battery::timeToEmpty() const
0071 {
0072     if (chargeState() != Solid::Battery::Charging) {
0073         int t = m_device->property(QStringLiteral("AvgTimeToEmpty")).toInt();
0074         return t == 65535 ? -1 : t * 60;
0075     }
0076     return -1;
0077 }
0078 
0079 qlonglong Battery::timeToFull() const
0080 {
0081     if (chargeState() == Solid::Battery::Charging) {
0082         int t = m_device->property(QStringLiteral("AvgTimeToFull")).toInt();
0083         return t == 65535 ? -1 : t * 60;
0084     }
0085     return -1;
0086 }
0087 
0088 double Battery::voltage() const
0089 {
0090     return m_device->property(QStringLiteral("Voltage")).toInt() / 1000.0;
0091 }
0092 
0093 double Battery::temperature() const
0094 {
0095     return m_device->property(QStringLiteral("Temperature")).toInt() / 100.0;
0096 }
0097 
0098 QString Battery::serial() const
0099 {
0100     return m_device->property(QStringLiteral("BatterySerialNumber")).toString();
0101 }
0102 
0103 bool Battery::isPresent() const
0104 {
0105     return m_device->property(QStringLiteral("ExternalConnected")).toBool();
0106 }
0107 
0108 Solid::Battery::BatteryType Battery::type() const
0109 {
0110     // TODO - how to figure that one out? Just presume we're
0111     // only called with the main battery.
0112     return Solid::Battery::PrimaryBattery;
0113 }
0114 
0115 int Battery::chargePercent() const
0116 {
0117     // always calculate since FullyCharged remains true down to 92% or so.
0118     int maxCapacity = m_device->property(QStringLiteral("MaxCapacity")).toInt();
0119     if (maxCapacity == 0) {
0120         return 0; // prevent divide by 0
0121     }
0122     return int(m_device->property(QStringLiteral("CurrentCapacity")).toInt() * 100.0 / maxCapacity + 0.5);
0123 }
0124 
0125 int Battery::capacity() const
0126 {
0127     if (m_device->iOKitPropertyExists(QStringLiteral("PermanentFailureStatus")) //
0128         && m_device->property(QStringLiteral("PermanentFailureStatus")).toInt()) {
0129         return 0;
0130     }
0131     return 100;
0132 }
0133 
0134 bool Battery::isRechargeable() const
0135 {
0136     return m_device->property(QStringLiteral("CycleCount")).toInt() > 1;
0137 }
0138 
0139 bool Battery::isPowerSupply() const
0140 {
0141     /* clang-format off */
0142     return m_device->iOKitPropertyExists(QStringLiteral("BatteryInstalled"))
0143            ? m_device->property(QStringLiteral("BatteryInstalled")).toBool()
0144            : true;
0145     /* clang-format on */
0146 }
0147 
0148 Solid::Battery::ChargeState Battery::chargeState() const
0149 {
0150     if (m_device->property(QStringLiteral("IsCharging")).toBool()) {
0151         return Solid::Battery::Charging;
0152     }
0153     if (m_device->property(QStringLiteral("FullyCharged")).toBool()) {
0154         return Solid::Battery::FullyCharged;
0155     }
0156     return Solid::Battery::Discharging;
0157 }
0158 
0159 #include "moc_iokitbattery.cpp"