Comments (21)
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py
index 2a48b83..046e30f 100644
--- a/py3status/modules/battery_level.py
+++ b/py3status/modules/battery_level.py
@@ -92,7 +92,7 @@ discharging
{'color': '#FF0000', 'full_text': u'\u2340'}
"""
-from re import findall
+from re import findall, search
import itertools
import math
@@ -178,6 +178,7 @@ class Py3status:
def post_config_hook(self):
self.last_known_status = ""
+ self.last_known_capacity = 1
# Guess mode if not set
if self.measurement_mode is None:
if Path(self.sys_battery_path).is_dir():
@@ -258,13 +259,14 @@ class Py3status:
findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0]
)
battery["charging"] = "Charging" in acpi_battery_lines[0]
- battery["capacity"] = int(
- findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
- )
# ACPI only shows time remaining if battery is discharging or
# charging
try:
+ battery["capacity"] = int(
+ findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
+ )
+ self.last_known_capacity = battery["capacity"]
battery["time_remaining"] = "".join(
findall(
r"(?<=, )(\d+:\d+:\d+)(?= remaining)|"
@@ -273,6 +275,7 @@ class Py3status:
)[0]
)
except IndexError:
+ battery["capacity"] = self.last_known_capacity
battery["time_remaining"] = FULLY_CHARGED
# TODO: Not implemented yet
@@ -285,9 +288,17 @@ class Py3status:
# Separate the output because each pair of lines corresponds to a
# single battery. Now the list index will correspond to the index of
# the battery we want to look at
- acpi_list = [acpi_list[i : i + 2] for i in range(0, len(acpi_list) - 1, 2)]
+ temp_acpi_list = {}
+ for line in acpi_list:
+ number = search(r"Battery (\d+)", line).group(1)
+ temp_acpi_list.setdefault(number, []).append(line)
+
+ new_acpi_list = {}
+ for k, v in temp_acpi_list.items():
+ if "rate information unavailable" not in "|".join(v):
+ new_acpi_list[k] = v
- return [_parse_battery_info(battery) for battery in acpi_list]
+ return [_parse_battery_info(battery) for battery in new_acpi_list.values()]
def _extract_battery_info_from_sys(self):
"""
from py3status.
More information needed. Paste acpi -b -i
output and... maybe again when/if the error occurs.
I think the output hides some values when it's full. The fix might be something like this. Not 0
tho.
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py
index 2a48b83..809e5d5 100644
--- a/py3status/modules/battery_level.py
+++ b/py3status/modules/battery_level.py
@@ -258,13 +258,13 @@ class Py3status:
findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0]
)
battery["charging"] = "Charging" in acpi_battery_lines[0]
- battery["capacity"] = int(
- findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
- )
# ACPI only shows time remaining if battery is discharging or
# charging
try:
+ battery["capacity"] = int(
+ findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
+ )
battery["time_remaining"] = "".join(
findall(
r"(?<=, )(\d+:\d+:\d+)(?= remaining)|"
@@ -274,6 +274,7 @@ class Py3status:
)
except IndexError:
battery["time_remaining"] = FULLY_CHARGED
+ battery["capacity"] = 0
# TODO: Not implemented yet
battery["power"] = 0.0
from py3status.
More information needed. Paste
acpi -b -i
output and... maybe again when/if the error occurs.I think the output hides some values when it's full. The fix might be something like this. Not
0
tho.diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py index 2a48b83..809e5d5 100644 --- a/py3status/modules/battery_level.py +++ b/py3status/modules/battery_level.py @@ -258,13 +258,13 @@ class Py3status: findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0] ) battery["charging"] = "Charging" in acpi_battery_lines[0] - battery["capacity"] = int( - findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] - ) # ACPI only shows time remaining if battery is discharging or # charging try: + battery["capacity"] = int( + findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] + ) battery["time_remaining"] = "".join( findall( r"(?<=, )(\d+:\d+:\d+)(?= remaining)|" @@ -274,6 +274,7 @@ class Py3status: ) except IndexError: battery["time_remaining"] = FULLY_CHARGED + battery["capacity"] = 0 # TODO: Not implemented yet battery["power"] = 0.0
Battery 0: Discharging, 0%, rate information unavailable
Battery 1: Full, 100%
Battery 1: design capacity 3100 mAh, last full capacity 2905 mAh = 93%
The battery 1 is the important one, I don't really know what battery 0 is.
I could probably make a check if "percent" == 100 (pseudocode), and if so not write the module, as making a module with a empty text makes it not show it. (For some reason, I think it's intended tho.)
(The error is ocurring right now)
from py3status.
The fix
More information needed. Paste
acpi -b -i
output and... maybe again when/if the error occurs.
I think the output hides some values when it's full. The fix might be something like this. Not0
tho.diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py index 2a48b83..809e5d5 100644 --- a/py3status/modules/battery_level.py +++ b/py3status/modules/battery_level.py @@ -258,13 +258,13 @@ class Py3status: findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0] ) battery["charging"] = "Charging" in acpi_battery_lines[0] - battery["capacity"] = int( - findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] - ) # ACPI only shows time remaining if battery is discharging or # charging try: + battery["capacity"] = int( + findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] + ) battery["time_remaining"] = "".join( findall( r"(?<=, )(\d+:\d+:\d+)(?= remaining)|" @@ -274,6 +274,7 @@ class Py3status: ) except IndexError: battery["time_remaining"] = FULLY_CHARGED + battery["capacity"] = 0 # TODO: Not implemented yet battery["power"] = 0.0Battery 0: Discharging, 0%, rate information unavailable Battery 1: Full, 100% Battery 1: design capacity 3100 mAh, last full capacity 2905 mAh = 93%
The battery 1 is the important one, I don't really know what battery 0 is. I could probably make a check if "percent" == 100 (pseudocode), and if so not write the module, as making a module with a empty text makes it not show it. (For some reason, I think it's intended tho.) (The error is ocurring right now)
The fix seems to work with battery["capacity"]
being 100
.
@lasers Could it be applied as a pull request?
I can't seem to get my error consistently. I tried to apply the patch but even when unpatching the error works weirdly.
from py3status.
You can keep modified battery_level.py
in ~/.config/py3status/modules/
. I don't have a setup ready to test this module nor have I studied the module code. My trivial concern is that what would happen with multiple working batteries.
Also, yes, you can make a pull request.
from py3status.
You can keep modified
battery_level.py
in~/.config/py3status/modules/
. I don't have a setup ready to test this module nor have I studied the module code. My trivial concern is that what would happen with multiple working batteries.Also, yes, you can make a pull request.
I'll then apply the patch properly as I can have it in my user folder, I dislike overriding python...
But the issue I have is that I can't seem what I should put in the value as if I put 0 it causes a divisionbyzero, but if I put 1 it causes the battery to be at 0%.
from py3status.
Less issue for you, but still not right due to not storing battery index too in the cache.
Use last known capacity. Untested. It should be 1 on first run, then whatever capacity acpi gave.
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py
index 2a48b83..f5cb943 100644
--- a/py3status/modules/battery_level.py
+++ b/py3status/modules/battery_level.py
@@ -178,6 +178,7 @@ class Py3status:
def post_config_hook(self):
self.last_known_status = ""
+ self.last_known_capacity = 1 # fake
# Guess mode if not set
if self.measurement_mode is None:
if Path(self.sys_battery_path).is_dir():
@@ -258,13 +259,14 @@ class Py3status:
findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0]
)
battery["charging"] = "Charging" in acpi_battery_lines[0]
- battery["capacity"] = int(
- findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
- )
# ACPI only shows time remaining if battery is discharging or
# charging
try:
+ battery["capacity"] = int(
+ findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
+ )
+ self.last_known_capacity = battery["capacity"]
battery["time_remaining"] = "".join(
findall(
r"(?<=, )(\d+:\d+:\d+)(?= remaining)|"
@@ -274,6 +276,7 @@ class Py3status:
)
except IndexError:
battery["time_remaining"] = FULLY_CHARGED
+ battery["capacity"] = self.last_known_capacity
# TODO: Not implemented yet
battery["power"] = 0.0
The PR should come from somebody confirming this to be working, not writing untested PRs like me.
from py3status.
Less issue for you, but still not right due to not storing battery index too in the cache.
Use last known capacity. Untested. It should be 1 on first run, then whatever capacity acpi gave.
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py index 2a48b83..f5cb943 100644 --- a/py3status/modules/battery_level.py +++ b/py3status/modules/battery_level.py @@ -178,6 +178,7 @@ class Py3status: def post_config_hook(self): self.last_known_status = "" + self.last_known_capacity = 1 # fake # Guess mode if not set if self.measurement_mode is None: if Path(self.sys_battery_path).is_dir(): @@ -258,13 +259,14 @@ class Py3status: findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0] ) battery["charging"] = "Charging" in acpi_battery_lines[0] - battery["capacity"] = int( - findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] - ) # ACPI only shows time remaining if battery is discharging or # charging try: + battery["capacity"] = int( + findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] + ) + self.last_known_capacity = battery["capacity"] battery["time_remaining"] = "".join( findall( r"(?<=, )(\d+:\d+:\d+)(?= remaining)|" @@ -274,6 +276,7 @@ class Py3status: ) except IndexError: battery["time_remaining"] = FULLY_CHARGED + battery["capacity"] = self.last_known_capacity # TODO: Not implemented yet battery["power"] = 0.0The PR should come from somebody confirming this to be working, not writing untested PRs like me.
Thanks, applied that patch, will wait for a week or two to see if I experience any issues.
from py3status.
Issue: It still thinks the battery doesn't have capacity. It doesn't seem to save the data...
from py3status.
Can you give me the following outputs? Charging, Discharging, and Full.
EDIT: It might work better if it got a charging / discharging output just once.
from py3status.
Supposedly charging:
Battery 0: Not charging, 98%
Battery 1: Discharging, 0%, rate information unavailable
Discharging:
Battery 0: Discharging, 98%, 03:47:31 remaining
Battery 1: Discharging, 0%, rate information unavailable
Charging:
Battery 0: Charging, 98%, 00:02:03 until charged
Battery 1: Discharging, 0%, rate information unavailable
The other battery sometimes appears and disappears randomly, but note that the hardware only has one physical battery.
from py3status.
Taken with acpi -b -i
? If yes, well, it doesn't print capacity for your batteries... It should look something like this.
"""
# Get the battery info from acpi
# Example Discharging
Battery 0: Discharging, 94%, 09:23:28 remaining
Battery 0: design capacity 5703 mAh, last full capacity 5283 mAh = 92%
Battery 1: Unknown, 98%
Battery 1: design capacity 1880 mAh, last full capacity 1370 mAh = 72%
# Example Charging
Battery 0: Charging, 96%, 00:20:40 until charged
Battery 0: design capacity 5566 mAh, last full capacity 5156 mAh = 92%
Battery 1: Unknown, 98%
Battery 1: design capacity 1879 mAh, last full capacity 1370 mAh = 72%
"""
Nothing we can do here. Possibly better to fix up sys
and/or to look into adding tlp
support if there is a good battery statistics output py3status can use on the bar.
from py3status.
Taken with
acpi -b -i
? If yes, well, it doesn't print capacity for your batteries... It should look something like this.""" # Get the battery info from acpi # Example Discharging Battery 0: Discharging, 94%, 09:23:28 remaining Battery 0: design capacity 5703 mAh, last full capacity 5283 mAh = 92% Battery 1: Unknown, 98% Battery 1: design capacity 1880 mAh, last full capacity 1370 mAh = 72% # Example Charging Battery 0: Charging, 96%, 00:20:40 until charged Battery 0: design capacity 5566 mAh, last full capacity 5156 mAh = 92% Battery 1: Unknown, 98% Battery 1: design capacity 1879 mAh, last full capacity 1370 mAh = 72% """Nothing we can do here. Possibly better to fix up
sys
and/or to look into addingtlp
support if there is a good battery statistics output py3status can use on the bar.
Oh, sorry. wait a sec.
# Supposedly charging (it really discharges)
Battery 0: Discharging, 0%, rate information unavailable
Battery 1: Not charging, 99%
Battery 1: design capacity 3100 mAh, last full capacity 2813 mAh = 90%
# Discharging
Battery 0: Discharging, 0%, rate information unavailable
Battery 1: Discharging, 99%, 13:23:49 remaining
Battery 1: design capacity 3100 mAh, last full capacity 2813 mAh = 90%
# Charging
Battery 0: Discharging, 0%, rate information unavailable
Battery 1: Charging, 98%, charging at zero rate - will never fully charge.
Battery 1: design capacity 3100 mAh, last full capacity 2821 mAh = 91%
# Charging (later)
Battery 0: Discharging, 0%, rate information unavailable
Battery 1: Charging, 98%, 00:36:09 until charged
Battery 1: design capacity 3100 mAh, last full capacity 2821 mAh = 91%
from py3status.
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py
index 2a48b83..a1d0210 100644
--- a/py3status/modules/battery_level.py
+++ b/py3status/modules/battery_level.py
@@ -92,7 +92,7 @@ discharging
{'color': '#FF0000', 'full_text': u'\u2340'}
"""
-from re import findall
+from re import findall, search
import itertools
import math
@@ -178,6 +178,7 @@ class Py3status:
def post_config_hook(self):
self.last_known_status = ""
+ self.last_known_capacity = 1 # fake
# Guess mode if not set
if self.measurement_mode is None:
if Path(self.sys_battery_path).is_dir():
@@ -258,13 +259,14 @@ class Py3status:
findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0]
)
battery["charging"] = "Charging" in acpi_battery_lines[0]
- battery["capacity"] = int(
- findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
- )
# ACPI only shows time remaining if battery is discharging or
# charging
try:
+ battery["capacity"] = int(
+ findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1]
+ )
+ self.last_known_capacity = battery["capacity"]
battery["time_remaining"] = "".join(
findall(
r"(?<=, )(\d+:\d+:\d+)(?= remaining)|"
@@ -273,6 +275,7 @@ class Py3status:
)[0]
)
except IndexError:
+ battery["capacity"] = self.last_known_capacity
battery["time_remaining"] = FULLY_CHARGED
# TODO: Not implemented yet
@@ -285,9 +288,12 @@ class Py3status:
# Separate the output because each pair of lines corresponds to a
# single battery. Now the list index will correspond to the index of
# the battery we want to look at
- acpi_list = [acpi_list[i : i + 2] for i in range(0, len(acpi_list) - 1, 2)]
+ new_acpi_list = {}
+ for line in acpi_list:
+ number = int(search(r"Battery (\d+)", line).group(1))
+ new_acpi_list.setdefault(number, []).append(line)
- return [_parse_battery_info(battery) for battery in acpi_list]
+ return [_parse_battery_info(battery) for battery in new_acpi_list.values()]
def _extract_battery_info_from_sys(self):
"""
from py3status.
new_acpi_list.setdefault(number, []).append(line)
Thanks, will wait a few days to see if this one works properly. :)
from py3status.
I just found a issue, for some weird reason it seems to just out of the blue change the percentage from 99% to 50%, I can prove any debug data needed if I am given the command (as I know py3status -dl file
won't work properly as no exception is ocurring)
from py3status.
I don't remember if this is how it works, but you can try adding self.py3.log(new_acpi_list.values())
line right after that loop. It should show up in file
along with other noises. Check to see if it's working.... and when you ran into that issue again, check the file immediately.
from py3status.
2023-04-03 14:44:37 INFO Module `battery_level`: dict_values([['Battery 0: Not charging, 99%', 'Battery 0: design capacity 3100 mAh, last full capacity 2814 mAh = 90%'], ['Battery 1: Discharging, 0%, rate information unavailable']])
2023-04-03 14:44:37 INFO method battery_level returned {'composite': [{'full_text': '49% \uf242 (None)', 'instance': ' 0', 'name': 'battery_level', 'background': '#282828'}], 'instance': '', 'name': 'battery_level'}.
I think I just found out the error, there's a extra battery (which I can't practically remove), that always has 0% so the avereage of the percentages is 49%.
- Found the device which makes the issue, I'll try to see how can I bodge it to not present a empty battery (it's a wireless mouse receiver) (seems like when I use it via bluetooth it doesn't show it, which is nice but that also can break my workflow once I add more hosts on my kvm (that is, more laptops because I'm not using the mouse on the rare times I switch to the output of my local server)), I think it's a issue with acpi not handling
hidpp_battery_25
properly. (As /sys/class/power_supply/hidpp_battery_25/capacity shows 95, which means the mouse is 95% full)
from py3status.
Yeah. Your Battery 0
gave capacity this time. This wasn't in one of your outputs before. There is a method later down the road that puts all batteries together to make an average percent... thus this issue. It may be ideal to split everything up so we loop through each battery (ie with format_battery
).
Few ways to fix this.
- Rewriting this module from scratch to loop batteries.
- Add
batteries
config to follow certain batteries. If empty, all. - Find a fix via acpi.
from py3status.
Yeah. Your
Battery 0
gave capacity this time. This wasn't in one of your outputs before. There is a method later down the road that puts all batteries together to make an average percent... thus this issue. It may be ideal to split everything up so we loop through each battery (ie withformat_battery
).Few ways to fix this.
- Rewriting this module from scratch to loop batteries.
That'd take a lot of work.- Add
batteries
config to follow certain batteries. If empty, all.
That would have a way to somehow tell the battery without using a identifier as the id changes when the remote thing is unplugged- Find a fix via acpi.
^ That'd be the best solution, as checking the internal files in/sys/class/power_supply
there's the battery and the capacity shows up properly.
I ended up going with the current aproach of using the mouse via bluetooth. I'll just have to remember to disable bluetooth when I go out with my laptop (as that consumes battery).
Currently I will rename the module override file and see if no issues ocurr and if any issues ocurr (the system still giving me some kind of error), I'd make a PR, but even then, it's a bit sad that they don't expose all the proper files so acpi doesn't work.
@lasers Is it possible to detect a invalid battery (by the fact that it doesn't report rated capacity) and remove it from the dictionary of batteries?
from py3status.
diff --git a/py3status/modules/battery_level.py b/py3status/modules/battery_level.py index 2a48b83..046e30f 100644 --- a/py3status/modules/battery_level.py +++ b/py3status/modules/battery_level.py @@ -92,7 +92,7 @@ discharging {'color': '#FF0000', 'full_text': u'\u2340'} """ -from re import findall +from re import findall, search import itertools import math @@ -178,6 +178,7 @@ class Py3status: def post_config_hook(self): self.last_known_status = "" + self.last_known_capacity = 1 # Guess mode if not set if self.measurement_mode is None: if Path(self.sys_battery_path).is_dir(): @@ -258,13 +259,14 @@ class Py3status: findall(r"(?<= )(\d+)(?=%)", acpi_battery_lines[0])[0] ) battery["charging"] = "Charging" in acpi_battery_lines[0] - battery["capacity"] = int( - findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] - ) # ACPI only shows time remaining if battery is discharging or # charging try: + battery["capacity"] = int( + findall(r"(?<= )(\d+)(?= mAh)", acpi_battery_lines[1])[1] + ) + self.last_known_capacity = battery["capacity"] battery["time_remaining"] = "".join( findall( r"(?<=, )(\d+:\d+:\d+)(?= remaining)|" @@ -273,6 +275,7 @@ class Py3status: )[0] ) except IndexError: + battery["capacity"] = self.last_known_capacity battery["time_remaining"] = FULLY_CHARGED # TODO: Not implemented yet @@ -285,9 +288,17 @@ class Py3status: # Separate the output because each pair of lines corresponds to a # single battery. Now the list index will correspond to the index of # the battery we want to look at - acpi_list = [acpi_list[i : i + 2] for i in range(0, len(acpi_list) - 1, 2)] + temp_acpi_list = {} + for line in acpi_list: + number = search(r"Battery (\d+)", line).group(1) + temp_acpi_list.setdefault(number, []).append(line) + + new_acpi_list = {} + for k, v in temp_acpi_list.items(): + if "rate information unavailable" not in "|".join(v): + new_acpi_list[k] = v - return [_parse_battery_info(battery) for battery in acpi_list] + return [_parse_battery_info(battery) for battery in new_acpi_list.values()] def _extract_battery_info_from_sys(self): """
Thanks, seems to work properly. Do you think this would negatively affect other users?, if it won't I'm pretty sure a PR can be made.
from py3status.
Related Issues (20)
- Undocumented requirement of dateutil HOT 3
- Add connexion status in kdeconnector module HOT 7
- Error: status_command process exited unexpectedly (exit 1) HOT 3
- Problem whit Modules. HOT 1
- Question: How to hide unavailable disk in `diskdata` module HOT 2
- Time Freezes HOT 14
- Battery Level Notification Doesn't Show Until I3 Bar Is Shown HOT 2
- How to add other text in the format area? (arch_updates) HOT 3
- The getargspec() function got removed in Python 3.11 HOT 2
- py3status not recognising dbus import after PEP668 changes HOT 6
- 100% cpu usage when called outside of a graphical terminal or i3 HOT 6
- 'Clock' module only shows '?' now. HOT 5
- Drop pydbus HOT 3
- Drop mkdocs-simple-hooks
- Drop setuptools HOT 2
- [Proposal] playerctl module HOT 3
- dbus installation problem HOT 2
- Bluetooth module fails on wake up from suspend HOT 15
- https://py3status.readthedocs.io/ is 404 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from py3status.