VR-25 / acc

Advanced Charging Controller
https://github.com/Magisk-Modules-Repo/acc
GNU General Public License v3.0
1.76k stars 109 forks source link

Provide an option to force enable battery idle mode #106

Closed ysc3839 closed 2 years ago

ysc3839 commented 3 years ago

My phone supports battery idle mode but acc says it's not working. I found that it's because test_charging_switch function checks if battery/status contains "not" to determine if it's working. However the kernel of my phone doesn't report it's not charging, it just charge with a low current. So can you provide an option to force enable battery idle mode, or check it using current_now?

VR-25 commented 3 years ago

What's the current_now threshold?

ysc3839 commented 3 years ago

I just found that when I using the charger comes with the phone, the battery_charging_enabled is not working. The device is Redmi K40, with official system. It's working with a QC3.0 and a USB PD (using C to C cable) charger. When charging disabled and the screen is on, current_now is positive, between 60000 and 200000. When the screen is off, it sometimes is negative, between -4000 and -40000.

VR-25 commented 3 years ago

I just found that when I using the charger comes with the phone, the battery_charging_enabled is not working. The device is Redmi K40, with official system. It's working with a QC3.0 and a USB PD (using C to C cable) charger.

Refer to https://github.com/VR-25/acc#warp-vooc-and-other-fast-charging-tech .

When charging disabled and the screen is on, current_now is positive, between 60000 and 200000. When the screen is off, it sometimes is negative, between -4000 and -40000.

Ok, I'll see what can be done about this.

ysc3839 commented 3 years ago

Here is the data recorded using while true; do cat current_now; sleep 1s; done:

# charging, screen off
-2632811
-2595213
-2594725
-2601072
-2624510
-2643065
# echo 0 > battery_charging_enabled
-12207
-37109
5371
-17089
-48828
-51757
-39550
-39062
-5859
142089
65917
74706
-43457
-41992
12207
-15136
17089
41503
73242
92773
86914
97656
31738
# screen on
1457030
228515
93261
441406
428710
262695
383300
262695
644530
572753
310546
534667
606933
569335
348144
365722
501464
1383788
689452
951171
356445

Battery is 80%.

VR-25 commented 3 years ago

Based on this information, I think a better solution is having a switch flag to disable charging status checking.

ysc3839 commented 3 years ago

I think we can use a editable threshold value, for example:

echo 0 > battery_charging_enabled
sleep 1s
current = $(cat current_now)
if current > 0: it's not charging
if current < 0:
  if abs(current) < editable_current_threshold: it's not charging
  else: it's charging

if charging, fallback to input_suspend
VR-25 commented 3 years ago

ACC now support plugins. Those come in the form of shell scripts that override functions and some variables. The current version loads plugins from /data/adb/vr-25/acc-data/**pluggins**/. Yes, there's a typo there. accd must be restarted to load plugins. Only .sh files are considered.

Below is the function that checks the charging status. Return codes: 0: ((Dis|Not )charging) 1: Charging

not_charging() {
  if test -f sm????_bms/status; then
    grep -Eiq "${1-dis|not}" sm????_bms/status
  else
    grep -Eiq "${1-dis|not}" $batt/status
  fi
}

Overriding charging status based on the value of battery_charging_enabled:

not_charging() {
  local value=
  if [ X${chargingSwitch[@]-} = "Xbattery_charging_enabled 1 0" ]; then
    value= $(cat battery_charging_enabled)
    [ $value -eq 0 ]
  else
    if test -f sm????_bms/status; then
      grep -Eiq "${1-dis|not}" sm????_bms/status
    else
      grep -Eiq "${1-dis|not}" $batt/status
    fi
}
VR-25 commented 3 years ago

@ysc3839, does your device report CHARGE_TYPE? (acc -i)

ysc3839 commented 3 years ago

@VR-25 CHARGE_TYPE=Fast When plugged in. Even when connected to computer USB. CHARGE_TYPE=N/A When unplugged.

VR-25 commented 3 years ago

accv2021.9.15(202109150).zip If current drops by 25% or more after disable_charging() is called, not_charging() returns true, regardless of the charging status reported by the kernel. Try it.

VR-25 commented 3 years ago

accv2021.9.15.1(202109151).zip Enhancements

ysc3839 commented 3 years ago

@VR-25 Thank you very much! AccA reports idle mode is supported. I need more time waiting for full charge.

ysc3839 commented 3 years ago

I just found acc crashed, the log says:

/system/bin/acc[580]: 0.279296: unexpected '.'
/system/bin/acc[580]:  (currNow * 25) / 100 : expression recurses on parameter 'currNow'
VR-25 commented 3 years ago

