tile

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2020 License: BSD-3-Clause Imports: 11 Imported by: 0

README

PkgGoDev Go Report Card

LIFX LAN Tile API

Please refer to project README or GoDoc page for more informations.

Documentation

Overview

Package tile implements LIFX LAN Protocol for LIFX Tile devices:

https://lan.developer.lifx.com/v2.0/docs/tile-control

A tile device is also a light device and implements all light APIs.

Please refer to its parent package for more background/context.

Example (Draw)

This example demonstrates how to draw a single frame on a tile device.

package main

import (
	"context"
	"log"
	"time"

	"github.com/fishy/lifxlan/tile"
)

func main() {
	// Need proper initialization on real code.
	var (
		device tile.Device
		// Important to set timeout to context when requiring ack.
		timeout time.Duration
		// ColorBoard to draw.
		cb tile.ColorBoard
	)

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	if err := device.SetColors(
		ctx,
		nil, // conn, use nil so that SetColors will maintain it for us
		cb,
		0,    // fade in duration
		true, // ack
	); err != nil {
		log.Fatal(err)
	}
}
Output:

Example (DrawContinuously)

This example demonstrates how to draw frames continuously on a tile device.

package main

import (
	"context"
	"log"
	"time"

	"github.com/fishy/lifxlan/tile"
)

func main() {
	// Need proper initialization on real code.
	var (
		device tile.Device
		// Important to set timeout to context when requiring ack.
		timeout time.Duration
		// Interval between frames.
		interval time.Duration
		// Function to return the next frame.
		nextFrame func() tile.ColorBoard
	)

	conn, err := device.Dial()
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	for range time.Tick(interval) {
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		defer cancel()
		if err := device.SetColors(
			ctx,
			conn,
			nextFrame(),
			0,    // fade in duration
			true, // ack
		); err != nil {
			log.Fatal(err)
		}
	}
}
Output:

Index

Examples

Constants

View Source
const (
	GetDeviceChain   lifxlan.MessageType = 701
	StateDeviceChain lifxlan.MessageType = 702
	GetTileState64   lifxlan.MessageType = 707
	StateTileState64 lifxlan.MessageType = 711
	SetTileState64   lifxlan.MessageType = 715
)

Tile related MessageType values.

Variables

This section is empty.

Functions

This section is empty.

Types

type Board

type Board interface {
	Width() int
	Height() int

	// OnTile returns true if coordinate (x, y) is on a tile.
	OnTile(x, y int) bool
}

Board defines a board for a tile device (collection of tiles).

Assuming every tile is 8x8, and we have 3 tiles arranged as:

+--+    +--+
|  |    |  |
|  |+--+|  |
+--+|  |+--+
    |  |
    +--+

Then the width of the board would be 24, and the height would be 12. The coordinate of the topleft corner would be (0, 11) and the coordinate of the bottomright corner of the middle tile would be (15, 0).

The size is also guaranteed to be trimmed. Which means that on the above example, if either the left or the right tile is removed from the device, the size would change to 16x12. But if the middle tile is removed from the device, the size would change to 24x8 with a 8x8 blackhole in the middle.

type BoardData

type BoardData struct {
	// The size of the board.
	Coordinate

	// Parsed index data, with size X*Y.
	Data [][]*IndexData
	// Parsed reverse coordinate data,
	// with size len(tiles)*tileWidth*tileHeight,
	// The coordinate is the coordinate of this tile pixel on the board.
	ReverseData [][][]Coordinate
}

BoardData is the parsed, normalized board data.

The zero value represents an empty board of size 0x0.

func ParseBoard

func ParseBoard(tiles []*Tile) BoardData

ParseBoard parses tiles into BoardData.

type ColorBoard

type ColorBoard [][]*lifxlan.Color

ColorBoard represents a board of colors.

The zero value returns nil color on every coordinate.

func MakeColorBoard

func MakeColorBoard(width, height int) ColorBoard

MakeColorBoard creates a ColorBoard with the given size.

Example

This example demonstrates how to make a ColorBoard of random colors for a board.

package main

import (
	"github.com/fishy/lifxlan"
	"github.com/fishy/lifxlan/tile"
)

func main() {
	// Variables should be initialized properly in real code.
	var (
		board tile.Board

		// Should return a random color.
		colorGenerator func() *lifxlan.Color
	)

	// This makes a full size ColorBoard.
	// If you only need to draw partially and leave the rest of the board black,
	// you can use smaller width/height values that's enough to cover the area you
	// want to draw.
	cb := tile.MakeColorBoard(board.Width(), board.Height())
	for x := 0; x < board.Width(); x++ {
		for y := 0; y < board.Height(); y++ {
			if !board.OnTile(x, y) {
				// This coordinate is not on any tile so there's no need to draw it.
				continue
			}
			cb[x][y] = colorGenerator()
		}
	}
}
Output:

func (ColorBoard) GetColor

func (cb ColorBoard) GetColor(x, y int) *lifxlan.Color

GetColor returns the color at the given coordinate.

If the given coordinate is out of boundary, nil color will be returned.

type Coordinate

type Coordinate struct {
	X, Y int
}

Coordinate defines a simple 2D coordinate.

type Device

