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"