用樹莓派做一個炫酷的天氣預(yù)報

教大家如何在樹莓派上自己動手做一個天氣預(yù)報。此次教程需要大家有一定的python 基礎(chǔ),沒有也沒關(guān)系,文末我會放出我已寫好的代碼供大家下載。

首先在開始之前?需要申請高德地圖API,去高德地圖官網(wǎng)注冊一下,然后創(chuàng)建一個天氣應(yīng)用(免費(fèi)的),得到一個免費(fèi)key。然后開始擼碼了 (說一下,我用的是python 3)

1.下面給出調(diào)用高德地圖API,獲取天氣數(shù)據(jù)的方法。將申請的key替換進(jìn)url中,再將你的城市代碼(網(wǎng)上可查,可以具體到區(qū))替換下即可。


def GetWeatherInfo():

? ? url ="http://restapi.amap.com/v3/weather/weatherInfo?key=xxxxxxxxxxxxx&city=420115&extensions=all"#將xxxxxx替換為你申請的key,city代碼替換為你的城市代碼try:

? ? ? ? html = requests.get(url)

? ? ? ? data = json.loads(html.text)

? ? ? ? # #將JSON編碼的字符串轉(zhuǎn)換回Python數(shù)據(jù)結(jié)構(gòu)# output result of json# print(data)return data

? ? except:

? ? ? ? returnNone


2.系統(tǒng)信息及配置

# coding = utf-8import subprocessimport timeimport os#device :eth0,wlan0def get_ip(device):

? ? ip = subprocess.check_output("ip -4 addr show "+ device +" | grep inet | awk '{print $2}' | cut -d/ -f1", shell = True).strip()

? ? return ip# Return % of CPU used by user as a character string? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #def getCPUuse():#? ? return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))def getCPUuse():? #calculate CPU with two short time, time2 - time1? time1 = os.popen('cat /proc/stat').readline().split()[1:5]?

? ? ? ? time.sleep(0.2)?

? ? ? ? time2 = os.popen('cat /proc/stat').readline().split()[1:5]?

? ? ? ? deltaUsed = int(time2[0])-int(time1[0])+int(time2[2])-int(time1[2])?

? ? ? ? deltaTotal = deltaUsed + int(time2[3])-int(time1[3])?

? ? ? ? cpuUsage = float(deltaUsed)/float(deltaTotal)*100return cpuUsagedef net_stat():?

? ? net = []?

? ? f = open("/proc/net/dev")?

? ? lines = f.readlines()?

? ? f.close()?

? ? forlineinlines[2:]:?

? ? ? ? con = line.split()?

? ? ? ? """

? ? ? ? intf = {}

? ? ? ? intf['interface'] = con[0].lstrip(":")

? ? ? ? intf['ReceiveBytes'] = int(con[1])

? ? ? ? intf['ReceivePackets'] = int(con[2])

? ? ? ? intf['ReceiveErrs'] = int(con[3])

? ? ? ? intf['ReceiveDrop'] = int(con[4])

? ? ? ? intf['ReceiveFifo'] = int(con[5])

? ? ? ? intf['ReceiveFrames'] = int(con[6])

? ? ? ? intf['ReceiveCompressed'] = int(con[7])

? ? ? ? intf['ReceiveMulticast'] = int(con[8])

? ? ? ? intf['TransmitBytes'] = int(con[9])

? ? ? ? intf['TransmitPackets'] = int(con[10])

? ? ? ? intf['TransmitErrs'] = int(con[11])

? ? ? ? intf['TransmitDrop'] = int(con[12])

? ? ? ? intf['TransmitFifo'] = int(con[13])

? ? ? ? intf['TransmitFrames'] = int(con[14])

? ? ? ? intf['TransmitCompressed'] = int(con[15])

? ? ? ? intf['TransmitMulticast'] = int(con[16])

? ? ? ? """?

