Working with Flow
python-yeelightのドキュメントを読んでいると、あらかじめ電球の遷移状態を設定しているFlowというモードがあるそうです。
“Flow” is a special mode the bulb can be set to, which is basically a list of transitions to perform in succession. For example, a flow can be a constant cycling of colors from one to the next, until it is stopped, or it can be a quick blink of a certain color
久しぶりにyeelightを使ってみたかったので、"Flow"の動作を確認できる環境を作ってみました。
環境
Python version:3.9.7
OS: windows 10.0
yeelightのIPアドレスの検出
以前、Yeelightに関する記事を書いたのですが、IPアドレスの取得について省略して記載したので、はまってしまいました(汗)
今回は、反省を踏まえて、詳細に書いておきます。スマホでYeelightをセットアップし、「LAN Control」を有効化します。セットアップ方法については、こちらに沿って設定しました。その後、下記のプログラムを実行すると、出力結果にIPアドレスが出てきます。('ip': 'xxx.xxx.xx.xxx'の部分)
yeelight.discover_bulbs()では、デバイスのネットワークと機能を確認することができます。
import yeelight
yeelight.discover_bulbs()
出力結果
[{'ip': 'xxx.xxx.xx.xxx', 'port': 55443, 'capabilities': {'id': '0x0000000002dfb19a', 'model': 'color4', 'fw_ver': '39', 'support': 'get_prop set_default set_power toggle set_bright set_scene cron_add cron_get cron_del start_cf stop_cf set_ct_abx adjust_ct set_name set_adjust adjust_bright adjust_color set_rgb set_hsv set_music udp_sess_new udp_sess_keep_alive udp_chroma_sess_new', 'power': 'off', 'bright': '1', 'color_mode': '1', 'ct': '4000', 'rgb': '9685622', 'hue': '99', 'sat': '41', 'name': ''}}]
プログラム
guiで操作したかったので、tkinterを使っています。Tkinterの説明については、次の見出しで説明します。ここでは、yeelightに関係するブブについて説明します。yeelight.Bulb("IPアドレス")
は、上記で確認したIPアドレスを入力してください。self.bulb.turn_on(effect="smooth")
では、lightをonにしています。effectは、suddenとsmoothが設定できます。smoothにすると、徐々にライトが光り始めます。詳細は、こちらのドキュメントを確認してください。
turn_offも同様にlightをoffにしています。
flow = Flow(count=0, transitions=disco())
では、ライブラリであらかじめ設定されている条件を読み込んで、self.bulb.start_flow(flow)
で照明の色を変化が開始します。例えば、transitionsにdisco()を設定すると、ディスコっぽい照明の色で変化していきます。countは、設定されている色の変化のflowを繰り返す操作になります。指定回数終わると、デフォルトの光に戻ります。ただし、0回だと設定を解除するまで永遠に変化します。self.bulb.stop_flow()
は、色の変化途中の状態でストップすることができます。
プログラムは、githubに置いてます。
import time
import yeelight
from yeelight import *
import tkinter as tk
from tkinter import ttk
from yeelight.transitions import *
from yeelight import Flow
class gui:
def __init__(self, main_window):
# Variable setting
self.bulb = yeelight.Bulb("IPアドレス") # Set up IP address for yeelight.
self.function_btn = [
"alarm",
"christmas",
"disco",
"lsd",
"police",
"police2",
"random_loop",
"rgb",
"slowdown",
"strobe",
"strobe_color",
"temp",
]
# Main window
self.main_window = main_window
self.main_window.geometry("800x400")
self.main_window.title("Yeelight operation v0.10")
self.label_grid(self.main_window, "Light", 0, 0)
self.btn_grid(self.main_window, "On", self.turn_on_light, 0, 1, tk.SE)
self.btn_grid(self.main_window, "Off", self.turn_off_light, 0, 2, tk.SE)
self.label_grid(self.main_window, "Transitions", 1, 0)
self.func_combobox = ttk.Combobox(
self.main_window,
text="combo_file",
state="readonly",
value=self.function_btn,
width=30,
)
self.func_combobox.set(self.function_btn[0])
self.func_combobox.bind("<<ComboboxSelected>>", self.effect_event)
self.func_combobox.grid(row=1, column=1, columnspan=3)
self.label_grid(self.main_window, "Flow", 2, 0)
self.btn_grid(self.main_window, "Start", self.start_flow, 2, 1, tk.SE)
self.btn_grid(self.main_window, "Stop", self.stop_flow, 2, 2, tk.SE)
self.btn_grid(self.main_window, "Reset", self.reset_flow, 2, 3, tk.SE)
self.btn_grid(self.main_window, "Exit", self.close_window, 3, 3, tk.SE)
def btn_grid(self, set_frame, btn_name, act_command, r_num, c_num, stk):
button = tk.Button(set_frame, text=btn_name, width=10, command=act_command)
return button.grid(row=r_num, column=c_num, sticky=stk, padx=10, pady=10)
def label_grid(self, set_frame, title, r_num, c_num):
label = tk.Label(set_frame, text=title)
return label.grid(row=r_num, column=c_num, sticky=tk.W, padx=10, pady=10)
def turn_on_light(self):
self.bulb.turn_on(effect="smooth")
def turn_off_light(self):
self.bulb.turn_off(effect="smooth")
def effect_event(self, arg):
self.transition = self.func_combobox.get()
def start_flow(self):
func_name = self.transition
if func_name == "alarm":
flow = Flow(count=0, transitions=alarm()) # Cycle forever.
elif func_name == "christmas":
flow = Flow(count=0, transitions=christmas()) # Cycle forever.
elif func_name == "disco":
flow = Flow(count=0, transitions=disco()) # Cycle forever.
elif func_name == "lsd":
flow = Flow(count=0, transitions=lsd()) # Cycle forever.
elif func_name == "police":
flow = Flow(count=0, transitions=police()) # Cycle forever.
elif func_name == "police2":
flow = Flow(count=0, transitions=police2()) # Cycle forever.
elif func_name == "random_loop":
flow = Flow(count=0, transitions=random_loop()) # Cycle forever.
elif func_name == "rgb":
flow = Flow(count=0, transitions=rgb()) # Cycle forever.
elif func_name == "slowdown":
flow = Flow(count=0, transitions=slowdown()) # Cycle forever.
elif func_name == "strobe":
flow = Flow(count=0, transitions=strobe()) # Cycle forever.
elif func_name == "strobe_color":
flow = Flow(count=0, transitions=strobe_color()) # Cycle forever.
elif func_name == "temp":
flow = Flow(count=0, transitions=temp()) # Cycle forever.
self.bulb.start_flow(flow)
def stop_flow(self):
self.bulb.stop_flow()
def reset_flow(self):
flow = Flow(count=1, transitions=pulse(red=255, green=255, blue=255))
self.bulb.start_flow(flow)
def close_window(self):
self.main_window.destroy()
# self.main_window.quit()
def main():
main_window = tk.Tk()
gui(main_window)
main_window.mainloop()
if __name__ == "__main__":
main()
TKinter
フレームは、下記のようにmain_windowにラベルやボタンを配置するようにしました。
1番上のLightでは、ライトのon/offを操作します。
2番目でtransitionsに設定する照明のモードをComboboxで選択できるようにしています。
3番目は、2番で設定した照明モードを開始、停止、リセットすることができます。
一番下のExitは、GUIを立ち下げます。