Changeset View
Changeset View
Standalone View
Standalone View
src/solid/devices/backends/iokit/iokitbattery.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | Copyright 2009 Harald Fernengel <harry@kdevelop.org> | 2 | Copyright 2009 Harald Fernengel <harry@kdevelop.org> | ||
3 | Copyright 2017 René J.V. Bertin <rjvbertin@gmail.com> | ||||
3 | 4 | | |||
4 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | 7 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) version 3, or any | 8 | version 2.1 of the License, or (at your option) version 3, or any | ||
8 | later version accepted by the membership of KDE e.V. (or its | 9 | later version accepted by the membership of KDE e.V. (or its | ||
9 | successor approved by the membership of KDE e.V.), which shall | 10 | successor approved by the membership of KDE e.V.), which shall | ||
10 | act as a proxy defined in Section 6 of version 3 of the license. | 11 | act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | 12 | | |||
12 | This library is distributed in the hope that it will be useful, | 13 | This library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | 16 | Lesser General Public License for more details. | ||
16 | 17 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 18 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | 19 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 20 | */ | ||
20 | 21 | | |||
21 | #include "iokitbattery.h" | 22 | #include "iokitbattery.h" | ||
22 | #include "iokitdevice.h" | 23 | #include "iokitdevice.h" | ||
23 | 24 | | |||
24 | #include <QtCore/qdebug.h> | 25 | #include <QDebug> | ||
25 | 26 | | |||
26 | // TODO - emit the signals | 27 | // TODO - emit the signals | ||
27 | 28 | | |||
28 | using namespace Solid::Backends::IOKit; | 29 | using namespace Solid::Backends::IOKit; | ||
29 | 30 | | |||
30 | Battery::Battery(IOKitDevice *device) | 31 | Battery::Battery(IOKitDevice *device) | ||
31 | : DeviceInterface(device) | 32 | : DeviceInterface(device) | ||
32 | { | 33 | { | ||
33 | } | 34 | } | ||
34 | 35 | | |||
35 | Battery::~Battery() | 36 | Battery::~Battery() | ||
36 | { | 37 | { | ||
38 | } | ||||
39 | | ||||
40 | // properties: QMap(("AdapterInfo", QVariant(int, 0)) | ||||
41 | // ("Amperage", QVariant(int, 0)) | ||||
42 | // ("AvgTimeToEmpty", QVariant(int, 65535)) | ||||
43 | // ("AvgTimeToFull", QVariant(int, 65535)) | ||||
44 | // ("BatteryInstalled", QVariant(bool, true)) | ||||
45 | // ("BatteryInvalidWakeSeconds", QVariant(int, 30)) | ||||
46 | // ("BatterySerialNumber", QVariant(QString, "W01286PEED3BA")) | ||||
47 | // ("BootPathUpdated", QVariant(int, 1501532930)) | ||||
48 | // ("CellVoltage", QVariant(QVariantList, (QVariant(int, 4136), QVariant(int, 4134), QVariant(int, 4134), QVariant(int, 0)))) | ||||
49 | // ("CurrentCapacity", QVariant(int, 5552)) | ||||
50 | // ("CycleCount", QVariant(int, 16)) | ||||
51 | // ("DesignCapacity", QVariant(int, 5770)) | ||||
52 | // ("DesignCycleCount", QVariant(int, 1000)) | ||||
53 | // ("DeviceName", QVariant(QString, "bq20z451")) | ||||
54 | // ("ExternalChargeCapable", QVariant(bool, true)) | ||||
55 | // ("ExternalConnected", QVariant(bool, true)) | ||||
56 | // ("FirmwareSerialNumber", QVariant(int, 48)) | ||||
57 | // ("FullPathUpdated", QVariant(int, 1502790621)) | ||||
58 | // ("FullyCharged", QVariant(bool, true)) | ||||
59 | // ("IOGeneralInterest", QVariant(QString, "IOCommand is not serializable")) | ||||
60 | // ("InstantAmperage", QVariant(int, 0)) | ||||
61 | // ("InstantTimeToEmpty", QVariant(int, 65535)) | ||||
62 | // ("IsCharging", QVariant(bool, false)) | ||||
63 | // ("LegacyBatteryInfo", QVariant(QVariantMap, QMap(("Amperage", QVariant(int, 0)) | ||||
64 | // ("Capacity", QVariant(int, 5814)) | ||||
65 | // ("Current", QVariant(int, 5552)) | ||||
66 | // ("Cycle Count", QVariant(int, 16)) | ||||
67 | // ("Flags", QVariant(int, 5)) | ||||
68 | // ("Voltage", QVariant(int, 12403))))) | ||||
69 | // ("Location", QVariant(int, 0)) | ||||
70 | // ("ManufactureDate", QVariant(int, 16106)) | ||||
71 | // ("Manufacturer", QVariant(QString, "SMP")) | ||||
72 | // ("ManufacturerData", QVariant(QByteArray, "\x00\x00\x00\x00\x02\x01\x00\n\x01X\x00\x00\x02K6c\x03""00A\x03""ATL\x00\x12\x00\x00")) | ||||
73 | // ("MaxCapacity", QVariant(int, 5814)) | ||||
74 | // ("MaxErr", QVariant(int, 1)) | ||||
75 | // ("OperationStatus", QVariant(int, 58435)) | ||||
76 | // ("PackReserve", QVariant(int, 200)) | ||||
77 | // ("PermanentFailureStatus", QVariant(int, 0)) | ||||
78 | // ("PostChargeWaitSeconds", QVariant(int, 120)) | ||||
79 | // ("PostDischargeWaitSeconds", QVariant(int, 120)) | ||||
80 | // ("Temperature", QVariant(int, 2965)) | ||||
81 | // ("TimeRemaining", QVariant(int, 0)) | ||||
82 | // ("UserVisiblePathUpdated", QVariant(int, 1502790679)) | ||||
83 | // ("Voltage", QVariant(int, 12403)) | ||||
84 | // ("className", QVariant(QString, "AppleSmartBattery"))) | ||||
85 | | ||||
86 | qlonglong Battery::timeToEmpty() const | ||||
87 | { | ||||
88 | if (chargeState() != Solid::Battery::Charging) { | ||||
89 | int t = m_device->property(QStringLiteral("AvgTimeToEmpty")).toInt(); | ||||
90 | return t == 65535 ? -1 : t * 60; | ||||
91 | } | ||||
92 | return -1; | ||||
93 | } | ||||
94 | | ||||
95 | qlonglong Battery::timeToFull() const | ||||
96 | { | ||||
97 | if (chargeState() == Solid::Battery::Charging) { | ||||
98 | int t = m_device->property(QStringLiteral("AvgTimeToFull")).toInt(); | ||||
99 | return t == 65535 ? -1 : t * 60; | ||||
100 | } | ||||
101 | return -1; | ||||
102 | } | ||||
103 | | ||||
104 | double Battery::voltage() const | ||||
105 | { | ||||
106 | return m_device->property(QStringLiteral("Voltage")).toInt() / 1000.0; | ||||
107 | } | ||||
108 | | ||||
109 | double Battery::temperature() const | ||||
110 | { | ||||
111 | return m_device->property(QStringLiteral("Temperature")).toInt() / 100.0; | ||||
112 | } | ||||
113 | | ||||
37 | 114 | | |||
115 | QString Battery::serial() const | ||||
116 | { | ||||
117 | return m_device->property(QStringLiteral("BatterySerialNumber")).toString(); | ||||
38 | } | 118 | } | ||
39 | 119 | | |||
40 | bool Battery::isPresent() const | 120 | bool Battery::isPresent() const | ||
41 | { | 121 | { | ||
42 | return m_device->property(QLatin1String("ExternalConnected")).toBool(); | 122 | return m_device->property(QStringLiteral("ExternalConnected")).toBool(); | ||
43 | } | 123 | } | ||
44 | 124 | | |||
45 | Solid::Battery::BatteryType Battery::type() const | 125 | Solid::Battery::BatteryType Battery::type() const | ||
46 | { | 126 | { | ||
47 | // TODO - how to figure that one out? | 127 | // TODO - how to figure that one out? Just presume we're | ||
48 | return Solid::Battery::UnknownBattery; | 128 | // only called with the main battery. | ||
129 | return Solid::Battery::PrimaryBattery; | ||||
49 | } | 130 | } | ||
50 | 131 | | |||
51 | int Battery::chargePercent() const | 132 | int Battery::chargePercent() const | ||
52 | { | 133 | { | ||
53 | if (m_device->property(QLatin1String("FullyCharged")).toBool()) { | 134 | // always calculate since FullyCharged remains true down to 92% or so. | ||
54 | return 100; | 135 | int maxCapacity = m_device->property(QStringLiteral("MaxCapacity")).toInt(); | ||
55 | } | | |||
56 | | ||||
57 | int maxCapacity = m_device->property(QLatin1String("MaxCapacity")).toInt(); | | |||
58 | if (maxCapacity == 0) { | 136 | if (maxCapacity == 0) { | ||
59 | return 0; // prevent divide by 0 | 137 | return 0; // prevent divide by 0 | ||
60 | } | 138 | } | ||
61 | return m_device->property(QLatin1String("CurrentCapacity")).toInt() / maxCapacity; | 139 | return int(m_device->property(QStringLiteral("CurrentCapacity")).toInt() * 100.0 / maxCapacity + 0.5); | ||
62 | } | 140 | } | ||
63 | 141 | | |||
64 | int Battery::capacity() const | 142 | int Battery::capacity() const | ||
65 | { | 143 | { | ||
66 | // TODO | 144 | if (m_device->iOKitPropertyExists(QStringLiteral("PermanentFailureStatus")) | ||
145 | && m_device->property(QStringLiteral("PermanentFailureStatus")).toInt()) { | ||||
146 | return 0; | ||||
147 | } | ||||
67 | return 100; | 148 | return 100; | ||
68 | } | 149 | } | ||
69 | 150 | | |||
70 | bool Battery::isRechargeable() const | 151 | bool Battery::isRechargeable() const | ||
71 | { | 152 | { | ||
72 | return m_device->property(QLatin1String("DesignCycleCount")).toInt() > 1; | 153 | return m_device->property(QStringLiteral("CycleCount")).toInt() > 1; | ||
73 | } | 154 | } | ||
74 | 155 | | |||
75 | bool Battery::isPowerSupply() const | 156 | bool Battery::isPowerSupply() const | ||
76 | { | 157 | { | ||
77 | // TODO | 158 | return m_device->iOKitPropertyExists(QStringLiteral("BatteryInstalled")) | ||
78 | return true; | 159 | ? m_device->property(QStringLiteral("BatteryInstalled")).toBool() | ||
160 | : true; | ||||
79 | } | 161 | } | ||
80 | 162 | | |||
81 | Solid::Battery::ChargeState Battery::chargeState() const | 163 | Solid::Battery::ChargeState Battery::chargeState() const | ||
82 | { | 164 | { | ||
83 | if (m_device->property(QLatin1String("IsCharging")).toBool()) { | 165 | if (m_device->property(QStringLiteral("IsCharging")).toBool()) { | ||
84 | return Solid::Battery::Charging; | 166 | return Solid::Battery::Charging; | ||
85 | } | 167 | } | ||
86 | if (m_device->property(QLatin1String("FullyCharged")).toBool()) { | 168 | if (m_device->property(QStringLiteral("FullyCharged")).toBool()) { | ||
87 | return Solid::Battery::NoCharge; | 169 | return Solid::Battery::FullyCharged; | ||
88 | } | 170 | } | ||
89 | return Solid::Battery::Discharging; | 171 | return Solid::Battery::Discharging; | ||
90 | } | 172 | } | ||
91 | 173 | |