2022年1月30日 星期日

Hassio + Node-Red

Hassio + Node-Red 

hassio安裝node-red外掛程式後,在配置注意以下:

1credential_secret隨便編寫英文字母即可,usernamepassword(注意有兩個)需單獨設定並且不能與hass帳號密碼重複,password最好設置為大小寫字母跟數位的組合,ssl沒有開啟的話設置為falsetruce可以試試看),設置完成後點擊save

2、點擊start運行外掛程式並查看下方log資訊(可通過刷新更新log資訊),確保『Node-RED』外掛程式正常運行後才可以點擊“OPEN WEB UI”。有可能需要重啟就正常啦。

3、登錄時用的帳戶密碼是hass的帳戶和密碼,不是配置時設定的帳戶和密碼!!




2022年1月12日 星期三

Python 練習

Python 練習

1.梯形面積 計算
2.球體積  計算
3.攝氏溫度轉華氏  計算
4.坪數轉平方公尺  計算
5. BMI 計算


 
import math
#===============================
def trapezoid_1():
    while True:
        print ('1.梯形面積 計算')
        # input獲取的資料均為 字串
        a = input('請輸入梯形的上底長度:')
        # 判斷如果輸入的資料不是數位的時候跳出,如果是就繼續
        if not a.isdigit():
            continue
        b = input('請輸入梯形的下底長度:')
        if not b.isdigit():
            continue
        h = input('請輸入梯形的高:')
        if not h.isdigit():
            continue
    
        s = (float(a) + float(b)) * float(h) / 2
        print("梯形的面積為:%.2f" %s , end='')
        print('平方單位\n\n')
        # 這裡需要將str 轉換成 float
        break 
#===============================
def spherical_2() :
    while True:
        print ('2.球體積  計算')
        r=float(input("請輸入半徑:"))
        circumference=2*math.pi*r
        area=math.pi*r*r
        sarea=4*math.pi*r*r
        volume=4/3*math.pi*r**3
        print ( "圓的半徑: %.2f" % r)
        print ( "圓的周長: %.2f" % circumference)
        print ( "圓的面積: %.2f"% area, end='')
        print('平方單位') 
        print ( "球的表面積: %.2f"% sarea , end='')
        print('平方單位')
        print ( "球的體積: %.2f" % volume , end='')
        print('立方單位\n\n')
        
        break
#===============================
def Celsius_3() :
    while True:
        # 攝氏轉華氏 c2f.py
        print ('3.攝氏溫度轉華氏  計算')
        degree_c = int(input("請輸入攝氏溫度:"))
        degree_f = degree_c * 1.8 +32 
        print ("攝氏 %d 度等於華氏 %.2f 度\n\n" % (degree_c,degree_f))
        break
#===============================
def Pingnumber_4() :
    while True:
        # 1 坪=3.3058 平方公尺
        print ('4.坪數轉平方公尺  計算')
        ping = float(input("請輸入坪數 :"))
        squareM = ping*3.33058 
        print ("%.2f 坪數等於 %.2f 成平方公尺\n\n" % (ping,squareM))
        break
#===============================   
def BMI_5() :
    while True:
        print ('5. BMI 計算')
        h = float(input('請輸入身高(cm):'))/100
        # 使用 float 轉換成浮點數後除以 100 ( 因為身高可能會有小數點 )
        w = float(input('請輸入體重(kg):'))
        # 使用 float 轉換成浮點數 ( 因為體重可能會有小數點 )
    
        bmi = w/(h*h)                           # 套用公式計算
    
        print ("身高為 %.2f  (M)" % (h))
        print ("體重為 %.2f  (kg)" % (w))  
        print('你的 BMI 數值為:%.2f  (kg)\n\n' % (bmi) )         # 你的 BMI 數值為: 
        break
