Tiles
LIFX Tiles are square devices containing an 8x8 matrix of 64 individually controllable LEDs. These devices are also special in that you can join up to 5 of them in a chain which then behaves like a single device. The tile closest to the power supply will be the master tile and is the one you send messages to for control of any tile in the chain.
Backwards Compatibility
When not using the Tile messages (essentially any message that doesn't have a
tile_index
attribute) the whole chain is controlled. For example if you send a SetColor (102) message to a tile, all the tiles in the chain will change to the chosen color. This means applications that already support the current protocol do not need to make any changes to support controlling all the tiles at once.
Addressing the zones
When you set colors on the Tile you specify an array of 64 colors. The order of that array for a right side up tile is as follows:
Individual Tile Control
Tiles can be controlled individually using the tile_index
and length
properties for Tile messages. Tiles are indexed with the master tile being represented with zero, and increasing by one for each tile after. When addressing tiles the tile_index
represents the first tile that should process the command, and the length
value represents how many tiles should process the command beginning with the tile specified in tile_index
and continuing to the tiles immediately following that one.
The following diagrams illustrate the use of tile_index
and length
parameters.
Tile Positioning
The user_x
and user_y
fields from StateDeviceChain (702) contain positioning information for each tile. Each tile is positioned in a 2D space. The point represents the location of the center of the tile and the unit of measurement is one tile width. So if you have 3 tiles in a chain with user_x
and user_y
of (0, 0), (-0.5, 1) and (0.5, -1) then you'd have something like:
These position values are stored in the tile and are meant to be used by client applications in order to locate the tiles on a 2D plane. This can then be used to apply images across the set of tiles, or match up the borders of a tile when displaying a pattern. You may change these values using SetUserPosition (703)
Tile Orientation
The LIFX tiles have an accelerometer in them that allows the device to know what orientation the tiles are in (upright, rotated left, rotated right, upside down, face up, face down)
This information is given back to you as a (x, y, z)
triplet for each tile from the StateDeviceChain (702) packet. You may use the following code to determine the rotation of your tile.
def nearest_orientation(x, y, z):
"""
Determine which orientation maps to the provided x, y, z
"""
absX = abs(x)
absY = abs(y)
absZ = abs(z)
if x == -1 and y == -1 and z == -1:
# Invalid data, assume right-side up.
return "RightSideUp"
elif absX > absY and absX > absZ:
if x > 0:
return "RotatedRight"
else:
return "RotatedLeft"
elif absZ > absX and absZ > absY:
if z > 0:
return "FaceDown"
else:
return "FaceUp"
else:
if y > 0:
return "UpsideDown"
else:
return "RightSideUp"
You can also "rotate" the 64 colors you send to a tile with the following code
def reorient(colors, orientation):
"""
Return the colors in the different order given our orientation
"""
if orientation in ("RightSideUp", "FaceUp", "FaceDown":
# The colors are already in the correct order
return colors
new_colors = []
for index, color in enumerate(colors):
new_index = rotated_index(i, orientation)
new_colors.append((new_index, color))
# We now sort the new_colors array so that it appears like
# [(0, c1), (1, c2), ...]
new_colors = sorted(new_colors)
# and we return a list of just the colors
return [color for index, color in new_colors]
def rotated_index(i, orientation):
"""
Give new index for i given our orientation
"""
x = i % 8
y = i // 8
if orientation == "UpsideDown":
new_x = 7 - x
new_y = 7 - y
elif orientation == "RotatedLeft":
new_x = 7 - y
new_y = x
elif orientation == "RotatedRight":
new_x = y
new_y = 7 - x
else:
# For all other orientations the x and y don't change
new_x = x
new_y = y
return new_x + (new_y * 8)
Updated almost 4 years ago