硬汉嵌入式论坛

 找回密码
 立即注册
查看: 279|回复: 0
收起左侧

[STM32H7] 基于STM32H7和ESP32S3的网络收音机开发实战指南[番外篇1]socket网络编程的应用:天气&热搜&时钟【1-3】

[复制链接]

8

主题

13

回帖

42

积分

新手上路

积分
42
发表于 2025-12-24 19:36:39 | 显示全部楼层 |阅读模式
本帖最后由 穹顶之下2018 于 2025-12-24 19:43 编辑

摘要
本文介绍socket编程在实际生活中的常见应用。本文需要读者具有计算机网络基础知识(http,udp,tcp等)、Python编程基础知识。
注:代码只需微改即可运行在pc端。下文demo均运行在esp32s3上,并测试通过。其中涉及的账号密码问题,需读者自行注册或修改

心知天气【需私钥】、百度热搜【公开api】、网络NTP时钟
    简要说明:
        心知和百度,都是发起http get请求,返回json格式的结果,而后解析获取相应数据。
        NTP网络时钟则是向指定ntp服务器的特定端口发起udp请求,而后解析返回的数据。

测试demo
#----------------------------------------------------------
import network,time
wlan = network.WLAN()   
wlan.active(True)   

def do_connect(ssid,passwd):
    if not wlan.isconnected(): #wlan.scan()
        print('connecting to network...')
        wlan.connect(ssid,passwd)
        timout = 0
        while not wlan.isconnected():
            time.sleep(1)
            if timout >= 10:
                break
    print('network config:', wlan.ipconfig('addr4'))
    print('MAC config:', ''.join(['{:02X}'.format(x) for x in wlan.config('mac')]))  
do_connect('你的wifi账号','你的wifi密码')


import json,requests

#百度热搜的JSON接口
def getBaiduHotInfo(req):

    topic = ['homepage','realtime','livelihood','finance','phrase','novel','movie','teleplay','car','game']
    url = 'https://top.baidu.com/api/board?platform=wise&tab=' #完整链接示意:'https://top.baidu.com/api/board?platform=wise&tab=realtime'
    baiduhoturl1 = "https://top.baidu.com/board?tab=realtime" # 百度热搜网页版官方 API
    baiduhoturl2= "https://api.1314.cool/getbaiduhot/" #返回百度实时热点共30条,每3分钟更新一次


    try:
        res = requests.get(url+topic[req])
    except Exception as err:
        print("getBaiduHotInfo failed...", err)
        return None
    else:
        res = res.content
        _res = json.loads(res)
        words = []
        if _res['success'] is True and _res['error']['code'] == 0:
            ptr = _res['data']['cards'][0]['content'][0]['content']
            for word in ptr:
                if word['isTop'] is False:
                    print(word['index'],word['word']) #debug
                words.append(word['word'])
        #print(words) #debug
        return words

