Ansible tools for operating and managing fleets of Blinksticks in harmony using the Blinkstick Python library.

Overview

Blinkstick Ansible

deploy workflow

Much of the inspiration is from https://github.com/arvydas/blinkstick-python/wiki where some of the python snippets worked as-is and some did not. Some of the snippets are from Python 2.7 and wouldn't work on Python 3.X. I am using At least Python 3.8 for everything python related.

The reason for creating this repository was for me to have an easy way to operate 4 Blinkstick Nanos that I had bought for my raspberry pi kubernetes cluster. Having multiple nodes with separate Blinksticks, I wanted an abstraction layer on all four nodes that makes managing the configurations less monotonous. I have supplied several roles that can be executed against the blinksticks.

Install

Instructions

Get the following packages and materials on the machine executing Ansible. I am using 4 Blinkstick Nanos for this project, but any blinkstick should work.

Modify inventory/all.yaml with your own IP addresses and blinkstick serial numbers. Ensure that you have passwordless ssh setup to all nodes before proceeding with any Ansible configuration.

Example entry looks like...

node1: # name of the host. Arbitruary, it can be anything.
  ansible_host: 192.168.0.1 # IP address of the host
  serial: BS000001-3.0 # Run ansible-playbook main.yaml -t get-info to get this value for each node.

If you want to find the blinkstick serial numbers after mofifying the IP addresses, run the get-info tag. This saves you from logging into each node to find the serials.

Available Tags

tag description
get-info Collects all blinkstick information across all nodes. This includes serial numbers.
install Install all python packages defined in the python_packages list variable in main.yaml.
cpu-usage Monitors CPU usage using psutil and returns the appropriate color based on the percentage. This script runs indefinitely and checks every second.
internet-status When executed, a python script checks for internet access. If internet is up, color is green, if internet is down, color switches to purple.
aliases Used to create aliases that can be used directly in the command-line to execute the defined roles without knowing the full ansible-playbook command.
rave Executes a sequenece to perform a lightshow on all blinksticks.
off Turn all blinksticks off.
# Deploy everything !!
ansible-playbook main.yaml -t deploy
  # executes the following...
  # -t get-info
  # -t install
  # -t cpu-usage
  # -t internet-status
  # -t aliases

# Retrieve all Blinkstick information and serial number. Ensure the blinkstick is plugged into a USB slot before executing.
ansible-playbook main.yaml -t get-info

# Install all python library dependancies. Add or removes in the the python_packages list in main.yaml and re run this command to make the change on all nodes. 
ansible-playbook main.yaml -t install

# This roles uses the blinkstick python library to substitute the serial number from the ansible inventory and parse it as python. The script is then executed on the remote machines.
ansible-playbook main.yaml -t cpu-usage

# This roles uses the blinkstick python library to substitute the serial number from the ansible inventory and parse it as python. 
# A python script will continuously monitor the CPU percentage of the nodes and update the color accordingly.
ansible-playbook main.yaml -t internet-status

# Throw a party to celebrate getting everything installed.
ansible-playbook main.yaml -t rave

# Set the base color and brightness
ansible-playbook main.yaml -t base-config

# Or... pass the brightness and color inline using extra vars
ansible-playbook main.yaml -t base-config -e color=cyan -e brightness=50

# Turn all the Blinksticks off. (Useful for nighttime when you want to sleep. Use a cron to turn off automatically.)
ansible-playbook main.yaml -t off

# Creates aliases in either ~/.zprofile or ~/.bashrc, dynamically decided by the role.
ansible-playbook main.yaml -t aliases
  # The following aliases are added to either ~/.zprofile or ~/.bashrc....
  # blink-base
  # blink-day
  # blink-night
  # blink-rave
  # blink-off

Cron Scheduler

Add lines to the vars.crons section of cron.yaml to create cron jobs that execute locally on the machine running Ansible.

vars:
  crons:
    day:   { minute: '0', hour: '8',  weekday: '*',   disabled: 'no', tag: 'base-config', brightness: '70', color: 'green' }
    night: { minute: '0', hour: '21', weekday: '*',   disabled: 'no', tag: 'base-config', brightness: '20', color: 'cyan' }
    rave:  { minute: '0', hour: '17', weekday: 'FRI', disabled: 'no', tag: 'rave',        brightness: '80', color: 'cyan' }

To apply cron schedules from the root of the repository...

ansible-playbook cron.yaml

Troubleshooting

Blinkstick is having problems with python 3.9.2. I installed the latest version of Raspian (Debian Bullseye) and it ships with 3.9.2. On the other nodes, I was using <=3.8.2 so installed python 3.8.2 on Debian and got it to work using the steps below.

