Add python led programs
This commit is contained in:
94
pyleds/lib/FakeStrip.py
Normal file
94
pyleds/lib/FakeStrip.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from rpi_ws281x import PixelStrip
|
||||
import atexit
|
||||
|
||||
|
||||
class _LedData(object):
|
||||
_led: []
|
||||
|
||||
def __init__(self, channel, size):
|
||||
self.size = size
|
||||
self.channel = channel
|
||||
|
||||
def __getitem__(self, pos):
|
||||
"""Return the 24-bit RGB color value at the provided position or slice
|
||||
of positions.
|
||||
"""
|
||||
# Handle if a slice of positions are passed in by grabbing all the values
|
||||
# and returning them in a list.
|
||||
if isinstance(pos, slice):
|
||||
return [self._led[n] for n in range(*pos.indices(self.size))]
|
||||
# Else assume the passed in value is a number to the position.
|
||||
else:
|
||||
return self._led[pos]
|
||||
|
||||
def __setitem__(self, pos, value):
|
||||
"""Set the 24-bit RGB color value at the provided position or slice of
|
||||
positions.
|
||||
"""
|
||||
# Handle if a slice of positions are passed in by setting the appropriate
|
||||
# LED data values to the provided values.
|
||||
if isinstance(pos, slice):
|
||||
index = 0
|
||||
for n in range(*pos.indices(self.size)):
|
||||
self._led[n] = value[index]
|
||||
index += 1
|
||||
# Else assume the passed in value is a number to the position.
|
||||
# else:
|
||||
self._led[pos] = value
|
||||
|
||||
|
||||
class FakeStrip(PixelStrip):
|
||||
_brightness: int
|
||||
|
||||
def __init__(self, num, pin, freq_hz=800000, dma=10, invert=False,
|
||||
brightness=255, channel=0, strip_type=None, gamma=None):
|
||||
|
||||
if gamma is None:
|
||||
# Support gamma in place of strip_type for back-compat with
|
||||
# previous version of forked library
|
||||
if type(strip_type) is list and len(strip_type) == 256:
|
||||
gamma = strip_type
|
||||
# strip_type = None
|
||||
else:
|
||||
gamma = list(range(256))
|
||||
|
||||
# Initialize the channel in use
|
||||
self._channel = None
|
||||
self._gamma = gamma
|
||||
self._brightness = brightness
|
||||
|
||||
# Grab the led data array.
|
||||
self._led_data = _LedData(self._channel, num)
|
||||
|
||||
# Substitute for __del__, traps an exit condition and cleans up properly
|
||||
atexit.register(self._cleanup)
|
||||
|
||||
def _cleanup(self):
|
||||
# Clean up memory used by the library when not needed anymore.
|
||||
if self._channel is not None:
|
||||
self._channel = None
|
||||
|
||||
def setGamma(self, gamma):
|
||||
if type(gamma) is list and len(gamma) == 256:
|
||||
self._gamma = gamma
|
||||
|
||||
def begin(self):
|
||||
"""Initialize library, must be called once before other functions are called."""
|
||||
return
|
||||
|
||||
def show(self):
|
||||
"""Update the display with the data from the LED buffer."""
|
||||
return # render
|
||||
|
||||
def getBrightness(self) -> int:
|
||||
return self._brightness
|
||||
|
||||
def setBrightness(self, brightness: int):
|
||||
"""Scale each LED in the buffer by the provided brightness.
|
||||
A brightness of 0 is the darkest and 255 is the brightest.
|
||||
"""
|
||||
self._brightness = brightness
|
||||
|
||||
def numPixels(self):
|
||||
"""Return the number of pixels in the display."""
|
||||
return self._led_data.size
|
||||
33
pyleds/lib/Litsimaja.py
Normal file
33
pyleds/lib/Litsimaja.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from rpi_ws281x import PixelStrip
|
||||
from lib.FakeStrip import FakeStrip
|
||||
from lib.LoopSwitch import LoopSwitch
|
||||
|
||||
|
||||
class Litsimaja(object):
|
||||
_strip: PixelStrip
|
||||
_loops: []
|
||||
|
||||
def __init__(self):
|
||||
self._strip = FakeStrip(290, 18, 800000, 10, False, 255, 0, 4104)
|
||||
self._loops = []
|
||||
self._strip.begin()
|
||||
|
||||
def count_pixels(self) -> int:
|
||||
return self._strip.numPixels()
|
||||
|
||||
def get_strip(self) -> PixelStrip:
|
||||
return self._strip
|
||||
|
||||
def set_pixel_color(self, n: int, color: int) -> None:
|
||||
self._strip.setPixelColor(n, color)
|
||||
|
||||
def show(self) -> None:
|
||||
self._strip.show()
|
||||
|
||||
def add_loop(self, loop: LoopSwitch):
|
||||
self._loops.append(loop)
|
||||
|
||||
def clear_loops(self):
|
||||
for loop in self._loops:
|
||||
loop.stop()
|
||||
self._loops.clear()
|
||||
11
pyleds/lib/LoopSwitch.py
Normal file
11
pyleds/lib/LoopSwitch.py
Normal file
@@ -0,0 +1,11 @@
|
||||
class LoopSwitch(object):
|
||||
_run: bool
|
||||
|
||||
def __init__(self):
|
||||
self._run = True
|
||||
|
||||
def stop(self):
|
||||
self._run = False
|
||||
|
||||
def status(self) -> bool:
|
||||
return self._run
|
||||
17
pyleds/lib/Program.py
Normal file
17
pyleds/lib/Program.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from lib.Litsimaja import Litsimaja
|
||||
from lib.LoopSwitch import LoopSwitch
|
||||
|
||||
|
||||
class Program:
|
||||
_lm: Litsimaja
|
||||
_loop: LoopSwitch
|
||||
|
||||
def __init__(self, lm: Litsimaja):
|
||||
self._lm = lm
|
||||
self._loop = LoopSwitch()
|
||||
|
||||
def get_loop(self):
|
||||
return self._loop
|
||||
|
||||
def run(self, args: [] = None):
|
||||
pass
|
||||
40
pyleds/lib/ProgramLoading.py
Normal file
40
pyleds/lib/ProgramLoading.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from os import scandir
|
||||
from lib.Litsimaja import Litsimaja
|
||||
from lib.Program import Program
|
||||
|
||||
|
||||
def resolve(namespace: str, class_name: str):
|
||||
m_name = 'program.' + namespace + '.' + class_name
|
||||
module = __import__(m_name, None, None, [m_name])
|
||||
return module
|
||||
|
||||
|
||||
def run(namespace: str, class_name: str, lm: Litsimaja, logger, args: [] = None):
|
||||
module = resolve(namespace, class_name)
|
||||
loaded_class = getattr(module, class_name)
|
||||
program = loaded_class(lm)
|
||||
logger.info('Loaded "' + module.name() + '" from ' + namespace + '.' + class_name + ' with args: ' + repr(args))
|
||||
lm.add_loop(program.get_loop())
|
||||
program.run(args)
|
||||
|
||||
|
||||
def list_all(grouped: bool = False):
|
||||
all_programs = []
|
||||
programs = []
|
||||
for entry in scandir('program'):
|
||||
if entry.is_dir():
|
||||
for file in scandir('program/' + entry.name):
|
||||
if file.is_file() and file.name[-3:] == '.py':
|
||||
try:
|
||||
program_name = file.name[: -3]
|
||||
module = resolve(entry.name, program_name)
|
||||
if hasattr(module, program_name) and issubclass(getattr(module, program_name), Program):
|
||||
programs.append({'prg': entry.name + '.' + program_name, 'name': module.name()})
|
||||
except AttributeError:
|
||||
continue
|
||||
if grouped and len(programs) > 0:
|
||||
all_programs.append({'group': entry.name, 'programs': programs})
|
||||
programs = []
|
||||
if not grouped:
|
||||
all_programs = programs
|
||||
return all_programs
|
||||
Reference in New Issue
Block a user