Documentation ¶
Index ¶
- Constants
- func MACAdressToFrameAddress(mac []byte) uint64
- func ReadString(r io.Reader, maxLength int) (string, error)
- func WriteString(w io.Writer, s string, length int) (int64, error)
- type Client
- type Frame
- type FrameAddress
- type GetVersionMessage
- type HBSK
- type Header
- type MultiZoneApplicationRequest
- type Packet
- type Payload
- type ProtocolHeader
- type RawPayload
- type SetAccessPointMessage
- type SetColorMessage
- type SetColorZonesMessage
- type SetLabelMessage
- type StateVersionMessage
Constants ¶
const ( MaxHue uint16 = 65535 FullSaturation uint16 = 65535 FullBrightness uint16 = 65535 Warm uint16 = 2500 Cool uint16 = 9000 )
const ( MsgTypeUnknown = 0 MsgTypeSetLabel = 24 MsgTypeStateLabel = 25 MsgTypeGetVersion = 32 MsgTypeStateVersion = 33 MsgTypeSetColorMessage = 102 MsgTypeSetColorZonesMessage = 501 MsgTypeSetAccessPoint = 305 ProtocolNumber = 1024 LabelLength = 32 WifiSSIDLength = 32 WifiPasswordLength = 64 )
Variables ¶
This section is empty.
Functions ¶
func MACAdressToFrameAddress ¶
Types ¶
type Client ¶
type Frame ¶
type Frame struct { Size uint16 // 16 bits - Size of entire message in bytes (including this field) Origin uint8 // 2 bits - Message origin indicator (must be zero) Tagged bool // 1 bit - Determines usage of the Frame address target field Addressable bool // 1 bit - Message includes a target address (must be one) Protocol uint16 // 12 bits - Protocol number (must be 1024 [decimal]) Source uint32 // 32 bits - Source identifier: unique value set by the client, used by responses }
The Frame section contains information about the following:
* Size of the entire message * LIFX Protocol number: must be 1024 (decimal) * Use of the Frame Address target field * Source identifier
The tagged field is a boolean flag that indicates whether the Frame Address target field is being used to address an individual device or all devices. For discovery using Device::GetService the tagged field should be set to one (1) and the target should be all zeroes. In all other messages the tagged field should be set to zero (0) and the target field should contain the device MAC address. The device will then respond with a Device::StateService message, which will include its own MAC address in the target field. In all subsequent messages that the client sends to the device, the target field should be set to the device MAC address, and the tagged field should be set to zero (0).
The source identifier allows each client to provide an unique value, which will be included by the LIFX device in any message that is sent in response to a message sent by the client. If the source identifier is a non-zero value, then the LIFX device will send a unicast message to the IP address and port of the client that sent the originating message. If the source identifier is a zero value, then the LIFX device may send a broadcast message that can be received by all clients on the same sub-net. See _ack_required_ and _res_required_ fields in the Frame Address.
func DecodeFrame ¶
DecodeFrame reads eight bytes from a Reader, and returns the first part of a LIFX header.
type FrameAddress ¶
type FrameAddress struct { Target uint64 // 64 bits - 6 byte device address (MAC address) or zero (0) means all devices Reserved1 [6]uint8 // 48 bits - must all be zero Reserved2 uint8 // 6 bits - reserved AckRequired bool // 1 bits - Acknowledgment message required ResRequired bool // 1 bits - Response message required Sequence uint8 // 8 bits - Wrap around message sequence number }
The Frame Address section contains the following routing information:
* Target device address * Acknowledgement message is required flag * State response message is required flag * Message sequence number
The target device address is 8 bytes long, when using the 6 byte MAC address then left-justify the value and zero-fill the last two bytes. A target device address of all zeroes effectively addresses all devices on the local network. The Frame tagged field must be set accordingly.
There are two flags that cause a LIFX device to send a message in response. In these cases, the source identifier in the response message will be set to the same value as that in the requesting message sent by the client.
- _ack_required_ set to one (1) will cause the device to send an Device::Acknowledgement message
- _res_required_ set to one (1) within a Set message, e.g Light::SetPower will cause the device to send the corresponding State message, e.g Light::StatePower
The client can use acknowledgments to determine that the LIFX device has received a message. However, when using acknowledgments to ensure reliability in an over-burdened lossy network ... causing additional network packets may make the problem worse.
Client that don't need to track the updated state of a LIFX device can choose not to request a response, which will reduce the network burden and may provide some performance advantage. In some cases, a device may choose to send a state update response independent of whether _res_required_ is set.
The sequence number allows the client to provide a unique value, which will be included by the LIFX device in any message that is sent in response to a message sent by the client. This allows the client to distinguish between different messages sent with the same source identifier in the Frame. See _ack_required_ and _res_required_ fields in the Frame Address.
func DecodeFrameAddress ¶
func DecodeFrameAddress(r io.Reader) (*FrameAddress, error)
DecodeFrameAddress reads sixteen bytes from a Reader, and returns the second part of a LIFX header.
func (*FrameAddress) Len ¶
func (f *FrameAddress) Len() int
type GetVersionMessage ¶
type GetVersionMessage struct {
// contains filtered or unexported fields
}
func (*GetVersionMessage) Type ¶
func (m *GetVersionMessage) Type() uint16
type HBSK ¶
HSBK is used to represent the color and color temperature of a light.
The color is represented as an HSB (Hue, Saturation, Brightness) value.
The color temperature is represented in K (Kelvin) and is used to adjust the warmness / coolness of a white light, which is most obvious when saturation is close zero.
Hue: range 0 to 65535 Saturation: range 0 to 65535 Brightness: range 0 to 65535 Kelvin: range 2500° (warm) to 9000° (cool)
type Header ¶
type Header struct { Frame Frame FrameAddress FrameAddress ProtocolHeader ProtocolHeader }
Header combines Frame, FrameAddress and ProtocolHeader.
func DecodeHeader ¶
DecodeHeader reads an entire LIFX header and returns the resulting struct.
type MultiZoneApplicationRequest ¶
type MultiZoneApplicationRequest uint8
const ( MultiZoneNoApply MultiZoneApplicationRequest = 0 MultiZoneApply MultiZoneApplicationRequest = 1 MultiZoneApplyOnly MultiZoneApplicationRequest = 2 )
type Packet ¶
Packet combines Header and a payload to form a complete LIFX message.
func DecodePacket ¶
DecodeHeader reads an entire LIFX message and returns the resulting struct.
type ProtocolHeader ¶
type ProtocolHeader struct { Reserved1 uint64 // 64 bits - Reserved Type uint16 // 16 bits - Message type determines the Payload being used Reserved2 uint16 // 16 bits - Reserved }
The Protocol header contains the following information about the message:
* Message type which determines what action to take (based on the Payload)
func DecodeProtocolHeader ¶
func DecodeProtocolHeader(r io.Reader) (*ProtocolHeader, error)
func (*ProtocolHeader) Len ¶
func (p *ProtocolHeader) Len() int
type RawPayload ¶
type RawPayload struct { Data []byte // contains filtered or unexported fields }
Catch-all for unknown payload types
func DecodeRawPayload ¶
func DecodeRawPayload(r io.Reader, length int) (*RawPayload, error)
func (*RawPayload) Len ¶
func (m *RawPayload) Len() int
func (*RawPayload) Type ¶
func (m *RawPayload) Type() uint16
type SetAccessPointMessage ¶
type SetAccessPointMessage struct { Reserved1 byte // Really don't know what this is. Set to 0x02 from the example. SSID string PSK string Security byte // contains filtered or unexported fields }
SetAccessPoint - Packet 305
Sets WiFi configuration. Undocumented at LIFX. Figures.
Reverse engineered using https://github.com/tserong/lifx-hacks/blob/master/onboard.py
func DecodeSetAccessPointMessage ¶
func DecodeSetAccessPointMessage(r io.Reader) (*SetAccessPointMessage, error)
func (*SetAccessPointMessage) Len ¶
func (m *SetAccessPointMessage) Len() int
func (*SetAccessPointMessage) Type ¶
func (m *SetAccessPointMessage) Type() uint16
type SetColorMessage ¶
type SetColorMessage struct { Reserved uint8 Color HBSK Duration uint32 // contains filtered or unexported fields }
Sent by a client to change the light state.
The duration is the color transition time in milliseconds.
If the Frame Address res_required field is set to one (1) then the device will transmit a State message.
func DecodeSetColorMessage ¶
func DecodeSetColorMessage(r io.Reader) (*SetColorMessage, error)
func (*SetColorMessage) Len ¶
func (m *SetColorMessage) Len() int
func (*SetColorMessage) Type ¶
func (m *SetColorMessage) Type() uint16
type SetColorZonesMessage ¶
type SetColorZonesMessage struct { StartIndex uint8 EndIndex uint8 Color HBSK Duration uint32 Apply MultiZoneApplicationRequest // contains filtered or unexported fields }
func DecodeSetColorZonesMessage ¶
func DecodeSetColorZonesMessage(r io.Reader) (*SetColorZonesMessage, error)
func (*SetColorZonesMessage) Len ¶
func (m *SetColorZonesMessage) Len() int
func (*SetColorZonesMessage) Type ¶
func (m *SetColorZonesMessage) Type() uint16
type SetLabelMessage ¶
type SetLabelMessage struct { Label string // contains filtered or unexported fields }
SetLabel - Packet 24
This packet lets you set the label on the device. The label is a string you assign to the device and will be displayed as the name of the device in the LIFX mobile apps.
Will return one StateLabel (25) message.
func DecodeSetLabelMessage ¶
func DecodeSetLabelMessage(r io.Reader) (*SetLabelMessage, error)
func (*SetLabelMessage) Len ¶
func (m *SetLabelMessage) Len() int
func (*SetLabelMessage) Type ¶
func (m *SetLabelMessage) Type() uint16
type StateVersionMessage ¶
type StateVersionMessage struct { Vendor uint32 Product uint32 Reserved6 [4]byte // contains filtered or unexported fields }
func (*StateVersionMessage) Len ¶
func (m *StateVersionMessage) Len() int
func (*StateVersionMessage) Type ¶
func (m *StateVersionMessage) Type() uint16