#===============================
# 主程式
#===============================
while True:
    print ('1.梯形面積 計算')
    print ('2.球體積  計算')
    print ('3.攝氏溫度轉華氏  計算')
    print ('4.坪數轉平方公尺  計算')
    print ('5. BMI 計算')
    print ('==================')
    in1 = input('請輸入1至5:')
    if not in1.isdigit():
        continue
        
    if  int(in1)==1:
        trapezoid_1()
    elif  int(in1)==2:
        spherical_2()
    elif  int(in1)==3:
        Celsius_3()
    elif  int(in1)==4:
        Pingnumber_4()
    elif  int(in1)==5:
        BMI_5()       
    else :
        print('請重新輸入1至5')
    continue


Python socket基本使用

Python socket基本使用




三次握手協定的過程:

  1. 客戶端(通過執行connect函式)向伺服器端傳送一個SYN包,請求一個主動打開。該包攜帶客戶端為這個連接請求而設定的亂數A作為訊息序列號。
  2. 伺服器端收到一個合法的SYN包後,把該包放入SYN佇列中;回送一個SYN/ACK。ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序號B
  3. 客戶端收到SYN/ACK包後,傳送一個ACK包,該包的序號被設定為A+1,而ACK的確認碼則為B+1。然後客戶端的connect函式成功返回。當伺服器端收到這個ACK包的時候,把請求影格從SYN佇列中移出,放至ACCEPT佇列中;這時accept函式如果處於阻塞狀態,可以被喚醒,從ACCEPT佇列中取出ACK包,重新建立一個新的用於雙向通信的sockfd,並返回。

源自https://www.itread01.com/content/1545266524.html

1)socket函式

  功能:使用給定的地址族、套接字型別、協議編號(預設為0)來建立套接字。

  格式:socket.socket([family[, type[, proto]]])

  引數:

    family : AF_INET (預設ipv4),AF_INET6(ipv6) , AF_UNIX(Unix系統程序間通訊).

    type : SOCK_STREAM (TCP), SOCK_DGRAM(UDP) .

    protocol : 一般為0或者預設

  備註:如果socket建立失敗會丟擲一個socket.error異常

2)伺服器端函式

   a)bind函式

  格式:s.bind(address)

  功能:將地址address繫結到套接字, 地址以元組(host,port)的形式表示。

  引數:

    address為元組(host,port)

    host: ip地址, 為一個字串

    post: 自定義主機號, 為整型

b)listen函式

  格式:s.listen(backlog)

  功能:使伺服器的這個埠和IP處於監聽狀態,等待網路中某一客戶機的連線請求。如果客戶端有連線請求,埠就會接受這個連線。

  引數:backlog : 作業系統可以掛起的最大連線數量。該值至少為1,大部分應用程式設為5就可以了

c)accept函式

  格式:s.accept()

  功能:接受遠端計算機的連線請求,建立起與客戶機之間的通訊連線。伺服器處於監聽狀態時,如果某時刻獲得客戶機的連線請求,此時並不是立即處理這個請求,而是將這個請求放在等待佇列中,當系統空閒時再處理客戶機的連線請求。

  返回值:返回一個數組(conn,address),其中conn是新的套接字物件,可以用來接收和傳送資料。address是連線客戶端的地址

3)客戶端函式

  a)connect函式

  格式:s.connect(address)

  功能:用來請求連線遠端伺服器

  引數:address為遠端伺服器地址, 格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤

  b)connect_ex函式

  格式:s.connect_ex(address)

  備註:connect()函式的擴充套件版本,出錯時返回出錯碼,而不是丟擲異常

4)通用函式

  a)recv函式

  格式:s.recv(bufsize[,flag])

  功能:接收遠端主機傳來的資料

  引數:

    bufsize : 指定要接收的資料大小

    flag : 提供有關訊息的其他資訊,通常可以忽略

  返回值:返回值為資料以字串形式</code>

  b)send函式

  格式:s.send(string[,flag])

  功能:傳送資料給指定的遠端主機

  引數:

    string : 要傳送的字串資料

    flag : 提供有關訊息的其他資訊,通常可以忽略

  返回值:返回值是要傳送的位元組數量,該數量可能小於string的位元組大小。

c)sendall函式

  格式:s.sendall(string[,flag])

  功能:內部呼叫了send函式,完整發送TCP資料。將string中的資料傳送到連線的套接字,但在返回之前會嘗試傳送所有資料。

  引數:同send函式

  返回值 : 成功返回None,失敗則丟擲異常。

d)close函式

  格式:s.close()

  功能:關閉套接字

e)recvfrom函式

  格式:s.recvfrom(bufsize[.flag])

  功能:與recv()類似,區別是返回值不同

  返回值:返回一個數組(data,address),其中data是包含接收資料的字串,address是傳送資料的套接字地址。

f)sendto函式

  格式:s.sendto(string[,flag],address)

  功能:將資料傳送到套接字

  引數:

    string : 要傳送的字串資料

    flag : 提供有關訊息的其他資訊,通常可以忽略

    address是形式為(ipaddr,port)的元組,指定遠端地址

  返回值:返回值是要傳送的位元組數量

  備註:該函式主要用於UDP協議。

g)settimeout函式

  格式:s.settimeout(timeout)

  功能:設定套接字操作的超時期

  引數:timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛建立套接字時設定,因為它們可能用於連線的操作(如 client 連線最多等待5s )

h)getpeername函式

  格式:s.getpeername()

  功能:獲取連線套接字的遠端地址

  返回值:返回值通常是元組(ipaddr,port)。

i)getsockname函式

  格式:s.getsockname()

  功能:獲取套接字自己的地址

  返回值:通常是一個元組(ipaddr,port)

  socket中常用的函式就上面這些了。先用上面這些函式嘗試TCP協議下的socket通訊。


import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8088))
mes_to_server = '你好,Linux公社www.linuxidc.com伺服器!'.encode('utf-8')#傳送的資料必須是byte型別
sk.send(mes_to_server)
mes_from_server = sk.recv(1024).decode('utf-8')
print(mes_from_server)
sk.close() 



import socket
sk = socket.socket()
sk.bind(('127.0.0.1' ,8088))
sk.listen(5)
print('正在等待Linux公社客戶端連線……')
conn , addr = sk.accept()
print('Linux公社客戶端已連線到伺服器……')
mes_from_client = conn.recv(1024).decode('utf-8')
print(mes_from_client)
mes_to_server = '你好,Linux公社www.linuxidc.com客戶端,已收到您的資訊!'.encode('utf-8')#傳送的資料必須是byte型別
conn.send(mes_to_server)
conn.close()
sk.close()


2022年1月9日 星期日

Python Tkinter Control Arduino LED

 Python  Tkinter Control  Arduino LED

需使用Virtual Seria;l Ports Emulator 

模擬Pair 方式 COM5<-->COM7 

 (Python  Tkinter Com port = 7)





import serial
import time
import tkinter

def quit():
    global tkTop
    ser.write(bytes('L', 'UTF-8'))
    tkTop.destroy()
def set_button1_state():
        global b
        b += 1
        varLabel.set("LED ON ")
        ser.write(bytes('H', 'UTF-8'))
        varLabel2.set(b)
        print(b)
def set_button2_state():
        varLabel.set("LED OFF")
        ser.write(bytes('L', 'UTF-8'))
ser = serial.Serial('com7', 9600)
print("Reset Arduino")
time.sleep(3)
ser.write(bytes('L', 'UTF-8'))
tkTop = tkinter.Tk()
tkTop.geometry('300x200')
tkTop.title("IoT24hours")
label3 = tkinter.Label(text = 'Building Python GUI to interface an arduino,'
                      '\n and control an LED',font=("Courier", 12,'bold')).pack()