private_key = '你的私钥,注册心知获得'
public_key = ""
city = 'shenzhen'
def getWeatherInfo(req):
    global city
    weatherapi1 = "https://weathernew.pae.baidu.com/weathernew/pc?query=%E5%B9%BF%E4%B8%9C%E6%B7%B1%E5%9C%B3%E5%A4%A9%E6%B0%94&srcid=4982&forecast=long_day_forecast"
    '''
    心知 在线文档 https://seniverse.yuque.com/hyper_data/datasets/start?
         加密传输 https://seniverse.yuque.com/hyper_data/api_v4/nke5p8   
    '''
    apidict = { #k必须是不可变的,如字符串,数字或元组  v可以取任何数据类型
        #天气实况
        'weather':'https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=city&language=zh-Hans&unit=c',
        #生活指数
        'life':'https://api.seniverse.com/v3/life/suggestion.json?key=your_api_key&location=city&language=zh-Hans&days=5',     
        #获取指定城市未来最多 15 天每天的白天和夜间预报,以及昨日的历史天气。付费用户可获取全部数据,免费用户只返回3天天气预报
        'daily':'https://api.seniverse.com/v3/weather/daily.json?key=your_api_key&location=city&language=zh-Hans&unit=c&start=0&days=5',
        #农历、节气、生肖
        'calendar':'https://api.seniverse.com/v3/life/chinese_calendar.json?key=your_api_key&start=0&days=7'   
    }
    def getFinalAPI(req):
        cmdList = ('weather','life','daily','calendar')
        tmp = apidict[cmdList[req]]
        if tmp.find('your_api_key') > -1 and tmp.find('city') > -1:
            url = tmp.replace("your_api_key",private_key,1).replace("city",city,1)
        elif tmp.find('your_api_key') > -1:
            url = tmp.replace("your_api_key",private_key,1)
        print(url) #debug
        return url
        
    try:
        res = requests.get(getFinalAPI(req))
    except Exception as err:
        print("getWeatherInfo failed...", err)
        return None
    else:            
        res = res.content #print(res) debug
        _res = json.loads(res)
        if req == 0: #TODO
            print(_res['results'][0]['now'])
        elif req == 1:
            pass #内容太多,TODO
        elif req == 2: #TODO
            for daily in _res['results'][0]['daily']:
                print(daily['low'],'~',daily['high'])
        elif req == 3:
            pass #b'{"status":"You do not have access to this API.","status_code":"AP010002"}'
            
import ntptime
#https://github.com/micropython/micropython-lib/blob/master/micropython/net/ntptime/ntptime.py
#https://docs.micropython.org/en/ ... html#time.localtime
def getBeijingTimeInfo():
    ALIBABA_NTP_SERVERS = [ # 阿里巴巴 NTP 服务器列表 库默认pool.ntp.org
        "ntp.aliyun.com",    #主服务器
        "ntp1.aliyun.com",   #备用服务器1
        "ntp2.aliyun.com",   #备用服务器2
        "ntp3.aliyun.com"    #备用服务器3
    ]
    ntptime.host = ALIBABA_NTP_SERVERS[0]  #优先使用主服务器
    ntptime.timeout = 0.1 #NTP请求超时时间
    #ntptime.settime()  #同步时间


    #循环尝试备用服务器(增强稳定性)
    '''
    for server in ALIBABA_NTP_SERVERS:
        try:
            print(f"Trying NTP server: {server}")
            ntptime.host = server
            ntptime.settime()  
            print(f"Successfully synced with {server}")
            return True
        except OSError as e:
            print(f"Failed to sync with {server}: {e}")
            time.sleep(1)  # 失败后延迟1秒重试
    print("All NTP servers failed!")
    return False
    '''
   
    try:
        timestamp = ntptime.time()
        #if time.gmtime(0)[0]==2000:
        #     timestamp += (3155673600-2208988800) #转回标准的1970开始计时
        timestamp += (8*3600) #东八区
        '''
            month is 1-12
            mday is 1-31
            hour is 0-23
            minute is 0-59
            second is 0-59
            weekday is 0-6 for Mon-Sun
            yearday is 1-366
        '''   
        timinfo = time.localtime(timestamp) #秒数转时间
        print(timinfo)
        return timinfo
    except Exception as err:
        print('get nettime err...',err)
        return None
            
getBaiduHotInfo(1)       #获取百度热搜json结果      
getWeatherInfo(0)          #获取心知天气json结果      
getBeijingTimeInfo()       #获取ntp服务器的返回结果   

#----------------------------------------------------------

网页返回内容截图
5.png
热搜结果
2.png


天气结果
{"results":[{"location":{"id":"WS10730EM8EV","name":"深圳","country":"CN","path":"深圳,深圳,广东,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"晴","code":"1","temperature":"20"},"last_update":"2025-12-24T19:20:22+08:00"}]}
3.png

NTP实现
4.png

后续内容预告
    后续将介绍除hls协议之外,当前网络fm项目最最常用的 Icecast Stream 直播协议【超级简单socket连接上即可一直读音频流,直接送入解码即可】。将以http mp3 fm音频流为例进行分析与实战。

    如果读者有更有意思的适合mcu的网络应用,可以说说。





1.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-1-10 08:05 , Processed in 0.051039 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表