? ? ? ? intf = dict(?

? ? ? ? ? ? zip(?

? ? ? ? ? ? ? ? ( 'interface','ReceiveBytes','ReceivePackets',?

? ? ? ? ? ? ? ? ? 'ReceiveErrs','ReceiveDrop','ReceiveFifo',?

? ? ? ? ? ? ? ? ? 'ReceiveFrames','ReceiveCompressed','ReceiveMulticast',?

? ? ? ? ? ? ? ? ? 'TransmitBytes','TransmitPackets','TransmitErrs',?

? ? ? ? ? ? ? ? ? 'TransmitDrop','TransmitFifo','TransmitFrames',?

? ? ? ? ? ? ? ? ? 'TransmitCompressed','TransmitMulticast' ),?

? ? ? ? ? ? ? ? ( con[0].rstrip(":"),int(con[1]),int(con[2]),?

? ? ? ? ? ? ? ? ? int(con[3]),int(con[4]),int(con[5]),?

? ? ? ? ? ? ? ? ? int(con[6]),int(con[7]),int(con[8]),?

? ? ? ? ? ? ? ? ? int(con[9]),int(con[10]),int(con[11]),?

? ? ? ? ? ? ? ? ? int(con[12]),int(con[13]),int(con[14]),?

? ? ? ? ? ? ? ? ? int(con[15]),int(con[16]), )?

? ? ? ? ? ? )?

? ? ? ? )?


? ? ? ? net.append(intf)?

? ? returnnet


3.主程序。執(zhí)行文件

#encoding: utf-8import pygameimport timeimport weatherAPI import SystemInfofromdatetimeimport datetime# 顯示圖片函數(shù)def ShowPicture(picturepath,x0,y0):?

? ? background=pygame.image.load(picturepath)

? ? background.convert_alpha()

? ? window.blit(background,(x0,y0))

? ? returndef ShowCircle():

? ? pygame.draw.circle(window,pygame.Color(255,255,255),(width/2,height/2),radius,fill)

? ? return# 劃線函數(shù),起始坐標(biāo),終點(diǎn)坐標(biāo)def ShowLine(x0,y0,x1,y1):

? ? pygame.draw.line(window,pygame.Color(255,255,255),(x0,y0),(x1,y1),fill)

? ? returnYellow=(255,255,0)

Red=(255,0,0)

LightBlue=(190,190,255)

Green=(0,255,0)

Black=(0,0,0)

White=(255,255,255)# 畫框函數(shù)def ShowRec(x0,y0,x1,y1,color,fill):

? ? pygame.draw.rect(window,color,(x0,y0,x1,y1),fill)

? ? return# 字符串顯示函數(shù)def ShowStr(mystring,x0,y0,size):

? ? font=pygame.font.Font('gkai00mp.ttf',size,bold=1)

? ? textSuface=font.render(mystring,1,pygame.Color(255,255,255))

? ? window.blit(textSuface,(x0,y0))? ? ? ? ? ? ? ? ? ?

? ? returndef ShowStr2(mystring,x0,y0,size):

? ? font=pygame.font.Font('gkai00mp.ttf',size,bold=1)

? ? textSuface=font.render(mystring,1,pygame.Color(255,255,0))

? ? window.blit(textSuface,(x0,y0))? ? ? ? ? ? ? ? ? ?

? ? returndef ShowStr3(mystring,x0,y0,size):

? ? font=pygame.font.Font('gkai00mp.ttf',size,bold=1)

? ? textSuface=font.render(mystring,1,pygame.Color(0,255,0))

? ? window.blit(textSuface,(x0,y0))? ? ? ? ? ? ? ? ? ?

? ? return#背景參數(shù)設(shè)置? ? ? ? ? ? ? ? ? ? ? ? ? ? width=1280height=800fill=1#初始化背景pygame.init()

window=pygame.display.set_mode((width,height),pygame.FULLSCREEN)#全屏# window=pygame.display.set_mode((width,height))#不全屏window.fill(pygame.Color(0,0,0))# back=pygame.image.load(r"/home/pi/ccj/c.jpg")? #圖片位置loop=0

last_ip = ip =''updatingtime=""Title_X=width

WeatherValidation=Falsewhile True:

? ? # window.blit(back,(0,0))? #對齊的坐標(biāo)window.fill(pygame.Color(0,0,0))#背景色0為黑# ShowPicture("a_3.gif",20,450)#draw grids#ShowStr(u"時間",10,20,80)ShowRec(10,10,width-20,height-80,White,1)#畫一個大框ShowLine(10,height/5,width-10,height/5)

