用树莓派做一个炫酷的天气预报

教大家如何在树莓派上自己动手做一个天气预报。此次教程需要大家有一定的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:

        returnNone


2.系统信息及配置

# 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.主程序。执行文件

#encoding: utf-8import pygameimport timeimport weatherAPI import SystemInfofromdatetimeimport datetime# 显示图片函数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# 划线函数,起始坐标,终点坐标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)# 画框函数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))                   

    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#背景参数设置                            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))  #对齐的坐标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 ="自动化实验室欢迎您"    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')

        #当前时间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 :#记录请求数据时间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]#明天天气预报# 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=Falsepygame.quit()


公众号回复 “树莓派天气”  即可下载我为大家打包好的文件。下载好文件以后,解压文件会得到如下文件:1,天气图标文件夹pictures,2,字体文件gkai00mp.ttf,3,系统配置文件SystemInfo.py,4,获取天气数据文件weatherAPI.py,5,主程序pyMain.py 。将这些文件放在同一文件夹下,复制拷贝到树莓派上,为文件夹赋予权限,命令sudo chmod 777 文件夹名。最后终端执行命令运行主程序(sudo python3 pyMain.py)。此时应该就可以看到预报的画面。能看懂代码的人可自行修改 具体显示的背景、颜色、大小、布局、位置 、显示字体大小等。


关注一下,更多精彩,不容错过!

👇👇👇

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容