在樹莓派上用 python 做一個炫酷的天氣預報


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

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

 

1.下面給出調用高德地圖API,獲取天氣數據的方法。將申請的key替換進url中,再將你的城市代碼(網上可查,可以具體到區)替換下即可。

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編碼的字符串轉換回Python數據結構
        # output result of json
        # print(data)
        return data
    except:
        return None

 

2.系統信息及配置

# coding = utf-8
import subprocess
import time
import os
#device :eth0,wlan0
def 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)*100  
        return cpuUsage

def net_stat():  
    net = []  
    f = open("/proc/net/dev")  
    lines = f.readlines()  
    f.close()  
    for line in lines[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)  
    return net

 

3.主程序。執行文件

#encoding: utf-8
import pygame
import time
import weatherAPI 
import SystemInfo
from datetime import datetime

# 顯示圖片函數
def ShowPicture(picturepath,x0,y0):  
    background=pygame.image.load(picturepath)
    background.convert_alpha()
    window.blit(background,(x0,y0))
    return
def ShowCircle():
    pygame.draw.circle(window,pygame.Color(255,255,255),(width/2,height/2),radius,fill)
    return
# 划線函數,起始坐標,終點坐標
def ShowLine(x0,y0,x1,y1):
    pygame.draw.line(window,pygame.Color(255,255,255),(x0,y0),(x1,y1),fill)
    return
Yellow=(255,255,0)
Red=(255,0,0)
LightBlue=(190,190,255)
Green=(0,255,0)
Black=(0,0,0)
White=(255,255,255)
# 畫框函數
def ShowRec(x0,y0,x1,y1,color,fill):
    pygame.draw.rect(window,color,(x0,y0,x1,y1),fill)
    return
# 字符串顯示函數
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))                    
    return

def 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))                    
    return
def 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
#背景參數設置                            
width=1280
height=800
fill=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=False
while True:
    # window.blit(back,(0,0))  #對齊的坐標
    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-21
    ShowStr(myclock,0,0,180)
    mydate=time.strftime("%Y-%m-%d",mylocaltime)#2017-04-21
    ShowStr(mydate,810,5,90)
    mytime=time.strftime("%A",mylocaltime)#Thursday
    ShowStr(mytime,830,90,85)
    
    name = "自動化實驗室歡迎您"
    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 show
    NetInfoOld=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 show
    ShowRec(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)

    if loop % 60==0 : 
        future = datetime.strptime('2019-1-1 00:00:00','%Y-%m-%d %H:%M:%S')
        #當前時間
        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####################################
    if loop % 10800==0 :                                        #update per 3 hours
        jsonArr=weatherAPI.GetWeatherInfo()
        if jsonArr!=None :                                      #記錄請求數據時間
            updatingtime=time.strftime("%H:%M:%S",mylocaltime)    
            if jsonArr["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"])
    if WeatherValidation==True:
        # AQI=result["aqi"]
        # index=result["index"]
        # index0=index[0]
        # daily=result["daily"]
        # day1=daily[1]#明天天氣預報
        # day2=daily[2]#明天天氣預報
        # day3=daily[3]#明天天氣預報
        # day4=daily[4]#明天天氣預報              
    # ##        #室外溫濕度
    #     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("接下來轉:"+result["casts"][0]["nightweather"],width/4-10,height/5*2+50,48)
        # ShowStr("zhesgii",width/2+20,height/5+10,120)
        ShowStr("風力:"+result["casts"][0]["daypower"]+"",width/4-10,height/5*2+110,48)
    # ##        #空氣質量
    #     ShowStr("PM2.5:",width/2+280,height/5+120,32)
    #     ShowStr(AQI["pm2_5"],width/2+400,height/5-20,200)
    #     ShowStr("空氣質量:"+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)
    #     #未來幾天天氣預報
        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("未來轉:"+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("未來轉:"+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("未來轉:"+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)
    # #記錄請求數據時間
        ShowStr3("Last update:"+updatingtime,width/4*3+15,height/5*3,30)
        ShowStr2("這里是滾動字幕顯示區,加循環可實現動態效果",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=False
pygame.quit()

 

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

 

👇👇👇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM