3

I have a function to collect temperature (values from text files) which uses a partly predefined path. However, sometimes the path does not exist if the temperature sensor wasn't loaded (is disconnected). How can I set a condition or exception to skip a loop if a path is not available?

I wanted to use continue, but i have no idea what condition to set with it.

def read_all(): 

    base_dir = '/sys/bus/w1/devices/'
    sensors=['28-000006dcc43f', '28-000006de2bd7', '28-000006dc7ea9', '28-000006dd9d1f','28-000006de2bd8']

    for sensor in sensors:

        device_folder = glob.glob(base_dir + sensor)[0]
        device_file = device_folder + '/w1_slave'

        def read_temp_raw():
            catdata = subprocess.Popen(['cat',device_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            out,err = catdata.communicate()
            out_decode = out.decode('utf-8')
            lines = out_decode.split('\n')
            return lines
SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
Miroslav
  • 33
  • 3

2 Answers2

3

Use os.path.isfile and os.path.isdir() to check.

for sensor in sensors:
    device_folders = glob.glob(base_dir + sensor)
    if len(device_folders) == 0:
        continue
    device_folder = device_folders[0]
    if not os.path.isdir(base_dir):
        continue
    device_file = device_folder + '/w1_slave'
    if not os.path.isfile(device_file)
        continue
    ....
luoluo
  • 5,353
  • 3
  • 30
  • 41
  • probably want `continue` there, not `break`, so the rest of the sensors are still processed – tmdavison Aug 28 '15 at 11:23
  • Update to continue @tom. – luoluo Aug 28 '15 at 11:25
  • after adding what you've suggested, it stops in a loop when sensor is missing and reports IndexError: list index out of range. – Miroslav Aug 28 '15 at 11:54
  • It was coursed by `device_folders = glob.glob(base_dir + sensor)[0]`, I updated my answer. If you are trying to read a file, use `with` statement is better. @Miroslav – luoluo Aug 28 '15 at 11:58
  • great, this works. skips sensor which is not online and continues... gret. thanks for help. – Miroslav Aug 28 '15 at 12:15
  • what i have found. you disconnect a sensor and run the script. it skips the sensor as intended which works great. BUT, when i disconnect sensor while script is running, it stops right before the loop with the missing sensor and waits. until i plug it in. then it continues.i can temporarily solve the problem adding modprobe w1-therm and modprobew1-gpio to the loop. every loop is "scans" and creates folders depending on what it found. but still, if sensor is unpluged in the loop after loading the folder in the variable before reading from the file, it stucks and whole script stops and waits.. – Miroslav Aug 28 '15 at 12:31
2

I'm not sure why you are using subprocess.Popen to read the file. Why not just open() it and read()?.

A python way to handle missing dir or file is something like this:

for sensor in sensors:
    try:
        device_folder = glob.glob(base_dir + sensor)[0]
        device_file = device_folder + '/w1_slave'
        with open(device_file) as fd: # auto does fd.close()
            out = fd.read()
    except (IOError,IndexError):
        continue
    out_decode = out.decode('utf-8')
    ...

If you want to avoid hanging in open() or read() you can add a signal handler and give yourself an alarm signal after, say, 5 seconds. This will interrupt the function, and move you into the except clause.

Setup the signal handler at the start:

import signal
def signal_handler(signal, frame):
    raise IOError
signal.signal(signal.SIGALRM, signal_handler)

and modify your loop to call alarm(5) before the part that might hang. Call alarm(0) at the end to cancel the alarm.

for sensor in sensors:
    signal.alarm(5)
    try:
        device_file = ...
        with open(device_file) as fd:
            out = fd.read()
    except (IOError,IndexError):
        continue
    finally:
        signal.alarm(0)
    print "ok"
    ...
meuh
  • 11,500
  • 2
  • 29
  • 45
  • Probably worth explaining what `IOError` is and a note on using `try except` as it doesn't seem like the OP is familiar with it. – SuperBiasedMan Aug 28 '15 at 11:58
  • this case does exactly the same in terms of error report. I have used sub process as it was recommended due to occasional problems with reading it. but as I am very new to python, i have no clue... – Miroslav Aug 28 '15 at 12:04
  • @Miroslav I handled the IndexError; sorry I hadnt understood what you were seeing. – meuh Aug 28 '15 at 17:00