tkTop.counter = 0
b = tkTop.counter
varLabel = tkinter.IntVar()
tkLabel = tkinter.Label(textvariable=varLabel, )
tkLabel.pack()
varLabel2 = tkinter.IntVar()
tkLabel2 = tkinter.Label(textvariable=varLabel2, )
tkLabel2.pack()
button1 = tkinter.IntVar()
button1state = tkinter.Button(tkTop,
    text="ON",
    command=set_button1_state,
    height = 4,
    fg = "black",
    width = 8,
    bd = 5,
    activebackground='green'
)
button1state.pack(side='top', ipadx=10, padx=10, pady=15)
button2 = tkinter.IntVar()
button2state = tkinter.Button(tkTop,
    text="OFF",
    command=set_button2_state,
    height = 4,
    fg = "black",
    width = 8,
    bd = 5
)
button2state.pack(side='top', ipadx=10, padx=10, pady=15)
tkButtonQuit = tkinter.Button(
    tkTop,
    text="Quit",
    command=quit,
    height = 4,
    fg = "black",
    width = 8,
    bg = 'yellow',
    bd = 5
)
tkButtonQuit.pack(side='top', ipadx=10, padx=10, pady=15)
tkinter.mainloop()

Arduino程式

const int ledPin = 13; // pin the LED is attached to
int incomingByte; // variable stores serial data

void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}

void loop() {
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H') {
digitalWrite(ledPin, HIGH);
Serial.println("Getting H"); //print out to serial monitor to check state
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
Serial.println("Getting L"); //print out to serial monitor to check state
}
}
}

2022年1月8日 星期六

Python 簡易計算機

Python 簡易計算機



# Python program to create a simple GUI
# calculator using Tkinter
# import everything from tkinter module
from tkinter import *
# globally declare the expression variable
expression = ""
def Exit():
    sys.exit() 
    
# Function to update expression
# in the text entry box
def press(num):
# point out the global expression variable
global expression
# concatenation of string
expression = expression + str(num)
# update the expression by using set method
equation.set(expression)

# Function to evaluate the final expression
def equalpress():
# Try and except statement is used
# for handling the errors like zero
# division error etc.
# Put that code inside the try block
# which may generate the error
try:
global expression
# eval function evaluate the expression
# and str function convert the result
# into string
total = str(eval(expression))
equation.set(total)
# initialize the expression variable
# by empty string
expression = ""
# if error is generate then handle
# by the except block
except:
equation.set(" error ")
expression = ""

# Function to clear the contents
# of text entry box
def clear():
global expression
expression = ""
equation.set("")

