Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensors_temperatures no such file error #966

Closed
nicolargo opened this issue Feb 2, 2017 · 27 comments
Closed

Sensors_temperatures no such file error #966

nicolargo opened this issue Feb 2, 2017 · 27 comments

Comments

@nicolargo
Copy link
Contributor

On my Dell XPS 13 on Ubuntu 16.04, with the latest 5.1.0 release and Puthon 2.7, i have the following error:

In [3]: psutil.sensors_battery()
---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)
<ipython-input-3-2cfac8b92a01> in <module>()
----> 1 psutil.sensors_battery()

/usr/local/lib/python2.7/dist-packages/psutil/__init__.pyc in sensors_battery()
   2244         - power_plugged: True if the AC power cable is connected.
   2245         """
-> 2246         return _psplatform.sensors_battery()
   2247 
   2248     __all__.append("sensors_battery")

/usr/local/lib/python2.7/dist-packages/psutil/_pslinux.pyc in sensors_battery()
   1110     power_plugged = cat(os.path.join(POWER_SUPPLY_PATH, "AC0/online"),
   1111                         fallback=b"0") == b"1"
-> 1112     energy_now = int(cat(root + "/energy_now"))
   1113     power_now = int(cat(root + "/power_now"))
   1114     percent = int(cat(root + "/capacity"))

/usr/local/lib/python2.7/dist-packages/psutil/_pslinux.pyc in cat(fname, fallback, binary)
    286     """Return file content."""
    287     try:
--> 288         f = open_binary(fname) if binary else open_text(fname)
    289     except IOError:
    290         if fallback != _DEFAULT:

/usr/local/lib/python2.7/dist-packages/psutil/_pslinux.pyc in open_binary(fname, **kwargs)
    185 
    186 def open_binary(fname, **kwargs):
--> 187     return open(fname, "rb", **kwargs)
    188 
    189 

IOError: [Errno 2] No such file or directory: '/sys/class/power_supply/BAT0/energy_now'

When i have a look on the /sys/class/power_supply/BAT0/ folder, no energy_now file but another ones:

# ll /sys/class/power_supply/BAT0/
total 0
-rw-r--r-- 1 root root 4096 janv. 29 17:03 alarm
-r--r--r-- 1 root root 4096 janv. 29 15:45 capacity
-r--r--r-- 1 root root 4096 janv. 29 17:03 capacity_level
-r--r--r-- 1 root root 4096 janv. 29 15:45 charge_full
-r--r--r-- 1 root root 4096 janv. 29 15:45 charge_full_design
-r--r--r-- 1 root root 4096 janv. 29 15:45 charge_now
-r--r--r-- 1 root root 4096 janv. 29 15:45 current_now
-r--r--r-- 1 root root 4096 janv. 29 17:03 cycle_count
lrwxrwxrwx 1 root root    0 janv. 29 17:03 device -> ../../../PNP0C0A:00/
-r--r--r-- 1 root root 4096 janv. 29 15:45 manufacturer
-r--r--r-- 1 root root 4096 janv. 29 15:45 model_name
drwxr-xr-x 2 root root    0 janv. 29 17:03 power/
-r--r--r-- 1 root root 4096 janv. 29 15:45 present
-r--r--r-- 1 root root 4096 janv. 29 15:45 serial_number
-r--r--r-- 1 root root 4096 janv. 29 15:45 status
lrwxrwxrwx 1 root root    0 janv. 29 15:45 subsystem -> ../../../../../../class/power_supply/
-r--r--r-- 1 root root 4096 janv. 29 15:45 technology
-r--r--r-- 1 root root 4096 janv. 29 15:45 type
-rw-r--r-- 1 root root 4096 janv. 29 15:45 uevent
-r--r--r-- 1 root root 4096 janv. 29 15:45 voltage_min_design
-r--r--r-- 1 root root 4096 janv. 29 15:45 voltage_now
@giampaolo
Copy link
Owner

Shit! I am also on Ubuntu 16.04 and I have that file (but I don't have charge_now as you do). It appears /sys/class/power_supply directory structure is not reliable. :-\

@giampaolo
Copy link
Owner

giampaolo commented Feb 2, 2017

@nicolargo can you try this, then take a look at the output of acpi -b to see if the values match?

def sensors_battery():
    root = os.path.join(POWER_SUPPLY_PATH, "BAT0")
    if not os.path.exists(root):
        return None

    power_plugged = cat(os.path.join(POWER_SUPPLY_PATH, "AC0/online"),
                        fallback=b"0") == b"1"

    if os.path.exists(root + "/energy_now"):
        remaining_capacity = int(cat(root + "/energy_now"))
    elif os.path.exists(root + "/charge_now"):
        remaining_capacity = int(cat(root + "/charge_now"))
    else:
        return None

    if os.path.exists(root + "/power_now"):
        present_rate = int(cat(root + "/power_now"))
    elif os.path.exists(root + "/current_now"):
        present_rate = int(cat(root + "/current_now"))
    else:
        return None

    if os.path.exists(root + "/capacity"):
        percent = int(cat(root + "/capacity"))
    else:
        if os.path.exists(root + "/charge_full"):
            max_capacity = int(cat(root + "/charge_full"))
        elif os.path.exists(root + "/energy_full"):
            max_capacity = int(cat(root + "/energy_full"))
        else:
            return None
        percent = 100.0 * remaining_capacity / max_capacity

    if power_plugged:
        secsleft = _common.POWER_TIME_UNLIMITED
    else:
        try:
            secsleft = int(remaining_capacity / present_rate * 3600)
        except ZeroDivisionError:
            secsleft = _common.POWER_TIME_UNKNOWN

    return _common.sbattery(percent, secsleft, power_plugged)

@nicolargo
Copy link
Contributor Author

@giampaolo The https://gist.github.com/nicolargo/292c0c6c9ea935c08b5163549e473c20 return None on my system...

Here is the return of acpi -b:

Battery 0: Full, 100%

@giampaolo
Copy link
Owner

giampaolo commented Feb 2, 2017

@nicolargo I think this one should work:

def sensors_battery():
    """Return battery information."""
    null = object()

    def multi_cat(*paths):
        """Read content of multiple files which may not exist.
        # If none of them exist returns None.
        """
        for path in paths:
            ret = cat(path, fallback=null)
            if ret != null:
                return int(ret)
        return None

    root = os.path.join(POWER_SUPPLY_PATH, "BAT0")
    if not os.path.exists(root):
        return None

    # Base metrics.
    energy_now = multi_cat(
        root + "/energy_now",
        root + "/charge_now")
    power_now = multi_cat(
        root + "/power_now",
        root + "/current_now")
    energy_full = multi_cat(
        root + "/energy_full",
        root + "/charge_full")
    if energy_now is None or power_now is None:
        return None

    # Percent.  If we have energy_full the percentage will be more
    # prece compare to reading /capacity file (float vs. int).
    if energy_full is not None:
        try:
            percent = 100.0 * energy_now / energy_full
        except ZeroDivisionError:
            percent = 0.0
    else:
        percent = int(cat(root + "/capacity"), fallback=-1)
        if percent == -1:
            return None

    # Secs left.
    power_plugged = cat(os.path.join(POWER_SUPPLY_PATH, "AC0/online"),
                        fallback=b"0") == b"1"
    if power_plugged:
        secsleft = _common.POWER_TIME_UNLIMITED
    else:
        try:
            secsleft = int(energy_now / power_now * 3600)
        except ZeroDivisionError:
            secsleft = _common.POWER_TIME_UNKNOWN

    return _common.sbattery(percent, secsleft, power_plugged)

@nicolargo
Copy link
Contributor Author

Yes it is !

$ python ./sb.py 
sbattery(percent=100.0, secsleft=21391200, power_plugged=False)

@giampaolo
Copy link
Owner

giampaolo commented Feb 2, 2017

OK, good. Is power_plugged=False correct? Was your power cable not plugged?

@nicolargo
Copy link
Contributor Author

Always display power_plugged=False either the cable is connected or not...

Another issue if i unplug and plug it and quickly run the script i have the following error:

 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
sbattery(percent=100.0, secsleft=21391200, power_plugged=False)
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
sbattery(percent=100.0, secsleft=21391200, power_plugged=False)
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
sbattery(percent=99.326825984517, secsleft=14400, power_plugged=False)
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
sbattery(percent=99.326825984517, secsleft=14400, power_plugged=False)
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
Traceback (most recent call last):
  File "./sb.py", line 75, in <module>
    print sensors_battery()
  File "./sb.py", line 50, in sensors_battery
    root + "/current_now")
  File "./sb.py", line 30, in multi_cat
    ret = cat(path, fallback=null)
  File "./sb.py", line 24, in cat
    return f.read().strip()
IOError: [Errno 19] No such device
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
Traceback (most recent call last):
  File "./sb.py", line 75, in <module>
    print sensors_battery()
  File "./sb.py", line 50, in sensors_battery
    root + "/current_now")
  File "./sb.py", line 30, in multi_cat
    ret = cat(path, fallback=null)
  File "./sb.py", line 24, in cat
    return f.read().strip()
IOError: [Errno 19] No such device
 ~ ▶ tmp ▶ $ ▶ python ./sb.py 
sbattery(percent=100.0, secsleft=21391200, power_plugged=False)
 ~ ▶ tmp ▶ $ ▶ 

@giampaolo
Copy link
Owner

OK, I committed that change so now this should be fixed. As for the power cable, that is determined by:

~/svn/psutil {master}$ cat /sys/class/power_supply/AC0/online 
0

E.g., now it's 0 in my case because it's unplugged, otherwise it'd have been 1.
I suppose you don't have that file?

@giampaolo
Copy link
Owner

1f30d13 should fix the IOError you bumped into by disconnecting the power cable. If that happens it should now return None.

@nicolargo
Copy link
Contributor Author

Ok it works ! None is returned instead of exception.

I also confirm that i do not have any /sys/class/power_supply/AC0/online file...

@giampaolo
Copy link
Owner

@nicolargo what about cat /sys/class/power_supply/BAT0/status when you're fully charged?
Does it return "Charging"?

@nicolargo
Copy link
Contributor Author

It return "Full"....

giampaolo added a commit that referenced this issue Feb 2, 2017
@giampaolo
Copy link
Owner

@nicolargo how about 0a02bdc?

@giampaolo
Copy link
Owner

OK, new version is out.

@nicolargo
Copy link
Contributor Author

Thanks @giampaolo !

@giampaolo
Copy link
Owner

You're welcome. If you decide to use this in glances please report back if you bump into any issue. These APIs are new and not tested in production.

@asergi
Copy link

asergi commented Feb 3, 2017

@giampaolo psutil 5.1.x:

charge:     97.34%
left:       7:23:46
status:     discharging
plugged in: no

The last two are wrong on my laptop. In fact:

$ cat /sys/class/power_supply/BAT0/status
Charging

Also, I don't have AC but ADP:

$ cat /sys/class/power_supply/ADP0/online
1

Using acpi:

$ acpi -b -a
Battery 0: Charging, 97%, 00:11:30 until charged
Adapter 0: on-line

@giampaolo
Copy link
Owner

I don't understand how power_plugged can be False. The logic looks correct (also if you don't have AC0):

psutil/psutil/_pslinux.py

Lines 1154 to 1161 in fef8ef0

elif os.path.exists(root + "/status"):
status = cat(root + "/status", fallback="").lower()
if status == "discharging":
power_plugged = False
elif status in ("charging", "full"):
power_plugged = True
else:
power_plugged = None

@asergi
Copy link

asergi commented Feb 3, 2017

power_plugged is not False but always None:

>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=89.4559730790802, secsleft=24654, power_plugged=None)

@giampaolo
Copy link
Owner

Could you try to understand why?
If this is true:

$ cat /sys/class/power_supply/BAT0/status
Charging

...then it should return True

@giampaolo giampaolo reopened this Feb 3, 2017
@asergi
Copy link

asergi commented Feb 3, 2017

It's a Python 2 vs 3 issue.

Python 2:

>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=92.23219293325856, secsleft=-2, power_plugged=True)

Python 3:

>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=92.23219293325856, secsleft=25144, power_plugged=None)

@giampaolo
Copy link
Owner

I see the problem now (typing one). Thanks. Fix is coming.

@giampaolo
Copy link
Owner

This should now be fixed in ca01be5. Can you please verify?

@asergi
Copy link

asergi commented Feb 3, 2017

>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=67.07795849691531, secsleft=4160, power_plugged=False)
>>> psutil.sensors_battery()
sbattery(percent=67.12187324733595, secsleft=<BatteryTime.POWER_TIME_UNLIMITED: -2>, power_plugged=True)

power_plugged is now ok while secsleft not.

@giampaolo
Copy link
Owner

No that is correct. If power cable is connected it is supposed to return POWER_TIME_UNLIMITED.

@asergi
Copy link

asergi commented Feb 3, 2017

Ah, just an oversight. It works, thanks.

@giampaolo
Copy link
Owner

OK, psutil 5.1.2 is out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants