Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4874

Raspberry Pi OS • Shutdown on startup

$
0
0
Hello & Thanks for any insights. I have a python 3.11.2 script running on a Pi Zero 2 W (Raspberry Pi OS 64 bit Lite) that starts upon power on (power supply is solid) from rc.local, runs for hours, then executes a shutdown using: os.system("sudo shutdown -h now"). The problem is that upon the next power on, the system immediately shuts down with the message: Broadcast message from root@raspberrypi (Wed…): The system will power off now! At this point the only way to recover is to re-image the SD card (64G).

I have written a short Python script (including imports) that executes the same shutdown command from rc.local after a 60 second delay (so I can regain control). This script runs as expected and does not cause the system to immediately shut down after power on. Neither this script, nor my larger script causes the problem when executed from a terminal over SSH.

I have installed the following packages using the following commands:
sudo apt update
sudo apt full-upgrade
sudo apt install -y python3-pip
sudo apt install -y python3-pillow
sudo apt install -y python3-picamera2 --no-install-recommends

and edited rc.local thus: python /home/pi/web.py (added before “exit 0”). Entire python script is attached. I am not an accomplished Python programmer and I know nothing about Linux, so if you say “look in the log file”, please add where & how. Thanks to all!

(AC power is switched off at midnight and back on 30 minutes later)
The suspect code is about 3/4 of the way down "if(hours == '22')"

Code:

