Skip to content

Commit

Permalink
Merge pull request #1 from redraw/perfomance-fix
Browse files Browse the repository at this point in the history
Performance fix
  • Loading branch information
redraw authored Jun 1, 2024
2 parents daec2af + 0b15ec0 commit ceecf07
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 84 deletions.
175 changes: 133 additions & 42 deletions src/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,43 @@ package main

import (
"encoding/json"
"errors"
"image/color"
"net"
"sync"
"time"

log "github.com/sirupsen/logrus"
)

type WizDevice struct {
IP string
MAC string
State map[string]interface{}
State WizState
conn *net.UDPConn
mu sync.Mutex
}

type WizState struct {
Mac string `json:"mac"`
Dimming float64 `json:"dimming"`
State bool `json:"state"`
Rssi float64 `json:"rssi"`
Temp float64 `json:"temp"`
R int `json:"r"`
G int `json:"g"`
B int `json:"b"`
}

type WizParams map[string]interface{}

type WizPayload struct {
Method string `json:"method"`
Params WizParams `json:"params"`
}

func (wd *WizDevice) Close() {
wd.conn.Close()
}

func NewWizDevice(ip, mac string) (*WizDevice, error) {
Expand All @@ -27,79 +53,144 @@ func NewWizDevice(ip, mac string) (*WizDevice, error) {
}

device := &WizDevice{
IP: ip,
MAC: mac,
conn: conn,
State: make(map[string]interface{}),
IP: ip,
MAC: mac,
conn: conn,
}

return device, nil
}