# Driver code
if __name__ == "__main__":
# create a GUI window
gui = Tk()
# set the background colour of GUI window
gui.configure(background="light green")
# set the title of GUI window
gui.title("Simple Calculator")
# set the configuration of GUI window
gui.geometry("402x285")
# StringVar() is the variable class
# we create an instance of this class
equation = StringVar()
# create the text entry box for
# showing the expression .
expression_field = Entry(gui, textvariable=equation)
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
expression_field.grid(columnspan=4, ipadx=70)
# create a Buttons and place at a particular
# location inside the root window .
# when user press the button, the command or
# function affiliated to that button is executed .
button1 = Button(gui, text=' 1 ', fg='black', bg='red',
command=lambda: press(1), height=2, width=10)
button1.grid(row=2, column=0)
button2 = Button(gui, text=' 2 ', fg='black', bg='red',
command=lambda: press(2), height=2, width=10)
button2.grid(row=2, column=1)
button3 = Button(gui, text=' 3 ', fg='black', bg='red',
command=lambda: press(3), height=2, width=10)
button3.grid(row=2, column=2)
button4 = Button(gui, text=' 4 ', fg='black', bg='red',
command=lambda: press(4), height=2, width=10)
button4.grid(row=3, column=0)
button5 = Button(gui, text=' 5 ', fg='black', bg='red',
command=lambda: press(5), height=2, width=10)
button5.grid(row=3, column=1)
button6 = Button(gui, text=' 6 ', fg='black', bg='red',
command=lambda: press(6), height=2, width=10)
button6.grid(row=3, column=2)
button7 = Button(gui, text=' 7 ', fg='black', bg='red',
command=lambda: press(7), height=2, width=10)
button7.grid(row=4, column=0)
button8 = Button(gui, text=' 8 ', fg='black', bg='red',
command=lambda: press(8), height=2, width=10)
button8.grid(row=4, column=1)
button9 = Button(gui, text=' 9 ', fg='black', bg='red',
command=lambda: press(9), height=2, width=10)
button9.grid(row=4, column=2)
button0 = Button(gui, text=' 0 ', fg='black', bg='red',
command=lambda: press(0), height=2, width=10)
button0.grid(row=5, column=0)
plus = Button(gui, text=' + ', fg='black', bg='red',
command=lambda: press("+"), height=2, width=10)
plus.grid(row=2, column=3)
minus = Button(gui, text=' - ', fg='black', bg='red',
command=lambda: press("-"), height=2, width=10)
minus.grid(row=3, column=3)
multiply = Button(gui, text=' * ', fg='black', bg='red',
command=lambda: press("*"), height=2, width=10)
multiply.grid(row=4, column=3)
divide = Button(gui, text=' / ', fg='black', bg='red',
command=lambda: press("/"), height=2, width=10)
divide.grid(row=5, column=3)
equal = Button(gui, text=' = ', fg='black', bg='red',
command=equalpress, height=2, width=10)
equal.grid(row=5, column=2)
clear = Button(gui, text='Clear', fg='black', bg='red',
command=clear, height=2, width=10)
clear.grid(row=5, column=1)
Decimal= Button(gui, text='.', fg='black', bg='red',
command=lambda: press('.'), height=2, width=10)
Decimal.grid(row=6, column=0)

Exit = Button(gui, text='Exit', fg='black', bg='blue',
command=Exit, height=2, width=10)
Exit.grid(row=6, column=1)

# start the GUI
gui.mainloop()


Python Tkinter widget

Python tkinter 提供了下列 21 種 GUI 元件, 稱為 widget (視窗元件) 或 control (控制項), 所謂 widget 乃 Window gadget 之意  :

  1. Label (標籤)
  2. Button (按鈕)
  3. Radiobutton (單選圓鈕)
  4. Checkbutton (核取方塊)
  5. Entry (文字欄位)
  6. Frame (框)
  7. LabelFrame (文字框)
  8. Listbox (清單方塊)
  9. Text (文字框)
  10. Message 
  11. PanedWindow
  12. Scrollbar (捲軸)
  13. Scale
  14. Spinbox
  15. Menu (選單)
  16. OptionMenu
  17. Menubutton (選單按鈕)
  18. Canvas (畫布)
  19. Image (圖片)
  20. Bitmap (點陣圖)
  21. Toplevel

Python-Tkinter Scrollbar

 Python-Tkinter Scrollbar

w = Scrollbar(master, options) 

Parameters:

  • master: This parameter is used to represents the parent window.
  • options: There are many options which are available and they can be used as key-value pairs separated by commas.

Options:
Following are commonly used Option can be used with this widget :-

  • activebackground: This option is used to represent the background color of the widget when it has the focus.
  • bg: This option is used to represent the background color of the widget.
  • bd: This option is used to represent the border width of the widget.
  • command: This option can be set to the procedure associated with the list which can be called each time when the scrollbar is moved.
  • cursor: In this option, the mouse pointer is changed to the cursor type set to this option which can be an arrow, dot, etc.
  • elementborderwidth: This option is used to represent the border width around the arrow heads and slider. The default value is -1.
  • Highlightbackground: This option is used to focus highlighcolor when the widget doesn’t have the focus.
  • highlighcolor: This option is used to focus highlighcolor when the widget has the focus.
  • highlightthickness: This option is used to represent the thickness of the focus highlight.
  • jump: This option is used to control the behavior of the scroll jump. If it set to 1, then the callback is called when the user releases the mouse button.
  • orient: This option can be set to HORIZONTAL or VERTICAL depending upon the orientation of the scrollbar.
  • repeatdelay: This option tells the duration up to which the button is to be pressed before the slider starts moving in that direction repeatedly. The default is 300 ms.
  • repeatinterval: The default value of the repeat interval is 100.
  • takefocus: You can tab the focus through a scrollbar widget
  • troughcolor: This option is used to represent the color of the trough.
  • width: This option is used to represent the width of the scrollbar.

