def morph(self, end_color: RGB, duration: int = 1000, steps: int = 50) -> None: duration = RangeInt(duration, 1, self.MAX_DURATION, "duration") steps = RangeInt(steps, 1, self.MAX_STEPS, "steps") r_end, g_end, b_end = end_color start_color = self.getColor() r_start, g_start, b_start = start_color gradient: List[RGB] = [] steps += 1 for n in range(1, steps): d = 1.0 * n / float(steps) r = (r_start * (1 - d)) + (r_end * d) g = (g_start * (1 - d)) + (g_end * d) b = (b_start * (1 - d)) + (b_end * d) gradient.append(RGB(int(r), int(g), int(b))) gradient.append(end_color) ms_delay = float(duration) / float(1000 * steps) for grad in gradient: self.setColor(grad) time.sleep(ms_delay) self.setColor(end_color)
def intsToRGB(red: int = 0, green: int = 0, blue: int = 0) -> RGB: if not all([ 0 <= red <= 255, 0 <= green <= 255, 0 <= blue <= 255, ]): raise FadeStickColorException(f"One ore more colors are " f"below 0 or above 255. Given {red}, {green}, {blue}.") return RGB(red, green, blue)
def getColor(self) -> RGB: from core.FadeStickUSB import sendControlTransfer, R_USB_RECV, R_CLEAR_FEATURE device_bytes = sendControlTransfer(self, R_USB_RECV, R_CLEAR_FEATURE, FS_MODE_COLOR, dataOrLength=4) rgb = RGB(device_bytes[1], device_bytes[2], device_bytes[3]) return invertRGB(rgb) if self.inverse else rgb
def hexToRGB(hex_str: str) -> RGB: if not hex_str: raise FadeStickColorException("Hex string missing or None") if len(hex_str) != 8: raise FadeStickColorException(f"Hex string {hex_str} must be of the format 0xNNNNNN") try: hex_octets: Final = HEX_COLOR_RE.match(hex_str).groups()[0] except AttributeError: raise ValueError(f"'{hex_str}' is not a valid hexadecimal color value.") hex_lower = hex_octets.lower() return RGB(int(hex_lower[0:2], 16), int(hex_lower[2:4], 16), int(hex_lower[4:6], 16))
def morph(self, end_color: RGB, duration: int = 1000, steps: int = MAX_STEPS) -> None: duration = RangeInt(duration, 1, self.MAX_DURATION, "duration") steps = RangeInt(steps, 1, self.MAX_STEPS, "steps") r_end, g_end, b_end = end_color start_color = self.getColor() r_start, g_start, b_start = start_color pattern: Pattern = Pattern() ms_delay = floor(float(duration) / float(steps)) for n in range(0, steps): # Range is exclusive d = 1.0 * (n + 1) / float(steps) r = (r_start * (1 - d)) + (r_end * d) g = (g_start * (1 - d)) + (g_end * d) b = (b_start * (1 - d)) + (b_end * d) pattern.addColorAndDuration(RGB(int(r), int(g), int(b)), ms_delay) from core.FadeStickUSB import sendControlTransfer, R_USB_SEND, R_SET_CONFIG sendControlTransfer(self, R_USB_SEND, R_SET_CONFIG, FS_MODE_PATTERN, pattern.getBytePattern())
def test_create(self): cd = ColorDuration(RGB(0, 0, 0), 100) self.assertEqual(100, cd.duration) self.assertEqual(RGB(0, 0, 0), cd.color)
def test_set_color_name(self): rgb = self.device.setColor("red") self.assertEqual(RGB(255, 0, 0), rgb)
def test_large_r(self): with self.assertRaises(FadeStickColorException): RGB(256, 0, 0)
def test_max(self): self.assertEqual((255, 255, 255), RGB(255, 255, 255))
def test_normal(self): self.assertEqual((1, 2, 3), RGB(1, 2, 3))
def test_abstract(self): with self.assertRaises(NotImplementedError) as m: cls = FadeStickBase() cls.blink(RGB(0, 0, 0)) self.assertIn("Method 'blink' is abstract", str(m.exception))
def test_get_color_mixed(self): rgb = self.device.setColor(10, 20, 30) self.assertEqual(RGB(10, 20, 30), rgb) curr_rgb = self.device.getColor() self.assertEqual(RGB(10, 20, 30), curr_rgb)
def test_get_color_white(self): rgb = self.device.setColor(255, 255, 255) self.assertEqual(RGB(255, 255, 255), rgb) curr_rgb = self.device.getColor() self.assertEqual(RGB(255, 255, 255), curr_rgb)
def test_get_color_black(self): rgb = self.device.setColor(0, 0, 0) self.assertEqual(RGB(0, 0, 0), rgb) curr_rgb = self.device.getColor() self.assertEqual(RGB(0, 0, 0), curr_rgb)
def test_large_duration(self): with self.assertRaises(RangeIntException): ColorDuration(RGB(0, 0, 0), 10000)
def test_small_duration(self): with self.assertRaises(RangeIntException): ColorDuration(color=RGB(0, 0, 0), duration=-1)
def invertRGB(rgb: RGB) -> RGB: return RGB(255 - rgb.red, 255 - rgb.green, 255 - rgb.blue)
def test_min(self): self.assertEqual((0, 0, 0), RGB(0, 0, 0))
def scaleToRGB(value: float, minIsGreen: bool = True, minScale: float = 0.0, maxScale: float = 1.0) -> RGB: boundedValue = min(maxScale, max(minScale, value)) red = int(floor(boundedValue * 255)) green = int(floor((1.0 - boundedValue) * 255)) return RGB(red, green, 0) if minIsGreen else RGB(green, red, 0)
def test_negative_b(self): with self.assertRaises(FadeStickColorException): RGB(0, 0, -1)
def setColor(self, red: int, green: int, blue: int) -> RGB: return self.setColor(RGB(red, green, blue))
def test_nlarge_b(self): with self.assertRaises(FadeStickColorException): RGB(0, 0, 256)
def test_set_color_hex(self): rgb = self.device.setColor("0xff0000") self.assertEqual(RGB(255, 0, 0), rgb)