HomeTaskerCharge Test - Tasker charger performance tool

Charge Test – Tasker charger performance tool

How long before I get there?

Anker sent me a care package with 2 nice chargers and some bold claims about charging speeds. To verify this, I need a tool. Obviously, I’m not going to sit and watch my phones charging with a stopwatch or camera pointing at it like some popular YouTubers. I’m going to use my wits and the power of Tasker.

I had created this post ages ago, but I changed it to run on stock Tasker without plugins, I hope you like the revamp more!

Tasker to the rescue

I have a different approach this time, as I want more detailed data. I’m not just interested in total charge time, but I want the ability to draw charge profiles, charts and see how the charge rate changes during the charge cycle. That’s more useful data to look at, but also a little more complex profile. Don’t worry I will include the basic information as well.

I will include the NodeRED end to upload the data and create the graphs automatically! One more reason to get hooked on NodeRED! To manage the data, I will be passing it as JSON, if you want a refresh on how to create and read JSON format (don’t worry, this isn’t complicated) I have a 5 min guide to JSON as well.

How does it work?

Tasker Charger Test checks the battery level every 30 seconds. To make sure that it does so only when needed, I introduced a condition that requires the battery to be lower than 5% and AC charger connected. I do that, to only log complete charge cycles. If the battery reaches 100%, the test is stopped automatically, and data uploaded then wiped.

If you wonder why Tasks names have weird prefixes, see my post about organising projects in Tasker and other organisation tips. It’s worth keeping stuff organised and getting into the habit before the list of projects gets too long!

CT_Test Charger

The test starts when the battery hits 5% and the phone is connected to an AC charger. In this task, there is a main loop that checks and stores the value of the %BATT every 30 seconds. Before this happens, I want to create a notification on the phone with options to add the charger name and option to cancel and wipe the data from the current test.


Since I’m using multiple phones, it’s good to trace the phone info as well. I have created 3 variables to keep the information with each set %CTA_PhoneName, %CTA_BatteryCapacity & %CTA_Proto. CTA prefix allows me to wipe all related variables that start with CT without discarding these values. These should be set before you run the test as the battery capacity is used to calculate the charge score.

It’s nice to include that information in the notification as well, in case you need to take the screenshots and verify that all values had been set correctly. I wrapped that in IF condition that checks if values had been set.

This notification has 2 actions one to cancel the test via CT_Cancel task (unplugging the cable will do the same) and to add the name (default name: “n/a”) via CT_Add Name. Both actions will simply run corresponsive tasks.

CT_Add Name

To add the name, use Status Bar action to collapse the notification shade, cancel the existing notification by the title “Charger Test In Progress” and use Input Dialog to add the name of the charger tested. This will create %input – local variable which you can use to set the name of the charger with Variable Set action as %CT_name.

Lastly, update the notification with the chargers name in the title. If you used the name in the title of the notification, you will have to create one more variable %CT_NotificationTitle and store the %CT_name Test in Progress. It’s needed later to cancel the notification with a correct name.

Back to main task

If you haven’t changed the name, you should add Variable Set and save the unchanged notification title Charging Test In Progress. Before we make our loop, create a new variable %CT_ChargeStart and set it to %TIMES (variable storing time in ms). We will need this to calculate our delta. It’s outside our loop as we want this value once.

To have detailed data about the charging process we need arrays. These will store the charge values in an orderly fashion. Use Array Push action to create %CT_BatteryArray & %CT_TimeArray and set these to %BATT and %TIMES respectively pushing data to 1st position. Name the 1st one with the label: loop.

Use Wait action and set it to 30 sec then use Go-To in label mode to loop back to our loop task. To repeat this while charging, you need IF condition %BATT<100. It will loop until the battery is charged.

When the battery is full, the loop is broken and we can start filling in more data. First, we need to duplicate %CT_BatteryArray & %CT_TimeArray actions to add the values for 100% and Set Variable %CT_delta and calculate the total charge time in minutes:

 ((%TIMEMS - %CT_ChargeStart)/1000)/60

Make sure to select “Do Maths” to make it work. We have to do more maths to calculate the charge score, set another variable %CT_Score to calculate the number of milliamps per minute:

 %CTA_BatteryCapacity / %CT_delta