func (wd *WizDevice) sendCommand(method string, params map[string]interface{}) error {
log.Debugf("> %v params=%v", method, params)
func (wd *WizDevice) sendCommand(payload WizPayload) (interface{}, error) {
wd.mu.Lock()
defer wd.mu.Unlock()

log.Debugf("> %+v", payload)

payload := map[string]interface{}{
"method": method,
"params": params,
}
body, err := json.Marshal(payload)
if err != nil {
return err
return nil, err
}

_, err = wd.conn.Write(body)
if err != nil {
return err
return nil, err
}

response := make([]byte, 4096)
n, err := wd.conn.Read(response)
if err != nil {
return err
bytes := make([]byte, 4096)
if err := wd.conn.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
return nil, err
}

var respData struct {
Result map[string]interface{} `json:"result"`
}
err = json.Unmarshal(response[:n], &respData)
n, err := wd.conn.Read(bytes)
if err != nil {
return err
return nil, err
}

log.Debugf("< %v", respData)
var response struct {
Method string `json:"method"`
}
if err := json.Unmarshal(bytes[:n], &response); err != nil {
return nil, err
}

if method == "getPilot" {
wd.State = respData.Result
switch response.Method {
case "getPilot":
var data struct {
Result WizState `json:"result"`
}
if err := json.Unmarshal(bytes[:n], &data); err != nil {
return nil, err
}
log.Debugf("< %+v", data.Result)
wd.State = data.Result
return data.Result, nil

case "setPilot":
var data struct {
Result struct {
Success bool `json:"success"`
} `json:"result"`
}
if err := json.Unmarshal(bytes[:n], &data); err != nil {
return nil, err
}
log.Debugf("< %+v", data.Result)
return data.Result.Success, nil
}

return nil
return nil, errors.New("unknown response")
}

func (wd *WizDevice) GetState() (map[string]interface{}, error) {
if err := wd.sendCommand("getPilot", nil); err != nil {
return nil, err
func (wd *WizDevice) GetState() (WizState, error) {
request := WizPayload{Method: "getPilot"}

res, err := wd.sendCommand(request)
if err != nil {
return WizState{}, err
}
return wd.State, nil

return res.(WizState), nil
}

func (wd *WizDevice) SetPower(on bool) error {
state := map[string]interface{}{"state": on}
return wd.sendCommand("setPilot", state)
func (wd *WizDevice) SetPower(on bool) (bool, error) {
request := WizPayload{
Method: "setPilot",
Params: WizParams{"state": on},
}

res, err := wd.sendCommand(request)
if err != nil {
return false, err
}

return res.(bool), nil
}

func (wd *WizDevice) SetBrightness(value int) error {
state := map[string]interface{}{"dimming": value}
return wd.sendCommand("setPilot", state)
func (wd *WizDevice) SetBrightness(value float64) (bool, error) {
request := WizPayload{
Method: "setPilot",
Params: WizParams{"dimming": value},
}

res, err := wd.sendCommand(request)
if err != nil {
return false, err
}

return res.(bool), nil
}

func (wd *WizDevice) SetTemperature(value int) error {
state := map[string]interface{}{"temp": value}
return wd.sendCommand("setPilot", state)
func (wd *WizDevice) SetTemperature(value float64) (bool, error) {
request := WizPayload{
Method: "setPilot",
Params: WizParams{"temp": value},
}

res, err := wd.sendCommand(request)
if err != nil {
return false, err
}

return res.(bool), nil
}

func (wd *WizDevice) SetColor(rgb color.Color) error {
func (wd *WizDevice) SetColor(rgb color.Color) (bool, error) {
r, g, b, _ := rgb.RGBA()
state := map[string]interface{}{"r": int(r >> 8), "g": int(g >> 8), "b": int(b >> 8)}
return wd.sendCommand("setPilot", state)

request := WizPayload{
Method: "setPilot",
Params: WizParams{
"r": int(r >> 8),
"g": int(g >> 8),
"b": int(b >> 8),
},
}

res, err := wd.sendCommand(request)
if err != nil {
return false, err
}

return res.(bool), nil
}
55 changes: 33 additions & 22 deletions src/fleet.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,50 +37,61 @@ func (wf *WizFleet) Start() {

func (wf *WizFleet) monitorDevice(device *WizDevice) {
for {
err := device.sendCommand("getPilot", nil)
if err != nil {
log.Printf("Error getting state for device %s: %v", device.IP, err)
if state, err := device.GetState(); err == nil {
log.Debugf("Device %s state: %+v", device.IP, state)
}
time.Sleep(1 * time.Second)
time.Sleep(5 * time.Second)
}
}

func (wf *WizFleet) SetPower(on bool) error {
if wf.SelectedDevice != nil {
return wf.SelectedDevice.SetPower(on)
}
for _, device := range wf.Devices {
go device.SetPower(on)
if _, err := wf.SelectedDevice.SetPower(on); err != nil {
return err
}
} else {
for _, device := range wf.Devices {
go device.SetPower(on)
}
}
return nil
}

func (wf *WizFleet) SetBrightness(value int) error {
func (wf *WizFleet) SetBrightness(value float64) error {
if wf.SelectedDevice != nil {
return wf.SelectedDevice.SetBrightness(value)
}
for _, device := range wf.Devices {
go device.SetBrightness(value)
if _, err := wf.SelectedDevice.SetBrightness(value); err != nil {
return err
}
} else {
for _, device := range wf.Devices {
go device.SetBrightness(value)
}
}
return nil
}

func (wf *WizFleet) SetTemperature(value int) error {
func (wf *WizFleet) SetTemperature(value float64) error {
if wf.SelectedDevice != nil {
return wf.SelectedDevice.SetTemperature(value)
}
for _, device := range wf.Devices {
go device.SetTemperature(value)
if _, err := wf.SelectedDevice.SetTemperature(value); err != nil {
return err
}
} else {
for _, device := range wf.Devices {
go device.SetTemperature(value)
}
}
return nil
}

func (wf *WizFleet) SetColor(rgb color.Color) error {
if wf.SelectedDevice != nil {
return wf.SelectedDevice.SetColor(rgb)
}
for _, device := range wf.Devices {
go device.SetColor(rgb)
if _, err := wf.SelectedDevice.SetColor(rgb); err != nil {
return err
}
} else {
for _, device := range wf.Devices {
go device.SetColor(rgb)
}
}
return nil
}
Expand Down
Loading

0 comments on commit ceecf07

Please sign in to comment.