|
|
package lifx
import ( "encoding/binary" "fmt" "git.aiterp.net/lucifer/new-server/models" "math" "time" )
type GetService struct{}
func (p *GetService) Decode([]byte) error { return nil }
func (p *GetService) Encode() []byte { return []byte{} }
func (p *GetService) PacketType() uint16 { return 2 }
func (p *GetService) Flags() (ackRequired bool, resRequired bool) { return false, true }
func (p *GetService) String() string { return "GetService()" }
type GetVersion struct{}
func (p *GetVersion) Decode([]byte) error { return nil }
func (p *GetVersion) Encode() []byte { return []byte{} }
func (p *GetVersion) PacketType() uint16 { return 32 }
func (p *GetVersion) Flags() (ackRequired bool, resRequired bool) { return false, true }
func (p *GetVersion) String() string { return "GetVersion()" }
type GetHostFirmware struct{}
func (p *GetHostFirmware) Decode([]byte) error { return nil }
func (p *GetHostFirmware) Encode() []byte { return []byte{} }
func (p *GetHostFirmware) PacketType() uint16 { return 14 }
func (p *GetHostFirmware) Flags() (ackRequired bool, resRequired bool) { return false, true }
func (p *GetHostFirmware) String() string { return "GetHostFirmware()" }
type StateHostFirmware struct { BuildTime time.Time Major uint16 Minor uint16 }
func (p *StateHostFirmware) Decode(data []byte) error { if len(data) < 20 { return models.ErrPayloadTooShort }
ts := int64(binary.LittleEndian.Uint64(data[0:8]))
p.BuildTime = time.Unix(ts/1000000000, ts%1000000000) p.Major = binary.LittleEndian.Uint16(data[16:18]) p.Minor = binary.LittleEndian.Uint16(data[18:20])
return nil }
func (p *StateHostFirmware) Encode() []byte { var data [20]byte
binary.LittleEndian.PutUint64(data[0:8], uint64(p.BuildTime.UnixNano())) binary.LittleEndian.PutUint16(data[16:18], p.Major) binary.LittleEndian.PutUint16(data[18:20], p.Minor)
return data[:] }
func (p *StateHostFirmware) PacketType() uint16 { return 15 }
func (p *StateHostFirmware) Flags() (ackRequired bool, resRequired bool) { return false, false }
func (p *StateHostFirmware) String() string { return fmt.Sprintf("StateHostFirmware(major=%d, minor=%d, build=%s)", p.Major, p.Minor, p.BuildTime.Format(time.RFC3339)) }
type StateVersion struct { Vendor uint32 Product uint32 }
func (p *StateVersion) Decode(data []byte) error { if len(data) < 8 { return models.ErrPayloadTooShort }
p.Vendor = binary.LittleEndian.Uint32(data[0:4]) p.Product = binary.LittleEndian.Uint32(data[4:8])
return nil }
func (p *StateVersion) Encode() []byte { var data [12]byte
binary.LittleEndian.PutUint32(data[0:4], p.Vendor) binary.LittleEndian.PutUint32(data[4:8], p.Product)
return data[:] }
func (p *StateVersion) PacketType() uint16 { return 33 }
func (p *StateVersion) Flags() (ackRequired bool, resRequired bool) { return false, false }
func (p *StateVersion) String() string { return fmt.Sprintf("StateVersion(vendor=%d, product=%d)", p.Vendor, p.Product) }
type GetColor struct{}
func (p *GetColor) Decode([]byte) error { return nil }
func (p *GetColor) Encode() []byte { return []byte{} }
func (p *GetColor) PacketType() uint16 { return 101 }
func (p *GetColor) Flags() (ackRequired bool, resRequired bool) { return false, true }
func (p *GetColor) String() string { return "GetColor()" }
type Acknowledgement struct{}
func (p *Acknowledgement) Decode([]byte) error { return nil }
func (p *Acknowledgement) Encode() []byte { return []byte{} }
func (p *Acknowledgement) PacketType() uint16 { return 45 }
func (p *Acknowledgement) Flags() (ackRequired bool, resRequired bool) { return false, true }
func (p *Acknowledgement) String() string { return "Acknowledgement()" }
type SetColor struct { Hue float64 Sat float64 Bri float64 Kelvin int TransitionTime time.Duration }
func (p *SetColor) Decode(data []byte) error { if len(data) < 13 { return models.ErrPayloadTooShort }
hue := binary.LittleEndian.Uint16(data[1:3]) sat := binary.LittleEndian.Uint16(data[3:5]) bri := binary.LittleEndian.Uint16(data[5:7]) kelvin := binary.LittleEndian.Uint16(data[7:9]) transitionMs := binary.LittleEndian.Uint32(data[9:13])
p.Hue = float64(hue) / (65536 / 360) p.Sat = float64(sat) / 65535 p.Bri = float64(bri) / 65535 p.Kelvin = int(kelvin) p.TransitionTime = time.Duration(transitionMs) * time.Millisecond
return nil }
func (p *SetColor) Encode() []byte { var data [13]byte
data[0] = 0x00 // reserved
binary.LittleEndian.PutUint16(data[1:3], uint16(math.Mod(p.Hue, 360)*(65536/360))) binary.LittleEndian.PutUint16(data[3:5], uint16(p.Sat*65535)) binary.LittleEndian.PutUint16(data[5:7], uint16(p.Bri*65535)) binary.LittleEndian.PutUint16(data[7:9], uint16(p.Kelvin)) binary.LittleEndian.PutUint32(data[9:13], uint32(p.TransitionTime.Milliseconds()))
return data[:] }
func (p *SetColor) PacketType() uint16 { return 102 }
func (p *SetColor) Flags() (ackRequired bool, resRequired bool) { return true, false }
func (p *SetColor) String() string { return fmt.Sprintf("SetColor(hsvk={%f, %f, %f, %d}, ttime=%s)", p.Hue, p.Sat, p.Bri, p.Kelvin, p.TransitionTime, ) }
type SetLightPower struct { On bool TransitionTime time.Duration }
func (p *SetLightPower) Decode(data []byte) error { if len(data) < 6 { return models.ErrPayloadTooShort }
level := binary.LittleEndian.Uint16(data[0:2]) transitionMs := binary.LittleEndian.Uint32(data[2:6])
p.On = level > 0 p.TransitionTime = time.Duration(transitionMs) * time.Millisecond
return nil }
func (p *SetLightPower) Encode() []byte { var data [6]byte
if p.On { data[0], data[1] = 0xff, 0xff } else { data[0], data[1] = 0x00, 0x00 } binary.LittleEndian.PutUint32(data[2:6], uint32(p.TransitionTime.Milliseconds()))
return data[:] }
func (p *SetLightPower) PacketType() uint16 { return 117 }
func (p *SetLightPower) Flags() (ackRequired bool, resRequired bool) { return true, false }
func (p *SetLightPower) String() string { return fmt.Sprintf("SetLightPower(on=%t, ttime=%s)", p.On, p.TransitionTime, ) }
type StateService struct { Service int Port int }
func (p *StateService) String() string { return fmt.Sprintf("StateService(service=%d, port=%d)", p.Service, p.Port) }
func (p *StateService) Decode(data []byte) error { if len(data) < 5 { return models.ErrPayloadTooShort }
p.Service = int(data[0]) p.Port = int(binary.LittleEndian.Uint32(data[1:5]))
return nil }
func (p *StateService) Encode() []byte { var data [5]byte data[0] = uint8(p.Service) binary.LittleEndian.PutUint32(data[1:5], uint32(p.Port))
return data[:] }
func (p *StateService) PacketType() uint16 { return 3 }
func (p *StateService) Flags() (ackRequired bool, resRequired bool) { return false, false }
type LightState struct { Hue float64 Sat float64 Bri float64 Kelvin int On bool Label string }
func (p *LightState) String() string { return fmt.Sprintf("LightState(hsvk=(%f, %f, %f, %d), on=%t, label=%+v)", p.Hue, p.Sat, p.Bri, p.Kelvin, p.On, p.Label, ) }
func (p *LightState) Decode(data []byte) error { if len(data) < 52 { return models.ErrPayloadTooShort }
hue := binary.LittleEndian.Uint16(data[0:2]) sat := binary.LittleEndian.Uint16(data[2:4]) bri := binary.LittleEndian.Uint16(data[4:6]) kelvin := binary.LittleEndian.Uint16(data[6:8]) power := binary.LittleEndian.Uint16(data[10:12])
p.Hue = float64(hue) / (65536 / 360) p.Sat = float64(sat) / 65535 p.Bri = float64(bri) / 65535 p.Kelvin = int(kelvin) p.On = power > 32767
p.Label = "" for i, v := range data[14:46] { if v == 0 { p.Label = string(data[14 : 14+i]) break } }
return nil }
func (p *LightState) Encode() []byte { var data [52]byte
power := uint16(0) if p.On { power = 0xffff }
binary.LittleEndian.PutUint16(data[0:2], uint16(math.Mod(p.Hue, 360)*(65536/360))) binary.LittleEndian.PutUint16(data[2:4], uint16(p.Sat*65535)) binary.LittleEndian.PutUint16(data[4:6], uint16(p.Bri*65535)) binary.LittleEndian.PutUint16(data[6:8], uint16(p.Kelvin)) binary.LittleEndian.PutUint16(data[10:12], power)
label := p.Label labelBytes := []byte(label) for len(labelBytes) > 31 { label = label[:len(label)-1] labelBytes = []byte(label) } copy(data[14:], labelBytes)
return data[:] }
func (p *LightState) PacketType() uint16 { return 107 }
func (p *LightState) Flags() (ackRequired bool, resRequired bool) { return false, false }
|