Next, set a new variable %CT_chargestat to a JSON formatted information about charging statistics.

"phone": "%CTA_PhoneName",
"battery": %CTA_BatteryCapacity,
"proto" : "%CTA_Protocols",
"score" : %CT_Score,
"name" : "%CT_name",
"chargeStart" : %CT_ChargeStart,
"chargeStop" : %TIMEMS,
"chargeDelta" : %CT_delta,
"level" : [%CT_BatteryArray()],
"timestamp" : [%CT_TimeArray()]

As a redundancy, you can also push this to an array %CTA_data to have a complete backlog of the test taken.

Lastly, turn off the profile with Profile Status to prevent further updates, use Notify Cancel to remove permanent test notification and use Notify to create a new notification with basic charging info like charger name (%CTname) and time taken (%CT_delta).


Our test notification has a cancel option. it triggers this task. To cancel the test we have to cancel the existing notification with the title %CT_NotificationTitle, then use Flash to provide feedback, Stop out main task CT_Test Charger and disable the profile.

Once all this had been done you can use Variable Clear to search for pattern %CT_* and clear all variables.


To save the progress, upload tasks uses the HTTP request action to send our JSON stored in %CT_chargestat. To send this to NodeRED, set the request to POST, use %CTA_credentials in CT_PhoneData to set your username and password for NodeRED HTTP request (user:password) and include the data in the Body section of the request.

Your URL should look something like this:


Please note that IP can be replaced with hostname or DDNS and the port of your NodeRED may vary based on your configuration. Once data is uploaded, use Variable Clear to search for pattern %CT_* and clear all variables.

You can add a confirmation Flash action IF %http_reponse = 200 and cancel notification with the title “Charger Test Finished”. Add Wait of 20 seconds and clear variables that match %CT_*.

A1: Variable Set [ Name:%CTA_PhoneName To:Xiaomi Mi 9
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]