the issue appears when executing blinkstick using sudo blinkstick. This is essentially a workaround using a workaround because even with Python 3.8 there are problems which are outlined in this issue. Shown below is the output on each version followed by steps to get it working on your system using Python 3.8. I think even using Python 3.7 would just work out of the box without the extra steps...

Python 3.9 Output

sys.exit(main()) File "/usr/local/bin/blinkstick", line 220, in main sticks = blinkstick.find_all() File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 1566, in find_all result.extend([BlinkStick(device=d)]) File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 217, in __init__ self.bs_serial = self.get_serial() File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 283, in get_serial return self._usb_get_string(self.device, 3) File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 221, in _usb_get_string return usb.util.get_string(device, index, 1033) File "/usr/local/lib/python3.9/dist-packages/usb/util.py", line 260, in get_string return buf[2:buf[0]].tostring().decode('utf-16-le') IndexError: array index out of range">
pi@kube1:~/python38-env $ python3 --version
Python 3.9.2

pi@kube1:~/python38-env $ sudo blinkstick --blink green
Traceback (most recent call last):
  File "/usr/local/bin/blinkstick", line 331, in <module>
    sys.exit(main())
  File "/usr/local/bin/blinkstick", line 220, in main
    sticks = blinkstick.find_all()
  File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 1566, in find_all
    result.extend([BlinkStick(device=d)])
  File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 217, in __init__
    self.bs_serial = self.get_serial()
  File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 283, in get_serial
    return self._usb_get_string(self.device, 3)
  File "/usr/local/lib/python3.9/dist-packages/blinkstick/blinkstick.py", line 221, in _usb_get_string
    return usb.util.get_string(device, index, 1033)
  File "/usr/local/lib/python3.9/dist-packages/usb/util.py", line 260, in get_string
    return buf[2:buf[0]].tostring().decode('utf-16-le')
IndexError: array index out of range

Python 3.8 Output

pi@kube1:~/python38-env $ source ./bin/activate
(python38-env) pi@kube1:~/python38-env $ python --version
Python 3.8.2

Change file /usr/local/bin/blinkstick interpretor from #!/usr/bin/env python to #!/home/pi/python38-env/bin/python3

(python38-env) pi@kube1:~/python38-env $ head -5 /usr/local/bin/blinkstick
#!/home/pi/python38-env/bin/python3

from optparse import OptionParser, IndentedHelpFormatter, OptionGroup
from blinkstick import blinkstick

Run sudo blinkstick --blink green

(python38-env) pi@kube1:~/python38-env $ sudo blinkstick --blink green
(python38-env) pi@kube1:~/python38-env $

Install Blinkstick inside Python 3.8 virtual environment

Create Python 3.8 virtual environment

# Install python 3.8 on debian: https://linuxize.com/post/how-to-install-python-3-8-on-debian-10/

mkdir ~/python38-env && cd ~/python38-env
python3.8 -m venv .
source ./bin/activate

Perform Python 3.8 workaround steps

sudo apt-get install dos2unix
sudo pip install pyusb
sudo pip install blinkstick
sudo chmod +x /usr/local/bin/blinkstick
sudo dos2unix /usr/local/bin/blinkstick

Change python interpretor for blinktick module

Note: In my case I used python38-env as the target folder when creating the virtual env in the early steps.

By changing the interpreter in the module directly will allow Blinkstick to function when the virtual env is deactivated.

#!/usr/bin/env python to #!/home/pi/python38-env/bin/python3

Run sudo blinkstick and you should see the help menu.

Running sudo blinkstick --blink green works on the host.

Reference

Install Python 3.8 on Debian 10: https://linuxize.com/post/how-to-install-python-3-8-on-debian-10/ Install Python 3.8 on Debian 11: https://www.linuxcapable.com/how-to-install-python-3-8-on-debian-11-bullseye/ I used the Debian 10 tutorial for installing on bullseye but then found this version. Looks like it installs 3.8.12 instead of 3.8.2 Python 3.8 workaround reference: https://github.com/arvydas/blinkstick-python/issues/34

You might also like...
The ABR Control library is a python package for the control and path planning of robotic arms in real or simulated environments.
The ABR Control library is a python package for the control and path planning of robotic arms in real or simulated environments.

The ABR Control library is a python package for the control and path planning of robotic arms in real or simulated environments. ABR Control provides API's for the Mujoco, CoppeliaSim (formerly known as VREP), and Pygame simulation environments, and arm configuration files for one, two, and three-joint models, as well as the UR5 and Kinova Jaco 2 arms. Users can also easily extend the package to run with custom arm configurations. ABR Control auto-generates efficient C code for generating the control signals, or uses Mujoco's internal functions to carry out the calculations.

