如何让我的 Python 代码在网络断开时重新启动

How can I get my Python Code to restart when the network disconnects

我有一段 Python 代码 运行 作为通过 API 提取天气数据的服务。

当一切都很好时,代码本身运行得很好,即网络,但我注意到有时 Pi 上拉 API 数据的 WiFi 会掉线,然后 python代码似乎停止了。

我有一小行代码提供最基本的日志,但我想大大改进它。日志代码只为我提供了 datetime.now,所以我可以看到上次代码 运行 是什么时候。

#!/usr/bin/python3

#import modules
import cymysql
from time import sleep
from urllib.request import urlopen
import json
import datetime

#set MySQl Variables
host = "localhost"
user = "xxx"
password = "xxx"
schema = "xxx"

#connect to MySQL DB
db = cymysql.connect(host, user, password, schema)
curs = db.cursor()

#set api key for DarkSky API
apikey="xxx"
# Latitude & longitude
lati="-26.20227"
longi="28.04363"

# Add units=si to get it in sensible ISO units.
url="https://api.forecast.io/forecast/"+apikey+"/"+lati+","+longi+"?units=si"

#begin infinite loop
while True:

        #convert API reading to json and readable array 'weather'
        meteo=urlopen(url).read()
        meteo = meteo.decode('utf-8')
        weather = json.loads(meteo)

        #set variables for current weather
        cTemp = (weather['currently']['temperature'])
        cCond = (weather['currently']['summary'])
        cRain1 =  (weather['currently']['precipProbability'])
        cRain2 = cRain1*100
        cIcon = (weather['currently']['icon'])
        oaSum = (weather['daily']['summary'])

        #print variables - for testing purposes
        #print (cTemp)
        #print (cCond)
        #print (cRain2)
        #print (cIcon)
        #print (oaSum)

        #extract daily data from 'weather' array
        daily = (weather['daily']['data'])

        #create new arrays for daily variables
        listHigh = []
        listLow = []
        listCond = []
        listRain = []
        listIcon = []

        #set daily variables
        for i in daily:
                listHigh.append(i['temperatureHigh'])

        for i in range(0,len(listHigh)):
                high1 = listHigh[0]
                high2 = listHigh[1]
                high3 = listHigh[2]
                high4 = listHigh[3]
                high5 = listHigh[4]
                high6 = listHigh[5]
                high7 = listHigh[6]
                high8 = listHigh[7]

        for o in daily:
                listLow.append(o['temperatureLow'])

        for o in range(0,len(listLow)):
                low1 = listLow[0]
                low2 = listLow[1]
                low3 = listLow[2]
                low4 = listLow[3]
                low5 = listLow[4]
                low6 = listLow[5]
                low7 = listLow[6]
                low8 = listLow[7]

        for p in daily:
                listCond.append(p['summary'])

        for p in range(0,len(listCond)):
                cond1 = listCond[0]
                cond2 = listCond[1]
                cond3 = listCond[2]
                cond4 = listCond[3]
                cond5 = listCond[4]
                cond6 = listCond[5]
                cond7 = listCond[6]
                cond8 = listCond[7]

        for m in daily:
                listRain.append(m['precipProbability'])

        for m in range(0,len(listRain)):
                rain1 = listRain[0]
                rain2 = listRain[1]
                rain3 = listRain[2]
                rain4 = listRain[3]
                rain5 = listRain[4]
                rain6 = listRain[5]
                rain7 = listRain[6]
                rain8 = listRain[7]

        #convert rain chance to readable percentage
        prain1 = rain1*100
        prain2 = rain2*100
        prain3 = rain3*100
        prain4 = rain4*100
        prain5 = rain5*100
        prain6 = rain6*100
        prain7 = rain7*100
        prain8 = rain8*100

        for l in daily:
                listIcon.append(l['icon'])

        for l in range (0,len(listIcon)):
                icon1 = listIcon[0]
                icon2 = listIcon[1]
                icon3 = listIcon[2]
                icon4 = listIcon[3]
                icon5 = listIcon[4]
                icon6 = listIcon[5]
                icon7 = listIcon[6]
                icon8 = listIcon[7]

        #print daily variables - for testing purposes
        #print (high1)
        #print (low1)
        #print (cond1)
        #print (prain1)
        #print (icon1)
        #print (high2)
        #print (low2)
        #print (cond2)
        #print (prain2)
        #print (icon2)

        #update data in DataBase
        try:
                sql_update_query = """UPDATE weather SET current_temp = %s, cur$
                varis = (cTemp, cCond, cRain2, cIcon, high1, low1, cond1, prain$
                curs.execute(sql_update_query, varis)
                db.commit()
        except db.Error as error:
                print("Error: {}".format(error))
                db.rollback()

        #write date to log file
        with open ("/home/pi/CoRo/Projects/WeatherMan/weatherlog.txt", mode="w") as file:
                file.write('Last Data was pulled at: %s' %(datetime.datetime.now()))
        #set loop to sleep for 10 minutes and go again
        sleep(600)

我知道数据库代码被截断了,但这只是放入数据库的变量,我可以看到它有效。

但是,如果网络断开,代码将停止,数据库将保留最后轮询的 API 数据。

如果 API 获取失败,我将如何重新启动 python 代码?

提前致谢,

您可以重写代码中将天气数据提取为函数或单独模块的部分。这将允许您仅在网络连接正常时调用它。下面是一些伪代码:

if network_connection:
    pull_weather_data()
else:
    do_something()

do_something() 可能需要重新连接到网络,例如重置您的网络适配器。

您可以通过尝试 ping 您的路由器或外部 IP 来确定网络连接的状态,例如 Google 的 DNS 服务器(8.8.8.8 或 8.8.4.4)之一。

要避免嵌套循环,您可以使用 continue 子句。例如:

while True:
    if network_connection:
        pull_weather_data()
    else:
        reset_network_connection()
        time.sleep(180) # Sleep for 3 minutes.
        continue

continue 会将解释器发送回 while 循环的开始。它将从那里检查网络连接并提取数据或重置网络连接并再睡 3 分钟。

使用上面的 Quernons 答案编辑如下代码:

#!/usr/bin/python3

#import modules
import os
import cymysql
from time import sleep
from urllib.request import urlopen
import json
import datetime

#set MySQl Variables
host = "localhost"
user = "xxx"
password = "xxx"
schema = "xxx"

#connect to MySQL DB
db = cymysql.connect(host, user, password, schema)
curs = db.cursor()

#set api key for DarkSky API
apikey="xxx"
# Latitude & longitude
lati="-26.20227"
longi="28.04363"

# Add units=si to get it in sensible ISO units not stupid Fahreneheit.
url="https://api.forecast.io/forecast/"+apikey+"/"+lati+","+longi+"?units=si"

#begin infinite loop
while True:

        #function to check if there is an internet connection
        def check_ping():
                hostname = "8.8.8.8"
                response = os.system("ping -c 1 " + hostname)
                #and then check the response...
                if response == 0:
                        pingstatus = 0
                else:
                        pingstatus = 1

                return pingstatus

        networkstatus = check_ping()

        #print check_ping() - for testing purposes
        #print (networkstatus)

        #function to pull weather data from API
        def get_weather():
          #insert weather data here with no changes

        if networkstatus == 0:
                get_weather()
        else:
                print ("Resetting Network Adapters")
                dwnnw = 'ifconfig wlan0 down'
                upnw = 'ifconfig wlan0 up'
                os.system(dwnnw)
                os.system(upnw)
                sleep(180)
                continue