lots of new code, probably doesnt run
This commit is contained in:
parent
aefccf6d03
commit
2a5427fadb
BIN
._README.md
Normal file
BIN
._README.md
Normal file
Binary file not shown.
BIN
._addtoDB.py
Normal file
BIN
._addtoDB.py
Normal file
Binary file not shown.
BIN
._carousel.py
Normal file
BIN
._carousel.py
Normal file
Binary file not shown.
BIN
._refreshdb.py
Normal file
BIN
._refreshdb.py
Normal file
Binary file not shown.
BIN
._ssbpost.sh
Normal file
BIN
._ssbpost.sh
Normal file
Binary file not shown.
@ -26,7 +26,8 @@ recommended hardware components:
|
||||
| micro-sd card | variable, $5.8 on amazon | |
|
||||
| buttons | $7 | https://www.adafruit.com/product/3582 |
|
||||
| camera | $7 | [aliexpres](https://www.aliexpress.com/item/32788881215.html?spm=a2g0s.12269583.0.0.55eb6619CDSuac) (confirmed works) or [alt-aliexpress](https://www.aliexpress.com/item/32293433078.html?spm=a2g0s.9042311.0.0.349f4c4dYCXYQ3)|
|
||||
| total: | | $65 plus shipping and tax, ~$75 total |
|
||||
| printer | $50 | buy this https://www.adafruit.com/product/2751 |
|
||||
| total: | | ~$115 |
|
||||
|
||||
you'll also need a micro-usb cable, usb power supply and materials to build a case from.
|
||||
|
||||
@ -63,11 +64,14 @@ you'll also need a micro-usb cable, usb power supply and materials to build a ca
|
||||
```
|
||||
sudo apt update -y && sudo apt upgrade -y
|
||||
sudo apt install unattended-upgrades python-dev python-pip python-buttonshim libjpeg-dev zlib1g-dev git -y
|
||||
pip install spidev tinydb pillow --no-cache-dir
|
||||
pip3 install spidev tinydb pillow pyqrcode qrcode --no-cache-dir
|
||||
```
|
||||
|
||||
(third line can take a while...)
|
||||
|
||||
probably also need to install _some_ of the libraries at https://github.com/adafruit/Python-Thermal-Printer but not all
|
||||
`sudo apt-get install git cups build-essential libcups2-dev libcupsimage2-dev python3-serial python3-pil python-unidecode` maybe don't need alllll of it
|
||||
|
||||
Now need to install an ARMv6 compatible NPM. This should work:
|
||||
```
|
||||
curl -o node.tar.gz https://unofficial-builds.nodejs.org/download/release/v13.8.0/node-v13.8.0-linux-armv6l.tar.gz
|
||||
|
17
addtoDB.py
17
addtoDB.py
@ -4,6 +4,7 @@
|
||||
#this script takes a file as an option and adds that file to the db and posts the file to scuttlebutt
|
||||
|
||||
import optparse
|
||||
import iterparse
|
||||
import traceback
|
||||
import os, sys
|
||||
import subprocess
|
||||
@ -26,12 +27,12 @@ def main():
|
||||
|
||||
|
||||
|
||||
def addFile(pathToImage, pathToDB, SSBidentify):
|
||||
def addFile(pathToImage, pathToDB, SSBidentify, composite):
|
||||
#init db
|
||||
db = TinyDB(pathToDB)
|
||||
|
||||
#add to db
|
||||
db.insert({'path': pathToImage, 'date': 4, 'ssb': SSBidentify})
|
||||
db.insert({'path': pathToImage, 'date': 4, 'ssb': SSBidentify, 'composite': composite})
|
||||
print("all done, added to db")
|
||||
#print("heres the whole db")
|
||||
#print(db.all())
|
||||
@ -45,7 +46,17 @@ def addFile(pathToImage, pathToDB, SSBidentify):
|
||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||
exit()
|
||||
|
||||
return pathToImage
|
||||
|
||||
# get the ssb json from the bash command we just ran
|
||||
newssb=result.stdout.read()
|
||||
|
||||
# iterate through new ssb posts
|
||||
for decoded in iterparse.parsy(newssb):
|
||||
# get the key for the post we just made
|
||||
key = decoded['key']
|
||||
|
||||
|
||||
return key
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
249
carousel.py
249
carousel.py
@ -16,6 +16,8 @@ import buttonshim
|
||||
import addtoDB
|
||||
import refreshdb
|
||||
import configparser
|
||||
import pyqrcode
|
||||
import qrcode
|
||||
from tinydb import TinyDB, Query
|
||||
from PIL import Image,ImageDraw,ImageFont
|
||||
|
||||
@ -63,8 +65,8 @@ try:
|
||||
bmp = Image.open(str(flierPath))
|
||||
Limage.paste(bmp)
|
||||
draw = ImageDraw.Draw(Limage)
|
||||
draw.text((2, 280), 'EBB', font = font18, fill = 255)
|
||||
draw.text((2, 300), 'version .02', font = font18, fill = 255)
|
||||
# draw.text((2, 280), 'EBB', font = font18, fill = 255)
|
||||
draw.text((2, 300), 'Scuttlebooth 2', font = font18, fill = 255)
|
||||
epd.display(epd.getbuffer(Limage))
|
||||
time.sleep(2)
|
||||
epd.sleep()
|
||||
@ -109,6 +111,19 @@ buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||
|
||||
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||
|
||||
# img concat from https://note.nkmk.me/en/python-pillow-concat-images/
|
||||
def get_concat_v(im1, im2):
|
||||
dst = Image.new('RGB', (im1.width, im1.height + im2.height))
|
||||
dst.paste(im1, (0, 0))
|
||||
dst.paste(im2, (0, im1.height))
|
||||
return dst
|
||||
|
||||
def get_concat_h(im1, im2):
|
||||
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
|
||||
dst.paste(im1, (0, 0))
|
||||
dst.paste(im2, (im1.width, 0))
|
||||
return dst
|
||||
|
||||
## MAIN LOOP ##
|
||||
while True:
|
||||
# chill for a bit, keep track of how long we're chilling
|
||||
@ -173,68 +188,102 @@ while True:
|
||||
#take pic
|
||||
if button_flag == "button_1":
|
||||
|
||||
#generate unique file_name
|
||||
unique = uuid.uuid4()
|
||||
unique = str(unique)
|
||||
jpgpath = imagesPath + unique + '.jpg'
|
||||
#generate 3 unique file_names
|
||||
unique1 = uuid.uuid4()
|
||||
unique1 = str(unique1)
|
||||
jpgpath1 = imagesPath + unique1 + '.jpg'
|
||||
unique2 = uuid.uuid4()
|
||||
unique2 = str(unique2)
|
||||
jpgpath2 = imagesPath + unique2 + '.jpg'
|
||||
unique3 = uuid.uuid4()
|
||||
unique3 = str(unique3)
|
||||
jpgpath3 = imagesPath + unique3 + '.jpg'
|
||||
|
||||
#generate unique bmp name
|
||||
bmpath = imagesPath + unique + '.bmp'
|
||||
|
||||
|
||||
#generate unique bmp names
|
||||
bmpath1 = imagesPath + unique1 + '.bmp'
|
||||
bmpath2 = imagesPath + unique2 + '.bmp'
|
||||
bmpath3 = imagesPath + unique3 + '.bmp'
|
||||
|
||||
|
||||
#loop in case we wanna re-take it
|
||||
exitPhotoMode = False
|
||||
while exitPhotoMode == False:
|
||||
|
||||
#take photo
|
||||
|
||||
#take fullsize photos
|
||||
try:
|
||||
result = subprocess.call(['raspistill', '-o', jpgpath, '-vf', '-hf', '-w', '300', '-h', '400', '-t', '1000'])
|
||||
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath1, '-vf', '-hf', '-w', '600', '-h', '800', '-t', '1000'])
|
||||
except:
|
||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||
exit()
|
||||
|
||||
#convert to bmp
|
||||
im = Image.open(jpgpath)
|
||||
im = im.convert("1")
|
||||
im.save(bmpath)
|
||||
|
||||
#display the image
|
||||
try:
|
||||
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath2, '-vf', '-hf', '-w', '600', '-h', '800', '-t', '1000'])
|
||||
except:
|
||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||
exit()
|
||||
try:
|
||||
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath3, '-vf', '-hf', '-w', '600', '-h', '800', '-t', '1000'])
|
||||
except:
|
||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||
exit()
|
||||
|
||||
#create half-size bmps for cycling through
|
||||
half1 = Image.open(jpgpath1)
|
||||
half2 = Image.open(jpgpath2)
|
||||
half3 = Image.open(jpgpath3)
|
||||
newsize = (300, 400)
|
||||
half1 = half1.resize(newsize)
|
||||
half2 = half1.resize(newsize)
|
||||
half3 = half1.resize(newsize)
|
||||
half1 = half1.convert("1")
|
||||
half1.save(bmpath1)
|
||||
half2 = im2.convert("1")
|
||||
half2.save(bmpath2)
|
||||
half3 = im3.convert("1")
|
||||
half3.save(bmpath3)
|
||||
|
||||
|
||||
|
||||
## CREATE screen image to display:
|
||||
|
||||
# create quarter sized bmps
|
||||
im1 = Image.open(jpgpath1)
|
||||
im2 = Image.open(jpgpath2)
|
||||
im3 = Image.open(jpgpath3)
|
||||
newsize = (150, 200)
|
||||
im1 = im1.resize(newsize)
|
||||
im2 = im2.resize(newsize)
|
||||
im3 = im3.resize(newsize)
|
||||
|
||||
#add quarter sized photos and instructions to the image to be rendered
|
||||
instructions = imagesPath + 'instructions.bmp'
|
||||
im4 = Image.open(instructions)
|
||||
Limage.paste(im1, (0,0))
|
||||
Limage.paste(im2, (150,0))
|
||||
Limage.paste(im3, (0,200))
|
||||
Limage.paste(im4, (150,200))
|
||||
|
||||
#add the menu
|
||||
# draw = ImageDraw.Draw(Limage)
|
||||
# font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 10)
|
||||
# draw.text((152, 200), 'press button 1 to:', font = font18, fill = 255)
|
||||
# draw.text((152, 220), 'post online', font = font18, fill = 255)
|
||||
# draw.text((152, 240), 'button 2: post photo', font = font18, fill = 255)
|
||||
# draw.text((152, 260), 'here only', font = font18, fill = 255)
|
||||
# draw.text((152, 280), 'button 3: retake', font = font18, fill = 255)
|
||||
# draw.text((152, 00), 'buttons 4 or 5:', font = font18, fill = 255)
|
||||
# draw.text((152, 640), 'exit photo mode', font = font18, fill = 255)
|
||||
|
||||
# display the image
|
||||
epd.init()
|
||||
bmp = Image.open(bmpath)
|
||||
Limage.paste(bmp)
|
||||
epd.display(epd.getbuffer(Limage))
|
||||
|
||||
#wait for user decision on photo
|
||||
waited = 0
|
||||
|
||||
|
||||
|
||||
#pulse LED while we wait for user to press something
|
||||
button_flag = "none"
|
||||
|
||||
#strobe light green yellow red for a while
|
||||
while (button_flag == "none") and (waited < 30):
|
||||
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
||||
time.sleep(.2)
|
||||
buttonshim.set_pixel(0xFF, 0xFF, 0x00)
|
||||
time.sleep(.2)
|
||||
buttonshim.set_pixel(0x00, 0xFF, 0x00)
|
||||
time.sleep(.2)
|
||||
buttonshim.set_pixel(0xFF, 0xFF, 0x00)
|
||||
time.sleep(.2)
|
||||
waited+=1
|
||||
|
||||
#if still not sure, give em the menu
|
||||
if button_flag == "none":
|
||||
#ok time to display menu
|
||||
draw = ImageDraw.Draw(Limage)
|
||||
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
|
||||
draw.text((2, 0), 'press button 1 to:', font = font18, fill = 255)
|
||||
draw.text((2, 40), 'post online', font = font18, fill = 255)
|
||||
draw.text((2, 80), 'button 2: post photo', font = font18, fill = 255)
|
||||
draw.text((2, 120), 'here only', font = font18, fill = 255)
|
||||
draw.text((2, 160), 'button 3: retake', font = font18, fill = 255)
|
||||
draw.text((2, 200), 'buttons 4 or 5:', font = font18, fill = 255)
|
||||
draw.text((2, 240), 'exit photo mode', font = font18, fill = 255)
|
||||
epd.display(epd.getbuffer(Limage))
|
||||
|
||||
#now just wait for them to press something
|
||||
while button_flag == "none":
|
||||
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
||||
time.sleep(.2)
|
||||
@ -247,12 +296,78 @@ while True:
|
||||
|
||||
#led to thinking mode
|
||||
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||
|
||||
|
||||
# if we're printing, generate image to print
|
||||
if button_flag == "button_1" or button_flag == "button_2" or button_flag == "button_3":
|
||||
#generate unique file_name
|
||||
unique = uuid.uuid4()
|
||||
unique = str(unique)
|
||||
composite = imagesPath + unique + '.jpg'
|
||||
|
||||
# concatenate images and save concatenated image at composite (is filepath)
|
||||
header = Image.open(composite)
|
||||
im1 = Image.open(jpgpath1)
|
||||
im2 = Image.open(jpgpath2)
|
||||
im3 = Image.open(jpgpath3)
|
||||
|
||||
get_concat_v(header, im1).save(composite)
|
||||
concaz = Image.open(conposite)
|
||||
get_concat_v(concaz, im2).save(composite)
|
||||
concaz = Image.open(conposite)
|
||||
get_concat_v(concaz, im3).save(composite)
|
||||
concaz = Image.open(conposite)
|
||||
|
||||
|
||||
#post to ssb
|
||||
#post to ssb and print
|
||||
if button_flag == "button_1":
|
||||
button_flag == "null"
|
||||
|
||||
|
||||
#add the photo to the db/ssb
|
||||
addtoDB.addFile(bmpath,dbPath,0)
|
||||
key = addtoDB.addFile(bmpath,dbPath,0,composite)
|
||||
|
||||
|
||||
|
||||
# Create qr code
|
||||
#from https://ourcodeworld.com/articles/read/554/how-to-create-a-qr-code-image-or-svg-in-python
|
||||
qr = qrcode.QRCode(
|
||||
version = 1,
|
||||
error_correction = qrcode.constants.ERROR_CORRECT_H,
|
||||
box_size = 4,
|
||||
border = 1,
|
||||
)
|
||||
# Add data
|
||||
qr.add_data(key)
|
||||
qr.make(fit=True)
|
||||
# Create an image from the QR Code instance
|
||||
img = qr.make_image()
|
||||
|
||||
|
||||
|
||||
# concatenate QR instructions with QR
|
||||
whereQRinstructionsAre = imagesPath + 'ssbqrinstgurct.bmp'
|
||||
qrInstruct = Image.open(whereQRinstructionsAre)
|
||||
|
||||
|
||||
|
||||
# concatenate QR+instructions to full composite for print
|
||||
|
||||
|
||||
#generate unique file_name
|
||||
unique = uuid.uuid4()
|
||||
unique = str(unique)
|
||||
FULLcomposite = imagesPath + unique + '.jpg'
|
||||
|
||||
get_concat_v(concaz, (get_concat_h(qrInstruct, img))).save(FULLcomposite)
|
||||
|
||||
# bash lp of Fullcomposite
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#update dbCount
|
||||
for item in db:
|
||||
dbCount = item.doc_id
|
||||
@ -267,7 +382,14 @@ while True:
|
||||
draw.text((2, 260), 'online!', font = font18, fill = 255)
|
||||
epd.display(epd.getbuffer(Limage))
|
||||
|
||||
#post only locally
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#post only locally and print
|
||||
if button_flag == "button_2":
|
||||
button_flag == "null"
|
||||
#add that file to the db. -1 tells addtoDB not to post to ssb.
|
||||
@ -285,17 +407,32 @@ while True:
|
||||
draw.text((2, 260), 'to this device only', font = font18, fill = 255)
|
||||
epd.display(epd.getbuffer(Limage))
|
||||
|
||||
#reshoot the picture
|
||||
#just print
|
||||
if button_flag == "button_3":
|
||||
button_flag == "null"
|
||||
#nothin! loop around... exitPhotoMode still false
|
||||
|
||||
try:
|
||||
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath3, '-vf', '-hf', '-w', '600', '-h', '800', '-t', '1000'])
|
||||
except:
|
||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||
exit()
|
||||
|
||||
|
||||
#exit photomode, delete photo
|
||||
if (button_flag == "button_4") or (button_flag == "button_5"):
|
||||
#reshoot
|
||||
if (button_flag == "button_4"):
|
||||
button_flag == "null"
|
||||
exitPhotoMode = True
|
||||
os.remove(bmpath)
|
||||
os.remove(jpgpath)
|
||||
|
||||
#exit photo mode
|
||||
if (button_flag == "button_5"):
|
||||
button_flag == "null"
|
||||
exitPhotoMode = True
|
||||
os.remove(bmpath)
|
||||
os.remove(jpgpath)
|
||||
|
||||
|
||||
#led off
|
||||
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||
|
BIN
install/images/._header.jpg
Normal file
BIN
install/images/._header.jpg
Normal file
Binary file not shown.
BIN
install/images/._instructions.bmp
Normal file
BIN
install/images/._instructions.bmp
Normal file
Binary file not shown.
BIN
install/images/._ssbqrinstgurct.bmp
Normal file
BIN
install/images/._ssbqrinstgurct.bmp
Normal file
Binary file not shown.
BIN
install/images/header.jpg
Normal file
BIN
install/images/header.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
BIN
install/images/instructions.bmp
Normal file
BIN
install/images/instructions.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
BIN
install/images/ssbqrinstgurct.bmp
Normal file
BIN
install/images/ssbqrinstgurct.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 527 KiB |
@ -4,7 +4,7 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash run-ssb.sh
|
||||
WorkingDirectory=/home/pi/bb
|
||||
WorkingDirectory=/home/pi/ebb
|
||||
StandardOutput=inherit
|
||||
StandardError=inherit
|
||||
Restart=always
|
||||
|
Loading…
Reference in New Issue
Block a user