import math from util import clamp, rescale class MovingHead: def __init__(self, start_addr): self.start_addr = start_addr self.pan = 0 # -pi/2 to pi/2 self.tilt = 0 # -3pi/2 to 3pi/2 self.speed = 0 self.dimmer = 0 # 0 to 1 self.rgbw = (0, 0, 0, 0) def __str__(self): return ( f"MovingHead({self.start_addr}): pan={self.pan!r}, " f"tilt={self.tilt!r}, speed={self.speed!r}, " f"dimmer={self.dimmer!r}, rgbw={self.rgbw!r}" ) def render(self, dst): pan = rescale(self.pan, (-1.5 * math.pi, 1.5 * math.pi), (255, 0)) pan = clamp(int(pan), (0, 255)) pan_fine = 0 tilt = rescale(self.tilt, (-0.5 * math.pi, 0.5 * math.pi), (0, 255)) tilt = clamp(int(tilt), (0, 255)) tilt_fine = 0 dimmer = clamp(7 + int(127 * self.dimmer), (7, 134)) (r, g, b, w) = self.rgbw channels = [ pan, pan_fine, tilt, tilt_fine, self.speed, dimmer, r, g, b, w, 0, # color mode 0, # auto jump speed 0, # control mode 0, # reset ] offset = self.start_addr - 1 dst[offset : offset + len(channels)] = channels