neema_t
Posts: 26
Joined: Tue Nov 12, 2013 9:38 pm

Everything is a file?

Tue Feb 02, 2016 11:14 am

Hi,

I'm experimenting with my Pi (B+) again for the first time in over a year and I want to figure out how to display a few things on 7-segment LED displays (specifically those tiny HP bubble 4 digit 7-seg ICs), but I can't work out how to actually extract the data from the Pi's operating system.

For instance, I'd like to display the amount of free space left on my SD card as a percentage. I know I can run df and it'll return the Use%, but I don't know how I could get that result into Python to send it to a 595 shift register. I know I've read that Linux (Raspbian at least) treats everything as either a file or a process, so is it possible that the data I want to find exists as a file that I could read with Python?

I remember once I worked out how to display the temperature of the Pi's CPU the same way, but that was because I was able to find and read a file that had the temperature contained within it. This is for a camera project, by the way. I'd ideally like to also show how many image files are in the photo folder, is there a way to do that by reading a file with Python? Or maybe there's a better method I've missed?

Thanks!


Edit: Maybe there's a way to write responses from the command line to a file...? For instance, if I type vcgencmd measure_temp the Pi responds with "temp=35.8'C", is there a way to make the Pi create a new file called, say, "temp.txt" with that response stored as text so I could use Python to read the 6th to 9th characters?

ghans
Posts: 7882
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Everything is a file?

Tue Feb 02, 2016 11:30 am

You can read the output of arbitary commands into python with the subprocess module :

http://www.bogotobogo.com/python/python ... module.php

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

User avatar
GTR2Fan
Posts: 1601
Joined: Sun Feb 23, 2014 9:20 pm
Location: South East UK

Re: Everything is a file?

Tue Feb 02, 2016 11:42 am

neema_t wrote:For instance, if I type vcgencmd measure_temp the Pi responds with "temp=35.8'C", is there a way to make the Pi create a new file called, say, "temp.txt" with that response stored as text so I could use Python to read the 6th to 9th characters?

Code: Select all

vcgencmd measure_temp >temp.txt
Pi2B Mini-PC/Media Centre: ARM=1GHz (+3), Core=500MHz, v3d=500MHz, h264=333MHz, RAM=DDR2-1200 (+6/+4/+4+schmoo). Sandisk Ultra HC-I 32GB microSD card on '50=100' OCed slot (42MB/s read) running Raspbian/KODI16, Seagate 3.5" 1.5TB HDD mass storage.

scotty101
Posts: 3938
Joined: Fri Jun 08, 2012 6:03 pm

Re: Everything is a file?

Tue Feb 02, 2016 12:13 pm

Counting the number of files (for example *.jpg) in a directory is pretty simple and can be done with three lines of code.

Code: Select all

import glob
myPath = "/home/pi/my_photos/"
jpgCounter = len(glob.glob1(myPath,"*.jpg"))
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Everything is a file?

Tue Feb 02, 2016 12:21 pm

It's much more efficient to do it with the subprocess module.

Something like:

Code: Select all

import subprocess

cmnd = subprocess.popen('df -h', stdout=os.PIPE)
cmnd.stdout.readline()
line = cmnd.stdout.readline()
#       Filesystem      Size  Used Avail Use% Mounted on
# line: rootfs          459G  8.9G  427G   3% /
#       0123456789012345678901234567890123456789
#       0         1         2         3

number = int(line[26:31])  # I think that's right; my python split memory is rusty
mult = line[31]
if mult == "M":
   number = number * 1000000
elif mult == "G":
   number = number * 1000000000
elif ... # you get the idea

# code here to close the subprocess correctly.

JimmyN
Posts: 1109
Joined: Wed Mar 18, 2015 7:05 pm
Location: Virginia, USA

Re: Everything is a file?

Tue Feb 02, 2016 1:37 pm

neema_t wrote:For instance, if I type vcgencmd measure_temp the Pi responds with "temp=35.8'C", is there a way to make the Pi create a new file called, say, "temp.txt" with that response stored as text so I could use Python to read the 6th to 9th characters?
You don't need to save it in a file, just store the value then use that to write to the display.
There are many ways to do it, I use this function.

Code: Select all

# Return CPU temperature as float                                     
def getCPUtemp():
    cTemp = os.popen('vcgencmd measure_temp').readline()
    return float(cTemp.replace("temp=","").replace("'C\n",""))

That retrieves the temperature, then strips away the "temp=" at the beginning and the " 'C " on the end, so that "getCPUtemperature" just holds the floating point number.

Later in the script loop I use "CPU_temp = getCPUtemp()" which calls the "getCPUtemp" function and places the floating point number in CPU_temp. I then use "CPU_temp" to write the value to the display.

neema_t
Posts: 26
Joined: Tue Nov 12, 2013 9:38 pm

Re: Everything is a file?

Tue Feb 02, 2016 2:13 pm

