def __init__(self, verbose, showUpdates): # initializations self.beVerbose = verbose self.dryRun = False self.colorCalculator = ColorCalculator() self.deviceConnected = False self.currentFrameCount = 0 self.targetTimePerFrame = 0.0 self.updateFrameTimestamp = datetime.datetime.now() self.asyncUpdateRateController = AsyncUpdateRateController( self, showUpdates) self.pixelMap = [ 42, 43, 44, 45, 46, 47, 48, 41, 20, 21, 22, 23, 24, 25, 40, 19, 18, 17, 16, 15, 26, 39, 10, 11, 12, 13, 14, 27, 38, 9, 8, 7, 6, 5, 28, 37, 0, 1, 2, 3, 4, 29, 36, 35, 34, 33, 32, 31, 30 ] # establish connection to device try: if not self.dryRun: self.serialConnection = serial.Serial(DEVICE_FILE, DEVICE_BAUDRATE) self.deviceConnected = True except serial.SerialException: print('can not connect to the Arduino; going on as dry run') self.dryRun = True # build header for buffer # unsigned char array, will transfered serially to the device self.buffer = array('B') # ASCII for 'A'; magic number self.buffer.append(65) # ASCII for 'd'; magic number self.buffer.append(100) # ASCII for 'a'; magic number self.buffer.append(97) # LED count high byte self.buffer.append((NUMBER_LEDS - 1) >> 8) # LED count low byte self.buffer.append((NUMBER_LEDS - 1) & 0xff) # checksum self.buffer.append((NUMBER_LEDS - 1) >> 8 ^ (NUMBER_LEDS - 1) & 0xff ^ 0x55) for _ in range(0, (NUMBER_LEDS * 3)): # fill up every channel of every LED with zeros self.buffer.append(255) # calculate max. useful frame rate which the serial bus can handle targetFPS = (DEVICE_BAUDRATE / 8) / sys.getsizeof(self.buffer) self.targetTimePerFrame = 1.0 / targetFPS # wait for initialization if not self.dryRun: if self.beVerbose: print('wait for Arduino to be initialized') sleep(5) # start frame rate controller self.asyncUpdateRateController.start()
def __init__(self, device): # initializations self.device = device self.colors = ColorController self.colorCalculator = ColorCalculator() self.hueAdditionPerFrame = 0.0 # animation settings self.currentHueAddition = 0.0 self.speed = 10
def __init__(self, device): # animation settings self.glowingPixelCount = 17 self.glowingPixelDegreeOfColorDivergence = 35 self.minimumSpeed = 50 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.randomGlowingPixels = {} self.sinFactorForHueAddition = 0
def __init__(self, verbose, showUpdates): # initializations self.beVerbose = verbose self.dryRun = False self.colorCalculator = ColorCalculator() self.deviceConnected = False self.currentFrameCount = 0 self.targetTimePerFrame = 0.0 self.updateFrameTimestamp = datetime.datetime.now() self.asyncUpdateRateController = AsyncUpdateRateController( self, showUpdates) self.pixelMap = [ 42, 43, 44, 45, 46, 47, 48, 41, 20, 21, 22, 23, 24, 25, 40, 19, 18, 17, 16, 15, 26, 39, 10, 11, 12, 13, 14, 27, 38, 9, 8, 7, 6, 5, 28, 37, 0, 1, 2, 3, 4, 29, 36, 35, 34, 33, 32, 31, 30 ] # establish connection to device try: if not self.dryRun: self.serialConnection = serial.Serial( DEVICE_FILE, DEVICE_BAUDRATE) self.deviceConnected = True except serial.SerialException: print('can not connect to the Arduino; going on as dry run') self.dryRun = True # build header for buffer # unsigned char array, will transfered serially to the device self.buffer = array('B') # ASCII for 'A'; magic number self.buffer.append(65) # ASCII for 'd'; magic number self.buffer.append(100) # ASCII for 'a'; magic number self.buffer.append(97) # LED count high byte self.buffer.append((NUMBER_LEDS - 1) >> 8) # LED count low byte self.buffer.append((NUMBER_LEDS - 1) & 0xff) # checksum self.buffer.append((NUMBER_LEDS - 1) >> 8 ^ (NUMBER_LEDS - 1) & 0xff ^ 0x55) for _ in range(0, (NUMBER_LEDS * 3)): # fill up every channel of every LED with zeros self.buffer.append(255) # calculate max. useful frame rate which the serial bus can handle targetFPS = (DEVICE_BAUDRATE / 8) / sys.getsizeof(self.buffer) self.targetTimePerFrame = 1.0 / targetFPS # wait for initialization if not self.dryRun: if self.beVerbose: print('wait for Arduino to be initialized') sleep(5) # start frame rate controller self.asyncUpdateRateController.start()
def __init__(self, device): # animation settings self.centerPositionX = 1 self.centerPositionY = 5 self.degreeOfColorDivergence = 30 self.distanceToDarkness = 3 self.speed = 0.01 self.iterationStep = 0 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.degreeFactor = 0 # construct array of precalculated values self.sinSummands = [[ 0.0 for x in range(self.device.getNumberOfLeds()) ] for x in range(self.device.getNumberOfLeds())]
def __init__(self): # initializations self.device = None self.colorCalculator = ColorCalculator() self.basisColor = ORANGE self.binaryClockColor = WHITE self.basisLightness = 0.50 self.binaryClockLightness = 1 # value predefinitions self.basisHue = 0 self.basisSaturation = 1 self.basisRedChannel = 0 self.basisGreenChannel = 0 self.basisBlueChannel = 0 self.binaryClockColorRedChannel = 0 self.binaryClockColorGreenChannel = 0 self.binaryClockColorBlueChannel = 0 # calculate variations of initial color self.calculateVariationsOfBasisValues()
def __init__(self, device): # animation settings self.centerPositionX = 1 self.centerPositionY = 5 self.degreeOfColorDivergence = 30 self.distanceToDarkness = 3 self.speed = 0.01 self.iterationStep = 0 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.degreeFactor = 0 # construct array of precalculated values self.sinSummands = [ [0.0 for x in range(self.device.getNumberOfLeds())] for x in range(self.device.getNumberOfLeds()) ]
class ColorChange(IssetHelper): def __init__(self, device): # initializations self.device = device self.colors = ColorController self.colorCalculator = ColorCalculator() self.hueAdditionPerFrame = 0.0 # animation settings self.currentHueAddition = 0.0 self.speed = 10 def start(self): self.hueAdditionPerFrame = 0.00001 * (self.speed + 1) def renderNextFrame(self): (currentHue, saturation, lightness) = self.colors.getBasisColorAsHsl() targetHue = self.colorCalculator.correctHueValue( currentHue + self.hueAdditionPerFrame) self.colors.setBasisColorAsHsl(targetHue, saturation, lightness) (r, g, b) = self.colors.getBasisColorAsRgb() self.device.setRgbToBuffer(r, g, b) # ***** getter ********************************** def getAttributes(self): return { 'speed': self.speed } # ***** setter ********************************** def setAttributes(self, attributes): if self.isset(attributes, 'speed'): speed = self.saveIntConvert(attributes['speed']) if speed >= 0: self.speed = speed self.start()
class ColorChange(IssetHelper): def __init__(self, device): # initializations self.device = device self.colors = ColorController self.colorCalculator = ColorCalculator() self.hueAdditionPerFrame = 0.0 # animation settings self.currentHueAddition = 0.0 self.speed = 10 def start(self): self.hueAdditionPerFrame = 0.00001 * (self.speed + 1) def renderNextFrame(self): (currentHue, saturation, lightness) = self.colors.getBasisColorAsHsl() targetHue = self.colorCalculator.correctHueValue( currentHue + self.hueAdditionPerFrame) self.colors.setBasisColorAsHsl(targetHue, saturation, lightness) (r, g, b) = self.colors.getBasisColorAsRgb() self.device.setRgbToBuffer(r, g, b) # ***** getter ********************************** def getAttributes(self): return {'speed': self.speed} # ***** setter ********************************** def setAttributes(self, attributes): if self.isset(attributes, 'speed'): speed = self.saveIntConvert(attributes['speed']) if speed >= 0: self.speed = speed self.start()
class RandomGlowAnimation(IssetHelper): def __init__(self, device): # animation settings self.glowingPixelCount = 17 self.glowingPixelDegreeOfColorDivergence = 35 self.minimumSpeed = 50 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.randomGlowingPixels = {} self.sinFactorForHueAddition = 0 def start(self): # precalculate factor needed for every iteration self.sinFactorForHueAddition = ( (self.glowingPixelDegreeOfColorDivergence / 360) / 2) # initialize glowing pixels list for i in range(0, self.glowingPixelCount): self.randomGlowingPixels[i] = self.initializeRandomPixel() def renderNextFrame(self): for i in range(0, self.glowingPixelCount): glowingPixel = self.randomGlowingPixels[i] glowingPixel['xAxisPosition'] = glowingPixel['xAxisPosition'] + 1 if (glowingPixel['xAxisPosition'] / glowingPixel['speedFactor']) > (math.pi * 2): self.randomGlowingPixels[i] = self.initializeRandomPixel() else: # calculate new hue and lightness for current frame (hueAddition, lightnessFactor) = self.getColorForIteration( glowingPixel['xAxisPosition'], glowingPixel['speedFactor']) targetHue = self.colors.basisHue + hueAddition targetLightness = self.colors.basisLightness * lightnessFactor # apply new hue and lightness to frame-buffer (r, g, b) = self.colorCalculator.convertHslToRgb( targetHue, self.colors.basisSaturation, targetLightness) self.device.setRgbColorToBufferForLedWithIndex( r, g, b, glowingPixel['index']) def getColorForIteration(self, xAxisPosition, speedFactor): sinus = math.sin(xAxisPosition / speedFactor) hueAddition = sinus * self.sinFactorForHueAddition # probably manipulate this value to make more beautiful light lightnessFactor = sinus * 0.5 + 0.5 return (hueAddition, lightnessFactor) def initializeRandomPixel(self): randomIndex = random.randint(0, self.device.getNumberOfLeds() - 1) if not self.pixelIndexIsUsed(randomIndex): # set basis color to pixel # self.device.setRgbColorToBufferForLedWithIndex(self.colors.getBasisColorAsRgb(), randomIndex) # instantiate new pixel values for iterative color calculation speedFactor = random.randint( self.minimumSpeed, self.minimumSpeed * SPEED_MULTIPLICATOR) return { 'index': randomIndex, 'xAxisPosition': 0, 'speedFactor': speedFactor } else: return self.initializeRandomPixel() def pixelIndexIsUsed(self, index): if self.randomGlowingPixels == {}: return False for pixel in self.randomGlowingPixels: try: if pixel['index'] == index: return True except (TypeError): return False return False # ***** getter ********************************** def getAttributes(self): return { 'pixelCount': self.glowingPixelCount, 'speed': self.minimumSpeed, 'oscillation': self.glowingPixelDegreeOfColorDivergence } # ***** setter ********************************** def setAttributes(self, attributes): recalculationRequired = False if self.isset(attributes, 'pixelCount'): pixelCount = self.saveIntConvert(attributes['pixelCount']) if pixelCount > 0: self.glowingPixelCount = pixelCount recalculationRequired = True if self.isset(attributes, 'speed'): speed = self.saveIntConvert(attributes['speed']) if speed >= 0: self.minimumSpeed = speed if self.isset(attributes, 'oscillation'): oscillation = self.saveIntConvert(attributes['oscillation']) if oscillation >= 0 and oscillation <= 360: self.glowingPixelDegreeOfColorDivergence = oscillation recalculationRequired = True if recalculationRequired: self.start()
class DeviceController: def __init__(self, verbose, showUpdates): # initializations self.beVerbose = verbose self.dryRun = False self.colorCalculator = ColorCalculator() self.deviceConnected = False self.currentFrameCount = 0 self.targetTimePerFrame = 0.0 self.updateFrameTimestamp = datetime.datetime.now() self.asyncUpdateRateController = AsyncUpdateRateController( self, showUpdates) self.pixelMap = [ 42, 43, 44, 45, 46, 47, 48, 41, 20, 21, 22, 23, 24, 25, 40, 19, 18, 17, 16, 15, 26, 39, 10, 11, 12, 13, 14, 27, 38, 9, 8, 7, 6, 5, 28, 37, 0, 1, 2, 3, 4, 29, 36, 35, 34, 33, 32, 31, 30 ] # establish connection to device try: if not self.dryRun: self.serialConnection = serial.Serial( DEVICE_FILE, DEVICE_BAUDRATE) self.deviceConnected = True except serial.SerialException: print('can not connect to the Arduino; going on as dry run') self.dryRun = True # build header for buffer # unsigned char array, will transfered serially to the device self.buffer = array('B') # ASCII for 'A'; magic number self.buffer.append(65) # ASCII for 'd'; magic number self.buffer.append(100) # ASCII for 'a'; magic number self.buffer.append(97) # LED count high byte self.buffer.append((NUMBER_LEDS - 1) >> 8) # LED count low byte self.buffer.append((NUMBER_LEDS - 1) & 0xff) # checksum self.buffer.append((NUMBER_LEDS - 1) >> 8 ^ (NUMBER_LEDS - 1) & 0xff ^ 0x55) for _ in range(0, (NUMBER_LEDS * 3)): # fill up every channel of every LED with zeros self.buffer.append(255) # calculate max. useful frame rate which the serial bus can handle targetFPS = (DEVICE_BAUDRATE / 8) / sys.getsizeof(self.buffer) self.targetTimePerFrame = 1.0 / targetFPS # wait for initialization if not self.dryRun: if self.beVerbose: print('wait for Arduino to be initialized') sleep(5) # start frame rate controller self.asyncUpdateRateController.start() # ***** controller handling ********************************** def writeBuffer(self): if self.deviceConnected: # write to serial port if not self.dryRun: try: self.serialConnection.flushOutput() self.serialConnection.write(bytearray(self.buffer)) except serial.SerialException: exc_type, _, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print('\n', exc_type, fname, exc_tb.tb_lineno, '\nerror sending data to device! closing connection') self.closeConnection() exit() # increment counter for FPS calculation self.currentFrameCount = self.currentFrameCount + 1 # limit the frame rate to what the serial connection is capable of self.frameRateLimiter() def frameRateLimiter(self): # measure current time currentTimestamp = datetime.datetime.now() updateFrameTimeDelta = currentTimestamp - self.updateFrameTimestamp self.updateFrameTimestamp = datetime.datetime.now() frameCalculationTime = updateFrameTimeDelta.microseconds / 1000000 if frameCalculationTime > self.targetTimePerFrame: return compensateTime = self.targetTimePerFrame - frameCalculationTime sleep(compensateTime) def closeConnection(self): self.deviceConnected = False if not self.dryRun: self.serialConnection.close() if self.beVerbose: print('serial connection closed') def clearBuffer(self): for i in range(6, 6 + (NUMBER_LEDS * 3)): self.buffer[i] = 0 # ***** getters ********************************** def getNumberOfLeds(self): return NUMBER_LEDS def getCurrentFps(self): return self.asyncUpdateRateController.currentFPS def getRgbFromBufferWithIndex(self, index): bufferIndex = 6 + (index * 3) redChannel = self.buffer[bufferIndex] greenChannel = self.buffer[bufferIndex + 1] blueChannel = self.buffer[bufferIndex + 2] return (redChannel, greenChannel, blueChannel) def getRgbFromBufferWithCoordinates(self, xIndex, yIndex): return self.getRgbFromBufferWithIndex(xIndex + (yIndex * NUMBER_LED_ROWS)) # ***** setters ********************************** def setRgbColorToBufferForLedWithIndex(self, redChannel, greenChannel, blueChannel, ledIndex): ledAddress = 6 + (ledIndex * 3) self.buffer[ledAddress] = self.colorCalculator.frameRgbValue( redChannel) self.buffer[ ledAddress + 1] = self.colorCalculator.frameRgbValue(greenChannel) self.buffer[ ledAddress + 2] = self.colorCalculator.frameRgbValue(blueChannel) def setRgbColorToBufferForLedWithCoordinates(self, redChannel, greenChannel, blueChannel, xIndex, yIndex): alignedIndex = xIndex + (yIndex * NUMBER_LED_ROWS) self.setRgbColorToBufferForLedWithIndex( redChannel, greenChannel, blueChannel, self.pixelMap[alignedIndex] ) def setRgbToBuffer(self, redChannel, greenChannel, blueChannel): for i in range(6, (NUMBER_LEDS * 3 + 6), 3): self.buffer[i] = self.colorCalculator.frameRgbValue(redChannel) self.buffer[ i + 1] = self.colorCalculator.frameRgbValue(greenChannel) self.buffer[ i + 2] = self.colorCalculator.frameRgbValue(blueChannel)
class _ColorController: def __call__(self): return self def __init__(self): # initializations self.device = None self.colorCalculator = ColorCalculator() self.basisColor = ORANGE self.binaryClockColor = WHITE self.basisLightness = 0.50 self.binaryClockLightness = 1 # value predefinitions self.basisHue = 0 self.basisSaturation = 1 self.basisRedChannel = 0 self.basisGreenChannel = 0 self.basisBlueChannel = 0 self.binaryClockColorRedChannel = 0 self.binaryClockColorGreenChannel = 0 self.binaryClockColorBlueChannel = 0 # calculate variations of initial color self.calculateVariationsOfBasisValues() def setDeviceReference(self, device): self.device = device # ***** value calculation ********************************** def calculateVariationsOfBasisValues(self): self.calculateBasisColorValuesFomHex() self.calculateBinaryClockColorValuesFromHex() def calculateBasisColorValuesFomHex(self): (bHue, bSaturation, bLightness) = self.colorCalculator.convertHexColorToHSL( self.basisColor) (bR, bG, bB) = self.colorCalculator.convertHexColorToRgb(self.basisColor) self.basisHue = bHue self.basisSaturation = bSaturation self.basisLightness = bLightness self.basisRedChannel = bR self.basisGreenChannel = bG self.basisBlueChannel = bB def calculateBasisColorValuesFomRgb(self): self.basisColor = self.colorCalculator.convertRgbToHexColor( self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) (bHue, bSaturation, bLightness) = self.colorCalculator.convertRgbToHsl( self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) self.basisHue = bHue self.basisSaturation = bSaturation self.basisLightness = bLightness def calculateBasisColorValuesFomHsl(self): (bR, bG, bB) = self.colorCalculator.convertHslToRgb(self.basisHue, self.basisSaturation, self.basisLightness) self.basisColor = self.colorCalculator.convertRgbToHexColor(bR, bG, bB) self.basisRedChannel = bR self.basisGreenChannel = bG self.basisBlueChannel = bB def calculateBinaryClockColorValuesFromHex(self): (r, g, b) = self.colorCalculator.convertHexColorToRgb(self.binaryClockColor) self.binaryClockColorRedChannel = r self.binaryClockColorGreenChannel = g self.binaryClockColorBlueChannel = b def calculateBinaryClockColorValuesFomRgb(self): self.binaryClockColor = self.colorCalculator.convertRgbToHexColor( self.binaryClockColorRedChannel, self.binaryClockColorGreenChannel, self.binaryClockColorBlueChannel) # ***** getter ********************************** def getBasisColorAsHex(self): return self.colorCalculator.getHtmlHexStringFromRgbColor( self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) def getBasisColorAsRgb(self): return (self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) def getBasisColorAsHsl(self): return (self.basisHue, self.basisSaturation, self.basisLightness) def getBasisLightness(self): return self.basisLightness def getTotalLightness(self): numberOfLeds = self.device.getNumberOfLeds() totalLightness = 0 for i in range(0, numberOfLeds): r, g, b = self.device.getRgbFromBufferWithIndex(i) totalLightness += self.colorCalculator.convertRgbToLightness( r, g, b) return totalLightness / numberOfLeds # ***** setter ********************************** def setBasisColorAsHex(self, hexColor): self.basisColor = hexColor self.calculateBasisColorValuesFomHex() def setBasisColorAsRgb(self, redChannel, greenChannel, blueChannel): self.basisRedChannel = redChannel self.basisGreenChannel = greenChannel self.basisBlueChannel = blueChannel self.calculateBasisColorValuesFomRgb() def setBasisColorAsHsl(self, hue, saturation, lightness): self.basisHue = hue self.basisSaturation = saturation self.basisLightness = lightness self.calculateBasisColorValuesFomHsl() def setBinaryClockColorAsHex(self, hexColor): self.binaryClockColor = hexColor self.calculateBinaryClockColorValuesFromHex() def setBinaryClockColorAsRgb(self, redChannel, greenChannel, blueChannel): self.binaryClockColorRedChannel = redChannel self.binaryClockColorGreenChannel = greenChannel self.binaryClockColorBlueChannel = blueChannel self.calculateBinaryClockColorValuesFomRgb() def setBasisLightness(self, lightness): if lightness > 1: lightness = 1 elif lightness < 0: lightness = 0 self.basisLightness = lightness self.setBasisColorAsHsl(self.basisHue, self.basisSaturation, lightness) def setBinaryClockLightness(self, lightness): if lightness > 1: lightness = 1 elif lightness < 0: lightness = 0 self.binaryClockLightness = lightness self.setBinaryClockColorAsHex( self.colorCalculator.setBrightnessToHexColor( self.binaryClockColor, lightness))
class DeviceController: def __init__(self, verbose, showUpdates): # initializations self.beVerbose = verbose self.dryRun = False self.colorCalculator = ColorCalculator() self.deviceConnected = False self.currentFrameCount = 0 self.targetTimePerFrame = 0.0 self.updateFrameTimestamp = datetime.datetime.now() self.asyncUpdateRateController = AsyncUpdateRateController( self, showUpdates) self.pixelMap = [ 42, 43, 44, 45, 46, 47, 48, 41, 20, 21, 22, 23, 24, 25, 40, 19, 18, 17, 16, 15, 26, 39, 10, 11, 12, 13, 14, 27, 38, 9, 8, 7, 6, 5, 28, 37, 0, 1, 2, 3, 4, 29, 36, 35, 34, 33, 32, 31, 30 ] # establish connection to device try: if not self.dryRun: self.serialConnection = serial.Serial(DEVICE_FILE, DEVICE_BAUDRATE) self.deviceConnected = True except serial.SerialException: print('can not connect to the Arduino; going on as dry run') self.dryRun = True # build header for buffer # unsigned char array, will transfered serially to the device self.buffer = array('B') # ASCII for 'A'; magic number self.buffer.append(65) # ASCII for 'd'; magic number self.buffer.append(100) # ASCII for 'a'; magic number self.buffer.append(97) # LED count high byte self.buffer.append((NUMBER_LEDS - 1) >> 8) # LED count low byte self.buffer.append((NUMBER_LEDS - 1) & 0xff) # checksum self.buffer.append((NUMBER_LEDS - 1) >> 8 ^ (NUMBER_LEDS - 1) & 0xff ^ 0x55) for _ in range(0, (NUMBER_LEDS * 3)): # fill up every channel of every LED with zeros self.buffer.append(255) # calculate max. useful frame rate which the serial bus can handle targetFPS = (DEVICE_BAUDRATE / 8) / sys.getsizeof(self.buffer) self.targetTimePerFrame = 1.0 / targetFPS # wait for initialization if not self.dryRun: if self.beVerbose: print('wait for Arduino to be initialized') sleep(5) # start frame rate controller self.asyncUpdateRateController.start() # ***** controller handling ********************************** def writeBuffer(self): if self.deviceConnected: # write to serial port if not self.dryRun: try: self.serialConnection.flushOutput() self.serialConnection.write(bytearray(self.buffer)) except serial.SerialException: exc_type, _, exc_tb = sys.exc_info() fname = os.path.split( exc_tb.tb_frame.f_code.co_filename)[1] print( '\n', exc_type, fname, exc_tb.tb_lineno, '\nerror sending data to device! closing connection') self.closeConnection() exit() # increment counter for FPS calculation self.currentFrameCount = self.currentFrameCount + 1 # limit the frame rate to what the serial connection is capable of self.frameRateLimiter() def frameRateLimiter(self): # measure current time currentTimestamp = datetime.datetime.now() updateFrameTimeDelta = currentTimestamp - self.updateFrameTimestamp self.updateFrameTimestamp = datetime.datetime.now() frameCalculationTime = updateFrameTimeDelta.microseconds / 1000000 if frameCalculationTime > self.targetTimePerFrame: return compensateTime = self.targetTimePerFrame - frameCalculationTime sleep(compensateTime) def closeConnection(self): self.deviceConnected = False if not self.dryRun: self.serialConnection.close() if self.beVerbose: print('serial connection closed') def clearBuffer(self): for i in range(6, 6 + (NUMBER_LEDS * 3)): self.buffer[i] = 0 # ***** getters ********************************** def getNumberOfLeds(self): return NUMBER_LEDS def getCurrentFps(self): return self.asyncUpdateRateController.currentFPS def getRgbFromBufferWithIndex(self, index): bufferIndex = 6 + (index * 3) redChannel = self.buffer[bufferIndex] greenChannel = self.buffer[bufferIndex + 1] blueChannel = self.buffer[bufferIndex + 2] return (redChannel, greenChannel, blueChannel) def getRgbFromBufferWithCoordinates(self, xIndex, yIndex): return self.getRgbFromBufferWithIndex(xIndex + (yIndex * NUMBER_LED_ROWS)) # ***** setters ********************************** def setRgbColorToBufferForLedWithIndex(self, redChannel, greenChannel, blueChannel, ledIndex): ledAddress = 6 + (ledIndex * 3) self.buffer[ledAddress] = self.colorCalculator.frameRgbValue( redChannel) self.buffer[ledAddress + 1] = self.colorCalculator.frameRgbValue(greenChannel) self.buffer[ledAddress + 2] = self.colorCalculator.frameRgbValue(blueChannel) def setRgbColorToBufferForLedWithCoordinates(self, redChannel, greenChannel, blueChannel, xIndex, yIndex): alignedIndex = xIndex + (yIndex * NUMBER_LED_ROWS) self.setRgbColorToBufferForLedWithIndex(redChannel, greenChannel, blueChannel, self.pixelMap[alignedIndex]) def setRgbToBuffer(self, redChannel, greenChannel, blueChannel): for i in range(6, (NUMBER_LEDS * 3 + 6), 3): self.buffer[i] = self.colorCalculator.frameRgbValue(redChannel) self.buffer[i + 1] = self.colorCalculator.frameRgbValue(greenChannel) self.buffer[i + 2] = self.colorCalculator.frameRgbValue(blueChannel)
class PulsingCircleAnimation(IssetHelper): def __init__(self, device): # animation settings self.centerPositionX = 1 self.centerPositionY = 5 self.degreeOfColorDivergence = 30 self.distanceToDarkness = 3 self.speed = 0.01 self.iterationStep = 0 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.degreeFactor = 0 # construct array of precalculated values self.sinSummands = [ [0.0 for x in range(self.device.getNumberOfLeds())] for x in range(self.device.getNumberOfLeds()) ] def start(self): # precalculated values self.degreeFactor = (self.degreeOfColorDivergence / 360) / 2 # calculate values for each pixel position for i in range(0, self.device.getNumberOfLeds()): for j in range(0, self.device.getNumberOfLeds()): x = i - self.centerPositionX y = j - self.centerPositionY self.sinSummands[i][j] = (math.sqrt((x * x) + (y * y)) * math.pi) / self.distanceToDarkness def renderNextFrame(self): # handle iteration counting and limit it to maxint if self.iterationStep < MAX_INT: self.iterationStep = self.iterationStep + 1 else: self.iterationStep = 0 for x in range(0, 7): for y in range(0, 7): # calculate new hue and lightness for current frame (hueAddition, lightnessFactor) = self.getColorForCoordinates(x, y) targetHue = self.colors.basisHue + hueAddition targetLightness = self.colors.basisLightness * lightnessFactor # apply new hue and lightness to frame-buffer (r, g, b) = self.colorCalculator.convertHslToRgb( targetHue, self.colors.basisSaturation, targetLightness ) self.device.setRgbColorToBufferForLedWithCoordinates(r, g, b, x, y) # ***** getter ********************************** def getColorForCoordinates(self, x, y): intensity = math.sin(self.sinSummands[x][y] - (self.iterationStep * self.speed)) newHue = intensity * self.degreeFactor newLightness = (intensity * 0.5) + 0.5 return (newHue, newLightness) def getAttributes(self): return { "size": self.distanceToDarkness, "speed": self.speed, "oscillation": self.degreeOfColorDivergence, "posX": self.centerPositionX, "posY": self.centerPositionY, } # ***** setter ********************************** def setAttributes(self, attributes): recalculationRequired = False if self.isset(attributes, "size"): size = self.saveFloatConvert(attributes["size"]) if size > 0: self.distanceToDarkness = size recalculationRequired = True if self.isset(attributes, "speed"): speed = self.saveFloatConvert(attributes["speed"]) if speed >= 0: self.speed = speed if self.isset(attributes, "oscillation"): oscillation = self.saveIntConvert(attributes["oscillation"]) if oscillation >= 0 and oscillation <= 360: self.degreeOfColorDivergence = oscillation recalculationRequired = True if self.isset(attributes, "posX"): posX = self.saveFloatConvert(attributes["posX"]) if posX >= 0 and posX <= 6: self.centerPositionX = posX recalculationRequired = True if self.isset(attributes, "posY"): posY = self.saveFloatConvert(attributes["posY"]) if posY >= 0 and posY <= 6: self.centerPositionY = posY recalculationRequired = True if recalculationRequired: self.start()
class _ColorController: def __call__(self): return self def __init__(self): # initializations self.device = None self.colorCalculator = ColorCalculator() self.basisColor = ORANGE self.binaryClockColor = WHITE self.basisLightness = 0.50 self.binaryClockLightness = 1 # value predefinitions self.basisHue = 0 self.basisSaturation = 1 self.basisRedChannel = 0 self.basisGreenChannel = 0 self.basisBlueChannel = 0 self.binaryClockColorRedChannel = 0 self.binaryClockColorGreenChannel = 0 self.binaryClockColorBlueChannel = 0 # calculate variations of initial color self.calculateVariationsOfBasisValues() def setDeviceReference(self, device): self.device = device # ***** value calculation ********************************** def calculateVariationsOfBasisValues(self): self.calculateBasisColorValuesFomHex() self.calculateBinaryClockColorValuesFromHex() def calculateBasisColorValuesFomHex(self): (bHue, bSaturation, bLightness) = self.colorCalculator.convertHexColorToHSL(self.basisColor) (bR, bG, bB) = self.colorCalculator.convertHexColorToRgb(self.basisColor) self.basisHue = bHue self.basisSaturation = bSaturation self.basisLightness = bLightness self.basisRedChannel = bR self.basisGreenChannel = bG self.basisBlueChannel = bB def calculateBasisColorValuesFomRgb(self): self.basisColor = self.colorCalculator.convertRgbToHexColor(self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) (bHue, bSaturation, bLightness) = self.colorCalculator.convertRgbToHsl(self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) self.basisHue = bHue self.basisSaturation = bSaturation self.basisLightness = bLightness def calculateBasisColorValuesFomHsl(self): (bR, bG, bB) = self.colorCalculator.convertHslToRgb(self.basisHue, self.basisSaturation, self.basisLightness) self.basisColor = self.colorCalculator.convertRgbToHexColor(bR, bG, bB) self.basisRedChannel = bR self.basisGreenChannel = bG self.basisBlueChannel = bB def calculateBinaryClockColorValuesFromHex(self): (r, g, b) = self.colorCalculator.convertHexColorToRgb(self.binaryClockColor) self.binaryClockColorRedChannel = r self.binaryClockColorGreenChannel = g self.binaryClockColorBlueChannel = b def calculateBinaryClockColorValuesFomRgb(self): self.binaryClockColor = self.colorCalculator.convertRgbToHexColor(self.binaryClockColorRedChannel, self.binaryClockColorGreenChannel, self.binaryClockColorBlueChannel) # ***** getter ********************************** def getBasisColorAsHex(self): return self.colorCalculator.getHtmlHexStringFromRgbColor(self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) def getBasisColorAsRgb(self): return (self.basisRedChannel, self.basisGreenChannel, self.basisBlueChannel) def getBasisColorAsHsl(self): return (self.basisHue, self.basisSaturation, self.basisLightness) def getBasisLightness(self): return self.basisLightness def getTotalLightness(self): numberOfLeds = self.device.getNumberOfLeds() totalLightness = 0 for i in range(0, numberOfLeds): r, g, b = self.device.getRgbFromBufferWithIndex(i) totalLightness += self.colorCalculator.convertRgbToLightness(r, g, b) return totalLightness / numberOfLeds # ***** setter ********************************** def setBasisColorAsHex(self, hexColor): self.basisColor = hexColor self.calculateBasisColorValuesFomHex() def setBasisColorAsRgb(self, redChannel, greenChannel, blueChannel): self.basisRedChannel = redChannel self.basisGreenChannel = greenChannel self.basisBlueChannel = blueChannel self.calculateBasisColorValuesFomRgb() def setBasisColorAsHsl(self, hue, saturation, lightness): self.basisHue = hue self.basisSaturation = saturation self.basisLightness = lightness self.calculateBasisColorValuesFomHsl() def setBinaryClockColorAsHex(self, hexColor): self.binaryClockColor = hexColor self.calculateBinaryClockColorValuesFromHex() def setBinaryClockColorAsRgb(self, redChannel, greenChannel, blueChannel): self.binaryClockColorRedChannel = redChannel self.binaryClockColorGreenChannel = greenChannel self.binaryClockColorBlueChannel = blueChannel self.calculateBinaryClockColorValuesFomRgb() def setBasisLightness(self, lightness): if lightness > 1: lightness = 1 elif lightness < 0: lightness = 0 self.basisLightness = lightness self.setBasisColorAsHsl(self.basisHue, self.basisSaturation, lightness) def setBinaryClockLightness(self, lightness): if lightness > 1: lightness = 1 elif lightness < 0: lightness = 0 self.binaryClockLightness = lightness self.setBinaryClockColorAsHex(self.colorCalculator.setBrightnessToHexColor(self.binaryClockColor, lightness))
class PulsingCircleAnimation(IssetHelper): def __init__(self, device): # animation settings self.centerPositionX = 1 self.centerPositionY = 5 self.degreeOfColorDivergence = 30 self.distanceToDarkness = 3 self.speed = 0.01 self.iterationStep = 0 # initializations self.colorCalculator = ColorCalculator() self.colors = ColorController self.device = device self.degreeFactor = 0 # construct array of precalculated values self.sinSummands = [[ 0.0 for x in range(self.device.getNumberOfLeds()) ] for x in range(self.device.getNumberOfLeds())] def start(self): # precalculated values self.degreeFactor = ((self.degreeOfColorDivergence / 360) / 2) # calculate values for each pixel position for i in range(0, self.device.getNumberOfLeds()): for j in range(0, self.device.getNumberOfLeds()): x = i - self.centerPositionX y = j - self.centerPositionY self.sinSummands[i][j] = (math.sqrt((x * x) + (y * y)) * math.pi) / self.distanceToDarkness def renderNextFrame(self): # handle iteration counting and limit it to maxint if self.iterationStep < MAX_INT: self.iterationStep = self.iterationStep + 1 else: self.iterationStep = 0 for x in range(0, 7): for y in range(0, 7): # calculate new hue and lightness for current frame (hueAddition, lightnessFactor) = self.getColorForCoordinates(x, y) targetHue = self.colors.basisHue + hueAddition targetLightness = self.colors.basisLightness * lightnessFactor # apply new hue and lightness to frame-buffer (r, g, b) = self.colorCalculator.convertHslToRgb( targetHue, self.colors.basisSaturation, targetLightness) self.device.setRgbColorToBufferForLedWithCoordinates( r, g, b, x, y) # ***** getter ********************************** def getColorForCoordinates(self, x, y): intensity = math.sin(self.sinSummands[x][y] - (self.iterationStep * self.speed)) newHue = intensity * self.degreeFactor newLightness = (intensity * 0.5) + 0.5 return (newHue, newLightness) def getAttributes(self): return { 'size': self.distanceToDarkness, 'speed': self.speed, 'oscillation': self.degreeOfColorDivergence, 'posX': self.centerPositionX, 'posY': self.centerPositionY } # ***** setter ********************************** def setAttributes(self, attributes): recalculationRequired = False if self.isset(attributes, 'size'): size = self.saveFloatConvert(attributes['size']) if size > 0: self.distanceToDarkness = size recalculationRequired = True if self.isset(attributes, 'speed'): speed = self.saveFloatConvert(attributes['speed']) if speed >= 0: self.speed = speed if self.isset(attributes, 'oscillation'): oscillation = self.saveIntConvert(attributes['oscillation']) if oscillation >= 0 and oscillation <= 360: self.degreeOfColorDivergence = oscillation recalculationRequired = True if self.isset(attributes, 'posX'): posX = self.saveFloatConvert(attributes['posX']) if posX >= 0 and posX <= 6: self.centerPositionX = posX recalculationRequired = True if self.isset(attributes, 'posY'): posY = self.saveFloatConvert(attributes['posY']) if posY >= 0 and posY <= 6: self.centerPositionY = posY recalculationRequired = True if recalculationRequired: self.start()