Fixup lcd_control line endings

This commit is contained in:
KemoNine 2020-08-16 01:54:36 -04:00
parent f6646bb353
commit bd5f040ae1

View file

@ -1,222 +1,222 @@
#!/usr/bin/python3 #!/usr/bin/python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#################### ####################
# Inspiration / Further Reading # Inspiration / Further Reading
#################### ####################
# https://circuitpython.readthedocs.io/projects/bh1750/en/latest/ # https://circuitpython.readthedocs.io/projects/bh1750/en/latest/
# https://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3 # https://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3
# https://stackoverflow.com/questions/16148735/how-to-implement-a-watchdog-timer-in-python # https://stackoverflow.com/questions/16148735/how-to-implement-a-watchdog-timer-in-python
# https://learn.adafruit.com/adafruit-bh1750-ambient-light-sensor # https://learn.adafruit.com/adafruit-bh1750-ambient-light-sensor
# https://learn.adafruit.com/adafruit-mini-pitft-135x240-color-tft-add-on-for-raspberry-pi/overview # https://learn.adafruit.com/adafruit-mini-pitft-135x240-color-tft-add-on-for-raspberry-pi/overview
import board import board
import busio import busio
import dbus import dbus
import digitalio import digitalio
import os import os
import time import time
from threading import Timer from threading import Timer
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
import adafruit_rgb_display.st7789 as st7789 import adafruit_rgb_display.st7789 as st7789
import adafruit_bh1750 import adafruit_bh1750
# Generic watchdog timer used for backlight controls # Generic watchdog timer used for backlight controls
class Watchdog: class Watchdog:
def __init__(self, timeout, userHandler=None): # timeout in seconds def __init__(self, timeout, userHandler=None): # timeout in seconds
self.timeout = timeout self.timeout = timeout
self.handler = userHandler if userHandler is not None else self.defaultHandler self.handler = userHandler if userHandler is not None else self.defaultHandler
self.timer = Timer(self.timeout, self.handler) self.timer = Timer(self.timeout, self.handler)
# Do NOT start timer by default ; we want this triggered by reset events that come through # Do NOT start timer by default ; we want this triggered by reset events that come through
# via the inotify filesystem watcher # via the inotify filesystem watcher
#self.timer.start() #self.timer.start()
def reset(self): def reset(self):
self.timer.cancel() self.timer.cancel()
self.timer = Timer(self.timeout, self.handler) self.timer = Timer(self.timeout, self.handler)
self.timer.start() self.timer.start()
def stop(self): def stop(self):
self.timer.cancel() self.timer.cancel()
def defaultHandler(self): def defaultHandler(self):
raise self raise self
# Cheat for walking only one level deep via os.walk (faster than other options) # Cheat for walking only one level deep via os.walk (faster than other options)
def walklevel(some_dir, level=1): def walklevel(some_dir, level=1):
some_dir = some_dir.rstrip(os.path.sep) some_dir = some_dir.rstrip(os.path.sep)
assert os.path.isdir(some_dir) assert os.path.isdir(some_dir)
num_sep = some_dir.count(os.path.sep) num_sep = some_dir.count(os.path.sep)
for root, dirs, files in os.walk(some_dir): for root, dirs, files in os.walk(some_dir):
yield root, dirs, files yield root, dirs, files
num_sep_this = root.count(os.path.sep) num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this: if num_sep + level <= num_sep_this:
del dirs[:] del dirs[:]
# bh1740 lux sensor # bh1740 lux sensor
i2c = busio.I2C(board.SCL, board.SDA) i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_bh1750.BH1750(i2c) sensor = adafruit_bh1750.BH1750(i2c)
# Configuration for CS and DC pins (these are FeatherWing defaults on M0/M4): # Configuration for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.CE0) cs_pin = digitalio.DigitalInOut(board.CE0)
dc_pin = digitalio.DigitalInOut(board.D25) dc_pin = digitalio.DigitalInOut(board.D25)
reset_pin = None reset_pin = None
# Setup button pins as inputs # Setup button pins as inputs
GPIO.setup(23, GPIO.IN) GPIO.setup(23, GPIO.IN)
GPIO.setup(24, GPIO.IN) GPIO.setup(24, GPIO.IN)
# Config for display baudrate (default max is 24mhz): # Config for display baudrate (default max is 24mhz):
BAUDRATE = 64000000 BAUDRATE = 64000000
# Setup SPI bus using hardware SPI: # Setup SPI bus using hardware SPI:
spi = board.SPI() spi = board.SPI()
# Create the ST7789 display: # Create the ST7789 display:
disp = st7789.ST7789( disp = st7789.ST7789(
spi, spi,
cs=cs_pin, cs=cs_pin,
dc=dc_pin, dc=dc_pin,
rst=reset_pin, rst=reset_pin,
baudrate=BAUDRATE, baudrate=BAUDRATE,
width=135, width=135,
height=240, height=240,
x_offset=53, x_offset=53,
y_offset=40, y_offset=40,
) )
# Create blank image for drawing. # Create blank image for drawing.
# Make sure to create image with mode 'RGB' for full color. # Make sure to create image with mode 'RGB' for full color.
height = disp.width # we swap height/width to rotate it to landscape! height = disp.width # we swap height/width to rotate it to landscape!
width = disp.height width = disp.height
image = Image.new('RGB', (width, height)) image = Image.new('RGB', (width, height))
rotation = 90 rotation = 90
# Get drawing object to draw on image. # Get drawing object to draw on image.
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
# Draw a black filled box to clear the image. # Draw a black filled box to clear the image.
draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0)) draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0))
disp.image(image, rotation) disp.image(image, rotation)
# Draw some shapes. # Draw some shapes.
# First define some constants to allow easy resizing of shapes. # First define some constants to allow easy resizing of shapes.
padding = -2 padding = -2
top = padding top = padding
bottom = height - padding bottom = height - padding
# Move left to right keeping track of the current x position for drawing shapes. # Move left to right keeping track of the current x position for drawing shapes.
x = 0 x = 0
# Alternatively load a TTF font. Make sure the .ttf font file is in the # Alternatively load a TTF font. Make sure the .ttf font file is in the
# same directory as the python script! # same directory as the python script!
# Some other nice fonts to try: http://www.dafont.com/bitmap.php # Some other nice fonts to try: http://www.dafont.com/bitmap.php
#font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 24) #font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 24)
font_small = font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 24) font_small = font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 24)
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 48) font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf', 48)
# Turn on the backlight # Turn on the backlight
backlight = digitalio.DigitalInOut(board.D22) backlight = digitalio.DigitalInOut(board.D22)
backlight.switch_to_output() backlight.switch_to_output()
backlight.value = True backlight.value = True
# Watchdog timer for screen on/off control based on button presses # Watchdog timer for screen on/off control based on button presses
# Turns off screen 10s after last button press # Turns off screen 10s after last button press
# Turns on screen for 10s when starting up # Turns on screen for 10s when starting up
# Restart fim slideshow when the screen blanks so there is an indicator when it's going to change the selection # Restart fim slideshow when the screen blanks so there is an indicator when it's going to change the selection
def backlight_callback(): def backlight_callback():
global backlight global backlight
backlight.value = False backlight.value = False
sysbus = dbus.SystemBus() sysbus = dbus.SystemBus()
systemd1 = sysbus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1') systemd1 = sysbus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
manager = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Manager') manager = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Manager')
job = manager.RestartUnit('fim.service', 'fail') job = manager.RestartUnit('fim.service', 'fail')
watchdog = Watchdog(10.0, backlight_callback) watchdog = Watchdog(10.0, backlight_callback)
# Figure out which albums are present as well as the special 'All' album # Figure out which albums are present as well as the special 'All' album
albums = [ 'All' ] albums = [ 'All' ]
selected_album = 0 selected_album = 0
try: try:
with open('/etc/default/fim_album_index', 'r') as f: with open('/etc/default/fim_album_index', 'r') as f:
selected_album = int(f.readline()) selected_album = int(f.readline())
except IOError: except IOError:
pass pass
except ValueError: except ValueError:
pass pass
for root, dirs, files in walklevel('/tank/pictures'): for root, dirs, files in walklevel('/tank/pictures'):
for folder in dirs: for folder in dirs:
if folder == '.stfolder': if folder == '.stfolder':
continue continue
albums.append(folder) albums.append(folder)
albums.sort() albums.sort()
# Method for drawing on the screen # Method for drawing on the screen
# Called by the button handlers since we don't need anything more than a basic while(1) main for this setup # Called by the button handlers since we don't need anything more than a basic while(1) main for this setup
def refresh_screen(): def refresh_screen():
global width, height, x, y, top, draw, selected_album, albums, font, font_small global width, height, x, y, top, draw, selected_album, albums, font, font_small
# Draw a black filled box to clear the image. # Draw a black filled box to clear the image.
draw.rectangle((0, 0, width, height), outline=0, fill=0) draw.rectangle((0, 0, width, height), outline=0, fill=0)
# Split the line on spaces and then add a blank line if needed to avoid crashes # Split the line on spaces and then add a blank line if needed to avoid crashes
text_lines = albums[selected_album].split(' ') text_lines = albums[selected_album].split(' ')
if len(text_lines) < 2: if len(text_lines) < 2:
text_lines.append('') text_lines.append('')
# Write some text # Write some text
y = top y = top
draw.text((x, y), text_lines[0], font=font, fill='#DCDCDC') draw.text((x, y), text_lines[0], font=font, fill='#DCDCDC')
y += font.getsize('0')[1] y += font.getsize('0')[1]
draw.text((x, y), text_lines[1], font=font, fill='#DCDCDC') draw.text((x, y), text_lines[1], font=font, fill='#DCDCDC')
lux = 'Light: %.2f Lux' % sensor.lux lux = 'Light: %.2f Lux' % sensor.lux
y = height - font_small.getsize(lux)[1] y = height - font_small.getsize(lux)[1]
draw.text((x, y), lux, font=font_small, fill='#DCDCDC') draw.text((x, y), lux, font=font_small, fill='#DCDCDC')
# Display image. # Display image.
disp.image(image, rotation) disp.image(image, rotation)
# Write current album when restarting the slideshow # Write current album when restarting the slideshow
def write_selected_album(): def write_selected_album():
with open('/etc/default/fim_album', 'w') as f: with open('/etc/default/fim_album', 'w') as f:
f.write(str(selected_album)) f.write(str(selected_album))
with open('/etc/default/fim_album_path', 'w') as f: with open('/etc/default/fim_album_path', 'w') as f:
if not selected_album == 0: if not selected_album == 0:
f.write('/tank/pictures/' + albums[selected_album]) f.write('/tank/pictures/' + albums[selected_album])
else: else:
f.write('/tank/pictures') f.write('/tank/pictures')
# Interrupt callback for changing albums (up) # Interrupt callback for changing albums (up)
def up_button(channel): def up_button(channel):
global selected_album, albums, backlight global selected_album, albums, backlight
backlight.value = True backlight.value = True
selected_album += 1 selected_album += 1
if selected_album >= len(albums): if selected_album >= len(albums):
selected_album = 0 selected_album = 0
refresh_screen() refresh_screen()
write_selected_album() write_selected_album()
watchdog.reset() watchdog.reset()
# Interrupt callback for changing albums (dn) # Interrupt callback for changing albums (dn)
def dn_button(channel): def dn_button(channel):
global selected_album, albums, backlight global selected_album, albums, backlight
backlight.value = True backlight.value = True
selected_album -= 1 selected_album -= 1
if selected_album < 0: if selected_album < 0:
selected_album = len(albums) - 1 selected_album = len(albums) - 1
refresh_screen() refresh_screen()
write_selected_album() write_selected_album()
watchdog.reset() watchdog.reset()
# Setup button interrupts # Setup button interrupts
GPIO.add_event_detect(23, GPIO.FALLING, callback=up_button, bouncetime=300) GPIO.add_event_detect(23, GPIO.FALLING, callback=up_button, bouncetime=300)
GPIO.add_event_detect(24, GPIO.FALLING, callback=dn_button, bouncetime=300) GPIO.add_event_detect(24, GPIO.FALLING, callback=dn_button, bouncetime=300)
# Draw initial screen state # Draw initial screen state
refresh_screen() refresh_screen()
# Kick off watchdog to start the 10s initial 'on' status # Kick off watchdog to start the 10s initial 'on' status
watchdog.reset() watchdog.reset()
# Work with the LCD / Buttons in an infinate loop # Work with the LCD / Buttons in an infinate loop
while True: while True:
time.sleep(300) time.sleep(300)