Python WHILE loop query


#1

Having eventually got envirphat database data scrolling across scrollphat on a different pi, I now need it to refresh itself every X minutes.

#!/usr/bin/env python

import signal
import time
import scrollphathd
from scrollphathd.fonts import font5x7
import mysql.connector
from mysql.connector import Error
con = mysql.connector.connect(host='192.168.################################)

str_len = 0
scroll_x = 0

### Create cursorS for each database element:
### Keep in buffer with =True
while True:
    curT = con.cursor(buffered=True)
    curY = con.cursor(buffered=True)
    curL = con.cursor(buffered=True)

### Use each cursor to read required data from database:
    curT.execute('SELECT Temp FROM readings ORDER BY Added DESC LIMIT 1')
    curY.execute('SELECT Yaxis FROM readings ORDER BY Added DESC LIMIT 1')
    curL.execute('SELECT Lux FROM readings ORDER BY Added DESC LIMIT 1') 
 
### Get rid of trailing comma from each SELECT result: 
    resultT = [row[0] for row in curT.fetchall()]
    resultY = [row[0] for row in curY.fetchall()]
    resultL = [row[0] for row in curL.fetchall()]

### Not essential, but let's show the 
### result of each SELECT query in the terminal:
    print resultT
    print resultY
    print resultL

    time.sleep(4)

### Set strings for display on Scroll PhatHD from SELECT results: 
    while True:
            temperature = resultT[0]
            yaxis = resultY[0]
            lux = resultL[0]


### Dim down Scroll Phat HD, and clear its buffer:            
            scrollphathd.set_brightness(0.1)
            scrollphathd.clear()


### Uncomment/comment the below line to rotate Scroll PhatHD by 180/upside down
            scrollphathd.rotate(degrees=180)


### Uncomment line below to test all data on Scroll PhatHD in one go.
### str_len = scrollphathd.write_string(" :-) %.1fC Y%i L%i "%(temperature, yaxis, lux), brightness=0.5)


### Check light levels and door angle (Yaxis) and report appripriately. Always show the temperature:
            if lux <= 100 and yaxis >=3500 :
                str_len = scrollphathd.write_string("Garage: light off & door closed.  %.1fC "%(temperature), x=0, y=0, font=font5x7)
            elif lux <= 100 and yaxis <500:
                str_len = scrollphathd.write_string("Garage: Light off & door open.  %.1fC "%(temperature), x=0, y=0, font=font5x7)        
            elif lux > 100 and yaxis <500:
                str_len = scrollphathd.write_string("Garage: Light on & door open.  %.1fC "%(temperature), x=0, y=0, font=font5x7)
            elif lux > 100 and yaxis >=3500:
                str_len = scrollphathd.write_string("Garage: Light on & door closed.  %.1fC "%(temperature), x=0, y=0, font=font5x7)
            elif yaxis >500 and yaxis <3499:
                str_len = scrollphathd.write_string("Garage door ajar %.1fC  "%(temperature), x=0, y=0, font=font5x7)


            scrollphathd.scroll_to(scroll_x, 0)
            scrollphathd.show()
            time.sleep(0.01)
            scroll_x += 1
            if scroll_x >= str_len:
                scroll_x = 0

Where do those while loops need to go so that the scrollphat picks up fresh data every X minutes?
It’s scrolling just fine, but with stale data.

Thank you.


#2

Honestly, I’d probably have the script scroll through everything once (or maybe a couple of times) and exit and then use crontab to set it up to run every minute.

Saves a lot of effort making the script robust and handling errors.

However, your current problem is that your inner loop is while True, and since True will never be anything but True that loop will continue running in perpetuity and never reach the outer while True loop.

Your inner loop is responsible for the scrolling text, and counts up the scroll_x variable until it’s greater than the string, before resetting it back to 0 with scroll_x = 0. If you were to place a break right after scroll_x = 0 with the same indentation then you would “break” out of your inner while True loop, and return control to the outer one which could update the database.

In this case, however, you would be hitting the database for every single line of text scrolled and a huge chunk of your code would be executed unecesarily.

What you ideally want is- in psuedocode -:

import stuff

set scroll phat brightness
set scroll phat rotation
establish database connection

while true:
    clear scroll phat
    reset scroll position to (0, 0)   (IIRC clear does this anyway)
    get data from database
    construct string to display
    str_len = show string on scroll phat
    while str_len > 0:
        scroll 1
        str_len -= 1
        sleep 0.01

This has a couple of benefits over your current flow:

  1. Only one while True loop, with the inner while str_len > 0 being very clear about intent
  2. It only writes the text string once for every outer loop iteration, and then scrolls it

See https://github.com/pimoroni/scroll-phat-hd/blob/master/examples/simple-scrolling.py for a simple scrolling example that writes a text string once to Scroll pHAT HD and then uses scroll(1) and show() to scroll it across the display.


#3

Ok, thank you.
I’m a bit busy with real work for a few days now, but will take a proper look when I get the chance to do so.