Add python led programs

This commit is contained in:
siinus
2020-11-08 01:47:25 +02:00
parent 1fc4303ae2
commit 103a5c9252
11 changed files with 3586 additions and 0 deletions

94
pyleds/lib/FakeStrip.py Normal file
View 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
View 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
View 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
View 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

View 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