如何在Polybar中用Golang避免循环并实现Hue灯切换
解决Polybar控制Philips Hue灯的循环切换与状态显示问题
问题核心
- 直接用Polybar
custom/script的exec属性调用切换程序时,因模块周期性重复执行exec,导致灯反复开关 - 点击触发切换无法同步显示状态图标,需要让
exec负责查询状态、点击事件负责执行切换
修复步骤
1. 修改Golang代码,支持双模式运行
让程序通过命令行参数区分「查询状态」和「执行切换」两种模式:
package main import ( "encoding/json" "flag" "fmt" "log" "net/http" "strings" ) type config struct { ip string user string } type State struct { On bool `json:"on"` } type StatusResponse struct { State State `json:"state"` } func main() { var cfg config var mode string flag.StringVar(&cfg.ip, "ip", "myip", "PHUE IP address") flag.StringVar(&cfg.user, "user", "my-user", "PHUE User") flag.StringVar(&mode, "mode", "status", "运行模式: status(查询状态)/toggle(切换开关)") flag.Parse() light1On := getLightStatus(cfg.ip, cfg.user, "1") light4On := getLightStatus(cfg.ip, cfg.user, "4") switch mode { case "toggle": // 执行切换逻辑:统一开关灯 targetState := !(light1On && light4On) action := "off" if targetState { action = "on" } turnLight(cfg.ip, cfg.user, "1", action) turnLight(cfg.ip, cfg.user, "4", action) case "status": // 输出状态对应的图标(可替换为你需要的图标字符) if light1On && light4On { fmt.Println("") // 灯亮图标 } else { fmt.Println("") // 灯灭图标 } } } // 重命名函数更准确 func turnLight(ip, user, lightID, action string) { url := fmt.Sprintf("http://%s/api/%s/lights/%s/state", ip, user, lightID) var turnStatus string if action == "on" { turnStatus = `{"on":true}` } else if action == "off" { turnStatus = `{"on":false}` } else { log.Fatalf("无效的action: %s", action) } req, err := http.NewRequest(http.MethodPut, url, strings.NewReader(turnStatus)) if err != nil { log.Fatalf("创建请求失败: %v", err) } req.Header.Set("Content-Type", "application/json") client := http.Client{} resp, err := client.Do(req) if err != nil { log.Fatalf("发送请求失败: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Fatalf("响应状态异常: %s", resp.Status) } } func getLightStatus(ip, user, lightID string) bool { url := fmt.Sprintf("http://%s/api/%s/lights/%s", ip, user, lightID) resp, err := http.Get(url) if err != nil { log.Fatalf("获取状态失败: %v", err) } defer resp.Body.Close() var status StatusResponse dec := json.NewDecoder(resp.Body) err = dec.Decode(&status) if err != nil { log.Fatalf("解析响应失败: %v", err) } return status.State.On }
2. 调整Polybar配置
让exec定期查询状态显示图标,click-left触发切换操作:
[module/hue] type = custom/script format = "%{T2}%{F#f6e58d}%output% %{F-}%{T-}Philip HUE" ; 每隔2秒查询一次状态,可根据需求调整 interval = 2 ; 执行状态查询模式,替换为你的HUE桥接器IP和用户ID exec = ~/.config/scripts/main -ip "你的HUE桥接器IP" -user "你的HUE用户ID" -mode status ; 点击时执行切换模式,加&让后台运行避免阻塞Polybar click-left = exec ~/.config/scripts/main -ip "你的HUE桥接器IP" -user "你的HUE用户ID" -mode toggle &
关键说明
- 避免循环:将切换逻辑从
exec移到click-left,exec仅负责查询状态,模块定期执行exec只会更新图标,不会触发开关 - 状态同步:通过
interval参数控制状态刷新频率,确保图标和实际灯状态一致 - 图标替换:代码中的
和是Nerd Fonts图标,可根据你的字体替换为其他合适的开关图标
内容的提问来源于stack exchange,提问作者xDonYeyox
相关产品推荐
相关产品推荐