Methods:
Methods used in this widgets are as follows:

  • get(): This method is used to returns the two numbers a and b which represents the current position of the scrollbar.
  • set(first, last): This method is used to connect the scrollbar to the other widget w. The yscrollcommand or xscrollcommand of the other widget to this method.

from tkinter import *

root = Tk()

root.geometry("150x200")

w = Label(root, text ='GeeksForGeeks',

font = "50")

w.pack()

scroll_bar = Scrollbar(root)

scroll_bar.pack( side = RIGHT,

fill = Y )

mylist = Listbox(root,

yscrollcommand = scroll_bar.set )

for line in range(1, 26):

mylist.insert(END, "Geeks " + str(line))

mylist.pack( side = LEFT, fill = BOTH )

scroll_bar.config( command = mylist.yview )

root.mainloop()



from tkinter import *
root = Tk()
root.title('PythonGuides')
root.geometry('400x300')
root.config(bg='#4A7A8C')
frame = Frame(root)
frame.pack(expand=True, fill=BOTH, padx=20, pady=20)
lb = Listbox(
    frame,
    font= (12)
    )
lb.pack(expand=True, fill=BOTH, side=LEFT)
sb = Scrollbar(
    frame, 
    orient=VERTICAL
    )
sb.pack(fill=Y, side=RIGHT)
lb.configure(yscrollcommand=sb.set)
sb.config(command=lb.yview)
lb.insert(0, 'Fruits')
lb.insert(1,'Citrus – oranges, limes, grapefruits and mandarins')
lb.insert(2,'Stone fruit – apricots, plums, peaches and nectarines')
lb.insert(3,'Tropical and exotic – mangoes a bananasnd ')
lb.insert(4,'Berries – kiwifruit, raspberries, strawberries, blueberries,  and passionfruit')
lb.insert(5,'Melons – honeydew melons, watermelons and rockmelons')
lb.insert(6, 'Vegetables')
lb.insert(7, 'Leafy green – spinach and silverbeet, lettuce')
lb.insert(8, 'Cruciferous – cabbage, broccoli, Brussels sprouts and cauliflower')
lb.insert(9, 'Marrow – zucchini, cucumber and pumpkin')
lb.insert(10, 'Root – yam, sweet potato and potato')
lb.insert(11, 'Edible plant stem – asparagus and celery')
lb.insert(12, 'Allium – garlic, onion and shallot')
root.mainloop()

from tkinter import *
root = Tk()
root.title('PythonGuides')
root.geometry('400x300')
root.config(bg='#4A7A8C')
frame = Frame(root)
frame.pack(expand=True, fill=BOTH, padx=20, pady=20)
lb = Listbox(
    frame,
    font= (12)
    )
lb.pack(expand=True, fill=BOTH)
sb = Scrollbar(
    frame, 
    orient=HORIZONTAL
    )
sb.pack(fill=X)
lb.configure(xscrollcommand=sb.set)
sb.config(command=lb.xview)
lb.insert(0, 'Not all heros wear capes.')
lb.insert(1, 'Game changers are in blue')
lb.insert(2, 'With great power comes great responsibility')
lb.insert(3, 'A noun phrase has a noun or pronoun as the main word')
lb.insert(4, 'With great power comes great responsibility')
lb.insert(5, 'contribute to open source, as this will help & motivate you.')
root.mainloop()


2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...