Wow, thanks for all the responses! Reading about the os.system and subprocess stuff brings back memories of me semi-logically trying to use subprocess.call to get temperature data but failing and falling back on os.system even though it's now obsolete, so I assume I must've done it this way back then (rather than making a file because yes, that's an inefficient workaround). I can't remember exactly how I extracted each place value from the float that returned to display it on the 7-seg display (since the display was 4-digit but all the segments were bussed I had two 595s daisy chained together; one for the segments and the other for the cathodes (or was it anodes?) of each digit) but if I worked it out before I'm sure I'll work it out again.

Thanks again!

User avatar
DougieLawson
Posts: 38481
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Everything is a file?

Tue Feb 02, 2016 11:09 pm

Why not read the temp from the pseudo file in /sys?

cat /sys/devices/virtual/thermal/thermal_zone0/temp

Code: Select all

[email protected] /sys $ cat /sys/devices/virtual/thermal/thermal_zone0/temp
18563
[email protected] /sys $ vcgencmd measure_temp
temp=18.6'C
[email protected] /sys $
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

I'll do your homework for you for a suitable fee.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

neema_t
Posts: 26
Joined: Tue Nov 12, 2013 9:38 pm

Re: Everything is a file?

Wed Feb 03, 2016 12:05 am

DougieLawson wrote:Why not read the temp from the pseudo file in /sys?

cat /sys/devices/virtual/thermal/thermal_zone0/temp

Code: Select all

[email protected] /sys $ cat /sys/devices/virtual/thermal/thermal_zone0/temp
18563
[email protected] /sys $ vcgencmd measure_temp
temp=18.6'C
[email protected] /sys $
That's how I did it before (I definitely recognise the 'thermal_zone0' part), hence the title of this thread; I was hoping to find a similar file describing free space. Thanks though, I'll take a look at that (again) tomorrow.

jahboater
Posts: 5430
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Everything is a file?

Wed Feb 03, 2016 9:49 am

And get disk information from /proc/diskstats
"We are in the beginning of a mass extinction, and all you can talk
about is money and fairy tales of eternal economic growth."
- Greta Thunberg

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Everything is a file?

Wed Feb 03, 2016 9:58 am

jahboater wrote:And get disk information from /proc/diskstats
It doesn't contain the available space on the disk or anything else useful for determining that.
https://www.kernel.org/doc/Documentatio ... -diskstats

User avatar
B.Goode
Posts: 9833
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Everything is a file?

Wed Feb 03, 2016 10:25 am

neema_t wrote:I was hoping to find a similar file describing free space. Thanks though, I'll take a look at that (again) tomorrow.
One thought (about simplifying, not finding the 'file') is to read man df and use the options there to trim the output you get to the bare minumum to make post-processing it with python simpler.

Maybe:

Code: Select all

[email protected] ~ $ df --output=pcent /
Use%
 51
The other thought, needing more real research:
df is simply a utility. Someone must have written it and made the source code available as part (probably) of the gnu utilities bundled with Raspbian. So the source code will be online for inspection. It is pretty much certain that the source of df must be calling some well-defined interface to the filesystem to extract the raw data on which the Use% figure is based. All you have to do is read the source to find what that interface is, and write your own simplified code to do the same thing.

(Or if you strike lucky someone knowledgeable here might tell you what that interface is and refer you to the documentation for its api.)

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Everything is a file?

Wed Feb 03, 2016 11:15 am

I had a bored moment. This is tested and working:

Code: Select all

from subprocess import Popen, PIPE

def GetDiskSpace(fs="/"):
    ''' Find out the space remaining on the specified filesystem
    If an error occurs, returns None, otherwise it returns
    the space in megabytes.
    Parameters to df are the following:
      --output=avail    show only the available space
      --block-size=1M   report the disk space in units of 1 Megabyte
      '''
    try:
        with Popen(['/bin/df', '--output=avail', '--block-size=1M', fs], stdout=PIPE) as cmnd:
            cmnd.stdout.readline()          # first line is heading
            line = cmnd.stdout.readline()   # second line is just the space in megabytes
            return int(line)            # convert the string to an integer
    except:
        return None
            
print ("There are", GetDiskSpace(), "Megs free on /")
print ("There are", GetDiskSpace("/boot"), "Megs free on /boot")
for a %Used number the relevant line would change to:

Code: Select all

        with Popen(['/bin/df', '--output=pcent',  fs], stdout=PIPE) as cmnd:

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Everything is a file?

Wed Feb 03, 2016 11:52 am

And this is the version using the API:

Code: Select all

import os
x = os.statvfs("\")
availBytes = x.f_bavail * x.f_bsize
The output of that matches the output of df. However I can't see how to get a value of %used that similarly matches df.

Code: Select all

used1 = 100 - 100.0 * x.f_bavail / x.f_blocks
is a 2% too high, but

Code: Select all

used2 = 100 - 100.0 * x.f_bfree / x.f_blocks
is 2% too low.

See man statvfs, after that your guess is as good as mine.[/s]

Edit: I've looked at the source and frankly I'm not much wiser but I have less hair. But for what it's worth this is the method df uses:

Code: Select all

used = x.f_blocks - x.f_bfree                 # The number of blocks that are in use
nonRootTotal = used + x.f_bavail           # The total number of blocks on the device that a non-root user can use
pcentUsed = int(100.0 * used / nonRootTotal +0.999999)
That matches the output of df.

User avatar
B.Goode
Posts: 9833
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Everything is a file?

Wed Feb 03, 2016 2:46 pm

B.Goode wrote:if you strike lucky someone knowledgeable here might tell you what that interface is and refer you to the documentation for its api.
Looks like you got lucky!

Kudos to @rurwin for sacrificing his hair to research this!

JimmyN
Posts: 1109
Joined: Wed Mar 18, 2015 7:05 pm
Location: Virginia, USA

Re: Everything is a file?

Wed Feb 03, 2016 5:05 pm

For free space, both RAM and disk, CPU utilization, etc, I use "psutil" (Python system and process utilities). It has a number of parameters so you can select what you want, and it will even provide it to you as a percentage rather than space if you prefer that.
But it won't fetch CPU temp.

Yes the example I gave you using "os.popen" is depreciated now, but then I'm old, retired, and more than a little depreciated myself so I tend to keep on with what I know until it doesn't work anymore. But that's probably more about old habits, rather than age :D

Return to “Beginners”