from PIL import Imagefrom PIL import ImageDrawfrom PIL import ImageFontfrom picamera2 import Picamera2import requestsimport datetimeimport timeimport ftplibimport os                def resolveWind(dir):                       # transform heading in degrees to "N" etc    wdir = ["N", "NE", "E", "SE", "S", "SW", "W", "NW","N"]    boundry = -22.5    index = 0    while(dir>(boundry+45)):        index = index + 1        boundry = boundry + 45    return wdir[index]    def ftpToWebsite(file):                     # ftp    try:        host = "stevensarns.com"            # website        port = 21        ftp.connect(host, port)        ftp.login("xxx", "xxx") # login, pw        ftp.cwd('/public_html/Colorado')    # change work dir, '/public_html/ExperimentalPics'        ftp.storbinary('STOR '+file, open(file, 'rb'))        print(file, "sent")                 # debug    except:        print("ftp failure")                # ftp error has occurred    finally:        return True                         # ftp has been started, needs ftp(close)def writeText(text, color, size, org, image):        color = color                     # noon forecast        textSize = size        font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",textSize)# font font path, size        image = image        draw = ImageDraw.Draw(image)        text = text        org  = org        draw.text((org), text, font=font, fill=(color))        return imagedef snap():                                 # snap, timestamp    filename = "pic.png"                    # name of file to create    now = datetime.datetime.now()           # get time now    now = now.strftime("%A %I:%M")          # format string    print("Snap", filename, now)            # show filename and timestamp    picam2.start()                          # start camera    time.sleep(2)                           # wait for camera to initialize    picam2.capture_file(filename)           # capture file (pic.jpg) do not picam2.close() png!    img = Image.open(filename)              # open file (pic.jpg)    draw = ImageDraw.Draw(img)              # Call draw Method to add 2D graphics in an image    font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",20)# font size & loc    draw.text((28, 5), now, font=font, fill=(0, 0, 0)) # location -x,-y, font color    img.save(filename)                      # Save, all images stored in same file as code    return filename                         # return pic.png# ------------------------ Main --------------------------------------------snapInterval     = 15                       # minutes between webcam snapsforecastInterval = 15                       # minutes between forecastslastHour         = 0                        # used to create 8 hourly pictureslastSnap         = 0                        # used to create hourly view w/ overlaylastForecast     = 0                        # save for next testfilename         = "pic.png"                # primary file to send to website  picam2           = Picamera2()ftp              = ftplib.FTP()os.environ['TZ'] = 'America/Denver'         # Set the timezonetime.tzset()                                # Apply the timezone changeconfig = picam2.create_still_configuration(main={"size": (640,480)}, lores={"size": (640, 480)}, display="lores")picam2.configure(config)picam2.still_configuration.size = (640,480) # image sizeftpActive = True                            # set ftp addprint("Start main loop")                    # end of setupwhile True:                                 # main loop    # wait for snap interval=>snap, overlay & ftp to website    now = int((time.time())/60)             # integer minutes (from forever)    hours = datetime.datetime.now()         # time data type    hours = hours.strftime("%H")            # hours in 24 hour format, zero padded e.g. 08 = 8AM    if(((now%snapInterval)==0) and (now!=lastSnap)): # interval passed?        lastSnap = now                      # fail test until 1 minute interval passes        print("Snap interval ", snapInterval)        filename = snap()                   # snap & stamp        ftpActive = ftpToWebsite(filename)  # ftp => website        print(filename, "=> website")      # debug                    # if this is an even hour change, save 1 of 8 pictures with hour as part of filename    # images are stored at 6AM, 8AM, 10AM, 12AM, 2PM, 4PM, 6PM & 8PM    # browser will display sequence, files are stored overwriting older files    if(((now%snapInterval)==0) and (hours != lastHour)): # has hour changed and pic snapped?        lastHour = hours                    # fail test until next hour        print("Hour =", hours)        if(hours=='06' or hours=='08' or hours=='10' or hours=='12' or hours=='14'            or hours=='16' or hours=='18' or hours=='20'): # is it time to store image?            title = "pic" + hours + ".png"  # construct filename with hour attached e.g. "pic08"            img = Image.open("pic.png")     # open snapped image with overlay            img.save(title)                 # save image & change to .png            ftpActive = ftpToWebsite(title) # set flag, send file to website            print(title, "=> website")      # show file sent                # overwrite timed images from yesterday with blank images    if(hours=='04'):                        #          print("Blank images => website")    # send 8 blanks        image = Image.new('RGB',(640,480),"rgb(0,0,0)") # black        image.save("pic06.png")                 # create blank image        ftpActive = ftpToWebsite("pic06.png")   # old file will be overwritten with pic.png        image.save("pic08.png")                 # this causes blanks to display at website        ftpActive = ftpToWebsite("pic08.png")   #         image.save("pic10.png")        ftpActive = ftpToWebsite("pic10.png")        image.save("pic12.png")        ftpActive = ftpToWebsite("pic12.png")        image.save("pic14.png")        ftpActive = ftpToWebsite("pic14.png")        image.save("pic16.png")        ftpActive = ftpToWebsite("pic16.png")        image.save("pic18.png")        ftpActive = ftpToWebsite("pic18.png")        image.save("pic20.png")        ftpActive = ftpToWebsite("pic20.png")       if(hours=='22'):                        # shut down at 10pm MDT (=11PM MST)                 print("Shutting down now")          # (mechanical AC timer switch does not know MDT/MST)        time.sleep(5)                       # time for message to transmit        os.system("sudo shutdown -h now")   # shutdown        while(True):            time.sleep(100)    # get 24 hour forecast and create 4 images in same directory as this code    # Virutal Crossing 1000 requests / day free api    if(((now%forecastInterval)==0) and (now!=lastForecast)): # interval passed?        lastForecast = now                  # don't call again until this minute passes        print("Request forecast")        # this url will elicit 24 hours of hourly forecast for 4 data elements: temperature, windspeed, wind direction and cloud cover        url = "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Salida,CO/today?key=xxx&include=hours&elements=temp,windspeed,winddir,precipprob,cloudcover"        response = requests.get(url)        # send api to virtual Crossing & get reply        data = response.json()              # do something json        hourly_data = data['days'][0]['hours']  # create python dictionary=>parameter:value        index = -1                          # hours start at 0 for midnight        temp        = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4]        precipProb  = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4]        wspeed      = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4]        cloudCover  = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4]        wdir = ["x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x","x",]                tof = -1                          # Time Of Forecast, hours start at 0 for midnight        for hour in hourly_data:  # transform json data into lists            tof += 1                      # index indicates the hour of the forecast            temp[tof]= int(hour['temp'])            precipProb[tof] = int(hour['precipprob'])            wspeed[tof]     = int(hour['windspeed'])            cloudCover[tof] = int(hour['cloudcover'])            wdir[tof]     = resolveWind(int(hour['winddir']))        tof = 10 # first Time Of Forecast to create image for website        while(tof<17):            print("Forecast", tof)          # create images of 10AM, 12AM, 2PM, 4PM forecasts            image = Image.new('RGB',(240,240),"rgb(200, 200, 200)") #size, color=grey            image.save("blankForecast.png") # start with blank, then add text            if(tof == 10):                text = "10 AM Forecast"            if(tof == 12):                text = "Noon Forecast"            if(tof == 14):                text = "2 PM Forecast"            if(tof == 16):                text = "4 PM Forecast"            writeText(text, (0,0,255), 25, (0,30), image)            image = writeText(("Temp    " + str(int(temp[tof])) + " F"), (255,0,0), 20, (0,80), image)                    image = writeText(("Precip: " + str(int(precipProb[tof])) + " %"), (255,0,0), 20, (0,110), image)            image = writeText(("Wind:   " + str(int(wspeed[tof])) + " mph"), (255,0,0), 20, (0,140), image)            image = writeText(("Dir:    " + (wdir[tof])), (255,0,0), 20, (0,170), image)            image = writeText(("Cloud:  " + str(int(cloudCover[tof])) + " %"), (255,0,0), 20, (0,200), image)            image.save('forecast'+ str(tof)+'.png')                    tof = tof + 2          print("Forecasts => website")        ftpActive = ftpToWebsite("forecast10.png")        ftpActive = ftpToWebsite("forecast12.png")        ftpActive = ftpToWebsite("forecast14.png")        ftpActive = ftpToWebsite("forecast16.png")        if(ftpActive):                      # has ftp been started?        ftpActive = False               # reset flag        try:            ftp.quit()                  # quit if active        except:            print("ftp never started")  # ftp.quit without start->error        finally:            print("ftp off")    time.sleep(2)                       # ^C keyboard int caught here (keep trying)            

Statistics: Posted by stevensarns — Wed Jul 31, 2024 7:55 pm



Viewing all articles
Browse latest Browse all 4874

Trending Articles