A2: Variable Set [ Name:%CTA_BatteryCapacity To:3300
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
A3: Variable Set [ Name:%CTA_Protocols To:Fast Charge 27W, Quick Charge 4+
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
A4: Variable Set [ Name:%CTA_credentials To:user:pass
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]

CT_Test Charger
Abort Existing Task
A1: Variable Set [ Name:%CT_NotificationTitle To:Charger Test In Progress
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
A2: If [ %CTA_PhoneName !Set | %CTA_BatteryCapacity !Set | %CTA_Protocols !Set ]
A3: Notify [ Title:Setup Needed Text:Please configure CT_PhoneData task first
Icon:mw_device_battery_alert Number:0 Permanent:On
:1 Repeat Alert:Off LED Colour:Blue LED Rate:0 Sound File:
Vibration Pattern: Category:Charger Actions:(2) ]
A4: Stop [ With Error:Off Task: ]
A5: End If
A6: Notify [ Title:Charger Test In Progress Text:The test is running on %CTA_PhoneName with %CTA_BatteryCapacity mAh . Supported protocols: %CTA_Protocols.
Icon:mw_device_battery_alert Number:0 Permanent:On
Priority:1 Repeat Alert:Off LED Colour:Blue LED Rate:0 Sound File:
Vibration Pattern: Category:Charger Actions:(2) ]
A7: Variable Set [ Name:%CT_ChargeStart To:%TIMEMS Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]

A8: Array Push [ Variable Array:%CT_BatteryArray Position:1 Value:%BATT Fill Spaces:On ]
A9: Array Push [ Variable Array:%CT_TimeArray Position:1 Value:%TIMEMS Fill Spaces:On ]
A10: Wait [ MS:0 Seconds:30 Minutes:0 Hours:0 Days:0 ]

A11: Goto [ Type:Action Label Number:2 Label:loop ] If [ %BATT < 100 ]
A12: Variable Set [ Name:%CT_name To:n/a Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ] If [ %CT_name !Set ] A13: Variable Set [ Name:%CT_delta To: ((%TIMEMS - %CT_ChargeStart)/1000)/60 Recurse Variables:Off Do Maths:On Append:Off Max Rounding Digits:1 ] A14: Variable Set [ Name:%CT_Score To:%CTA_BatteryCapacity / %CT_delta Recurse Variables:Off Do Maths:On Append:Off Max Rounding Digits:1 ] A15: Variable Set [ Name:%CT_chargestat To:{ "phone": "%CTA_PhoneName", "battery": %CTA_BatteryCapacity, "proto" : "%CTA_Protocols", "score" : %CT_Score, "name" : "%CT_name", "chargeStart" : %CT_ChargeStart, "chargeStop" : %TIMEMS, "chargeDelta" : %CT_delta, "level" : [%CT_BatteryArray()], "timestamp" : [%CT_TimeArray()]} Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ] A16: Array Push [ Variable Array:%ACT_data Position:1 Value:%CT_chargestat Fill Spaces:On ] A17: Profile Status [ Name:CT_Charge Monitor Set:Off ] A18: Notify Cancel [ Title:%CT_NotificationTitle Warn Not Exist:Off ] A19: Notify [ Title:Charger Test Finished Text:Your charger [%CT_name] statistics for %CTA_PhoneName (%CTA_BatteryCapacity mAh) Charge time from 5% to 100: %CT_delta min Charge completed at: %TIME Charge score: %CT_Score Icon:mw_device_battery_full Number:0 Permanent:Off Priority:5 Repeat Alert:Off LED Colour:Yellow LED Rate:0 Sound File: Vibration Pattern: Category:Charger Actions:(2) ]
CT_Add Name
A1: Status Bar [ Set:Collapsed ]
A2: Notify Cancel [ Title:%CT_NotificationTitle Warn Not Exist:Off ]
A3: Input Dialog [ Title:Charger name Text:enter charger name Default Input:
After (Seconds):60 Input Type: Use HTML:Off Pre-Select Input:Off ]
A4: Variable Set [ Name:%CT_name To:%input
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
A5: Variable Set [ Name:%CT_NotificationTitle To:%CT_name Test In Progress
Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
A6: Notify [ Title:%CT_NotificationTitle Text:The test is running on %CTA_PhoneName with %CTA_BatteryCapacity mAh . Supported protocols: %CTA_Protocols Icon:mw_device_battery_unknown Number:0
Permanent:On Priority:1 Repeat Alert:Off LED Colour:Blue LED Rate:0 Sound File:
Pattern: Category:Charger Actions:(2) ]
A1: HTTP Request [ Method:POST URL:http://%CTA_credentials@automation.local:1990/charger
Headers: Query Parameters: Body:%CT_chargestat File To Send:
File/Directory To Save With Output: Timeout (Seconds):30
Trust Any Certificate:On Automatically Follow Redirects:Off
Use Cookies:Off Continue Task After Error:On ]
A2: Status Bar [ Set:Collapsed ]
A3: Notify Cancel [ Title:Charger Test Finished Warn Not Exist:Off ]
If [ %http_response_code eq 200 ]
A4: Flash [ Text:Success Long:On ] If [ %http_response_code eq 200 ]
A5: Wait [ MS:0 Seconds:20 Minutes:0 Hours:0 Days:0 ]
A6: Variable Clear [ Name:%CT_* Pattern Matching:On Local Variables Only:Off Clear All Variables:On ]
A1: Notify Cancel [ Title:%CT_NotificationTitle Warn Not Exist:Off ]
A2: Flash [ Text:Test discarded Long:On ]
A3: Stop [ With Error:Off Task:CT_Test Charger ]
A4: Profile Status [ Name:CT_Charge Monitor Set:Off ]
A5: Variable Clear [ Name:%CT_* Pattern Matching:On Local Variables Only:Off Clear All Variables:On ]

Creating graphs and tables in NodeRED

Formatting data with JSON was a great idea since NodeRED will handle the processing and the Dashboard node will display the charging curve. Before we get nice images, we have to receive the information, process it and display it in the dashboard. I’m using node-red-node-ui-table to generate an interactive table for each test.


Add HTTP in and HTTP response nodes to get the JSON as msg.payload. Don’t forget to specify the directory (mine: charger) and type, which should match your Tasker’s HTTP Post request. If you planning to run your tests from outside WiFi, please read NodeRED security guide to secure all endpoints.

To display the graph correctly, for each entry in our array we have to send 3 params: name, timestamp and value. I wrote about the ways of sending multiple payloads in NodeRED, but for this tutorial, all you need to know is this:

{topic: "name", payload: 10, timestamp: 1234678990}

This is how the correct chart message looks like. To achieve this, I will iterate through all instances in the timestamp array, with each iteration, I will add a new entry to an array that will be pushed to the chart node:

var data = msg.payload;

var array = [];

for(var x in data.timestamp){
    array.push({topic: data.name, 
                payload: data.level[x], 
                timestamp: data.timestamp[x]});

return [array];

That function will take care of everything. If you want to add name and the total charge times too, use msg.payload.name and msg.payload.chargeDelta and send it to text nodes.


Table takes more values than the graph and displays this nicely in dashboard. To get it all organised, I have to create a specific JSON formatted msg.payload that looks like this:

{ "Charger name": data.name,
"Phone name": data.phone,
"Charging protocol": data.proto,
"Battery capacity (mAh)": data.battery ,
"Charge time": data.ChargeDelta,
"Charge score (mAh/min)": chargespeed}

This covers a single entry in my table. To display multiple entries, I have to create an array of entries and store it as flow variable.

If your NodeRED variables clear the values on reboot, you have to enable the context store. This way, all variables will be preserved and saves every 30 sec. For more information on how to do it, please follow this guide.

All this compacts to a single function node that does everything for you

// Code added here will be run once
// whenever the node is deployed.

var array = [];
flow.set("chargers", array);


var chargers =  flow.get("chargers");

if(chargers === undefined){
    chargers = [];

var data = msg.payload;

var update = {  "Charger name": data.name,
                "Phone name": data.phone,
                "charging protocol":  data.proto,
                "battery (mAh)": data.battery ,
                "charge time": data.chargeDelta,
                "score (mAh/min)": data.score};

flow.set("chargers", chargers);

msg.payload = chargers;

return msg;

Link this to the table node, and you will have your results stored and displayed in NodeRED dashboard. You can download th

Final thoughts

There you have it! Updated, streamlined and made it better. I understand, that you probably don’t need this project as much as I do, but it showcases how easy it is to tailor Tasker to create tools that do exactly what you need them to. Plus tricks used in this project can be repurposed for other projects. Let me know what do you think in this Reddit thread.

Project Download

Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.


Nothing says "Thank you" better than keeping my coffee jar topped up!


Support me on Patreon and get an early access to tutorial files and videos.


Bitcoin (BTC)

Use this QR to keep me caffeinated with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU

New to Tasker?

Tasker Quick Start – Getting started with Tasker

From newb to not so newbie in 10 min

Best Tasker Projects

How to use Raspberry PI as WOL (wake on lan) server

While you could wake up your PC from a mobile directly, having a dedicated server capable of doing so is the best solution. The reason is simple. You can hook up as many devices as you wish with a single endpoint. This is why Raspberry Pi is perfect for this.

How to wake on LAN computers and put it to sleep with Power Menu,...

How to Wake on LAN properly via Android, Alexa, Google Assistant and Web

7 awesome Bluetooth keyboard shortcuts for Android

7 unique Android shortcuts that you can add to any Bluetooth keyboard.

Smart overnight charging with Tasker

Still keeping your phone plugged in overnight? Try smarter overnight charging with this profile

One thing that Join app can’t do and how to fix it with Tasker

It's not possible to share the clipboard automatically between join accounts registered to 2 different emails. But you can fix this with tasker.

Essential Guides

Tasker: Seconds into DD:HH:MM:SS (dynamic)

It's time to.... ok it's a pun, but I will show you how to master time and convert seconds to DD:HH:MM:SS dynamically

4 ways to organise Tasker projects

Keep your Tasker tidy!

A better way to store Tasker credentials

The more clever way of managing credentials

Annoyed with dozens of AutoApps populating your app drawer? Here is a fix!

Clear your app drawer from the clutter in seconds

Putting AutoTools pie chart to a good use – SSID logger

Who wants a piece of the pie (chart)?