天氣光環時鐘+農曆提醒(NODE-RED)專題作品-micropython

天氣光環時鐘+農曆提醒(node-red)專題作品

前言:

前陣子參加益師傅發起的micropython,讓我再次提起興趣,因為擔任了技術支援的角色

,所以送我一套慧手科技的套件,由於我個人不會白白拿了東西放著,所以也讓自己動

起來參予這次的實作,但我個人不較不喜歡用搬運和模仿程式碼,所以加了一點自己的

創意在這套件裡,所以在完成階段性的作品,趁這時來紀錄一下筆記。

材料:

 接線圖:

功能演示

$末節附上程式碼下載

1.按鍵(1)近一小時天氣概況,溫濕度
2.按鍵(2)調控燈環,node-red調控燈環 
3.按鍵(3)顯示logo
4.農曆提醒-Line, 燈環同步
5.未實現:每日補充維它命並配發一顆維他命


程式碼區塊解析:

即時天氣-openweather API

這個得去open-weather公開網站申請api

以下的程式碼是抓取天氣的icon
# 即時天氣icons
data = requests.get('https://api.openweathermap.org/data/2.5/weather?q=Taipei,TW&lang=zh_tw&units=metric&appid=f7922c4d99e223e7380d80a7f3db6b64')
jsondatas = ujson.loads(data.text)
print(jsondatas['weather'][0]['icon'])

def checkIcon(n):
    path = "icons/" + n
    try:
        os.stat(path)
        return path
    except:
        return "/icons/na.bin"

def weather_icon():
    global jsondatas
    icon = jsondatas['weather'][0]['icon']
    path = checkIcon(icon + ".bin")
    f = open(path, "rb")
    buf = f.read()
    f.close()
    fb = framebuf.FrameBuffer(bytearray(buf), 48, 48, framebuf.MONO_VLSB)
    oled.blit(fb, 70, 10)


將取出的icon對應圖,就能隨著變化的天氣自動換圖
主程式的資料夾裡要再開一個icons的資料夾,裡面放
天氣的圖檔。
def imgs(imgPath):
    img = open(imgPath, "rb")
    img.readline()
    t = img.readline()
    x = int(t.split()[0])
    y = int(t.split()[1])
    iconNum = bytearray(img.read())
    convert = framebuf.FrameBuffer(iconNum, x, y, framebuf.MONO_HLSB)
    img.close()
    return convert

DHT11

def dht1x():
    global jsondatas
    try:
        dht11.measure()
    except Exception as e:
        print(e)
    temp = dht11.temperature()
    humi = dht11.humidity()
    print("t:{}, h:{}".format(temp, humi))
    time.sleep(2)
    oled.fill(0)
    oled.text("T:" + str(temp) + "*C", 0, 30)
    oled.text("H:" + str(humi) + ".%", 0, 40)
    date_and_time()
    weather_icon()
    oled.show()

時間的擷取

我不用那種硬體的時間模組,因為麻煩,不準而且還要用GPS來調整,所以
習慣用自己寫的node-red的時間來抓時間,即準時又方便
def date_and_time():
    # 日期時間api
    d = requests.get('http://worldtimeapi.org/api/timezone/Asia/Taipei')
    if d.status_code == 200:
        date = ujson.loads(d.text)['datetime'][0:10]
        times = ujson.loads(d.text)['datetime'][11:-16]
        h = int(ujson.loads(d.text)['datetime'][11:13])
        m = int(ujson.loads(d.text)['datetime'][14:16])
        oled.text(date, 0, 0)
        oled.text(times, 0, 10)
        print(date, "|", times)
        hP = int((h % n))
        mP = int((m / (60 / n) % n))
        print("hp:{}, mp:{}".format(hP, mP))
        hColor = (255, 0, 50)
        mColor = (50, 0, 255)
        clear()
        np[mP] = mColor
        np[hP] = hColor
        np.write()

MQTT

主要有兩大區塊,一個是callback,一個是負責不斷去取得和mqtt broker的連繫
def callback(topic, msg):
    #print(topic, msg)
    global n, p, np
    if topic==colorTopic:
        colorVal=msg.decode()
        colorDist=eval(colorVal)
        r=colorDist['r']
        g=colorDist['g']
        b=colorDist['b']
        clear()
        for i in range(n):
            np[i] = (r, g, b)
            np.write()
    if topic==alldayTopic:
        print(msg.decode())
        clear()
        for j in range(0,10):
            for i in range(n):
                np[i] = (50, 30, 200)
                np.write()
                time.sleep_ms(20)
                clear()
            print(j)
           
def connMQTT():
    try:
        client=MQTTClient(server_id, mqtt_server)
        client.set_callback(callback)
        client.connect()
        client.subscribe(alldayTopic)
        client.subscribe(colorTopic)
        print("connect to %s" % mqtt_server)
        return client
    except:
        print("not to connected for MQTT server!")
        machine.reset()

neopixels燈環

# neoplixel
n, p = 12, 5  # 燈數,#腳位
np = neopixel.NeoPixel(Pin(p), n)

def clear():
    global n, p, np
    for i in range(n):
        np[i] = (0, 0, 0)
        np.write()

def Neopixel():
    global n, p, np
    clear()
    for i in range(n):
        np[i] = (255, 0, 50)
        np.write()

全部把它拼起來使用按鍵來切換

這一部份如果單純用判斷on或off一定會出很多包,所以必須使用中斷函式irq()
使它去判斷上拉或下拉啓動時,切斷正在做的環節。
btn1 = Pin(34, Pin.IN, Pin.PULL_UP)
btn2 = Pin(36, Pin.IN, Pin.PULL_UP)
btn3 = Pin(35, Pin.IN, Pin.PULL_UP)
btn1.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_irq)
btn2.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_irq)
btn3.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_irq)

node-red

農民曆的部份我是去對岸的點晴數據-萬年曆查詢接口申請

農曆節點--NL_flows.json



申請萬年曆的API

申請token


範例取得農曆

燈環節點










留言

這個網誌中的熱門文章

使用PWM控制伺服馬達-micropython

DHT11+OLED+IFTTT+LINE-notity-micropython

BMP280氣壓,溫度模組-micropython