summaryrefslogtreecommitdiff
path: root/ledctl
diff options
context:
space:
mode:
authorIngar <ingar@telenet.be>2022-02-27 11:57:52 +0100
committerIngar <ingar@telenet.be>2022-02-27 11:57:52 +0100
commitec67080ce93e16fa838a83cc3968bbbe3bc6d485 (patch)
tree88beb9312a6c34712e3b9b18d0d96726ce4a8996 /ledctl
parent7902738ef38e30c5275feee2fec78d3c39ff7c93 (diff)
Preparing the repository to hold all charmpi tools.
Diffstat (limited to 'ledctl')
-rw-r--r--ledctl/Makefile5
-rw-r--r--ledctl/README.md21
-rw-r--r--ledctl/ledctl.py132
-rw-r--r--ledctl/systemd/led-boot.service10
-rw-r--r--ledctl/systemd/led-ready.service10
5 files changed, 178 insertions, 0 deletions
diff --git a/ledctl/Makefile b/ledctl/Makefile
new file mode 100644
index 0000000..2777bb8
--- /dev/null
+++ b/ledctl/Makefile
@@ -0,0 +1,5 @@
+install:
+ install -m 744 ledctl.py /usr/bin/ledctl
+ ln -sf /usr/bin/ledctl /usr/lib/systemd/system-shutdown/
+ install -m 644 systemd/led-boot.service /etc/systemd/system/led-boot.service
+ install -m 644 systemd/led-ready.service /etc/systemd/system/led-ready.service
diff --git a/ledctl/README.md b/ledctl/README.md
new file mode 100644
index 0000000..30c8b8a
--- /dev/null
+++ b/ledctl/README.md
@@ -0,0 +1,21 @@
+# ledctl
+
+A simple Python script to control a WS2812B LED or LED strip connected to a rasperry pi.
+systemd services are included to set the LED color depending on the current boot status.
+
+## Prerequisites
+
+Python 3
+The AdaFruit CircuitPython NeoPixel library
+
+## Configuration
+
+Blacklist the snd_bcm2835 module
+Edit /boot/config.txt and comment out dtparam=audio=on
+
+## Installation
+
+```
+sudo make install
+```
+
diff --git a/ledctl/ledctl.py b/ledctl/ledctl.py
new file mode 100644
index 0000000..da42efa
--- /dev/null
+++ b/ledctl/ledctl.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+
+import argparse
+import board
+import neopixel
+import time
+
+from os.path import exists
+
+# parse command line arguments
+
+# TODO parse multiple LEDs e.g. ./ledctl --led 1 red --led 2 white
+
+parser = argparse.ArgumentParser(description='Set LED colors')
+
+parser.add_argument('--led', type=int, help='LED number to control, starting at 1')
+parser.add_argument('color', type=str, help='color or command')
+
+args = parser.parse_args();
+
+# initialize LED array
+leds_max = 1
+leds_num = 0
+leds_array = neopixel.NeoPixel(board.D18, leds_max)
+
+# restore LED array from state file
+statefile = '/tmp/ledctl.state'
+
+if exists(statefile):
+ #print('reading ' + statefile)
+
+ with open(statefile, 'r') as f:
+ lines = f.readlines()
+ i = 0;
+ for line in lines:
+ values = [ int(number) for number in line.rstrip().split(' ')]
+ if (i < leds_max):
+ leds_array[i] = (values[0], values[1], values[2]);
+ i = i + 1
+ f.close()
+
+# figure out if we want to control a single LED or all of them
+if args.led:
+ if (args.led < 1) or (args.led > leds_max):
+ parser.error("led must be within range")
+ else:
+ leds_num = args.led;
+
+# default color is white
+leds_color = (255, 255, 255)
+
+def rgbval(colorname):
+ switch = {
+ 'on': (255, 255, 255),
+ 'off': (0, 0, 0),
+ 'white': (255, 255, 255),
+ 'black': (0, 0, 0),
+ 'red': (255, 0, 0),
+ 'green': (0, 255, 0),
+ 'blue': (0, 0, 255),
+ 'yellow': (255, 255, 0),
+ 'cyan': (0, 255, 255),
+ 'pink': (255, 0, 255),
+ 'boot': (63, 15, 0),
+ 'reboot' : (63, 15, 0),
+ 'ready': (0, 15, 0),
+ 'halt' : (0, 0, 0),
+ 'poweroff' : (0, 0, 0),
+ 'kexec' : (63, 0, 63),
+ }
+ return switch.get(colorname, (255, 255, 255))
+
+def hexval(letter):
+ switch = {
+ '0': 0,
+ '1': 1,
+ '2': 2,
+ '3': 3,
+ '4': 4,
+ '5': 5,
+ '6': 6,
+ '7': 7,
+ '8': 8,
+ '9': 9,
+ 'A': 10,
+ 'a': 10,
+ 'B': 11,
+ 'b': 11,
+ 'C': 12,
+ 'c': 12,
+ 'D': 13,
+ 'd': 13,
+ 'E': 14,
+ 'e': 14,
+ 'F': 15,
+ 'f': 15,
+ }
+ return switch.get(letter, 0)
+
+if args.color:
+ #print('color ' + args.color)
+ if args.color[:1] == '#':
+ red = 16 * hexval(args.color[1:2]) + hexval(args.color[2:3]);
+ green = 16 * hexval(args.color[3:4]) + hexval(args.color[4:5]);
+ blue = 16 * hexval(args.color[5:6]) + hexval(args.color[6:7]);
+ leds_color = (red, green, blue);
+ #print ('color %d %d %d' % leds_color)
+
+ else:
+ leds_color = rgbval(args.color);
+
+if (leds_num > 0):
+ #print('setting LED %d' % leds_num)
+
+ leds_array[leds_num - 1] = leds_color
+else:
+ #print('setting all LEDs')
+
+ leds_array.fill(leds_color)
+
+# write LED array to state file
+
+#print('writing ' + statefile)
+
+with open(statefile, 'w') as f:
+ for i in range(leds_max):
+ for c in range(3):
+ f.write ('%d ' % leds_array[i][c])
+ f.write('\n');
+
+ f.close()
+
diff --git a/ledctl/systemd/led-boot.service b/ledctl/systemd/led-boot.service
new file mode 100644
index 0000000..2414c8f
--- /dev/null
+++ b/ledctl/systemd/led-boot.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=ledctl to indicate boot in progress status.
+After=local-fs.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/ledctl boot
+
+[Install]
+WantedBy=multi-user.target
diff --git a/ledctl/systemd/led-ready.service b/ledctl/systemd/led-ready.service
new file mode 100644
index 0000000..1dc62e9
--- /dev/null
+++ b/ledctl/systemd/led-ready.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=ledctl indicate ready status
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/ledctl ready
+
+[Install]
+WantedBy=graphical.target