async def fill(self, random_orientations=False): plans_args = ["chain"] if self.background_option.type == "current": plans_args.append("colors") def e(error): log.error(error) plans = self.sender.make_plans(*plans_args) async for serial, name, info in self.sender.gatherer.gather( plans, self.serials, error_catcher=e): if name == "colors": self.info_by_serial[serial].colors = list(enumerate(info)) elif name == "chain": self.info_by_serial[ serial].coords = user_coords_to_pixel_coords( info["coords_and_sizes"]) def make_reorient(random_orientations, info): kwargs = {} if random_orientations: kwargs["randomize"] = True def reorient(index, colors): return info["reorient"](index, colors, **kwargs) return reorient self.info_by_serial[serial].reorient = make_reorient( random_orientations, info)
def from_user_coords(kls, coords_and_sizes, **kwargs): """ Create a TileApplier from the ``[((user_x, user_y), (width, height)), ...]`` returned by a GetDeviceChain message. """ normalized = user_coords_to_pixel_coords(coords_and_sizes) return kls(normalized, **kwargs)
async def start(self, serial, info, target, afr): errors = [] plans = ["chain"] if info.get("initial") is None: info["initial"] = {"colors": [], "power": 65535} plans.append("colors") plans.append("power") plans = make_plans(*plans) gatherer = Gatherer(target) got = await gatherer.gather_all(plans, serial, afr, error_catcher=errors) if errors: return errors, info chain = got[serial][1]["chain"] power = got[serial][1].get("power") colors = got[serial][1].get("colors") if power is not None: info["initial"]["power"] = power["level"] if colors is not None: info["initial"]["colors"] = colors pixel_coords = user_coords_to_pixel_coords(chain["coords_and_sizes"]) info["coords"] = [top_left for top_left, _ in pixel_coords] info["reorient"] = chain["reorient"] if info.get("pixels") is None: canvas = Canvas() def dcf(i, j): return Color(0, 0, 0, 3500) canvas.default_color_func = dcf length = len(info["coords"]) self.style_maker.set_canvas(canvas, length) info["pixels"], info["color_pixels"] = make_rgb_and_color_pixels( canvas, length) msgs = [DeviceMessages.SetPower(level=65535)] msgs.extend( canvas_to_msgs( canvas, coords_for_horizontal_line, duration=1, acks=True, reorient=info["reorient"], )) await target.script(msgs).run_with_all(serial, afr, error_catcher=errors) return errors, info
async def change(self, serial, tile_index, left_x, top_y, target, afr): if serial not in self.serials: return {"serial": serial, "data": None} user_x = (left_x + 4) / 8 user_y = (top_y - 4) / 8 msg = TileMessages.SetUserPosition(tile_index=tile_index, user_x=user_x, user_y=user_y, res_required=False) errors = [] await target.script(msg).run_with_all(serial, afr, error_catcher=errors, message_timeout=5) hp.async_as_background( self.highlight(serial, tile_index, target, afr, error_catcher=[], message_timeout=3)) if errors: return {"serial": serial, "data": None} plans = make_plans(chain=ChainPlan(refresh=True)) gatherer = Gatherer(target) got = await gatherer.gather_all(plans, serial, afr, error_catcher=errors, message_timeout=5) if serial in got and got[serial][0]: pixel_coords = user_coords_to_pixel_coords( got[serial][1]["chain"]["coords_and_sizes"]) self.serials[serial]["coords"] = [xy for xy, _ in pixel_coords] return {"serial": serial, "data": self.info_for_browser(serial)}
async def fill(self, random_orientations=False): msgs = [] if self.background_option.type == "current": msgs.append( TileMessages.GetState64.empty_normalise(tile_index=0, length=255, x=0, y=0, width=8)) msgs.append(TileMessages.GetDeviceChain()) async for pkt, _, _ in self.target.script(msgs).run_with( self.serials, self.afr): serial = pkt.serial if pkt | TileMessages.State64: self.info_by_serial[serial].states.append( (pkt.tile_index, pkt)) elif pkt | TileMessages.StateDeviceChain: if self.coords is None: coords = [] for tile in tiles_from(pkt): coords.append(((tile.user_x, tile.user_y), (tile.width, tile.height))) self.info_by_serial[ serial].coords = user_coords_to_pixel_coords(coords) orientations = orientations_from(pkt) if random_orientations: self.info_by_serial[serial].orientations = { i: random.choice(list(O.__members__.values())) for i in orientations } else: self.info_by_serial[serial].orientations = orientations
from collections import defaultdict import logging import asyncio import random import time log = logging.getLogger("photons_tile_paint.animation") class Finish(PhotonsAppError): pass coords_for_horizontal_line = user_coords_to_pixel_coords([[(0, 0), (8, 8)], [(1, 0), (8, 8)], [(2, 0), (8, 8)], [(3, 0), (8, 8)], [(4, 0), (8, 8)]]) async def tile_serials_from_reference(target, reference, afr): """ Given a reference, return all the serials that has a ``has_chain`` capability """ serials = [] async for pkt, _, _ in target.script(DeviceMessages.GetVersion()).run_with( reference, afr): if pkt | DeviceMessages.StateVersion: cap = capability_for_ids(pkt.product, pkt.vendor) if cap.has_chain:
# coding: spec from photons_themes.coords import user_coords_to_pixel_coords from photons_app.test_helpers import TestCase describe TestCase, "user_coords_to_pixel_coords": it "translates to top left corner": coords_and_sizes = [ ((1, 1), (8, 8)) , ((2, 2), (10, 9)) , ((3, 3), (6, 6)) ] normalized = user_coords_to_pixel_coords(coords_and_sizes) self.assertEqual(normalized , [ ((8 - 4, 8 + 4), (8, 8)) , ((20 - 5, int(18 + 4.5)), (10, 9)) , ((18 - 3, 18 + 3), (6, 6)) ] )