Quantcast
Channel: Moorescloud Dev Blog
Viewing all articles
Browse latest Browse all 34

A bit of NYE colour for Holiday!

$
0
0

Here’s a small Python program that uses the SecretAPI to send a stream of randomly coloured lights scrolling down your Holiday.

Usage: python nye.py ip-address-of-holiday optional-frame-rate

And here’s the code.  Copy and paste it in and have fun!

#!/usr/bin/python
#
"""
Holiday class implementation for the Secret API for Holiday by Moorescloud

Homepage and documentation: http://mooresclouddev.markpesce.com/

Copyright (c) 2013, Mark Pesce.
License: MIT (see LICENSE for details)
"""

__author__ = 'Mark Pesce'
__version__ = '1.0b4'
__license__ = 'MIT'

import sys, array, socket

class HolidaySecretAPI:

	NUM_GLOBES = 50

	# Storage for all 50 globe values
	# 
	globes = [ [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00] ]

	def __init__(self, addr=''):
		"""If remote, you better supply a valid address.  
		We'll throw an exception when you don't do this."""
		self.addr = addr    # IP address we're chatting with.
		self.port = 9988	# Secret API port
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP

	def setglobe(self, globenum, r, g, b):
		"""Set a globe"""
		if (globenum < 0) or (globenum >= self.NUM_GLOBES):
			return
		self.globes[globenum][0] = r
		self.globes[globenum][1] = g
		self.globes[globenum][2] = b

	def fill(self, r, g, b):
		"""Sets the whole string to a particular colour"""
		for e in self.globes:
			e[0] = int(r)
			e[1] = int(g)
			e[2] = int(b)

	def getglobe(self, globenum):
		"""Return a tuple representing a globe's RGB color value"""
		if (globenum < 0) or (globenum >= self.NUM_GLOBES):
			return False
		return (self.globes[globenum][0], self.globes[globenum][1], self.globes[globenum][2])

	def chase(self, direction="True"):
		"""Rotate all of the globes around - up if TRUE, down if FALSE"""
		return

	def rotate(self, newr, newg, newb, direction="True"):
		if direction == "True":
			for i in range(1, self.NUM_GLOBES):
				self.globes[self.NUM_GLOBES - i][0] = self.globes[self.NUM_GLOBES - (i+1)][0]
				self.globes[self.NUM_GLOBES - i][1] = self.globes[self.NUM_GLOBES - (i+1)][1]
				self.globes[self.NUM_GLOBES - i][2] = self.globes[self.NUM_GLOBES - (i+1)][2]
			self.setglobe(0, newr, newg, newb)
			return
		else:
			return		

		"""Rotate all of the globes up if TRUE, down if FALSE
		   Set the new start of the string to the color values"""
		return

	def render(self):
		"""The render routine sends out a UDP packet using the SecretAPI"""
		# Create the 160-byte array of data
		packet = array.array('B', [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])  # initialize basic packet, ignore first 10 bytes
		for g in self.globes:
			packet.append(g[0])
			packet.append(g[1])
			packet.append(g[2])

		# Send the packet to the Holiday
		self.sock.sendto(packet, (self.addr, self.port))
		return

# Just some basic testerating from the command linery
#
if __name__ == '__main__':
	if len(sys.argv) > 1:
		hol = HolidaySecretAPI(addr=sys.argv[1])
	else:
		sys.exit(1)
	if len(sys.argv) > 2:
		fps = float(sys.argv[2])
	else:
		fps = 10.0
	rate = 1.0/fps
	import random, time
	clr = [0, 1, 2]
	while True:
		clr[0] = random.randint(0, 255)
		clr[1] = random.randint(0, 255)
		clr[2] = random.randint(0, 255)
		clr[random.randint(0,2)] = 0  # knock out one colour component for richness
		hol.rotate(clr[0], clr[1], clr[2])
		hol.render()
		time.sleep(rate)

Update: Had a little think about it, and added some interpolation code. Now the string generates a random colour and moves from that to another random colour in a smooth transition. Essentially it means the globes become a series of rainbow washes moving down the string.

Usage: python nyebow.py ip-of-holiday frames-per-second frames-per-transition (last two are optional and both default to 10)

#!/usr/bin/python
#
"""
Holiday class implementation for the Secret API for Holiday by Moorescloud

Homepage and documentation: http://mooresclouddev.markpesce.com/

Copyright (c) 2013, Mark Pesce.
License: MIT (see LICENSE for details)
"""

__author__ = 'Mark Pesce'
__version__ = '1.0b4'
__license__ = 'MIT'

