Implement max charge current setting
This commit is contained in:
parent
ebd1e64ef7
commit
7042751703
11 changed files with 125 additions and 5 deletions
|
@ -44,6 +44,7 @@ Page {
|
|||
running: true
|
||||
onTriggered: {
|
||||
autoStopCharging.checked = settings.limitEnabled
|
||||
maxChargeCurrentSlider.value = settings.maxChargeCurrent
|
||||
highLimitSlider.value = settings.highLimit
|
||||
lowLimitSlider.value = settings.lowLimit
|
||||
highAlertSlider.value = settings.highAlert
|
||||
|
@ -181,6 +182,24 @@ Page {
|
|||
smallChange: 1
|
||||
largeChange: 5
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Maximum Charge Current")
|
||||
visible: settings.maxSupportedChargeCurrent > 0
|
||||
}
|
||||
|
||||
MySlider {
|
||||
id: maxChargeCurrentSlider
|
||||
visible: settings.maxSupportedChargeCurrent > 0
|
||||
minimumValue: 500000
|
||||
maximumValue: settings.maxSupportedChargeCurrent
|
||||
stepSize: 100000
|
||||
valueText: (value / 1000) + "mA"
|
||||
onReleased: save()
|
||||
function save() {
|
||||
settings.maxChargeCurrent = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
chmod 644 /sys/class/power_supply/battery/input_suspend 2>/dev/null
|
||||
chmod 644 /sys/class/power_supply/battery/charging_enabled 2>/dev/null
|
||||
chmod 644 /sys/class/power_supply/battery/constant_charge_current_max 2>/dev/null
|
||||
chmod 644 /sys/class/power_supply/usb/charger_disable 2>/dev/null
|
||||
chmod 644 /sys/class/power_supply/dollar_cove_battery/enable_charging 2>/dev/null
|
||||
exit 0
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
chmod 666 /sys/class/power_supply/battery/input_suspend 2>/dev/null
|
||||
chmod 666 /sys/class/power_supply/battery/charging_enabled 2>/dev/null
|
||||
chmod 666 /sys/class/power_supply/battery/constant_charge_current_max 2>/dev/null
|
||||
chmod 666 /sys/class/power_supply/usb/charger_disable 2>/dev/null
|
||||
chmod 666 /sys/class/power_supply/dollar_cove_battery/enable_charging 2>/dev/null
|
||||
exit 0
|
||||
|
|
|
@ -225,6 +225,8 @@ int Battery::getCharge(){ return charge; }
|
|||
|
||||
int Battery::getCurrent(){ return current; }
|
||||
|
||||
int Battery::getMaxChargeCurrent() { return maxChargeCurrent; }
|
||||
|
||||
QString Battery::getState() { return state; }
|
||||
|
||||
QString Battery::getHealth() { return health; }
|
||||
|
|
|
@ -31,6 +31,7 @@ class Battery : public QObject
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(int charge READ getCharge NOTIFY chargeChanged)
|
||||
Q_PROPERTY(int current READ getCurrent NOTIFY currentChanged)
|
||||
Q_PROPERTY(int maxChargeCurrent READ getMaxChargeCurrent)
|
||||
Q_PROPERTY(bool chargerConnected READ getChargerConnected NOTIFY chargerConnectedChanged)
|
||||
Q_PROPERTY(QString state READ getState NOTIFY stateChanged)
|
||||
Q_PROPERTY(bool chargingEnabled READ getChargingEnabled NOTIFY chargingEnabledChanged)
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
|
||||
int getCharge();
|
||||
int getCurrent();
|
||||
int getMaxChargeCurrent();
|
||||
bool getCharging();
|
||||
bool getChargerConnected();
|
||||
QString getState();
|
||||
|
@ -62,6 +64,7 @@ private:
|
|||
QFile* chargerConnectedFile = nullptr;
|
||||
QFile* stateFile = nullptr;
|
||||
QFile* chargingEnabledFile = nullptr;
|
||||
QFile* maxChargeCurrentFile = nullptr;
|
||||
Settings* settings = nullptr;
|
||||
Logger* logger = nullptr;
|
||||
|
||||
|
@ -74,6 +77,7 @@ private:
|
|||
bool chargerConnected = false; // Charger plugged in
|
||||
QString state = "idle"; // dis/charging, idle, unknown
|
||||
bool chargingEnabled = true; // Only ever disabled manually
|
||||
int maxChargeCurrent = 0; // Charge current limit in micro amps
|
||||
|
||||
QString health = "unknown"; // Good, warm, overheat. Might have Cold or Overvoltage depending on driver
|
||||
int temperature = 0x7FFFFFFF; // This value means "unknown" (32-bit INT_MAX)
|
||||
|
|
|
@ -38,6 +38,8 @@ Settings::Settings(Logger *newLogger, QObject *parent) : QObject(parent)
|
|||
loadInteger(sLimitEnabled, limitEnabled, 0, 1);
|
||||
loadInteger(sLowLimit, lowLimit, 5, 99);
|
||||
loadInteger(sHighLimit, highLimit, 6, 100);
|
||||
loadInteger(sMaxSupportedChargeCurrent, maxSupportedChargeCurrent, 0, 5000000);
|
||||
loadInteger(sMaxChargeCurrent, maxChargeCurrent, 0, maxSupportedChargeCurrent);
|
||||
loadInteger(sLogLevel, logLevel, 0, 2);
|
||||
|
||||
loadString(sLogFilename, logFilename);
|
||||
|
@ -72,6 +74,8 @@ int Settings::getLowNotificationsInterval() { return lowNotificationsInte
|
|||
int Settings::getHealthNotificationsInterval() { return healthNotificationsInterval; }
|
||||
int Settings::getLowLimit() { return lowLimit; }
|
||||
int Settings::getHighLimit() { return highLimit; }
|
||||
int Settings::getMaxChargeCurrent() { return maxChargeCurrent; }
|
||||
int Settings::getMaxSupportedChargeCurrent() { return maxSupportedChargeCurrent; }
|
||||
bool Settings::getLimitEnabled() { return limitEnabled == 1; }
|
||||
QString Settings::getLowAlertFile() { return lowAlertFile; }
|
||||
QString Settings::getHighAlertFile() { return highAlertFile; }
|
||||
|
@ -132,6 +136,11 @@ void Settings::setHighLimit(const int newLimit) {
|
|||
emit highLimitChanged(highLimit);
|
||||
}
|
||||
|
||||
void Settings::setMaxChargeCurrent(const int newCurrent) {
|
||||
if(saveInteger(sMaxChargeCurrent, newCurrent, maxChargeCurrent))
|
||||
emit maxChargeCurrentChanged(maxChargeCurrent);
|
||||
}
|
||||
|
||||
void Settings::setLimitEnabled(const bool newEnabled) {
|
||||
if(saveInteger(sLimitEnabled, (newEnabled ? 1 : 0), limitEnabled))
|
||||
emit limitEnabledChanged(limitEnabled);
|
||||
|
|
|
@ -33,6 +33,8 @@ class Settings : public QObject
|
|||
Q_PROPERTY(int healthNotificationsInterval READ getHealthNotificationsInterval WRITE setHealthNotificationsInterval NOTIFY healthNotificationsIntervalChanged)
|
||||
Q_PROPERTY(int highLimit READ getHighLimit WRITE setHighLimit NOTIFY highLimitChanged)
|
||||
Q_PROPERTY(int lowLimit READ getLowLimit WRITE setLowLimit NOTIFY lowLimitChanged)
|
||||
Q_PROPERTY(int maxChargeCurrent READ getMaxChargeCurrent WRITE setMaxChargeCurrent NOTIFY maxChargeCurrentChanged)
|
||||
Q_PROPERTY(int maxSupportedChargeCurrent READ getMaxSupportedChargeCurrent NOTIFY maxSupportedChargeCurrentChanged)
|
||||
Q_PROPERTY(bool limitEnabled READ getLimitEnabled WRITE setLimitEnabled NOTIFY limitEnabledChanged)
|
||||
Q_PROPERTY(QString highAlertFile READ getHighAlertFile NOTIFY highAlertFileChanged)
|
||||
Q_PROPERTY(QString lowAlertFile READ getLowAlertFile NOTIFY lowAlertFileChanged)
|
||||
|
@ -58,6 +60,8 @@ public:
|
|||
int getHealthNotificationsInterval();
|
||||
int getLowLimit();
|
||||
int getHighLimit();
|
||||
int getMaxChargeCurrent();
|
||||
int getMaxSupportedChargeCurrent();
|
||||
bool getLimitEnabled();
|
||||
QString getLowAlertFile();
|
||||
QString getHighAlertFile();
|
||||
|
@ -79,6 +83,7 @@ public:
|
|||
void setHealthNotificationsInterval(const int newInterval);
|
||||
void setLowLimit(const int newLimit);
|
||||
void setHighLimit(const int newLimit);
|
||||
void setMaxChargeCurrent(const int newCurrent);
|
||||
void setLimitEnabled(const bool newEnabled);
|
||||
void setNotificationTitle(const QString newText);
|
||||
void setNotificationLowText(const QString newText);
|
||||
|
@ -103,6 +108,8 @@ private:
|
|||
int limitEnabled = 1; // Converted to boolean for QML
|
||||
int lowLimit = 65;
|
||||
int highLimit = 70;
|
||||
int maxChargeCurrent = 0; // micro amps
|
||||
int maxSupportedChargeCurrent = 0; // micro amps
|
||||
QString lowAlertFile = "/usr/share/sounds/jolla-ambient/stereo/general_warning.wav";
|
||||
QString highAlertFile = "/usr/share/sounds/jolla-ambient/stereo/positive_confirmation.wav";
|
||||
QString healthAlertFile = lowAlertFile;
|
||||
|
@ -125,6 +132,8 @@ private:
|
|||
const char* sLimitEnabled = "limitEnabled";
|
||||
const char* sLowLimit = "lowLimit";
|
||||
const char* sHighLimit = "highLimit";
|
||||
const char* sMaxSupportedChargeCurrent = "maxSupportedChargeCurrent";
|
||||
const char* sMaxChargeCurrent = "maxChargeCurrent";
|
||||
const char* sLowAlertFile = "lowAlertFile";
|
||||
const char* sHighAlertFile = "highAlertFile";
|
||||
const char* sHealthAlertFile = "healthAlertFile";
|
||||
|
@ -153,6 +162,8 @@ signals:
|
|||
void limitEnabledChanged(bool);
|
||||
void lowLimitChanged(int);
|
||||
void highLimitChanged(int);
|
||||
void maxChargeCurrentChanged(int);
|
||||
void maxSupportedChargeCurrentChanged(int);
|
||||
void lowAlertFileChanged(QString);
|
||||
void highAlertFileChanged(QString);
|
||||
void healthAlertFileChanged(QString);
|
||||
|
|
|
@ -63,6 +63,38 @@ Battery::Battery(Logger* newLogger, bool loglevelSet, QCoreApplication *app, QOb
|
|||
if(currentFile) logL("Charging/discharging current file: " + currentFile->fileName());
|
||||
else logL("Charging/discharging current file: not found!");
|
||||
|
||||
// Maximum charge current in microamps, e.g. 3500000 (3500mA)
|
||||
filenames.clear();
|
||||
filenames << "/sys/class/power_supply/battery/constant_charge_current_max";
|
||||
|
||||
foreach(const QString& file, filenames) {
|
||||
if(!maxChargeCurrentFile && QFile::exists(file)) {
|
||||
maxChargeCurrentFile = new QFile(file, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(maxChargeCurrentFile) {
|
||||
logL("Max charge current file: " + maxChargeCurrentFile->fileName());
|
||||
if(maxChargeCurrentFile->open(QIODevice::WriteOnly)) {
|
||||
maxChargeCurrentFile->close();
|
||||
if(maxChargeCurrentFile->open(QIODevice::ReadOnly)) {
|
||||
maxSupportedChargeCurrent = maxChargeCurrentFile->readLine().trimmed().toInt();
|
||||
logL(QString("Maximum supported charge current: %1mA").arg(maxSupportedChargeCurrent / 1000));
|
||||
maxChargeCurrentFile->close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
logL("Max charge current file is not writable - feature disabled");
|
||||
delete maxChargeCurrentFile;
|
||||
maxChargeCurrentFile = Q_NULLPTR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
logL("Max charge current file: not found!");
|
||||
}
|
||||
settings->setMaxSupportedChargeCurrent(maxSupportedChargeCurrent);
|
||||
|
||||
// Battery/charging status: charging, discharging, full, empty, unknown (others?)
|
||||
filenames.clear();
|
||||
filenames << "/sys/class/power_supply/battery/status"
|
||||
|
@ -161,6 +193,7 @@ Battery::Battery(Logger* newLogger, bool loglevelSet, QCoreApplication *app, QOb
|
|||
else logL("Charger control file: not found!");
|
||||
|
||||
connect(settings, SIGNAL(resetTimers()), this, SLOT(resetTimers()));
|
||||
connect(settings, SIGNAL(setMaxChargeCurrent(int)), this, SLOT(setMaxChargeCurrent(int)));
|
||||
|
||||
updateTimer = new BackgroundActivity(app);
|
||||
highNotifyTimer = new BackgroundActivity(app);
|
||||
|
@ -192,6 +225,8 @@ Battery::Battery(Logger* newLogger, bool loglevelSet, QCoreApplication *app, QOb
|
|||
}
|
||||
|
||||
Battery::~Battery() {
|
||||
this->setMaxChargeCurrent(maxSupportedChargeCurrent);
|
||||
|
||||
updateTimer->stop();
|
||||
highNotifyTimer->stop();
|
||||
lowNotifyTimer->stop();
|
||||
|
@ -447,6 +482,25 @@ bool Battery::setChargingEnabled(const bool isEnabled) {
|
|||
return success;
|
||||
}
|
||||
|
||||
void Battery::setMaxChargeCurrent(int newCurrent) {
|
||||
if(maxChargeCurrentFile) {
|
||||
logM(QString("Setting max charging current to %1...").arg(newCurrent / 1000));
|
||||
if(newCurrent > maxSupportedChargeCurrent) {
|
||||
newCurrent = maxSupportedChargeCurrent;
|
||||
}
|
||||
if(maxChargeCurrentFile->open(QIODevice::WriteOnly)) {
|
||||
QString data = QString("%1").arg(newCurrent);
|
||||
if(!maxChargeCurrentFile->write(data.toLocal8Bit())) {
|
||||
logM("Could not write to max charging current file");
|
||||
}
|
||||
}
|
||||
else {
|
||||
logM("Could not open max charging current file");
|
||||
}
|
||||
maxChargeCurrentFile->close();
|
||||
}
|
||||
}
|
||||
|
||||
bool Battery::getChargerConnected() {
|
||||
return chargerConnected;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ private:
|
|||
QFile *currentFile = nullptr;
|
||||
QFile *stateFile = nullptr;
|
||||
QFile *chargingEnabledFile = nullptr;
|
||||
QFile *maxChargeCurrentFile = nullptr;
|
||||
QFile *temperatureFile = nullptr;
|
||||
QFile *healthFile = nullptr;
|
||||
Settings *settings = nullptr;
|
||||
|
@ -98,6 +99,8 @@ private:
|
|||
bool chargerConnected = false; // Charger plugged in
|
||||
QString state = "idle"; // dis/charging, idle, unknown
|
||||
bool chargingEnabled = true; // Only ever disabled manually
|
||||
int maxChargeCurrent = 0;
|
||||
int maxSupportedChargeCurrent = 0;
|
||||
|
||||
QString health = "unknown"; // Good, warm, overheat. Might have Cold or Overvoltage depending on driver
|
||||
int temperature = 0x7FFFFFFF; // This value means "unknown" (32-bit INT_MAX)
|
||||
|
@ -124,6 +127,7 @@ public slots:
|
|||
void showHighNotification();
|
||||
void showLowNotification();
|
||||
void showHealthNotification();
|
||||
void setMaxChargeCurrent(int newCurrent);
|
||||
};
|
||||
|
||||
#endif // BATTERY_H
|
||||
|
|
|
@ -96,11 +96,12 @@ Settings::Settings(Logger* newLogger, QObject *parent) : QObject(parent)
|
|||
notificationHealthWarnText = "Battery health is not good";
|
||||
notificationHealthCritText = "Battery health is critical";
|
||||
|
||||
// Do this here, because...
|
||||
watcher = new QFileSystemWatcher(QStringList(mySettings->fileName()), this);
|
||||
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(updateConfig(QString)));
|
||||
|
||||
// ...calling this deletes mySettings!
|
||||
// To trigger setting the initial config value
|
||||
maxChargeCurrent = 0;
|
||||
|
||||
updateConfig(mySettings->fileName());
|
||||
}
|
||||
|
||||
|
@ -123,6 +124,8 @@ void Settings::updateConfig(const QString path) {
|
|||
// Use the same file location as GUI for data exchange
|
||||
if(!mySettings) {
|
||||
mySettings = new QSettings(appName, appName, this);
|
||||
} else {
|
||||
mySettings->sync();
|
||||
}
|
||||
|
||||
logH("Updating configuration...");
|
||||
|
@ -139,6 +142,9 @@ void Settings::updateConfig(const QString path) {
|
|||
loadInteger(sLimitEnabled, limitEnabled, 0, 1);
|
||||
loadInteger(sLowLimit, lowLimit, 5, 99);
|
||||
loadInteger(sHighLimit, highLimit, 6, 100);
|
||||
if(loadInteger(sMaxChargeCurrent, maxChargeCurrent, 0, 5000000)) {
|
||||
emit setMaxChargeCurrent(maxChargeCurrent);
|
||||
}
|
||||
|
||||
notificationTitle = mySettings->value(sNotificationTitle, notificationTitle).toString();
|
||||
notificationLowText = mySettings->value(sNotificationLowText, notificationLowText).toString();
|
||||
|
@ -158,9 +164,6 @@ void Settings::updateConfig(const QString path) {
|
|||
logL(QString("Log level set to %1").arg((logLevel == 0 ? "low" : (logLevel == 1 ? "medium" : "high"))));
|
||||
}
|
||||
|
||||
delete mySettings;
|
||||
mySettings = nullptr;
|
||||
|
||||
// Let the file system settle...
|
||||
QThread::msleep(100);
|
||||
|
||||
|
@ -180,6 +183,7 @@ void Settings::updateConfig(const QString path) {
|
|||
// Getters condensed
|
||||
int Settings::getLowAlert() { return lowAlert; }
|
||||
int Settings::getHighAlert() { return highAlert; }
|
||||
int Settings::getMaxChargeCurrent() { return maxChargeCurrent; }
|
||||
int Settings::getHealthAlert() { return healthAlert; }
|
||||
int Settings::getHighNotificationsInterval() { return highNotificationsInterval; }
|
||||
int Settings::getLowNotificationsInterval() { return lowNotificationsInterval; }
|
||||
|
@ -197,3 +201,7 @@ QString Settings::getNotificationHealthTitle() { return notificationHealthTi
|
|||
QString Settings::getNotificationHealthWarnText() { return notificationHealthWarnText; }
|
||||
QString Settings::getNotificationHealthCritText() { return notificationHealthCritText; }
|
||||
int Settings::getLogLevel() { return logLevel; }
|
||||
|
||||
void Settings::setMaxSupportedChargeCurrent(int newCurrent) {
|
||||
mySettings->setValue(sMaxSupportedChargeCurrent, QByteArray::number(newCurrent));
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
|
||||
int getLowAlert();
|
||||
int getHighAlert();
|
||||
int getMaxChargeCurrent();
|
||||
int getHighNotificationsInterval();
|
||||
int getLowNotificationsInterval();
|
||||
int getHealthAlert();
|
||||
|
@ -55,6 +56,8 @@ public:
|
|||
QString getNotificationHealthWarnText();
|
||||
QString getNotificationHealthCritText();
|
||||
|
||||
void setMaxSupportedChargeCurrent(int newCurrent);
|
||||
|
||||
private:
|
||||
Logger* logger;
|
||||
QSettings* mySettings = nullptr;
|
||||
|
@ -70,6 +73,7 @@ private:
|
|||
// Default values
|
||||
int lowAlert = 25;
|
||||
int highAlert = 75;
|
||||
int maxChargeCurrent = 0;
|
||||
int healthAlert = 1; // 0=off, 1=warn, 2=crit
|
||||
int highNotificationsInterval = 60;
|
||||
int lowNotificationsInterval = 60;
|
||||
|
@ -101,6 +105,8 @@ private:
|
|||
const char* sLimitEnabled = "limitEnabled";
|
||||
const char* sLowLimit = "lowLimit";
|
||||
const char* sHighLimit = "highLimit";
|
||||
const char* sMaxChargeCurrent = "maxChargeCurrent";
|
||||
const char* sMaxSupportedChargeCurrent = "maxSupportedChargeCurrent";
|
||||
const char* sLowAlertFile = "lowAlertFile";
|
||||
const char* sHighAlertFile = "highAlertFile";
|
||||
const char* sHealthAlertFile = "healthAlertFile";
|
||||
|
@ -120,6 +126,7 @@ private slots:
|
|||
|
||||
signals:
|
||||
void resetTimers();
|
||||
void setMaxChargeCurrent(int newCurrent);
|
||||
};
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
|
Loading…
Reference in a new issue