? ? ShowLine(10,height/5*3,width-10,height/5*3)

? ? ShowLine(width/2,height/5,width/2,height-70)

? ? ShowLine(width/4,height/5*3,width/4,height-70)

? ? ShowLine(width/4*3,height/5*3,width/4*3,height-70)


? ? #time show? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mylocaltime=time.localtime()

? ? myclock=time.strftime("%H:%M:%S",mylocaltime)#13:15:03 2017-04-21ShowStr(myclock,0,0,180)

? ? mydate=time.strftime("%Y-%m-%d",mylocaltime)#2017-04-21ShowStr(mydate,810,5,90)

? ? mytime=time.strftime("%A",mylocaltime)#ThursdayShowStr(mytime,830,90,85)


? ? name ="自動化實(shí)驗室歡迎您"? ? ShowStr2(name,width/2+10,height/5*2-140,52)

? ? ip = SystemInfo.get_ip('wlan0')

? ? # ip = SystemInfo.get_ip('eth0')cpu_usage =SystemInfo.getCPUuse()

? ? ShowStr(ip,width/2+100,height/5*2-90,48)

? ? ShowStr("ip:",width/2+10,height/5*2-90,52)


? ? #netspeed showNetInfoOld=SystemInfo.net_stat()

? ? time.sleep(1)

? ? NetInfoNew=SystemInfo.net_stat()

? ? DownloadSpeed=(NetInfoNew[0]["ReceiveBytes"]-NetInfoOld[0]["ReceiveBytes"])/1048576#last second total flow -current second total flow UploadSpeed=(NetInfoNew[0]["TransmitBytes"]-NetInfoOld[0]["TransmitBytes"])/1048576? ? ShowRec(width/2+20,height/5*2-40,DownloadSpeed/10*600+20,48,Green,0)

? ? ShowRec(width/2+20,height/5*2+10,UploadSpeed/10*600+20,48,LightBlue,0)

? ? ShowStr("↓:"+str("%3.2f"%(DownloadSpeed))+"MB/s",width/2+20,height/5*2-40,48)

? ? ShowStr("↑:"+str("%3.2f"%(UploadSpeed))+"MB/s",width/2+20,height/5*2+10,48)

? ? #cpu_usage showShowRec(width/2+20,height/5*2+60,cpu_usage/100*600+60,48,Yellow,0)

? ? ShowStr("CPU usage:"+str("%2d"%cpu_usage)+"%",width/2+20,height/5*2+110,48)

? ? ifloop % 60==0 :

? ? ? ? future = datetime.strptime('2019-1-1 00:00:00','%Y-%m-%d %H:%M:%S')

? ? ? ? #當(dāng)前時間now = datetime.now()

? ? ? ? #求時間差delta = future - now

? ? ? ? hour = delta.seconds/60/60? ? ? ? minute = delta.seconds/60? ? ? ? seconds = delta.seconds - hour*60*60 - minute*60# print_now=now.strftime('%Y-%m-%d %H:%M:%S')# print("今天是:",print_now)# print("距離 2019-02-01 \"work\" 還剩下:%d天"%delta.days)# print(delta.days,hour, minute, seconds)? ? ShowStr2("倒計時:%dH (%dMin)"%(hour,minute),width/4*2+width/32+20,height/5*3+height/30+235,45)# #########################本地信息獲取完成########################################? print ("↓:"+str("%3.1f"%(DownloadSpeed))+"MB/s")#? print ("↑:"+str("%3.1f"%(UploadSpeed))+"MB/s")#print("CPU usage:"+str("%2d"%cpu_usage)+"%")# ########weather show####################################ifloop % 10800==0 :#update per 3 hoursjsonArr=weatherAPI.GetWeatherInfo()

? ? ? ? ifjsonArr!=None :#記錄請求數(shù)據(jù)時間updatingtime=time.strftime("%H:%M:%S",mylocaltime)? ?

? ? ? ? ? ? ifjsonArr["status"]!="1":

? ? ? ? ? ? ? ? print(jsonArr["msg"])

