Compare commits

8 Commits

19 changed files with 419 additions and 131 deletions

BIN
._README.md Normal file

Binary file not shown.

BIN
._addtoDB.py Normal file

Binary file not shown.

BIN
._carousel.py Normal file

Binary file not shown.

BIN
._epd4in2.py Normal file

Binary file not shown.

BIN
._refreshdb.py Normal file

Binary file not shown.

BIN
._ssbpost.sh Normal file

Binary file not shown.

View File

@@ -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,21 @@ 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
Do need to do this to install the printer:
```sudo lpadmin -p ZJ-58 -E -v serial:/dev/usb/lp0?baud=19200 -m zjiang/ZJ-58.ppd
sudo lpoptions -d ZJ-58```
certainly CUPS will cause you issues and you will need to reference https://www.cups.org/doc/man-cupsd.conf.html
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
@@ -77,6 +88,10 @@ sudo cp -r node-v13.8.0-linux-armv6l/* /usr/local
If that doesn't work you can [read more about installing node on arm v6 architecture](https://www.thepolyglotdeveloper.com/2018/03/install-nodejs-raspberry-pi-zero-w-nodesource/). Also [the builds are here](https://unofficial-builds.nodejs.org/).
might need to run `curl https://get.pimoroni.com/buttonshim | bash` to get the buttons to work
<br>
#### clone the repo
ideally right in your home directory.
@@ -84,7 +99,12 @@ ideally right in your home directory.
`git clone https://git.laboratoryb.org/trav/ebb.git`
#### setup SSB
I can't remember how I got ssb-server to work, `sudo npm install -g ssb-server` throws `illegal instruction`. Something to do with a woknky version of Node. So my **extremely** hacky workaround is to unzip `ssb-server.zip` from the install directory into `/usr/local/lib/node_modules/`. This is v bad and needs to be fixed asap. [SSB-server](https://github.com/ssbc/ssb-server) is made available via the MIT licese.
I can't remember how I got ssb-server to work, `sudo npm install -g ssb-server` throws `illegal instruction`. Something to do with a woknky version of Node.
##### My **extremely** hacky workaround:
1. `sudo npm install -g ssb-server` to add all the npm-side ssb stuff
2. unzip `ssb-server.zip` from the install directory into `/usr/local/lib/node_modules/` to actually have a working SSB server.
This is v bad and needs to be fixed asap. [SSB-server](https://github.com/ssbc/ssb-server) is made available via the MIT licese.
As long as the EBB repo is at `/home/pi/ebb` the following service files should be configured fine. Otherwise you gotta edit ssb.service and ebb-carousel.service and update the `WorkingDirectory` field.

View File

@@ -4,8 +4,10 @@
#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 json
import subprocess
from tinydb import TinyDB, Query
@@ -25,27 +27,43 @@ def main():
exit(1)
def addToDB(pathToImage, pathToDB,composite):
def addFile(pathToImage, pathToDB, SSBidentify):
#init db
#init db
db = TinyDB(pathToDB)
#add to db
db.insert({'path': pathToImage, 'date': 4, 'ssb': SSBidentify})
db.insert({'path': pathToImage, 'date': 4, 'ssb': '-2', 'composite': composite})
print("all done, added to db")
#print("heres the whole db")
#print(db.all())
def addToSSB(pathToImage, pathToDB, SSBidentify):
#unless you say don't post to ssb, post to ssb
if SSBidentify != -1:
#SEND TO SSB! WOOOO
try:
result = subprocess.call('./ssbpost.sh ' + pathToImage, shell=True)
result = subprocess.Popen('./ssbpost.sh ' + pathToImage, shell=True, stdout=subprocess.PIPE, )
except:
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()
print(newssb)
# ADD HERE A CHECK that newssb is _anything_ if ssb-server isn't running that may show as garbage that will crash the program
#convert string to object
json_object = json.loads(newssb)
# get the key for the post we just made
key = json_object["key"]
return key
if __name__ == '__main__':

View File

@@ -16,8 +16,10 @@ import buttonshim
import addtoDB
import refreshdb
import configparser
import pyqrcode
import qrcode
from tinydb import TinyDB, Query
from PIL import Image,ImageDraw,ImageFont
from PIL import Image,ImageDraw,ImageFont,ImageEnhance
## INITIALIZE ##
@@ -27,7 +29,7 @@ buttonshim.set_pixel(0xFF, 0x00, 0xFF)
#intervalTime is how many seconds before moving to next image (300 = 5 minutes)
#sync time is how many seconds before refreshing the DB from SSB
#this should be moved into the config file...
intervalTime = 1800
intervalTime = 200
syncTime = 3600
#keep track of where we are moving through intervalTime, syncTime and where we are in the db, and what flier we're currently displaying
timeIndex = 1200
@@ -63,10 +65,9 @@ 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()
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
@@ -76,21 +77,21 @@ except:
@buttonshim.on_press(buttonshim.BUTTON_A)
def button_a(button, pressed):
global button_flag
buttonshim.set_pixel(0xFF, 0x00, 0x00)
# buttonshim.set_pixel(0xFF, 0x00, 0x00)
button_flag = "button_1"
@buttonshim.on_press(buttonshim.BUTTON_B)
def button_b(button, pressed):
global button_flag
buttonshim.set_pixel(0x00, 0x00, 0xFF)
# buttonshim.set_pixel(0x00, 0x00, 0xFF)
button_flag = "button_2"
@buttonshim.on_press(buttonshim.BUTTON_C)
def button_c(button, pressed):
global button_flag
buttonshim.set_pixel(0x00, 0x00, 0xFF)
# buttonshim.set_pixel(0x00, 0x00, 0xFF)
button_flag = "button_3"
@buttonshim.on_press(buttonshim.BUTTON_D)
@@ -109,12 +110,62 @@ 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
def get_concat_h_blank(im1, im2, color=(0, 0, 0)):
dst = Image.new('RGB', (im1.width + im2.width, max(im1.height, im2.height)), color)
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
def pulse(speed):
time.sleep(1)
for scale in range(0, speed):
if scale >= 1:
scale = scale / speed
buttonshim.set_pixel(0x00, 0x00, int(0xff * scale))
for scale in range(speed, 0,-1):
if scale >= 1:
scale = scale / speed
buttonshim.set_pixel(0x00, 0x00, int(0xff * scale))
time.sleep(1)
for scale in range(0, speed):
if scale >= 1:
scale = scale / speed
buttonshim.set_pixel(0x00, int(0xff * scale), 0x00)
for scale in range(speed, 0,-1):
if scale >= 1:
scale = scale / speed
buttonshim.set_pixel(0x00, int(0xff * scale), 0x00)
time.sleep(1)
for scale in range(0, speed):
buttonshim.set_pixel(0xFF, 0x00, 0x00)
time.sleep(.02)
buttonshim.set_pixel(0xFF, 0xFF, 0x00)
time.sleep(.02)
buttonshim.set_pixel(0x00, 0xFF, 0x00)
time.sleep(.02)
buttonshim.set_pixel(0xFF, 0xFF, 0x00)
time.sleep(.02)
time.sleep(1)
## MAIN LOOP ##
while True:
# chill for a bit, keep track of how long we're chilling
time.sleep(2)
print("time:", timeIndex, "/", intervalTime, "index", dbIndex, "/", dbCount, "sync time:", syncIndex, "/", syncTime)
#iterate through syncTime and image time
syncIndex+=2
timeIndex+=2
@@ -123,10 +174,11 @@ while True:
if syncIndex >= syncTime:
#light up red while syncing db
buttonshim.set_pixel(0xFF, 0x00, 0x00)
refreshdb.fresh()
# refreshdb.fresh()
print ("uhhhhhhh skipping ssb refresh because broken also solpunk one stuck in customs rn :'(")
#db count may have changed
for item in db:
dbCount = item.doc_id
# for item in db:
# dbCount = item.doc_id
syncIndex = 0
buttonshim.set_pixel(0x00, 0x00, 0x00)
@@ -160,7 +212,6 @@ while True:
bmp = Image.open(flierPath)
Limage.paste(bmp)
epd.display(epd.getbuffer(Limage))
time.sleep(2)
timeIndex+=2
epd.sleep()
@@ -173,68 +224,112 @@ 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
pulse(20)
try:
result = subprocess.call(['raspistill', '-o', jpgpath, '-vf', '-hf', '-w', '300', '-h', '400', '-t', '1000'])
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath1, '--brightness', '55', '--contrast', '1.25','-vf', '-hf', '-w', '600', '-h', '800', '-t', '20'])
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)
pulse(20)
#display the image
try:
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath2, '--brightness', '55', '--contrast', '1.25','-vf', '-hf', '-w', '600', '-h', '800', '-t', '20'])
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
pulse(20)
try:
result = subprocess.call(['raspistill', '-rot', '180', '-o', jpgpath3, '--brightness', '55', '--contrast', '1.25', '-vf', '-hf', '-w', '600', '-h', '800', '-t', '20'])
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
buttonshim.set_pixel(0x00, 0x00, 0xff)
#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 = half2.resize(newsize)
half3 = half3.resize(newsize)
half1 = half1.convert("1")
half1.save(bmpath1)
half2 = half2.convert("1")
half2.save(bmpath2)
half3 = half3.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)
@@ -248,11 +343,90 @@ while True:
#led to thinking mode
buttonshim.set_pixel(0x00, 0x00, 0xFF)
#post to ssb
# 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)
headerIsAt = imagesPath + 'header.jpg'
header = Image.open(headerIsAt)
im1 = Image.open(jpgpath1)
im2 = Image.open(jpgpath2)
im3 = Image.open(jpgpath3)
get_concat_v(header, im1).save(composite)
concaz = Image.open(composite)
get_concat_v(concaz, im2).save(composite)
concaz = Image.open(composite)
get_concat_v(concaz, im3).save(composite)
concaz = Image.open(composite)
#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)
#add the photo strip to ssb
key = addtoDB.addToSSB(composite,dbPath,0)
# 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 = 6,
border = 1,
)
# Add data
qr.add_data(key)
qr.make(fit=True)
# Create an image from the QR Code instance
img = qr.make_image()
whereToSaveQR = imagesPath + 'QR.jpg'
img.save(whereToSaveQR)
# generate full composite for printing
color=(255, 255, 255)
dst = Image.new('RGB', (600, 2833), color)
dst.paste(concaz, (0, 0))
whereQRinstructionsAre = imagesPath + 'ssbqrinstgurct.jpg'
qrInstruct = Image.open(whereQRinstructionsAre)
dst.paste(qrInstruct, (0,2575))
dst.paste(img, (342,2575))
# whereInstructionsPlusQRis = imagesPath + 'instructionsPlusQR.jpg'
# get_concat_h_blank(qrInstruct, img, (255, 255, 255)).save(whereInstructionsPlusQRis)
# instr = Image.open(whereInstructionsPlusQRis)
#generate unique file_name
unique = uuid.uuid4()
unique = str(unique)
FULLcomposite = imagesPath + unique + '.jpg'
# save the full composite image for printing
dst.save(FULLcomposite)
#add each photo to the db
addtoDB.addToDB(bmpath1,dbPath,FULLcomposite)
addtoDB.addToDB(bmpath2,dbPath,FULLcomposite)
addtoDB.addToDB(bmpath3,dbPath,FULLcomposite)
# concatenate existing composite image with the instructions+QR composite for full composite image for print
# get_concat_v(concaz, instr).save(FULLcomposite)
# print Fullcomposite
try:
result = subprocess.call('lp ' + FULLcomposite, shell=True)
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
#update dbCount
for item in db:
dbCount = item.doc_id
@@ -260,21 +434,39 @@ while True:
#display the image to clear the menu (also display text "posted")
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
bmp = Image.open(bmpath)
bmp = Image.open(bmpath1)
Limage.paste(bmp)
draw = ImageDraw.Draw(Limage)
draw.text((2, 240), 'PHOTO POSTED', font = font18, fill = 255)
draw.text((2, 260), 'online!', font = font18, fill = 255)
draw.text((2, 240), 'photostrip posted', font = font18, fill = 255)
draw.text((2, 260), 'to SSB', font = font18, fill = 255)
epd.display(epd.getbuffer(Limage))
# move dbIndex to current photo so that reprint works right
dbIndex = dbCount
#post only locally
#post only locally and print
if button_flag == "button_2":
#led to thinking mode
buttonshim.set_pixel(0x00, 0x00, 0xFF)
button_flag == "null"
#add that file to the db. -1 tells addtoDB not to post to ssb.
addtoDB.addFile(bmpath,dbPath,-1)
#add each photo to the db
addtoDB.addToDB(bmpath1,dbPath,composite)
addtoDB.addToDB(bmpath2,dbPath,composite)
addtoDB.addToDB(bmpath3,dbPath,composite)
#update dbCount
for item in db:
dbCount = item.doc_id
# print concaz that we already generated
try:
result = subprocess.call('lp ' + composite, shell=True)
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
exitPhotoMode = True
#display the image to clear the menu (also display text "posted")
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
@@ -284,18 +476,56 @@ while True:
draw.text((2, 240), 'PHOTO POSTED', font = font18, fill = 255)
draw.text((2, 260), 'to this device only', font = font18, fill = 255)
epd.display(epd.getbuffer(Limage))
# move dbIndex to current photo so that reprint works right
dbIndex = dbCount
#reshoot the picture
#just print
if button_flag == "button_3":
#led to thinking mode
buttonshim.set_pixel(0x00, 0x00, 0xFF)
button_flag == "null"
#nothin! loop around... exitPhotoMode still false
#exit photomode, delete photo
if (button_flag == "button_4") or (button_flag == "button_5"):
button_flag == "null"
# print concaz that we already generated
try:
result = subprocess.call('lp ' + composite, shell=True)
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
exitPhotoMode = True
os.remove(bmpath)
os.remove(jpgpath)
#reshoot
if (button_flag == "button_4"):
# delete images
os.remove(bmpath1)
os.remove(bmpath2)
os.remove(bmpath3)
os.remove(jpgpath1)
os.remove(jpgpath2)
os.remove(jpgpath3)
# reset buttonflag and loop around to take pic again
button_flag == "null"
#delete images and exit photo mode
if (button_flag == "button_5"):
button_flag == "null"
buttonshim.set_pixel(0x00, 0x00, 0xff)
exitPhotoMode = True
#delete the images we took
os.remove(bmpath1)
os.remove(bmpath2)
os.remove(bmpath3)
os.remove(jpgpath1)
os.remove(jpgpath2)
os.remove(jpgpath3)
# display next image
timeIndex = intervalTime
#led off
buttonshim.set_pixel(0x00, 0x00, 0x00)
@@ -308,13 +538,15 @@ while True:
#move to the next image
elif button_flag == "button_2":
print ("next image")
timeIndex = intervalTime
button_flag = "null"
buttonshim.set_pixel(0x00, 0x00, 0xFF)
print ("next image")
timeIndex = intervalTime
button_flag = "null"
#go back to the previous image
elif button_flag == "button_3":
buttonshim.set_pixel(0x00, 0x00, 0xFF)
print ("previous image")
#we go back 2 because we have to account for calling timeIndex = intervalTime iterates forward by 1
dbIndex-=2
@@ -325,7 +557,8 @@ while True:
#delete current image
elif button_flag == "button_4":
elif button_flag == "button_5":
buttonshim.set_pixel(0x00, 0x00, 0xFF)
button_flag = "null"
#can't delete the default image
@@ -339,7 +572,7 @@ while True:
draw.text((2, 0), 'Are you sure', font = font18, fill = 255)
draw.text((2, 40), 'you want to delete', font = font18, fill = 255)
draw.text((2, 80), 'the current image?', font = font18, fill = 255)
draw.text((2, 120), 'Press button 4', font = font18, fill = 255)
draw.text((2, 120), 'Press button 5', font = font18, fill = 255)
draw.text((2, 160), 'again to confirm.', font = font18, fill = 255)
draw.text((2, 200), 'Press any other', font = font18, fill = 255)
draw.text((2, 240), 'button for no.', font = font18, fill = 255)
@@ -354,7 +587,7 @@ while True:
time.sleep(.05)
#sounds like delete time
if button_flag == "button_4":
if button_flag == "button_5":
Fruit = Query()
#results = db.search(Fruit.path == flierPath)
db.remove(Fruit.path == flierPath)
@@ -371,37 +604,39 @@ while True:
button_flag = "null"
buttonshim.set_pixel(0x00, 0x00, 0xFF)
#weather button!
elif button_flag == "button_5":
#reprint current set of pics
elif button_flag == "button_4":
button_flag = "null"
print ("button flag set to null...")
buttonshim.set_pixel(0x00, 0x00, 0xFF)
#ACTUALLY PARSE THE JSON DUH, THIS IS BROKEN
#grab the entry at dbIndex, newFlier is a dict
print ("getting db at")
print (dbIndex)
newFlier = db.get(doc_id=dbIndex)
#get the weather
#proc = subprocess.Popen(["wget", "http://wttr.in/btv_FnQT.png"], stdout=subprocess.PIPE)
proc = subprocess.Popen(["wget", "http://wttr.in/btv_FQT.png"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
#if that's an empty spot in the db we gotta keep lookin (probably wouldn't be in this case buuut whatever, this prevents errors)
while newFlier == None:
dbIndex+=1
newFlier = db.get(doc_id=dbIndex)
#convert
size = 400, 300
#too pixely
#im = Image.open("btv_FnQT.png")
#im = im.rotate(90, Image.NEAREST, "expand=1")
# get composite from db
flierPath = newFlier["composite"]
#sideways, no rotate
im = Image.open("btv_FQT.png")
if flierPath == None:
print ("no flier here...")
im.thumbnail(size, Image.BICUBIC)
im = im.convert("1")
im.save("btv.bmp")
# print composite
try:
result = subprocess.call('lp ' + flierPath, shell=True)
print ("printing...")
except:
print('traceback.format_exc():\n%s' % traceback.format_exc())
exit()
#display the weather
epd.init()
Limage = Image.new('1', (epd4in2.EPD_HEIGHT, epd4in2.EPD_WIDTH), 255) # 255: clear the frame
bmp = Image.open("btv.bmp")
Limage.paste(bmp)
epd.display(epd.getbuffer(Limage))
time.sleep(3)
timeIndex+=2
epd.sleep()
button_flag = "null"
buttonshim.set_pixel(0x00, 0x00, 0x00)
buttonshim.set_pixel(0x00, 0x00, 0x00)
button_flag = "null"
# chill for a bit, keep track of how long we're chilling
time.sleep(2)
print("time:", timeIndex, "/", intervalTime, "index", dbIndex, "/", dbCount, "sync time:", syncIndex, "/", syncTime)

View File

@@ -227,8 +227,8 @@ class EPD:
return 0
def getbuffer(self, image):
# print "bufsiz = ",(self.width/8) * self.height
buf = [0xFF] * ((self.width/8) * self.height)
print ("bufsiz = ",(self.width/8) * self.height)
buf = [0xFF] * int(((self.width/8) * self.height))
image_monocolor = image.convert('1')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
@@ -247,25 +247,25 @@ class EPD:
newx = y
newy = self.height - x - 1
if pixels[x, y] == 0:
buf[(newx + newy*self.width) / 8] &= ~(0x80 >> (y % 8))
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
return buf
def display(self, image):
self.send_command(DATA_START_TRANSMISSION_1)
for i in range(0, self.width * self.height / 8):
for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(DATA_START_TRANSMISSION_2)
for i in range(0, self.width * self.height / 8):
for i in range(0, int(self.width * self.height / 8)):
self.send_data(image[i])
self.send_command(DISPLAY_REFRESH)
self.wait_until_idle()
def Clear(self, color):
self.send_command(DATA_START_TRANSMISSION_1)
for i in range(0, self.width * self.height / 8):
for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(DATA_START_TRANSMISSION_2)
for i in range(0, self.width * self.height / 8):
for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(DISPLAY_REFRESH)
self.wait_until_idle()

View File

@@ -3,7 +3,7 @@ Description=the EBB carousel
After=network.target
[Service]
ExecStart=/usr/bin/python -u carousel.py
ExecStart=/usr/bin/python3 -u carousel.py
WorkingDirectory=/home/pi/ebb
StandardOutput=inherit
StandardError=inherit

BIN
install/images/._header.jpg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
install/images/header.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 KiB

View File

@@ -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

View File

@@ -3,11 +3,26 @@
#ok so this script should take an argument of an image and posts it
#add blob
blobID=$(cat $1 | ssb-server blobs.add)
blobID=$(cat $1 | ssb-server blobs.add) || exit 1
echo $blobID
#echo $blobID
#publish blob
#key=$(ssb-server publish --type post --text "![upload.bmp($blobID)]"
ssb-server publish --type post --text "![photo.bmp]($blobID)" --mentions.0.name photo.bmp --mentions.0.type image/bmp
#ssb-server publish --type post --text "a new photo from #dweb-camp 2022! ![photo.bmp]($blobID)" --mentions.0.name photo.jpg --mentions.0.type image/bmp --mentions.0.link
ssb-server publish . <<EOF
{
"type":"post",
"text":"a new photo from #dweb-camp 2022! ![photo.jpg]($blobID)",
"mentions": [
{
"name": "photo.jpg",
"type": "image/jpeg",
"link": "$blobID"
},
{"link":"#dweb-camp"}
]
}
EOF