import sys, array, socket

class HolidaySecretAPI:

	NUM_GLOBES = 50

	# Storage for all 50 globe values
	# 
	globes = [ [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00],
	[ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00], [ 0x00, 0x00, 0x00] ]

	def __init__(self, addr=''):
		"""If remote, you better supply a valid address.  
		We'll throw an exception when you don't do this."""
		self.addr = addr    # IP address we're chatting with.
		self.port = 9988	# Secret API port
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP

	def setglobe(self, globenum, r, g, b):
		"""Set a globe"""
		if (globenum < 0) or (globenum >= self.NUM_GLOBES):
			return
		self.globes[globenum][0] = r
		self.globes[globenum][1] = g
		self.globes[globenum][2] = b

	def fill(self, r, g, b):
		"""Sets the whole string to a particular colour"""
		for e in self.globes:
			e[0] = int(r)
			e[1] = int(g)
			e[2] = int(b)

	def getglobe(self, globenum):
		"""Return a tuple representing a globe's RGB color value"""
		if (globenum < 0) or (globenum >= self.NUM_GLOBES):
			return False
		return (self.globes[globenum][0], self.globes[globenum][1], self.globes[globenum][2])

	def chase(self, direction="True"):
		"""Rotate all of the globes around - up if TRUE, down if FALSE"""
		return

	def rotate(self, newr, newg, newb, direction="True"):
		if direction == "True":
			for i in range(1, self.NUM_GLOBES):
				self.globes[self.NUM_GLOBES - i][0] = self.globes[self.NUM_GLOBES - (i+1)][0]
				self.globes[self.NUM_GLOBES - i][1] = self.globes[self.NUM_GLOBES - (i+1)][1]
				self.globes[self.NUM_GLOBES - i][2] = self.globes[self.NUM_GLOBES - (i+1)][2]
			self.setglobe(0, newr, newg, newb)
			return
		else:
			return		

		"""Rotate all of the globes up if TRUE, down if FALSE
		   Set the new start of the string to the color values"""
		return

	def render(self):
		"""The render routine sends out a UDP packet using the SecretAPI"""
		# Create the 160-byte array of data
		packet = array.array('B', [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])  # initialize basic packet, ignore first 10 bytes
		for g in self.globes:
			packet.append(g[0])
			packet.append(g[1])
			packet.append(g[2])

		# Send the packet to the Holiday
		self.sock.sendto(packet, (self.addr, self.port))
		return

# Just some basic testerating from the command linery
#
if __name__ == '__main__':
	if len(sys.argv) > 1:
		hol = HolidaySecretAPI(addr=sys.argv[1])
	else:
		sys.exit(1)

	if len(sys.argv) > 2:
		fps = float(sys.argv[2])
	else:
		fps = 10.0
	rate = 1.0/fps

	if len(sys.argv) > 3:
		steps = int(sys.argv[3])
	else:
		steps = 10

	import random, time
	sclr = [ 0, 0, 0 ]
	eclr = [ 0, 0, 0 ]
	diff = [ 0.0, 0.0, 0.0 ]
	clr = [0, 1, 2]
	while True:

		# Copy the end colour to the start colour
		sclr[0] = eclr[0]
		sclr[1] = eclr[1]
		sclr[2] = eclr[2]

		# Generate a random colour end colour
		eclr[0] = random.randint(0, 255)
		eclr[1] = random.randint(0, 255)
		eclr[2] = random.randint(0, 255)
		eclr[random.randint(0,2)] = 0  # knock out one colour component for richness

		# Calculate the difference per frame
		diff[0] = float((eclr[0] - sclr[0]) / steps)
		diff[1] = float((eclr[1] - sclr[1]) / steps)
		diff[2] = float((eclr[2] - sclr[2]) / steps)

		for i in range(steps):
			r = int(sclr[0] + (diff[0] * i))
			if (r < 0): 				r = 0 			elif (r > 255):
				r = 255
			clr[0] = r
			g = int(sclr[1] + (diff[1] * i))
			if (g < 0): 				g = 0 			elif (g > 255):
				g = 255
			clr[1] = g
			b = int(sclr[2] + (diff[2] * i))
			if (b < 0): 				b = 0 			elif (b > 255):
				b = 255
			clr[2] = b

			hol.rotate(clr[0], clr[1], clr[2])
			hol.render()
			time.sleep(rate)

Have fun!


Viewing all articles
Browse latest Browse all 34

Latest Images

Trending Articles





Latest Images