Working with multiple tiles

The SDK treats multi-tile setups as first-class. Every tile is identified by its advertised BLE name (by default, anything starting with OmniTile_); give each DWM tag a unique name and the fleet API will pick them up.

Discover and connect

import asyncio
from omnitiles import TileFleet

async def main():
    async with await TileFleet.discover() as fleet:
        print(fleet.names)           # ['OmniTile_1', 'OmniTile_2', 'OmniTile_3']
        await fleet["OmniTile_2"].m1_extend(speed=255)

asyncio.run(main())

Using the fleet as an async context manager connects every tile on entry and disconnects them all on exit.

Broadcast an action in parallel

await fleet.broadcast(lambda t: t.m1_set_position(128))

broadcast runs the action against every tile via asyncio.gather, so the wall-clock time is roughly the time for the slowest tile, not the sum of all tiles. Use it for coordinated layout changes and waveforms.

Scripting a layout switch

async def go_flat(fleet):
    await fleet.broadcast(lambda t: t.m1_set_position(0))
    await fleet.broadcast(lambda t: t.m2_set_position(0))

async def go_staircase(fleet):
    heights = [0, 85, 170, 255]
    for name, height in zip(sorted(fleet.names), heights):
        await fleet[name].m1_set_position(height)

Sync fleet

from omnitiles import SyncFleet

with SyncFleet.discover() as fleet:
    for tile in fleet:
        tile.m1_extend(speed=200)

SyncFleet.broadcast works the same way but accepts an async action; everything runs on the SDK’s shared background loop.