This should be easy to fix. I'll work on it in a couple of hours.

VR-25 commented 3 years ago

accv2021.9.16(202109160).zip

VR-25 commented 3 years ago

accv2021.9.16.1(202109161).zip

VR-25 commented 3 years ago

accv2021.9.16.2(202109162).zip

VR-25 commented 3 years ago

accv2021.9.16.3(202109163).zip

VR-25 commented 3 years ago

accv2021.9.16.4(202109164).zip

elem089 commented 3 years ago

Hi all, first of all I'm not sure whether this is the right to ask the questions that are following. Don't hesitate to direct me to somewhere else (I quit using telegram, and the xda forum appears to be dead for acc related topics). Next I ask you to be patient with me: I tried to follow and understnad what so far has been discussed in here but most of it is beyond my horizon, to be honest. I've been running acc on various devices (2 old Xperias, plus 1 OP6 with latest OOS 11) since several years. I feel quite comfortable with the basic settings so far. And: I don't use ACCA, operate acc through terminal. Current acc version is 2021.9.5 Finally: I'm not at all a Linux expert, but I get along quite well.

Q1: after installing V2021.9.5 I ran the "Test charging switches" script which brought up some new switches, incl. the option to use more than one switch. I decided to go for one of the options, and I also set the "prioritizeBattIdleMode" option to "true"; so now my config file looks like this:

configVerCode=202108120 
capacity=(2 101 79 80 true) 
temperature=(40 60 90 65) 
cooldownRatio=( ) 
cooldownCurrent= 
cooldownCustom=() 
resetBattStats=(false false) 
chargingSwitch=(battery/op_disable_charge 0 1 battery/input_suspend 0 0) 
applyOnBoot=() 
applyOnPlug=() 
maxChargingCurrent=() 
maxChargingVoltage=() 
language=en 
runCmdOnPause=() 
ampFactor= 
voltFactor= 
loopCmd=() 
prioritizeBattIdleMode=true 
currentWorkaround=false

Then plugging the charger I see that - like before - it stops at 80%, and the battery icon drops the "being charged" indicator. But, where before it would quickly drop to 79%, then resume charging, it now remins at 80% for quite some time, like 5 - 10 minutes, and after that it also remains at 79% for a while before resuming to charage.

Question: is that the expected behaviour, or should the battery really stay at 80% with the icon telling me that the charger is still doing something? (I used to observe that behaviour on one of my Xperias: battery would remain at 80% like forever, and the battery icon would constantly tell me that the device is being charged)

Q2: In the above situation (charged up to 80%, charger is still plugged in, charger icon is OFF) I ran acc -i. Response was this:

:/ # acc -i 

Battery Service 
  AC powered: true 
  USB powered: false 
  Wireless powered: false 
  Max charging current: 1500000 
  Max charging voltage: 5000000 
  Charge counter: 2534962 
  status: 4 
  health: 2 
  present: true 
  level: 80 
  scale: 100 
  voltage: 4118 
  temperature: 263 
  technology: Li-ion 
  fastChargeStatus: false 

Uevent 
  BATTERY_HEALTH=83 
  BATTERY_TYPE=OP_3300mah 
  BQ_SOC=80 
  CAPACITY=80 
  CAPACITY_RAW=203 
  CC_STEP=0 
  CC_STEP_SEL=0 
  CHARGER_TEMP=345 
  CHARGER_TEMP_MAX=812 
  CHARGE_CONTROL_LIMIT=0 
  CHARGE_CONTROL_LIMIT_MAX=4 
  CHARGE_COUNTER=2534963 
  CHARGE_COUNTER_SHADOW=2295104 
  CHARGE_DONE=0 
--More--

Question: what does that all mean? Is there some kind of explanation available? Esp the lines below "Uevent" don't make too much sense to me (well, I can guess a few, but far from all). I checked Readme.md already; well, maybe not good enough?

Q3: finally: assuming that battery idle mode is now working for my (see Q1): is there some way for me to find out if it really is working?

Thanks for your work, and your patience, and all the best

VR-25 commented 3 years ago

@elem089, part of the output of acc -i is missing. The script uses the program more to page the output text. Pressing the down arrow or the apace bar reveals more text or the next page.

While I cannot tell with great certainty that idle mode is working, it seems so. Self discharge is a thing. Thus, although very slowly, the battery level is expected to drop even in regular idle mode. After all, it's as if the battery were physically disconnected from the phone.

acc -i (or the more concise acca -i) output STATUS=, which can be Charging, Not charging or Discharging. The second indicates that idle mode is active. You can filter the output with case insensitive egrep regular expressions (e.g., acc -i status, acca -i status\|curr).