? ? ? ? ? ? ? ? WeatherValidation=False

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? result=jsonArr["forecasts"][0]

? ? ? ? ? ? ? ? WeatherValidation=True

? ? ? ? ? ? ? ? #print (result["city"],result["weather"],result["temp"],result["temphigh"],result["templow"])ifWeatherValidation==True:

? ? ? ? # AQI=result["aqi"]# index=result["index"]# index0=index[0]# daily=result["daily"]# day1=daily[1]#明天天氣預(yù)報# day2=daily[2]#明天天氣預(yù)報# day3=daily[3]#明天天氣預(yù)報# day4=daily[4]#明天天氣預(yù)報? ? ? ? ? ? ? # ##? ? ? ? #室外溫濕度#? ? ShowPicture("pictures/"+result["img"]+".png",width/16,height/5+150)ShowStr("武漢市",width/32,height/5+10,60)

? ? ? ? ShowStr(result["city"],width/32,height/5+80,60)

? ? ? ? ShowStr(result["casts"][0]["dayweather"],width/32-25,height/5*2+50,120)

? ? ? ? ShowStr(result["casts"][0]["daytemp"]+"℃",width/4,height/5,160)


? ? ? ? ShowStr("氣溫最低:"+result["casts"][0]["nighttemp"] +"℃",width/4-10,height/5*2-20,48)

? ? ? ? ShowStr("接下來轉(zhuǎn):"+result["casts"][0]["nightweather"],width/4-10,height/5*2+50,48)

? ? ? ? # ShowStr("zhesgii",width/2+20,height/5+10,120)ShowStr("風(fēng)力:"+result["casts"][0]["daypower"]+"級",width/4-10,height/5*2+110,48)

? ? # ##? ? ? ? #空氣質(zhì)量#? ? ShowStr("PM2.5:",width/2+280,height/5+120,32)#? ? ShowStr(AQI["pm2_5"],width/2+400,height/5-20,200)#? ? ShowStr("空氣質(zhì)量:"+AQI["quality"],width/2+240,height/5*2-40,32)ShowPicture("pictures/"+result["casts"][0]["dayweather"]+".png",width/32+60,height/5+145)

? ? #? ? if Title_X<=-100:#? ? ? ? Title_X=width#? ? else:#? ? ? ? Title_X=Title_X-40#? ? ShowStr(index0["detail"],Title_X,height-50,40)#? ? #未來幾天天氣預(yù)報ShowStr("明天:"+result["casts"][1]["date"],width/32,height/5*3+height/30-10,30)

? ? ? ? ShowStr(result["casts"][1]["dayweather"],width/32,height/5*3+height/30+30,50)

? ? ? ? ShowStr(result["casts"][2]["daytemp"]+"℃",width/32,height/5*3+height/30+80,70)

? ? ? ? ShowStr("氣溫Min:"+result["casts"][1]["nighttemp"] +"℃",width/32-10,height/5*3+height/30+140,45)

? ? ? ? ShowStr("未來轉(zhuǎn):"+result["casts"][1]["nightweather"],width/32-10,height/5*3+height/30+180,45)

? ? ? ? ShowPicture("pictures/"+result["casts"][1]["dayweather"]+".png",width/32+170,height/5*3+height/30+45)

? ? #? ? ShowPicture("pictures/"+day1["day"]["img"]+".png",width/32,height/5*3+height/10)# ##ShowStr("后天:"+result["casts"][2]["date"],width/4+width/32,height/5*3+height/30-10,30)

? ? ? ? ShowStr(result["casts"][2]["dayweather"],width/4+width/32,height/5*3+height/30+30,50)

? ? ? ? ShowStr(result["casts"][2]["daytemp"]+"℃",width/4+width/32,height/5*3+height/30+80,70)

? ? ? ? ShowStr("氣溫Min:"+result["casts"][2]["nighttemp"] +"℃",width/4+width/32-10,height/5*3+height/30+140,45)

? ? ? ? ShowStr("未來轉(zhuǎn):"+result["casts"][2]["nightweather"],width/4+width/32-10,height/5*3+height/30+180,45)

? ? ? ? ShowPicture("pictures/"+result["casts"][2]["dayweather"]+".png",width/4+width/32+170,height/5*3+height/30+45)

