small bugfixes and deployment setup
This commit is contained in:
parent
bddcb587a1
commit
1e6f248da1
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
keys.py
|
||||
*.pyc
|
||||
.image-cache/
|
||||
.image-cache/
|
||||
test.png
|
36
deploy/deploy.playbook.yml
Normal file
36
deploy/deploy.playbook.yml
Normal file
@ -0,0 +1,36 @@
|
||||
- name: Basic setup tasks for Raspberry Pi
|
||||
hosts: raspberrypi
|
||||
become: true
|
||||
vars:
|
||||
code_dest: /home/pi/eink
|
||||
service_target_dir: /etc/systemd/system/
|
||||
|
||||
tasks:
|
||||
- name: Pull the latest version of the code
|
||||
git:
|
||||
repo: https://git.kluster.moll.re/remoll/eink.git
|
||||
dest: "{{ code_dest }}"
|
||||
version: main
|
||||
|
||||
- name: Install from the pipenv-file
|
||||
command: "pipenv install --system --deploy"
|
||||
args:
|
||||
chdir: "{{ code_dest }}"
|
||||
|
||||
- name: Copy unit files
|
||||
template:
|
||||
src: ./templates/{{ item }}.j2
|
||||
dest: "{{ service_target_dir }}/{{ item }}"
|
||||
loop:
|
||||
- eink-show.service
|
||||
- eink-show.timer
|
||||
|
||||
- name: Enable units
|
||||
systemd:
|
||||
daemon_reload: yes
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
enabled: yes
|
||||
loop:
|
||||
- eink-show.service
|
||||
- eink-show.timer
|
57
deploy/setup.playbook.yml
Normal file
57
deploy/setup.playbook.yml
Normal file
@ -0,0 +1,57 @@
|
||||
- name: Basic setup tasks for Raspberry Pi
|
||||
hosts: raspberrypi
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Add local ssh key
|
||||
ansible.posix.authorized_key:
|
||||
user: "{{ ansible_user }}"
|
||||
state: present
|
||||
# copy file present on the controller to the remote host
|
||||
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html
|
||||
key: "{{ lookup('file', '~/.ssh/default.pub') }}"
|
||||
|
||||
- name: apt update all packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: yes
|
||||
|
||||
- name: Install required packages
|
||||
apt:
|
||||
name:
|
||||
- git
|
||||
- python3-pipenv
|
||||
- python3-dev
|
||||
- python3-setuptools
|
||||
- python3-rpi.gpio
|
||||
- python3-spidev
|
||||
state: present
|
||||
|
||||
- name: Enable SPI and I2C interfaces
|
||||
lineinfile:
|
||||
path: /boot/config.txt
|
||||
regexp: "^#?(dtparam=i2c_arm|dtparam=spi)"
|
||||
line: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- "dtparam=i2c_arm=on"
|
||||
- "dtparam=spi=on"
|
||||
|
||||
- name: Reboot the Raspberry Pi
|
||||
reboot:
|
||||
delay: 5
|
||||
connect_timeout: 20
|
||||
reboot_timeout: 300
|
||||
|
||||
- name: Wait for the Raspberry Pi to reboot
|
||||
wait_for_connection:
|
||||
delay: 5
|
||||
timeout: 300
|
||||
|
||||
- name: Add wifi networks from secrets
|
||||
template:
|
||||
src: templates/wpa_supplicant.conf.j2
|
||||
dest: /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0600
|
14
deploy/templates/eink-show.service.j2
Normal file
14
deploy/templates/eink-show.service.j2
Normal file
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Show new photo onto the eink display
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
WorkingDirectory={{ code_dest }}
|
||||
#EnvironmentFile={{ service_config_dir }}/restic.env
|
||||
|
||||
ExecStart=python main.py
|
||||
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
9
deploy/templates/eink-show.timer.j2
Normal file
9
deploy/templates/eink-show.timer.j2
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Run photo update regularly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=Tue 11:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
0
deploy/templates/wpa_supplicant.conf.j2
Normal file
0
deploy/templates/wpa_supplicant.conf.j2
Normal file
@ -1,5 +1,6 @@
|
||||
from PIL import Image
|
||||
import io
|
||||
import os
|
||||
|
||||
black_base = [0, 0, 0]
|
||||
white_base = [255, 255, 255]
|
||||
@ -41,7 +42,8 @@ class ImageShrink:
|
||||
image = Image.open(io.BytesIO(image))
|
||||
image = self.shrink(image)
|
||||
image = self.convert_to_reduced_colors(image)
|
||||
# image.save("test.png")
|
||||
if os.uname().machine == "x86_64":
|
||||
image.save("test.png")
|
||||
return image
|
||||
|
||||
|
||||
@ -52,5 +54,9 @@ class ImageShrink:
|
||||
|
||||
|
||||
def convert_to_reduced_colors(self, image: Image) -> Image:
|
||||
# convert image to RGB if it's not first
|
||||
if image.mode != "RGB":
|
||||
print("Converting image to RGB")
|
||||
image = image.convert("RGB")
|
||||
new_image = image.quantize(colors = len(palette), palette=ref_image, dither=True)
|
||||
return new_image
|
||||
|
25
image_get.py
25
image_get.py
@ -14,18 +14,15 @@ class ImageGetter:
|
||||
headers = {
|
||||
"x-api-key": keys.immich_api_key
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.cached_num = 10
|
||||
self.cached_path = Path("./.image-cache/")
|
||||
pass
|
||||
cached_num = 10
|
||||
cached_path = Path("./.image-cache/")
|
||||
|
||||
|
||||
def get_random_image(self) -> bytearray:
|
||||
try:
|
||||
ids = self.get_random_image_ids(num=self.cached_num + 1)
|
||||
bytes = self.get_image_file(ids[0])
|
||||
self.save_cached_files(ids[1:])
|
||||
id = self.get_random_image_ids()[0]
|
||||
bytes = self.get_image_file(id)
|
||||
self.save_cached_files()
|
||||
except (h.ConnectError, h.HTTPStatusError, h.NetworkError, h.RequestError, h.DecodingError, h.TransportError, ImageGetException):
|
||||
print("Loading image from cache")
|
||||
bytes = self.load_cached_file()
|
||||
@ -50,6 +47,7 @@ class ImageGetter:
|
||||
ids = []
|
||||
for i in range(num):
|
||||
image = random.choice(images)
|
||||
print(f"Image considered: {image['exifInfo']}")
|
||||
ids.append(image["id"])
|
||||
|
||||
return ids
|
||||
@ -66,16 +64,21 @@ class ImageGetter:
|
||||
return response.content
|
||||
|
||||
|
||||
def save_cached_files(self, image_ids: list[str]) -> None:
|
||||
def save_cached_files(self) -> None:
|
||||
"""Ensures self.cached_num files are at self.cached_path at any time"""
|
||||
if not self.cached_path.exists():
|
||||
self.cached_path.mkdir()
|
||||
|
||||
present_count = len(list(self.cached_path.glob("*")))
|
||||
for i in range(self.cached_num - present_count):
|
||||
missing = self.cached_num - present_count
|
||||
if missing == 0:
|
||||
return
|
||||
|
||||
ids = self.get_random_image_ids(missing)
|
||||
for i, id in enumerate(ids):
|
||||
print(f"Caching image {i + 1}")
|
||||
new_cache = self.cached_path / f"{uuid.uuid4()}"
|
||||
new_cache.write_bytes(self.get_image_file(image_ids[i]))
|
||||
new_cache.write_bytes(self.get_image_file(id))
|
||||
|
||||
|
||||
def load_cached_file(self) -> bytearray:
|
||||
|
@ -1,8 +1,6 @@
|
||||
from PIL import Image, ImageDraw
|
||||
from waveshare-epaper import epd7in3f
|
||||
|
||||
|
||||
|
||||
# BLACK = 0x000000 # 0000 BGR
|
||||
# WHITE = 0xffffff # 0001
|
||||
# GREEN = 0x00ff00 # 0010
|
||||
|
Loading…
x
Reference in New Issue
Block a user