diff --git a/README.md b/README.md index 3b6eb93..0d0e794 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Blinkt!](blinkt-logo.png) -[![Build Status](https://travis-ci.com/pimoroni/blinkt.svg?branch=master)](https://travis-ci.com/pimoroni/blinkt) +[![Build Status](https://img.shields.io/github/actions/workflow/status/pimoroni/blinkt/test.yml?branch=main)](https://github.com/pimoroni/blinkt/actions/workflows/test.yml) [![Coverage Status](https://coveralls.io/repos/github/pimoroni/blinkt/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/blinkt?branch=master) [![PyPi Package](https://img.shields.io/pypi/v/blinkt.svg)](https://pypi.python.org/pypi/blinkt) [![Python Versions](https://img.shields.io/pypi/pyversions/blinkt.svg)](https://pypi.python.org/pypi/blinkt) diff --git a/examples/1d_tetris.py b/examples/1d_tetris.py index 406a13e..f9b71ea 100755 --- a/examples/1d_tetris.py +++ b/examples/1d_tetris.py @@ -90,5 +90,5 @@ def main(): update() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/examples/anvil-colour-control.py b/examples/anvil_colour_control.py similarity index 91% rename from examples/anvil-colour-control.py rename to examples/anvil_colour_control.py index 1b6a75f..3019a48 100755 --- a/examples/anvil-colour-control.py +++ b/examples/anvil_colour_control.py @@ -31,7 +31,7 @@ @anvil.server.callable def set_color(color_string): - print("Setting LEDs to {}".format(color_string)) + print(f"Setting LEDs to {color_string}") c = Color(color_string) blinkt.set_all(c.red * 255, c.green * 255, c.blue * 255, 1.0) blinkt.show() @@ -45,7 +45,7 @@ def clear(): # Display the URL where you can control the Blinkt LEDS -print("Control your Blinkt LEDs at {}".format(app.origin)) +print(f"Control your Blinkt LEDs at {app.origin}") print("Press Ctrl-C to exit") # Keep the script running until the user exits with Ctrl-C diff --git a/examples/binary_clock.py b/examples/binary_clock.py index 7e75db9..25be528 100755 --- a/examples/binary_clock.py +++ b/examples/binary_clock.py @@ -9,9 +9,7 @@ MODE_HOUR = 0 MODE_MIN = 1 MODE_SEC = 2 -MODE_NAMES = {MODE_HOUR: 'Hour mode', - MODE_MIN: 'Minute mode', - MODE_SEC: 'Seconds mode'} +MODE_NAMES = {MODE_HOUR: "Hour mode", MODE_MIN: "Minute mode", MODE_SEC: "Seconds mode"} time_to_stay_in_mode = 3 time_in_mode = 0 @@ -62,11 +60,7 @@ blinkt.set_pixel(7 - x, r, g, b) blinkt.show() - print('{h:2d}:{m:02d}:{s:02d}; mode: {mode}; time in mode: {tim}'.format(h=h, - m=m, - s=s, - mode=MODE_NAMES[mode], - tim=time_in_mode)) + print(f"{h:2d}:{m:02d}:{s:02d}; mode: {MODE_NAMES[mode]}; time in mode: {time_in_mode}") time_in_mode += 1 if time_in_mode == time_to_stay_in_mode: diff --git a/examples/binary_clock_meld.py b/examples/binary_clock_meld.py index add7f2e..116f05f 100755 --- a/examples/binary_clock_meld.py +++ b/examples/binary_clock_meld.py @@ -4,7 +4,7 @@ import blinkt -print('Hour = Red, Minute = Green, Second = Blue') +print("Hour = Red, Minute = Green, Second = Blue") blinkt.set_clear_on_exit() @@ -16,7 +16,7 @@ t = localtime() h, m, s = t.tm_hour, t.tm_min, t.tm_sec - print('{h:2d}:{m:02d}:{s:02d}'.format(h=h, m=m, s=s)) + print(f"{h:2d}:{m:02d}:{s:02d}") blinkt.clear() diff --git a/examples/blinkt_thermo.py b/examples/blinkt_thermo.py index e056c70..71e1a16 100755 --- a/examples/blinkt_thermo.py +++ b/examples/blinkt_thermo.py @@ -3,40 +3,35 @@ # Data from OpenWeatherMap # show_graph function adapted from cpu_temp.py -from sys import exit from time import sleep try: import requests except ImportError: - exit('This script requires the requests module\nInstall with: sudo pip install requests') + raise ImportError("This script requires the requests module\nInstall with: python3 -m pip install requests") import blinkt # Grab your API key here: http://openweathermap.org # List of city ID city.list.json.gz can be downloaded here http://bulk.openweathermap.org/sample/ -API_KEY = '' -CITY_ID = '' +API_KEY = "" +CITY_ID = "" -url = 'http://api.openweathermap.org/data/2.5/weather' +url = "http://api.openweathermap.org/data/2.5/weather" temp = 0 def update_weather(): global temp - payload = { - 'id': CITY_ID, - 'units': 'metric', - 'appid': API_KEY - } + payload = {"id": CITY_ID, "units": "metric", "appid": API_KEY} try: r = requests.get(url=url, params=payload) - temp = r.json().get('main').get('temp') - print('Temperture = ' + str(temp) + ' C') + temp = r.json().get("main").get("temp") + print("Temperture = " + str(temp) + " C") except requests.exceptions.ConnectionError: - print('Connection Error') + print("Connection Error") def show_graph(v, r, g, b): @@ -54,7 +49,7 @@ def show_graph(v, r, g, b): def draw_thermo(temp): v = temp v /= 40 - v += (1 / 8) + v += 1 / 8 show_graph(v, 255, 0, 0) diff --git a/examples/candle.py b/examples/candle.py index 3ef114f..b9aa5f0 100755 --- a/examples/candle.py +++ b/examples/candle.py @@ -2,12 +2,11 @@ import colorsys import time -from sys import exit try: import numpy as np except ImportError: - exit('This script requires the numpy module\nInstall with: python3 -m pip install numpy') + raise ImportError("This script requires the numpy module\nInstall with: python3 -m pip install numpy") import blinkt diff --git a/examples/cheerlights.py b/examples/cheerlights.py index 1783feb..0c53162 100755 --- a/examples/cheerlights.py +++ b/examples/cheerlights.py @@ -5,7 +5,7 @@ try: import requests except ImportError: - exit('This script requires the requests module\nInstall with: sudo pip install requests') + exit("This script requires the requests module\nInstall with: python3 -m pip install requests") import blinkt @@ -14,20 +14,20 @@ def hex_to_rgb(col_hex): """Convert a hex colour to an RGB tuple.""" - col_hex = col_hex.lstrip('#') + col_hex = col_hex.lstrip("#") return bytearray.fromhex(col_hex) while True: - r = requests.get('http://api.thingspeak.com/channels/1417/field/2/last.json', timeout=2) + r = requests.get("http://api.thingspeak.com/channels/1417/field/2/last.json", timeout=2) json = r.json() - if 'field2' not in json: - print('Error {status}: {error}'.format(status=json['status'], error=json['error'])) + if "field2" not in json: + print(f"Error {json['status']}: {json['error']}") time.sleep(5) continue - r, g, b = hex_to_rgb(json['field2']) + r, g, b = hex_to_rgb(json["field2"]) for i in range(blinkt.NUM_PIXELS): blinkt.set_pixel(i, r, g, b) diff --git a/examples/cpu_load.py b/examples/cpu_load.py index 1331229..e928820 100755 --- a/examples/cpu_load.py +++ b/examples/cpu_load.py @@ -1,11 +1,10 @@ #!/usr/bin/env python import time -from sys import exit try: import psutil except ImportError: - exit('This script requires the psutil module\nInstall with: sudo apt install python3-psutil') + raise ImportError("This script requires the psutil module\nInstall with: sudo apt install python3-psutil") import blinkt diff --git a/examples/cpu_temp.py b/examples/cpu_temp.py index 29b99e4..5f5686d 100755 --- a/examples/cpu_temp.py +++ b/examples/cpu_temp.py @@ -9,11 +9,11 @@ def get_cpu_temperature(): - process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE) + process = Popen(["vcgencmd", "measure_temp"], stdout=PIPE) output, _error = process.communicate() output = output.decode() - pos_start = output.index('=') + 1 + pos_start = output.index("=") + 1 pos_end = output.rindex("'") temp = float(output[pos_start:pos_end]) diff --git a/examples/extra_examples/drum_hits.py b/examples/extra_examples/drum_hits.py index dad43e5..8b4da7a 100755 --- a/examples/extra_examples/drum_hits.py +++ b/examples/extra_examples/drum_hits.py @@ -3,28 +3,27 @@ import glob import os import time -from sys import exit try: import drumhat except ImportError: - exit('This script requires the drumhat module\nInstall with: sudo pip install drumhat') + raise ImportError("This script requires the drumhat module\nInstall with: python3 -m pip install drumhat") try: import pygame except ImportError: - exit('This script requires the pygame module\nInstall with: sudo pip install pygame') + raise ImportError("This script requires the pygame module\nInstall with: python3 -m pip install pygame") import blinkt -DRUM_FOLDER = 'drums2' +DRUM_FOLDER = "drums2" BANK = os.path.join(os.path.dirname(__file__), DRUM_FOLDER) pygame.mixer.init(44100, -16, 1, 512) pygame.mixer.set_num_channels(16) -files = glob.glob(os.path.join(BANK, '*.wav')) +files = glob.glob(os.path.join(BANK, "*.wav")) files.sort() samples = [pygame.mixer.Sound(f) for f in files] @@ -40,7 +39,7 @@ def show_all(state): def handle_hit(event): samples[event.channel].play(loops=0) show_all(1) - print('You hit pad {}, playing: {}'.format(event.pad, files[event.channel])) + print(f"You hit pad {event.pad}, playing: {files[event.channel]}") def handle_release(): diff --git a/examples/extra_examples/pov_rainbow.py b/examples/extra_examples/pov_rainbow.py index d56bd2a..e3bd39a 100755 --- a/examples/extra_examples/pov_rainbow.py +++ b/examples/extra_examples/pov_rainbow.py @@ -2,12 +2,11 @@ import time from colorsys import hsv_to_rgb -from sys import exit try: from envirophat import motion except ImportError: - exit('This script requires the envirophat module\nInstall with: sudo pip install envirophat') + raise ImportError("This script requires the envirophat module\nInstall with: python3 -m pip install envirophat") import blinkt @@ -42,7 +41,7 @@ def millis(): if len(t) > 0: total_time = float(sum(t)) / len(t) - offset = ((millis() - t_start) / total_time) + offset = (millis() - t_start) / total_time # offset += direction * 10 diff --git a/examples/extra_examples/spirit_level.py b/examples/extra_examples/spirit_level.py index c48dfc8..784a76c 100755 --- a/examples/extra_examples/spirit_level.py +++ b/examples/extra_examples/spirit_level.py @@ -1,12 +1,11 @@ #!/usr/bin/env python import time -from sys import exit try: from envirophat import motion except ImportError: - exit('This script requires the envirophat module\nInstall with: sudo pip install envirophat') + raise ImportError("This script requires the envirophat module\nInstall with: python3 -m pip install envirophat") import blinkt diff --git a/examples/eyedropper.py b/examples/eyedropper.py index 429a5c1..d2ea621 100644 --- a/examples/eyedropper.py +++ b/examples/eyedropper.py @@ -7,7 +7,7 @@ import blinkt -print('Press Ctrl-C to quit.') +print("Press Ctrl-C to quit.") try: while True: @@ -15,10 +15,10 @@ im = ImageGrab.grab(bbox=(x - 1, y, x, y + 1)) rawrgb = list(im.getdata()) rgb = str(rawrgb)[2:-2] - r, g, b = rgb.split(', ') + r, g, b = rgb.split(", ") blinkt.set_all(r, g, b) blinkt.set_brightness(1) blinkt.show() time.sleep(0.01) except KeyboardInterrupt: - print('\n') + print("\n") diff --git a/examples/kitt.py b/examples/kitt.py index 4304089..d1f3311 100644 --- a/examples/kitt.py +++ b/examples/kitt.py @@ -4,20 +4,20 @@ import blinkt # so we can talk to our blinkt lights! -BRIGHTNESS = 0.2 # range is 0.0 to 1.0 -MAX_COLOUR = 255 # range is 0 to 255 -DECAY_FACTOR = 1.5 # how quickly should MAX_COLOUR fade? (1.5 works well) -TIME_SLEEP = 0.04 # seconds (0.04 works well) +BRIGHTNESS = 0.2 # range is 0.0 to 1.0 +MAX_COLOUR = 255 # range is 0 to 255 +DECAY_FACTOR = 1.5 # how quickly should MAX_COLOUR fade? (1.5 works well) +TIME_SLEEP = 0.04 # seconds (0.04 works well) PIXELS = blinkt.NUM_PIXELS # usually 8, can use fewer if you like! -blinkt.clear # make all pixels blank / black +blinkt.clear # make all pixels blank / black blinkt.set_brightness(BRIGHTNESS) brightpixel = -1 direction = 1 -print('Hello Michael.\nHow are you today?') +print("Hello Michael.\nHow are you today?") while True: # decay all pixels @@ -31,12 +31,12 @@ if brightpixel >= PIXELS - 1: brightpixel = PIXELS - 1 - direction = - abs(direction) + direction = -abs(direction) if brightpixel <= 0: brightpixel = 0 direction = abs(direction) blinkt.set_pixel(brightpixel, MAX_COLOUR, 0, 0) - blinkt.show() # draw the lights! + blinkt.show() # draw the lights! time.sleep(TIME_SLEEP) # wait a bit before working on next frame diff --git a/examples/larson_hue.py b/examples/larson_hue.py index b70a8eb..53ea617 100755 --- a/examples/larson_hue.py +++ b/examples/larson_hue.py @@ -14,7 +14,7 @@ start_time = time.time() while True: - delta = (time.time() - start_time) + delta = time.time() - start_time # Offset is a sine wave derived from the time delta # we use this to animate both the hue and larson scan @@ -34,13 +34,13 @@ sat = 1.0 val = max_val - (abs(offset - x) * FALLOFF) - val /= float(max_val) # Convert to 0.0 to 1.0 - val = max(val, 0.0) # Ditch negative values + val /= float(max_val) # Convert to 0.0 to 1.0 + val = max(val, 0.0) # Ditch negative values - xhue = hue # Grab hue for this pixel + xhue = hue # Grab hue for this pixel xhue += (1 - val) * 10 # Use the val offset to give a slight colour trail variation - xhue %= 360 # Clamp to 0-359 - xhue /= 360.0 # Convert to 0.0 to 1.0 + xhue %= 360 # Clamp to 0-359 + xhue /= 360.0 # Convert to 0.0 to 1.0 r, g, b = [int(c * 255) for c in colorsys.hsv_to_rgb(xhue, sat, val)] diff --git a/examples/mem_load.py b/examples/mem_load.py index fe0c410..5141a2e 100755 --- a/examples/mem_load.py +++ b/examples/mem_load.py @@ -1,12 +1,11 @@ #!/usr/bin/env python import time -from sys import exit try: import psutil except ImportError: - exit('This script requires the psutil module\nInstall with: python3 -m pip install psutil') + raise ImportError("This script requires the psutil module\nInstall with: python3 -m pip install psutil") import blinkt diff --git a/examples/morse_code.py b/examples/morse_code.py index 6f349d8..fbee738 100755 --- a/examples/morse_code.py +++ b/examples/morse_code.py @@ -37,13 +37,13 @@ def space(): # 0 is a space, 1 is a dot and 2 is a dash -MORSE = ' -... .. . -.. - -. . - . - -. -. - ' +MORSE = " -... .. . -.. - -. . - . - -. -. - " while True: for m in MORSE: - if m == ' ': + if m == " ": space() - elif m == '.': + elif m == ".": dot() - elif m == '-': + elif m == "-": dash() diff --git a/examples/mqtt.py b/examples/mqtt.py index 64860df..24f5c59 100755 --- a/examples/mqtt.py +++ b/examples/mqtt.py @@ -1,78 +1,74 @@ #!/usr/bin/env python -from sys import exit try: import paho.mqtt.client as mqtt except ImportError: - exit('This example requires the paho-mqtt module\nInstall with: sudo pip install paho-mqtt') + raise ImportError("This example requires the paho-mqtt module\nInstall with: python3 -m pip install paho-mqtt") import blinkt -MQTT_SERVER = 'iot.eclipse.org' +MQTT_SERVER = "iot.eclipse.org" MQTT_PORT = 1883 -MQTT_TOPIC = 'pimoroni/blinkt' +MQTT_TOPIC = "pimoroni/blinkt" # Set these to use authorisation MQTT_USER = None MQTT_PASS = None -print(""" +print( + f""" MQTT Blinkt! Control -This example uses public MQTT messages from {server} on port {port} to control Blinkt! +This example uses public MQTT messages from {MQTT_SERVER} on port {MQTT_PORT} to control Blinkt! -It will monitor the {topic} topic by default, and understands the following messages: +It will monitor the {MQTT_TOPIC} topic by default, and understands the following messages: rgb,,,, - Set a single pixel to an RGB colour. Example: rgb,1,255,0,255 clr - Clear Blinkt! You can use the online MQTT tester at http://www.hivemq.com/demos/websocket-client/ to send messages. -Use {server} as the host, and port 80 (Eclipse's websocket port). Set the topic to topic: {topic} -""".format( - server=MQTT_SERVER, - port=MQTT_PORT, - topic=MQTT_TOPIC -)) +Use {MQTT_SERVER} as the host, and port 80 (Eclipse's websocket port). Set the topic to topic: {MQTT_TOPIC} +""" +) def on_connect(client, userdata, flags, rc): - print('Connected with result code ' + str(rc)) + print("Connected with result code " + str(rc)) client.subscribe(MQTT_TOPIC) def on_message(client, userdata, msg): - data = msg.payload if isinstance(data, bytes): - data = data.decode('utf-8') - data = data.split(',') + data = data.decode("utf-8") + data = data.split(",") command = data.pop(0) - if command == 'clr' and len(data) == 0: + if command == "clr" and len(data) == 0: blinkt.clear() blinkt.show() return - if command == 'rgb' and len(data) == 4: + if command == "rgb" and len(data) == 4: try: pixel = data.pop(0) - if pixel == '*': + if pixel == "*": pixel = None else: pixel = int(pixel) if pixel > 7: - print('Pixel out of range: ' + str(pixel)) + print("Pixel out of range: " + str(pixel)) return - r, g, b = [int(x) & 0xff for x in data] + r, g, b = [int(x) & 0xFF for x in data] print(command, pixel, r, g, b) except ValueError: - print('Malformed command: ' + str(msg.payload)) + print("Malformed command: " + str(msg.payload)) return if pixel is None: @@ -92,7 +88,8 @@ def on_message(client, userdata, msg): client.on_message = on_message if MQTT_USER is not None and MQTT_PASS is not None: - print('Using username: {un} and password: {pw}'.format(un=MQTT_USER, pw='*' * len(MQTT_PASS))) + pw = "*" * len(MQTT_PASS) + print(f"Using username: {MQTT_USER} and password: {pw}") client.username_pw_set(username=MQTT_USER, password=MQTT_PASS) client.connect(MQTT_SERVER, MQTT_PORT, 60) diff --git a/examples/pulse.py b/examples/pulse.py index b260129..c6dd28a 100755 --- a/examples/pulse.py +++ b/examples/pulse.py @@ -2,12 +2,11 @@ import colorsys import time -from sys import exit try: import numpy as np except ImportError: - exit('This script requires the numpy module\nInstall with: sudo pip install numpy') + raise ImportError("This script requires the numpy module\nInstall with: python3 -m pip install numpy") import blinkt @@ -19,7 +18,7 @@ def make_gaussian(fwhm): y = x[:, np.newaxis] x0, y0 = 3.5, 3.5 fwhm = fwhm - gauss = np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / fwhm ** 2) + gauss = np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / fwhm**2) return gauss diff --git a/examples/resistor_clock.py b/examples/resistor_clock.py index 717d38d..1f4e983 100755 --- a/examples/resistor_clock.py +++ b/examples/resistor_clock.py @@ -5,14 +5,14 @@ import blinkt colours = [ - [0, 0, 0], # 0 black - [139, 69, 19], # 1 brown - [255, 0, 0], # 2 red - [255, 69, 0], # 3 orange - [255, 255, 0], # 4 yellow - [0, 255, 0], # 5 green - [0, 0, 255], # 6 blue - [128, 0, 128], # 7 violet + [0, 0, 0], # 0 black + [139, 69, 19], # 1 brown + [255, 0, 0], # 2 red + [255, 69, 0], # 3 orange + [255, 255, 0], # 4 yellow + [0, 255, 0], # 5 green + [0, 0, 255], # 6 blue + [128, 0, 128], # 7 violet [255, 255, 100], # 8 grey [255, 255, 255], # 9 white ] diff --git a/examples/rgb.py b/examples/rgb.py index 94f8ffc..476a69a 100755 --- a/examples/rgb.py +++ b/examples/rgb.py @@ -6,7 +6,7 @@ def usage(): - print('Usage: {} '.format(sys.argv[0])) + print(f"Usage: {sys.argv[0]} ") sys.exit(1) @@ -23,7 +23,7 @@ def usage(): if max(r, g, b) > 255: usage() -print('Setting Blinkt to {r},{g},{b}'.format(r=r, g=g, b=b)) +print(f"Setting Blinkt to {r},{g},{b}") blinkt.set_clear_on_exit(False) diff --git a/examples/setall.py b/examples/setall.py index 499af66..e12107a 100755 --- a/examples/setall.py +++ b/examples/setall.py @@ -6,7 +6,7 @@ import blinkt if len(argv) < 4 or len(argv) > 5: - sys.stderr.write("Syntax: {0} [brightness]\n".format(argv[0])) + sys.stderr.write(f"Syntax: {argv[0]} [brightness]\n") exit(1) red = int(argv[1]) diff --git a/examples/twitter_monitor.py b/examples/twitter_monitor.py deleted file mode 100755 index 23e5b72..0000000 --- a/examples/twitter_monitor.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -import time -from sys import exit - -try: - from tweepy import OAuthHandler, Stream - from tweepy.streaming import StreamListener -except ImportError: - exit('This script requires the tweepy module\nInstall with: sudo pip install tweepy') - -import blinkt - -ckey = '' # Consumer key -csecret = '' # Consumer secret -atoken = '' # Access token -asecret = '' # Access secret - - -class listener(StreamListener): - def on_data(self, data): - blink_blinkt() - return True - - def on_error(self, status): - print(status) - - -def blink_blinkt(): - for i in range(3): - for j in range(blinkt.NUM_PIXELS): - blinkt.set_pixel(j, 255, 0, 0) - - blinkt.show() - time.sleep(0.1) - - for j in range(blinkt.NUM_PIXELS): - blinkt.set_pixel(j, 0, 0, 0) - - blinkt.show() - time.sleep(0.2) - - -auth = OAuthHandler(ckey, csecret) -auth.set_access_token(atoken, asecret) -twitterstream = Stream(auth, listener()) -twitterstream.filter(track=['#INSERTHASHTAGHERE']) diff --git a/projects/mqtt/mqtt.py b/projects/mqtt/mqtt.py index 67b3f85..0560b17 100755 --- a/projects/mqtt/mqtt.py +++ b/projects/mqtt/mqtt.py @@ -7,7 +7,7 @@ try: import paho.mqtt.client as mqtt except ImportError: - raise ImportError("This example requires the paho-mqtt module\nInstall with: sudo pip install paho-mqtt") + raise ImportError("This example requires the paho-mqtt module\nInstall with: python3 -m pip install paho-mqtt") import blinkt @@ -19,12 +19,12 @@ MQTT_USER = None MQTT_PASS = None -description = """\ +description = f"""\ MQTT Blinkt! Control -This example uses MQTT messages from {server} on port {port} to control Blinkt! +This example uses MQTT messages from {MQTT_SERVER} on port {MQTT_PORT} to control Blinkt! -It will monitor the {topic} topic by default, and understands the following messages: +It will monitor the {MQTT_TOPIC} topic by default, and understands the following messages: rgb,,,, - Set a single pixel to an RGB colour. Example: rgb,1,255,0,255 clr - Clear Blinkt! @@ -32,47 +32,35 @@ You can use the online MQTT tester at http://www.hivemq.com/demos/websocket-client/ to send messages. -Use {server} as the host, and port 80 (Eclipse's websocket port). Set the topic to topic: {topic} -""".format( - server=MQTT_SERVER, - port=MQTT_PORT, - topic=MQTT_TOPIC -) +Use {MQTT_SERVER} as the host, and port 80 (Eclipse's websocket port). Set the topic to topic: {MQTT_TOPIC} +""" + parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawDescriptionHelpFormatter) -parser.add_argument('-H', '--host', default=MQTT_SERVER, - help='MQTT broker to connect to') -parser.add_argument('-P', '--port', default=MQTT_PORT, type=int, - help='port on MQTT broker to connect to') -parser.add_argument('-T', '--topic', action='append', - help='MQTT topic to subscribe to; can be repeated for multiple topics') -parser.add_argument('-u', '--user', - help='MQTT broker user name') -parser.add_argument('-p', '--pass', dest='pw', - help='MQTT broker password') -parser.add_argument('-q', '--quiet', default=False, action='store_true', - help='Minimal output (eg for running as a daemon)') -parser.add_argument('-g', '--green-hack', default=False, action='store_true', - help='Apply hack to green channel to improve colour saturation') -parser.add_argument('--timeout', default='0', - help='Pixel timeout(s). Pixel will blank if last update older than X seconds. May be a single number or comma-separated list. Use 0 for no timeout') -parser.add_argument('-D', '--daemon', metavar='PIDFILE', - help='Run as a daemon (implies -q)') +parser.add_argument("-H", "--host", default=MQTT_SERVER, help="MQTT broker to connect to") +parser.add_argument("-P", "--port", default=MQTT_PORT, type=int, help="port on MQTT broker to connect to") +parser.add_argument("-T", "--topic", action="append", help="MQTT topic to subscribe to; can be repeated for multiple topics") +parser.add_argument("-u", "--user", help="MQTT broker user name") +parser.add_argument("-p", "--pass", dest="pw", help="MQTT broker password") +parser.add_argument("-q", "--quiet", default=False, action="store_true", help="Minimal output (eg for running as a daemon)") +parser.add_argument("-g", "--green-hack", default=False, action="store_true", help="Apply hack to green channel to improve colour saturation") +parser.add_argument("--timeout", default="0", help="Pixel timeout(s). Pixel will blank if last update older than X seconds. May be a single number or comma-separated list. Use 0 for no timeout") +parser.add_argument("-D", "--daemon", metavar="PIDFILE", help="Run as a daemon (implies -q)") args = parser.parse_args() # Get timeout list into expected form -args.timeout = args.timeout.split(',') +args.timeout = args.timeout.split(",") if len(args.timeout) == 1: args.timeout = args.timeout * blinkt.NUM_PIXELS elif len(args.timeout) != blinkt.NUM_PIXELS: - print("--timeout list must be {} elements long".format(blinkt.NUM_PIXELS)) + print(f"--timeout list must be {blinkt.NUM_PIXELS} elements long") exit(1) try: args.timeout = [int(x) for x in args.timeout] except ValueError as e: - print("Bad timeout value: {}".format(e)) + print(f"Bad timeout value: {e}") exit(1) args.timeout = [x and x or 0 for x in args.timeout] @@ -80,14 +68,17 @@ if args.daemon: import signal + try: import daemon except ImportError: - raise ImportError("--daemon requires the daemon module. Install with: sudo pip install python-daemon") + print("--daemon requires the daemon module. Install with: python3 -m pip install python-daemon") + exit(1) try: import lockfile.pidlockfile except ImportError: - raise ImportError("--daemon requires the lockfile module. Install with: sudo pip install lockfile") + print("--daemon requires the lockfile module. Install with: python3 -m pip install lockfile") + exit(1) if not args.topic: args.topic = [MQTT_TOPIC] @@ -117,7 +108,7 @@ def cmd_brightness(self, bri): try: bri = float(bri) except ValueError: - print("Malformed command brightness, expected float, got: {}".format(str(bri))) + print(f"Malformed command brightness, expected float, got: {bri}") return blinkt.set_brightness(bri) blinkt.show() @@ -129,10 +120,10 @@ def cmd_rgb(self, pixel, data): else: pixel = int(pixel) if pixel > 7: - print("Pixel out of range: {}".format(str(pixel))) + print(f"Pixel out of range: {pixel}") return - r, g, b = [int(x) & 0xff for x in data] + r, g, b = [int(x) & 0xFF for x in data] if self.args.green_hack: # Green is about twice the luminosity for a given value # than red or blue, so apply a hackish linear compensation @@ -147,10 +138,10 @@ def cmd_rgb(self, pixel, data): b = b + 1 if not self.args.quiet: - print('rgb', pixel, r, g, b) + print("rgb", pixel, r, g, b) except ValueError: - print("Malformed RGB command: {} {}".format(str(pixel), str(data))) + print(f"Malformed RGB command: {pixel} {data}") return if pixel is None: @@ -165,20 +156,15 @@ def cmd_rgb(self, pixel, data): def on_connect(self, client, userdata, flags, rc): if not self.args.quiet: - print("Connected to {s}:{p} listening for topics {t} with result code {r}.\nSee {c} --help for options.".format( - s=self.args.host, - p=self.args.port, - t=', '.join(self.args.topic), - r=rc, - c=parser.prog - )) + print(f"Connected to {self.args.host}:{self.args.port} with result code {rc}.") + print(f"listening for topics {', '.join(self.args.topic)}.") + print(f"See {parser.prog} --help for options.") for topic in self.args.topic: client.subscribe(topic) def on_message(self, client, userdata, msg): - - data = msg.payload.decode('utf-8').strip().split(',') + data = msg.payload.decode("utf-8").strip().split(",") command = data.pop(0) print(command, data) @@ -218,9 +204,7 @@ def sigterm(signum, frame): daemon.daemon.get_maximum_file_descriptors = lambda: 32 args.quiet = True pidlf = lockfile.pidlockfile.PIDLockFile(args.daemon) - with daemon.DaemonContext( - pidfile=pidlf, - signal_map={signal.SIGTERM: sigterm}): + with daemon.DaemonContext(pidfile=pidlf, signal_map={signal.SIGTERM: sigterm}): client = PixelClient(args) client.loop_forever() else: diff --git a/pyproject.toml b/pyproject.toml index 7c38d53..25af28f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,6 +95,9 @@ skip = """ [tool.isort] line_length = 200 +[tool.black] +line-length = 200 + [tool.check-manifest] ignore = [ '.stickler.yml', diff --git a/requirements-examples.txt b/requirements-examples.txt new file mode 100644 index 0000000..499cb1d --- /dev/null +++ b/requirements-examples.txt @@ -0,0 +1,8 @@ +requests +paho-mqtt +psutil +numpy +envirophat +drumhat +pygame +numpy \ No newline at end of file diff --git a/tests/test_setup.py b/tests/test_setup.py index 7853ccb..e0fe006 100644 --- a/tests/test_setup.py +++ b/tests/test_setup.py @@ -7,3 +7,14 @@ def test_setup(gpiod): import blinkt with pytest.raises((RuntimeError, SystemExit)): blinkt.show() + + +def test_pixels(gpiod): + import blinkt + blinkt.set_pixel(0, 255, 0, 0) + blinkt.set_pixel(1, 0, 255, 0) + blinkt.set_pixel(2, 0, 0, 255) + + assert blinkt.set_pixel(0) == (255, 0, 0) + assert blinkt.set_pixel(1) == (0, 255, 0) + assert blinkt.set_pixel(2) == (0, 0, 255) \ No newline at end of file