type Device interface {
	light.Device

	Board

	// Tiles returns a copy of the tiles in this device.
	Tiles() []Tile

	// GetColors returns the current color board on this tile device.
	//
	// If conn is nil,
	// a new connection will be made and guaranteed to be closed before returning.
	// You should pre-dial and pass in the conn if you plan to call APIs on this
	// device repeatedly.
	//
	// This function will wait for len(Tiles()) response messages.
	// In case of one or more of the responses get dropped on the network,
	// this function will wait until context is cancelled.
	// So it's important to set an appropriate timeout on the context.
	GetColors(ctx context.Context, conn net.Conn) (ColorBoard, error)

	// SetColors sets the tile device with the given color board.
	//
	// If conn is nil,
	// a new connection will be made and guaranteed to be closed before returning.
	// You should pre-dial and pass in the conn if you plan to call APIs on this
	// device repeatedly.
	//
	// If ack is false,
	// this function returns nil error after the API is sent successfully.
	// If ack is true,
	// this function will only return nil error after it received all ack(s) from
	// the device.
	SetColors(ctx context.Context, conn net.Conn, cb ColorBoard, transition time.Duration, ack bool) error

	// TileWidth returns the width of the i-th tile.
	//
	// If i is out of bound, it returns the width of the first tile (index 0)
	// instead. If there's no known tiles, it returns 0.
	TileWidth(i int) uint8
}

Device is a wrapped lifxlan.Device that provides tile related APIs.

func Wrap

func Wrap(ctx context.Context, d lifxlan.Device, force bool) (Device, error)

Wrap tries to wrap a lifxlan.Device into a tile device.

When force is false and d is already a tile device, d will be casted and returned directly. Otherwise, this function calls a tile device API, and only returns a non-nil Device if it supports the API.

If the device is not a tile device, the function might block until ctx is cancelled.

When returning a valid tile device, the device's HardwareVersion is guaranteed to be cached.

type IndexData

type IndexData struct {
	// The coordinate inside the tile.
	Coordinate

	// The index of the tile.
	Index int
}

IndexData stores the data linked to a tile for a Board coordinate.

func (IndexData) String

func (id IndexData) String() string

type RawGetTileState64Payload

type RawGetTileState64Payload struct {
	TileIndex uint8
	Length    uint8

	X     uint8
	Y     uint8
	Width uint8
	// contains filtered or unexported fields
}

RawGetTileState64Payload defines the struct to be used for encoding and decoding.

https://lan.developer.lifx.com/v2.0/docs/tile-messages#section-gettilestate64-707

type RawSetTileState64Payload

type RawSetTileState64Payload struct {
	TileIndex uint8
	Length    uint8

	X        uint8
	Y        uint8
	Width    uint8
	Duration lifxlan.TransitionTime
	Colors   [64]lifxlan.Color
	// contains filtered or unexported fields
}

RawSetTileState64Payload defines the struct to be used for encoding and decoding.

https://lan.developer.lifx.com/v2.0/docs/tile-messages#section-settilestate64-715

type RawStateDeviceChainPayload

type RawStateDeviceChainPayload struct {
	StartIndex  uint8
	TileDevices [16]RawTileDevice
	TotalCount  uint8
}

RawStateDeviceChainPayload defines the struct to be used for encoding and decoding.

https://lan.developer.lifx.com/v2.0/docs/tile-messages#section-statedevicechain-702

type RawStateTileState64Payload

type RawStateTileState64Payload struct {
	TileIndex uint8

	X      uint8
	Y      uint8
	Width  uint8
	Colors [64]lifxlan.Color
	// contains filtered or unexported fields
}

RawStateTileState64Payload defines the struct to be used for encoding and decoding.

https://lan.developer.lifx.com/v2.0/docs/tile-messages#section-statetilestate64-711

type RawTileDevice

type RawTileDevice struct {
	AccelMeasX int16
	AccelMeasY int16
	AccelMeasZ int16

	UserX  float32
	UserY  float32
	Width  uint8
	Height uint8

	HardwareVersion lifxlan.HardwareVersion
	// contains filtered or unexported fields
}

RawTileDevice defines the struct to be used for encoding and decoding.

https://lan.developer.lifx.com/v2.0/docs/tile-messages#section-tile

type Rotation

type Rotation int

Rotation defines the rotation of a single tile.

NOTE: Currently only RotationRightSideUp is fully supported.

const (
	RotationRightSideUp Rotation = iota
	RotationRotateRight
	RotationRotateLeft
	RotationFaceDown
	RotationFaceUp
	RotationUpsideDown
)

Possible Rotation values.

func ParseRotation

func ParseRotation(x, y, z int16) Rotation

ParseRotation parses accelerator measurements into Rotation

func (Rotation) String

func (r Rotation) String() string

type Tile

type Tile struct {
	UserX    float32
	UserY    float32
	Width    uint8
	Height   uint8
	Rotation Rotation
}

Tile defines a single tile inside a TileDevice

func ParseTile

func ParseTile(raw *RawTileDevice) *Tile

ParseTile parses RawTileDevice into a Tile.

func (Tile) BoardCoordinates

func (t Tile) BoardCoordinates() (
	coordinates [][]Coordinate,
	min Coordinate,
	max Coordinate,
)

BoardCoordinates returns non-normalized coordinates of the pixels on this tile on the board.

"non-normalized" means that the coordinate might be negative.

The returned coordinates are guaranteed to be of the size of Width*Height.

func (Tile) Rotate

func (t Tile) Rotate(x, y int) (int, int)

Rotate rotates a given coordinate (x, y) based on tile's rotation and size.

x, y must satisfy: (0 <= x < width) && (0 <= y < height)

TODO: This function currently only handles RotationRightSideUp correctly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL