Как я могу получить мой код Python для перезагрузки, когда сеть отключается - PullRequest
0 голосов
/ 02 мая 2019

У меня есть часть кода Python, работающая как служба, которая извлекает данные о погоде через API.

Сам код прекрасно работает, когда все просто, например, сеть, но я заметил, что иногда WiFi на Pi, который извлекает данные API, падает, а затем коды 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 для опроса.

Как бы я перезапустил код Python в случае сбоя API?

Заранее спасибо,

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Вы можете переписать ту часть кода, которая извлекает данные о погоде, в виде функции или отдельного модуля.Это позволит вам звонить только тогда, когда работает сетевое соединение.Ниже приведен некоторый псевдокод:

if network_connection:
    pull_weather_data()
else:
    do_something()

do_something(). Это может быть попытка переподключения к сети, например сброс настроек сетевого адаптера.

Состояние сетевого подключения можно определить с помощьюпытаясь пропинговать ваш роутер или внешний IP-адрес, например DNS-сервер Google (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 минуты.

0 голосов
/ 03 мая 2019

Используя ответ 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





...