acc -t, as you probably already know, also tests whether idle mode is supported (battIdleMode=true). It looks for STATUS=Not charging.

Idle mode depends on the charging switch(es). Some support it by themselves, while others must be paired with other switches to achieve the effect. The next release will bring additional/enhanced idle mode support.

capacity=(2 101 79 80 true)

# capacity_freeze2 (cft) #
# This prevents Android from getting capacity readings below 2%.
# In doing so, it forces Android to report the actual battery capacity reported by the kernel.
# This comes at a cost of some overhead.
# It's useful on systems that shutdown before the battery is actually empty.
# One may also use it to mask the frequent charging on/off behavior of the cooldown feature.
# Changes to this variable require a daemon restart (automated by "acc --set").

Judging by your config and device, you probably don't need this. Disable with acc -s cft=false

elem089 commented 3 years ago

Many thanks, as always!

part of the output of acc -i is missing.

you're right; I felt it would turn out to be too long for this post (btw: by mistake I posted in this thread here instead of the "Possible solution for..." one; glad you still made sense of it ;))

capacity=(2 101 79 80 true)

Alright; I'll try with "false" instead; I assume though that I won't see any difference in the device's behaviour. Or would I?

UPDATE: very cool: with cft set to FALSE now the charging indicator stays on even after reaching 80%. And, yes: acc -i now is showing "STATUS=Not charging"! Is it correct to assume that further down where it says

CURRENT NOW=0 Amps
POWER NOW=0 Watts

is another indication for battIdle mode?

Thanks, once again

VR-25 commented 3 years ago

very cool: with cft set to FALSE now the charging indicator stays on even after reaching 80%. And, yes: acc -i now is showing "STATUS=Not charging"! Is it correct to assume that further down where it says

CURRENT NOW=0 Amps
POWER NOW=0 Watts

is another indication for battIdle mode?

Thanks, once again

Yes, CURRENT_NOW=0 generally indicates idle mode as well.

VR-25 commented 3 years ago

accdebug(202109164).zip This is a standard build for everyone.

idle.sh.zip @ysc3839, you need to extract this plugin to /dev/.vr25/acc/plugins/ and restart accd. I chose that path because it's volatile (great for debugging). But you can also place the plugin in /data/adb/vr25/acc-data/plugins/, which makes it immune to reboots. Volatile plugins override the permanent.

ysc3839 commented 3 years ago

@VR-25 How can I view real-time log of acc? Using logcat? And how to log something in plugin?

VR-25 commented 3 years ago

@VR-25 How can I view real-time log of acc? Using logcat? And how to log something in plugin?

acc -T Plugin verbose is included in the main log, but you can edit each plugin to redirect logs as you please.

seraphg commented 2 years ago

I just found that when I using the charger comes with the phone, the battery_charging_enabled is not working. The device is Redmi K40, with official system. It's working with a QC3.0 and a USB PD (using C to C cable) charger. When charging disabled and the screen is on, current_now is positive, between 60000 and 200000. When the screen is off, it sometimes is negative, between -4000 and -40000.

Hi @ysc3839 , Do you still have that K40 and is battery/battery_charging_enabled still working? I now have a K50p where battery idle mode works perfectly (with the latest dev build though), while my K40 doesn't work with battery/battery_charging_enabled at all:

1/24: battery/battery_charging_enabled 1 0 switch: off (0) current: -1383mA (Charging) switch: off (0) current: -1320mA (Charging) switch: off (0) current: -1293mA (Charging) switch: off (0) current: -1387mA (Charging) switch: off (0) current: -1222mA (Charging) switch: off (0) current: -1337mA (Charging) switch: off (0) current: -1341mA (Charging) switch: off (0) current: -1259mA (Charging) switch: off (0) current: -1173mA (Charging) switch: off (0) current: -1357mA (Charging) switch: off (0) current: -1309mA (Charging) switch: off (0) current: -1340mA (Charging) switch: off (0) current: -362mA (Charging) switch: off (0) current: -702mA (Charging) switch: off (0) current: -1324mA (Charging) Switch doesn't work ❌

I'm using MIUI 13.0.6 official ROM, and regular charger (not redmi's fast charger). In order to enable Idle mode, I have to use another charge switch:

16/24: battery/constant_charge_current_max 6000000 50000 switch: off (50000) current: -31mA (Idle) switch: on (6000000) current: -702mA (Charging) Switch works ✅

But this one seems not "real" Idle. There keeps having small amount of current, around 30mA.

So want to check with you, if you still have K40, how do you make Idle mode working?

Thanks, David