? ? #? ? ShowStr(day2["day"]["weather"],width/4+width/32,height/5*3+height/5-40,100)#? ? ShowStr(day2["day"]["windpower"],width/4+width/32+70,height/5*3+height/10,64)#? ? ShowStr(day2["night"]["templow"]+"~"+day2["day"]["temphigh"]+"℃",width/4+width/32,height-130,64)#? ? ShowPicture("pictures/"+day2["day"]["img"]+".png",width/4+width/32,height/5*3+height/10)# ##? ? ShowStr("大后天:"+result["casts"][3]["date"],width/4*2+width/32-25,height/5*3+height/30-10,30)

? ? ? ? ShowStr(result["casts"][3]["dayweather"],width/4*2+width/32-25,height/5*3+height/30+30,50)

? ? ? ? ShowStr(result["casts"][3]["daytemp"]+"℃",width/4*2+width/32-25,height/5*3+height/30+80,70)

? ? ? ? ShowStr("氣溫Min:"+result["casts"][3]["nighttemp"] +"℃",width/4*2+width/32-25,height/5*3+height/30+140,45)

? ? ? ? ShowStr("未來轉(zhuǎn):"+result["casts"][3]["nightweather"],width/4*2+width/32-25,height/5*3+height/30+180,45)

? ? ? ? ShowPicture("pictures/"+result["casts"][3]["dayweather"]+".png",width/4*2+width/32-25+170,height/5*3+height/30+45)

? ? #? ? ShowStr(day3["day"]["weather"],width/4*2+width/32,height/5*3+height/5-40,100)#? ? ShowStr(day3["day"]["windpower"],width/4*2+width/32+70,height/5*3+height/10,64)#? ? ShowStr(day3["night"]["templow"]+"~"+day2["day"]["temphigh"]+"℃",width/4*2+width/32,height-130,64)#? ? ShowPicture("pictures/"+day3["day"]["img"]+".png",width/4*2+width/32,height/5*3+height/10)# ##? ? ? ? ? ? ShowPicture("pictures/cj.png",width/4*3+width/32,height/5*3+height/30-15)

? ? #? ? ShowStr(day4["day"]["weather"],width/4*3+width/32,height/5*3+height/5-40,100)#? ? ShowStr(day4["day"]["windpower"],width/4*3+width/32+70,height/5*3+height/10,64)#? ? ShowStr(day4["night"]["templow"]+"~"+day2["day"]["temphigh"]+"℃",width/4*3+width/32,height-130,64)#? ? ShowPicture("pictures/"+day4["day"]["img"]+".png",width/4*3+width/32,height/5*3+height/10)# #記錄請求數(shù)據(jù)時間ShowStr3("Last update:"+updatingtime,width/4*3+15,height/5*3,30)

? ? ? ? ShowStr2("這里是滾動字幕顯示區(qū),加循環(huán)可實(shí)現(xiàn)動態(tài)效果",width/32-25,height/5*3+height/30+235,45)

? ? #update?


? ? pygame.display.update()


? ? loop +=1#全屏#for event in pygame.event.get():#? ? if event.type==pygame.KEYDOWN:#? ? ? ? running=Falsepygame.quit()


公眾號回復(fù) “樹莓派天氣”? 即可下載我為大家打包好的文件。下載好文件以后,解壓文件會得到如下文件:1,天氣圖標(biāo)文件夾pictures,2,字體文件gkai00mp.ttf,3,系統(tǒng)配置文件SystemInfo.py,4,獲取天氣數(shù)據(jù)文件weatherAPI.py,5,主程序pyMain.py 。將這些文件放在同一文件夾下,復(fù)制拷貝到樹莓派上,為文件夾賦予權(quán)限,命令sudo chmod 777 文件夾名。最后終端執(zhí)行命令運(yùn)行主程序(sudo python3 pyMain.py)。此時應(yīng)該就可以看到預(yù)報的畫面。能看懂代碼的人可自行修改?具體顯示的背景、顏色、大小、布局、位置 、顯示字體大小等。


關(guān)注一下,更多精彩,不容錯過!

??????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容