A ch341dll Wrap is for using in Python 32bits windows  to access I2C SPI and MDIO (by GPIO), and Demo with display PC sreen on OLED by i2c or SPI .
A ch341dll Wrap is for using in Python 32bits windows to access I2C SPI and MDIO (by GPIO), and Demo with display PC sreen on OLED by i2c or SPI .

ch341dll_wrap_typcal_app A ch341dll Wrap is for using in Python 32bits windows to access I2C SPI and MDIO (by GPIO). In addition, I provided 3 Demo. I

Designed a system that can efficiently sort recyclables and transfer them to corresponding bins using Python, a Raspberry Pi, and Quanser Labs.
Designed a system that can efficiently sort recyclables and transfer them to corresponding bins using Python, a Raspberry Pi, and Quanser Labs.

System for Sorting and Recycling Containers - Project 3 Table of contents Overview The challenge Screenshot My process Built with Code snippets What I

A python library written for the raspberry pi.

A python package for using certain components on the raspberry pi.

Robot Framework keyword library wrapper for atlassian-python-api

Robot Framework keyword library wrapper for atlassian-python-api

Python library for the Phomemo m02s bluetooth thermal printer

Phomemo M02S Python library This is a basic Python library for controlling the Phomemo M02S bluetooth thermal printer. It probably only works on Mac &

Python library to interact with the GCE Electronics IPX800 device
Python library to interact with the GCE Electronics IPX800 device

A python library to control a GCE-Electronics IPX800 V4 device through its API.

A rubiks cube timer using a distance sensor and a raspberry pi 4, and possibly the pi pico to reduce size and cost.
A rubiks cube timer using a distance sensor and a raspberry pi 4, and possibly the pi pico to reduce size and cost.

distance sensor cube timer A rubiks cube timer using a distance sensor and a raspberry pi 4, and possibly the pi pico to reduce size and cost. How to

Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives.
Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives.

Ingeniamotion Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives. Requirements Python 3

Owner
Greg Robinson
Delivery Consultant
Greg Robinson
A blender 2.9x addon for managing camera settings

TMG-Camera-Tools A blender 2.9x addon for managing camera settings Tutorial showcasing current features

Mainman002 12 Apr 16, 2022
A raspberrypi tools for python

raspberrypi-tools how to install: first clone this project: git clone https://github.com/Ardumine/rpi-tools.git then go to the folder cd rpi-tools and

null 1 Jan 4, 2022
Tools and documentation to aid in modifying the ADI ADALM Pluto firmware

Pluto firmware modifications This repository contains tools and documentation to aid in modifying the ADI ADALM Pluto firmware. Extraction of the Plut

Daniel Estévez 28 Dec 21, 2022
Unofficial Playdate reverse-engineering notes/tools - covers file formats, server API and USB commands

Unofficial Playdate reverse-engineering notes/tools - covers file formats, server API and USB commands ⚠️ This documentation is unofficial and is not

James 106 Dec 31, 2022
[unmaintained] WiFi tools for linux

Note: This project is unmaintained. While I would love to keep up the development on this project, it is difficult for me for several reasons: I don't

Rocky Meza 288 Dec 13, 2022
A PYTHON Library for Controlling Motors using SOLO Motor Controllers with RASPBERRY PI, Linux, windows, and more!

A PYTHON Library for Controlling Motors using SOLO Motor Controllers with RASPBERRY PI, Linux, windows, and more!

SOLO Motor Controllers 3 Apr 29, 2022
Scapy: the Python-based interactive packet manipulation program & library. Supports Python 2 & Python 3.

Scapy Scapy is a powerful Python-based interactive packet manipulation program and library. It is able to forge or decode packets of a wide number of

SecDev 8.3k Jan 8, 2023
a library for using WS2812b leds (aka neopixels) with Raspberry Pi Pico

pico_ws2812b a library for using WS2812b leds (aka neopixels) with Raspberry Pi Pico You'll first need to save the ws2812b.py file to your device (for

null 76 Nov 25, 2022
Example for Calculating Robot Dynamics Using Pinocchio Library

A Example for Calculating Robot Dynamics Using Pinocchio Library Developed by: Xinyang Tian. Platform: Linux + Pinocchio. In this work, i use Pinocchi

Rot_Tianers 33 Dec 28, 2022
Alternative firmware for ESP8266 with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at

Alternative firmware for ESP8266/ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability

Theo Arends 59 Dec 26, 2022