Geeman2000
Posts: 49
Joined: Mon Jun 15, 2015 7:17 am

I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 6:38 am

Hi All
I have a script that I run to measure temps via 1Wire using DS2482 bus and DS18B20 sensors. It basically adds temperatures to a database on a regular basis. The script runs and temps are added to DB for around 4 - 7 days then it throws an error and stops. I thought the SD card maybe corrupt so I created a fresh install on a new card but the behavior is persisting. Additional to the pi software I have added LAMP server, Samba and this (https://www.abelectronics.co.uk/kb/arti ... -1-wire-pi) added to rc.local to support the bus. There is also a concurrently running Python script that allows remote power on/off for hot water power via a pin.

The error message and script are shown below. Anybody have an idea what the problem maybe?

Code: Select all

pi@RPi-3:~/work $ python tempbus2.py
Traceback (most recent call last):
  File "tempbus2.py", line 63, in <module>
    tv.append(str(read_temp(sensor)))
  File "tempbus2.py", line 44, in read_temp
    while lines[0].strip()[-3:] != 'YES':
IndexError: list index out of range
The Python code is ;

Code: Select all

import MySQLdb as mdb
import sys
import time
import os #new


try:
    con = con = mdb.connect('localhost', 'x', 'x', 'x')
except (mdb.Error, mdb.Warning) as e:
    print(e)
    sys.exit(-1)

sensors=[
  ["28-0000066066dd", 1, "Hot Water", 1],
  ["28-000006600ffd", 1, "AC Inlet Passage", 2],
  ["28-0316529e61ff", 1, "AC Roof Xchange Inlet", 3],
  ["28-800000276014", 1, "Pool", 10],
  ["28-0416556147ff", 1, "AC Kitchen Outlet", 5],
  ["28-041655fdf1ff", 1, "AC Day Room Outlet", 6],
  ["28-041655fdc6ff", 1, "AC Outside Unit Fan Inlet", 7],
  ["28-0000066143fb", 1, "AC Outside Unit Fan Outlet", 8],
  ["28-0316526975ff", 1, "Wall Cavity", 9],
  ["28-041655e0f6ff", 1, "AC Roof Xchange Outlet", 4],
  ["28-000006616388", 1, "Pool Area Ambient", 11],
  ["28-031652f316ff", 1, "Roof", 12],
  ["28-0416557a76ff", 1, "Garage", 13],
  ["28-041655f892ff", 1, "Patio", 14],
  ["28-031652f44fff", 1, "Entrance", 15],
  ["28-0216168f76ee", 1, "HWS Tank Bot A1", 16],
  ["28-0116181438ee", 1, "HWS Tank Top A3", 17],
  ["28-02161512d8ee", 1, "HWS Tank Skin A2", 18],
  ["28-0116181714ee", 1, "Patio Abient A4", 19],
]

def temp_raw(sensor):

    temp_sensor = '/sys/bus/w1/devices/'+sensor+'/w1_slave'
    f = open(temp_sensor, 'r')
    lines = f.readlines()
    f.close()
    return lines
def read_temp(sensor):
    lines = temp_raw(sensor)
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = temp_raw(sensor)
    temp_output = lines[1].find('t=')
    if temp_output != -1:
        temp_string = lines[1].strip()[temp_output+2:]
        temp = round(float(temp_string) / 1000.0,1)
    return temp

while True:

    tv = []

    for t_sensor in sensors:
        sensor = t_sensor[0]
        temp_sensor = '/sys/bus/w1/devices/'+sensor+'/w1_slave'
        if t_sensor[1]:
            # print (temp_sensor)
            if os.path.isfile(temp_sensor): # new
                tv.append(str(read_temp(sensor)))
            else: # new
                tv.append("20") # new
        else:
            tv.append("nope")
            
#Convert tank top and ambient temps to float and estimate water temp
    top = float(tv[16])
    amb = float(tv[18])
    tank = 0.12*(top-amb)+top
    hwstempcalc = str(round(tank,1))
    tv.append(hwstempcalc)
    #print top, amb, tank, hwstempcalc, tv[19]

    try:
        cur = con.cursor()
        cur.execute("INSERT INTO templog(hw, ACi, ACri, poolw, ACko, \
            ACdro, ACoi, ACoo, wall, ACro, poola, roof, gar, pat, fe, \
            tankbot, tanktop, tankskin, patio, hwscalc) VALUES(%s, %s, %s, %s, \
            %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",(tv))

        con.commit()

    except mdb.Error as e:
        con.rollback()
        print "Error %d: %s" % (e.args[0], e.args[1])

    finally:
        if con:
            con.close()
            


    time.sleep(900)
    try:
        con = con = mdb.connect('localhost', 'x', 'x', 'x')
    except (mdb.Error, mdb.Warning) as e:
        print(e)
        sys.exit(-1)

MarkDH102
Posts: 476
Joined: Fri Feb 13, 2015 3:18 pm

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 7:02 am

Might be worth checking the length of 'lines' before you do the test for != 'YES'
I guess it's possible that once in a blue moon, lines could be empty.

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

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 7:52 am

MarkDH102 wrote:
Thu Jun 10, 2021 7:02 am
Might be worth checking the length of 'lines' before you do the test for != 'YES'
I guess it's possible that once in a blue moon, lines could be empty.

What Mark said....


And that, in turn, might be a consequence of the specific sensor you are checking having temporarily become unavailable or unresponsive.

User avatar
thagrol
Posts: 4988
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 8:26 am

Even then I doubt that particular test will do what you think it will.

You're comparing a list to a string. That's always going to retun False. .strip()[-3:] returns a three element list assuming the string being split has at least three elements.
I'm a volunteer. Take me for granted or abuse my support and I will walk away

All advice given is based on my experience. it worked for me, it may not work for you.
Need help? https://github.com/thagrol/Guides

Geeman2000
Posts: 49
Joined: Mon Jun 15, 2015 7:17 am

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 8:51 am

Thanks for the replies.

I'm a noob but have attempted to modify code based on my limited knowledge.
Is this change what is suggested?

Code: Select all

def read_temp(sensor):
    lines = temp_raw(sensor)
    if len(lines) > 1:
        while lines[0].strip()[-3:] != 'YES':
            time.sleep(0.2)
            lines = temp_raw(sensor)
        temp_output = lines[1].find('t=')
        if temp_output != -1:
            temp_string = lines[1].strip()[temp_output+2:]
            temp = round(float(temp_string) / 1000.0,1)
    else: temp = 20.0
     
    return temp

User avatar
thagrol
Posts: 4988
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 9:18 am

thagrol wrote:
Thu Jun 10, 2021 8:26 am
Even then I doubt that particular test will do what you think it will.

You're comparing a list to a string. That's always going to retun False. .strip()[-3:] returns a three element list assuming the string being split has at least three elements.
EDIT: Ignore me. I misread strip as split
I'm a volunteer. Take me for granted or abuse my support and I will walk away

All advice given is based on my experience. it worked for me, it may not work for you.
Need help? https://github.com/thagrol/Guides

User avatar
thagrol
Posts: 4988
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 9:29 am

Geeman2000 wrote:
Thu Jun 10, 2021 8:51 am
Thanks for the replies.

I'm a noob but have attempted to modify code based on my limited knowledge.
Is this change what is suggested?

Code: Select all

def read_temp(sensor):
    lines = temp_raw(sensor)
    if len(lines) > 1:
        while lines[0].strip()[-3:] != 'YES':
            time.sleep(0.2)
            lines = temp_raw(sensor)
        temp_output = lines[1].find('t=')
        if temp_output != -1:
            temp_string = lines[1].strip()[temp_output+2:]
            temp = round(float(temp_string) / 1000.0,1)
    else: temp = 20.0
     
    return temp
Yes but lines[0] returns only the first character of lines. Guess what? That'll always be one character long so can never be equal to "YES"

If what you actuall want is the last three characters of the first line in lines, try this:

Code: Select all

        while lines.splitlines()[0].strip()[-3:] != 'YES':
I'm a volunteer. Take me for granted or abuse my support and I will walk away

All advice given is based on my experience. it worked for me, it may not work for you.
Need help? https://github.com/thagrol/Guides

User avatar
Paeryn
Posts: 3277
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: I need help with "IndexError: list index out of range"

Thu Jun 10, 2021 9:50 pm

thagrol wrote:
Thu Jun 10, 2021 9:29 am
Yes but lines[0] returns only the first character of lines. Guess what? That'll always be one character long so can never be equal to "YES"

If what you actuall want is the last three characters of the first line in lines, try this:

Code: Select all

        while lines.splitlines()[0].strip()[-3:] != 'YES':
No, according to the OP lines is obtained using f.readlines() which returns a list of strings, each string being one line of the file, so lines[0] is a string containing the first line of the file.
Geeman2000 wrote:
Thu Jun 10, 2021 6:38 am

Code: Select all

def temp_raw(sensor):
    temp_sensor = '/sys/bus/w1/devices/'+sensor+'/w1_slave'
    f = open(temp_sensor, 'r')
    lines = f.readlines()
    f.close()
    return lines
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

MarkDH102
Posts: 476
Joined: Fri Feb 13, 2015 3:18 pm

Re: I need help with "IndexError: list index out of range"

Fri Jun 11, 2021 6:16 am

No, according to the OP lines is obtained using f.readlines() which returns a list of strings, each string being one line of the file, so lines[0] is a string containing the first line of the file.
Now, I thought that, but didn't like to say anything as my Python knowledge is not that brilliant. But I did wonder why his code had worked properly for some considerable time!

User avatar
thagrol
Posts: 4988
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: I need help with "IndexError: list index out of range"

Fri Jun 11, 2021 11:03 am

Paeryn wrote:
Thu Jun 10, 2021 9:50 pm
No, according to the OP lines is obtained using f.readlines() which returns a list of strings, each string being one line of the file, so lines[0] is a string containing the first line of the file.
Point taken. Let me offer my appologies. I obviously wasn't firing on all cylinders yesterday.
I'm a volunteer. Take me for granted or abuse my support and I will walk away

All advice given is based on my experience. it worked for me, it may not work for you.
Need help? https://github.com/thagrol/Guides

User avatar
Paeryn
Posts: 3277
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: I need help with "IndexError: list index out of range"

Fri Jun 11, 2021 11:23 am

thagrol wrote:
Fri Jun 11, 2021 11:03 am
Paeryn wrote:
Thu Jun 10, 2021 9:50 pm
No, according to the OP lines is obtained using f.readlines() which returns a list of strings, each string being one line of the file, so lines[0] is a string containing the first line of the file.
Point taken. Let me offer my appologies. I obviously wasn't firing on all cylinders yesterday.
I'd blame it on the hot weather, it usually makes me loose my attention and make silly mistakes that I wouldn't normally do. :|
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

User avatar
thagrol
Posts: 4988
Joined: Fri Jan 13, 2012 4:41 pm
Location: Darkest Somerset, UK
Contact: Website

Re: I need help with "IndexError: list index out of range"

Fri Jun 11, 2021 11:50 am

Paeryn wrote:
Fri Jun 11, 2021 11:23 am
thagrol wrote:
Fri Jun 11, 2021 11:03 am
Paeryn wrote:
Thu Jun 10, 2021 9:50 pm
No, according to the OP lines is obtained using f.readlines() which returns a list of strings, each string being one line of the file, so lines[0] is a string containing the first line of the file.
Point taken. Let me offer my appologies. I obviously wasn't firing on all cylinders yesterday.
I'd blame it on the hot weather, it usually makes me loose my attention and make silly mistakes that I wouldn't normally do. :|
Yeah. Hot weather and trying to see the eclipse despite the clouds. (I managed to).

There is one other potential issue not yet mentioned:

Python2 or python3?

In python 3 all strings are unicode. I doubt the output from the sensor is so there may be a need to encode/decode during processing. Otherwise the code may be trying to compare a byte string (from the sensor) with a unicode string of "YES".

Unless I'm wrong. Again. Which is very possible.
I'm a volunteer. Take me for granted or abuse my support and I will walk away

All advice given is based on my experience. it worked for me, it may not work for you.
Need help? https://github.com/thagrol/Guides

Geeman2000
Posts: 49
Joined: Mon Jun 15, 2015 7:17 am

Re: I need help with "IndexError: list index out of range"

Fri Jun 11, 2021 10:56 pm

Using Python 2.

It's 14 -21C here in Western Australia and we are enduring the cold till next spring.

Return to “Python”