Compare commits
8 Commits
master
...
scuttleboo
| Author | SHA1 | Date | |
|---|---|---|---|
| a00fd5a670 | |||
| b0b13a0769 | |||
| 424e9c1272 | |||
| 79ffecc4b9 | |||
| f8fa50c223 | |||
| 8e87c75c3a | |||
| 2a5427fadb | |||
| aefccf6d03 |
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
._epd4in2.py
Normal file
BIN
._epd4in2.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
README.md
26
README.md
@@ -26,7 +26,8 @@ recommended hardware components:
|
|||||||
| micro-sd card | variable, $5.8 on amazon | |
|
| micro-sd card | variable, $5.8 on amazon | |
|
||||||
| buttons | $7 | https://www.adafruit.com/product/3582 |
|
| 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)|
|
| 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.
|
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 update -y && sudo apt upgrade -y
|
||||||
sudo apt install unattended-upgrades python-dev python-pip python-buttonshim libjpeg-dev zlib1g-dev git -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...)
|
(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:
|
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
|
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/).
|
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>
|
<br>
|
||||||
#### clone the repo
|
#### clone the repo
|
||||||
ideally right in your home directory.
|
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`
|
`git clone https://git.laboratoryb.org/trav/ebb.git`
|
||||||
|
|
||||||
#### setup SSB
|
#### 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.
|
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.
|
||||||
|
|
||||||
|
|||||||
28
addtoDB.py
28
addtoDB.py
@@ -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
|
#this script takes a file as an option and adds that file to the db and posts the file to scuttlebutt
|
||||||
|
|
||||||
import optparse
|
import optparse
|
||||||
|
import iterparse
|
||||||
import traceback
|
import traceback
|
||||||
import os, sys
|
import os, sys
|
||||||
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
from tinydb import TinyDB, Query
|
from tinydb import TinyDB, Query
|
||||||
|
|
||||||
@@ -25,27 +27,43 @@ def main():
|
|||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def addToDB(pathToImage, pathToDB,composite):
|
||||||
|
|
||||||
def addFile(pathToImage, pathToDB, SSBidentify):
|
#init db
|
||||||
#init db
|
|
||||||
db = TinyDB(pathToDB)
|
db = TinyDB(pathToDB)
|
||||||
|
|
||||||
#add to db
|
#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("all done, added to db")
|
||||||
#print("heres the whole db")
|
#print("heres the whole db")
|
||||||
#print(db.all())
|
#print(db.all())
|
||||||
|
|
||||||
|
|
||||||
|
def addToSSB(pathToImage, pathToDB, SSBidentify):
|
||||||
|
|
||||||
#unless you say don't post to ssb, post to ssb
|
#unless you say don't post to ssb, post to ssb
|
||||||
if SSBidentify != -1:
|
if SSBidentify != -1:
|
||||||
#SEND TO SSB! WOOOO
|
#SEND TO SSB! WOOOO
|
||||||
try:
|
try:
|
||||||
result = subprocess.call('./ssbpost.sh ' + pathToImage, shell=True)
|
result = subprocess.Popen('./ssbpost.sh ' + pathToImage, shell=True, stdout=subprocess.PIPE, )
|
||||||
except:
|
except:
|
||||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||||
exit()
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
457
carousel.py
457
carousel.py
@@ -16,8 +16,10 @@ import buttonshim
|
|||||||
import addtoDB
|
import addtoDB
|
||||||
import refreshdb
|
import refreshdb
|
||||||
import configparser
|
import configparser
|
||||||
|
import pyqrcode
|
||||||
|
import qrcode
|
||||||
from tinydb import TinyDB, Query
|
from tinydb import TinyDB, Query
|
||||||
from PIL import Image,ImageDraw,ImageFont
|
from PIL import Image,ImageDraw,ImageFont,ImageEnhance
|
||||||
|
|
||||||
## INITIALIZE ##
|
## INITIALIZE ##
|
||||||
|
|
||||||
@@ -27,7 +29,7 @@ buttonshim.set_pixel(0xFF, 0x00, 0xFF)
|
|||||||
#intervalTime is how many seconds before moving to next image (300 = 5 minutes)
|
#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
|
#sync time is how many seconds before refreshing the DB from SSB
|
||||||
#this should be moved into the config file...
|
#this should be moved into the config file...
|
||||||
intervalTime = 1800
|
intervalTime = 200
|
||||||
syncTime = 3600
|
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
|
#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
|
timeIndex = 1200
|
||||||
@@ -63,10 +65,9 @@ try:
|
|||||||
bmp = Image.open(str(flierPath))
|
bmp = Image.open(str(flierPath))
|
||||||
Limage.paste(bmp)
|
Limage.paste(bmp)
|
||||||
draw = ImageDraw.Draw(Limage)
|
draw = ImageDraw.Draw(Limage)
|
||||||
draw.text((2, 280), 'EBB', font = font18, fill = 255)
|
# draw.text((2, 280), 'EBB', font = font18, fill = 255)
|
||||||
draw.text((2, 300), 'version .02', font = font18, fill = 255)
|
draw.text((2, 300), 'Scuttlebooth 2', font = font18, fill = 255)
|
||||||
epd.display(epd.getbuffer(Limage))
|
epd.display(epd.getbuffer(Limage))
|
||||||
time.sleep(2)
|
|
||||||
epd.sleep()
|
epd.sleep()
|
||||||
except:
|
except:
|
||||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||||
@@ -76,21 +77,21 @@ except:
|
|||||||
@buttonshim.on_press(buttonshim.BUTTON_A)
|
@buttonshim.on_press(buttonshim.BUTTON_A)
|
||||||
def button_a(button, pressed):
|
def button_a(button, pressed):
|
||||||
global button_flag
|
global button_flag
|
||||||
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
# buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
||||||
button_flag = "button_1"
|
button_flag = "button_1"
|
||||||
|
|
||||||
|
|
||||||
@buttonshim.on_press(buttonshim.BUTTON_B)
|
@buttonshim.on_press(buttonshim.BUTTON_B)
|
||||||
def button_b(button, pressed):
|
def button_b(button, pressed):
|
||||||
global button_flag
|
global button_flag
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
# buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
button_flag = "button_2"
|
button_flag = "button_2"
|
||||||
|
|
||||||
|
|
||||||
@buttonshim.on_press(buttonshim.BUTTON_C)
|
@buttonshim.on_press(buttonshim.BUTTON_C)
|
||||||
def button_c(button, pressed):
|
def button_c(button, pressed):
|
||||||
global button_flag
|
global button_flag
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
# buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
button_flag = "button_3"
|
button_flag = "button_3"
|
||||||
|
|
||||||
@buttonshim.on_press(buttonshim.BUTTON_D)
|
@buttonshim.on_press(buttonshim.BUTTON_D)
|
||||||
@@ -109,12 +110,62 @@ buttonshim.set_pixel(0x00, 0x00, 0x00)
|
|||||||
|
|
||||||
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 ##
|
## MAIN LOOP ##
|
||||||
while True:
|
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
|
#iterate through syncTime and image time
|
||||||
syncIndex+=2
|
syncIndex+=2
|
||||||
timeIndex+=2
|
timeIndex+=2
|
||||||
@@ -123,10 +174,11 @@ while True:
|
|||||||
if syncIndex >= syncTime:
|
if syncIndex >= syncTime:
|
||||||
#light up red while syncing db
|
#light up red while syncing db
|
||||||
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
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
|
#db count may have changed
|
||||||
for item in db:
|
# for item in db:
|
||||||
dbCount = item.doc_id
|
# dbCount = item.doc_id
|
||||||
syncIndex = 0
|
syncIndex = 0
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||||
|
|
||||||
@@ -160,7 +212,6 @@ while True:
|
|||||||
bmp = Image.open(flierPath)
|
bmp = Image.open(flierPath)
|
||||||
Limage.paste(bmp)
|
Limage.paste(bmp)
|
||||||
epd.display(epd.getbuffer(Limage))
|
epd.display(epd.getbuffer(Limage))
|
||||||
time.sleep(2)
|
|
||||||
timeIndex+=2
|
timeIndex+=2
|
||||||
epd.sleep()
|
epd.sleep()
|
||||||
|
|
||||||
@@ -173,68 +224,112 @@ while True:
|
|||||||
#take pic
|
#take pic
|
||||||
if button_flag == "button_1":
|
if button_flag == "button_1":
|
||||||
|
|
||||||
#generate unique file_name
|
#generate 3 unique file_names
|
||||||
unique = uuid.uuid4()
|
unique1 = uuid.uuid4()
|
||||||
unique = str(unique)
|
unique1 = str(unique1)
|
||||||
jpgpath = imagesPath + unique + '.jpg'
|
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
|
#loop in case we wanna re-take it
|
||||||
exitPhotoMode = False
|
exitPhotoMode = False
|
||||||
while exitPhotoMode == False:
|
while exitPhotoMode == False:
|
||||||
|
|
||||||
#take photo
|
|
||||||
|
#take fullsize photos
|
||||||
|
pulse(20)
|
||||||
|
|
||||||
try:
|
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:
|
except:
|
||||||
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
#convert to bmp
|
pulse(20)
|
||||||
im = Image.open(jpgpath)
|
|
||||||
im = im.convert("1")
|
|
||||||
im.save(bmpath)
|
|
||||||
|
|
||||||
#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()
|
epd.init()
|
||||||
bmp = Image.open(bmpath)
|
|
||||||
Limage.paste(bmp)
|
|
||||||
epd.display(epd.getbuffer(Limage))
|
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"
|
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":
|
while button_flag == "none":
|
||||||
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
buttonshim.set_pixel(0xFF, 0x00, 0x00)
|
||||||
time.sleep(.2)
|
time.sleep(.2)
|
||||||
@@ -248,11 +343,90 @@ while True:
|
|||||||
#led to thinking mode
|
#led to thinking mode
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
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":
|
if button_flag == "button_1":
|
||||||
button_flag == "null"
|
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
|
#update dbCount
|
||||||
for item in db:
|
for item in db:
|
||||||
dbCount = item.doc_id
|
dbCount = item.doc_id
|
||||||
@@ -260,21 +434,39 @@ while True:
|
|||||||
|
|
||||||
#display the image to clear the menu (also display text "posted")
|
#display the image to clear the menu (also display text "posted")
|
||||||
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
|
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
|
||||||
bmp = Image.open(bmpath)
|
bmp = Image.open(bmpath1)
|
||||||
Limage.paste(bmp)
|
Limage.paste(bmp)
|
||||||
draw = ImageDraw.Draw(Limage)
|
draw = ImageDraw.Draw(Limage)
|
||||||
draw.text((2, 240), 'PHOTO POSTED', font = font18, fill = 255)
|
draw.text((2, 240), 'photostrip posted', font = font18, fill = 255)
|
||||||
draw.text((2, 260), 'online!', font = font18, fill = 255)
|
draw.text((2, 260), 'to SSB', font = font18, fill = 255)
|
||||||
epd.display(epd.getbuffer(Limage))
|
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":
|
if button_flag == "button_2":
|
||||||
|
#led to thinking mode
|
||||||
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
button_flag == "null"
|
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
|
#update dbCount
|
||||||
for item in db:
|
for item in db:
|
||||||
dbCount = item.doc_id
|
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
|
exitPhotoMode = True
|
||||||
#display the image to clear the menu (also display text "posted")
|
#display the image to clear the menu (also display text "posted")
|
||||||
font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24)
|
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, 240), 'PHOTO POSTED', font = font18, fill = 255)
|
||||||
draw.text((2, 260), 'to this device only', font = font18, fill = 255)
|
draw.text((2, 260), 'to this device only', font = font18, fill = 255)
|
||||||
epd.display(epd.getbuffer(Limage))
|
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":
|
if button_flag == "button_3":
|
||||||
|
#led to thinking mode
|
||||||
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
button_flag == "null"
|
button_flag == "null"
|
||||||
#nothin! loop around... exitPhotoMode still false
|
|
||||||
|
|
||||||
#exit photomode, delete photo
|
# print concaz that we already generated
|
||||||
if (button_flag == "button_4") or (button_flag == "button_5"):
|
try:
|
||||||
button_flag == "null"
|
result = subprocess.call('lp ' + composite, shell=True)
|
||||||
|
except:
|
||||||
|
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||||
|
exit()
|
||||||
|
|
||||||
exitPhotoMode = True
|
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
|
#led off
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||||
@@ -308,13 +538,15 @@ while True:
|
|||||||
|
|
||||||
#move to the next image
|
#move to the next image
|
||||||
elif button_flag == "button_2":
|
elif button_flag == "button_2":
|
||||||
print ("next image")
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
timeIndex = intervalTime
|
print ("next image")
|
||||||
button_flag = "null"
|
timeIndex = intervalTime
|
||||||
|
button_flag = "null"
|
||||||
|
|
||||||
|
|
||||||
#go back to the previous image
|
#go back to the previous image
|
||||||
elif button_flag == "button_3":
|
elif button_flag == "button_3":
|
||||||
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
print ("previous image")
|
print ("previous image")
|
||||||
#we go back 2 because we have to account for calling timeIndex = intervalTime iterates forward by 1
|
#we go back 2 because we have to account for calling timeIndex = intervalTime iterates forward by 1
|
||||||
dbIndex-=2
|
dbIndex-=2
|
||||||
@@ -325,7 +557,8 @@ while True:
|
|||||||
|
|
||||||
|
|
||||||
#delete current image
|
#delete current image
|
||||||
elif button_flag == "button_4":
|
elif button_flag == "button_5":
|
||||||
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
button_flag = "null"
|
button_flag = "null"
|
||||||
|
|
||||||
#can't delete the default image
|
#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, 0), 'Are you sure', font = font18, fill = 255)
|
||||||
draw.text((2, 40), 'you want to delete', 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, 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, 160), 'again to confirm.', font = font18, fill = 255)
|
||||||
draw.text((2, 200), 'Press any other', 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)
|
draw.text((2, 240), 'button for no.', font = font18, fill = 255)
|
||||||
@@ -354,7 +587,7 @@ while True:
|
|||||||
time.sleep(.05)
|
time.sleep(.05)
|
||||||
|
|
||||||
#sounds like delete time
|
#sounds like delete time
|
||||||
if button_flag == "button_4":
|
if button_flag == "button_5":
|
||||||
Fruit = Query()
|
Fruit = Query()
|
||||||
#results = db.search(Fruit.path == flierPath)
|
#results = db.search(Fruit.path == flierPath)
|
||||||
db.remove(Fruit.path == flierPath)
|
db.remove(Fruit.path == flierPath)
|
||||||
@@ -371,37 +604,39 @@ while True:
|
|||||||
button_flag = "null"
|
button_flag = "null"
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
buttonshim.set_pixel(0x00, 0x00, 0xFF)
|
||||||
|
|
||||||
#weather button!
|
#reprint current set of pics
|
||||||
elif button_flag == "button_5":
|
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
|
#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)
|
||||||
#proc = subprocess.Popen(["wget", "http://wttr.in/btv_FnQT.png"], stdout=subprocess.PIPE)
|
while newFlier == None:
|
||||||
proc = subprocess.Popen(["wget", "http://wttr.in/btv_FQT.png"], stdout=subprocess.PIPE)
|
dbIndex+=1
|
||||||
(out, err) = proc.communicate()
|
newFlier = db.get(doc_id=dbIndex)
|
||||||
|
|
||||||
#convert
|
# get composite from db
|
||||||
size = 400, 300
|
flierPath = newFlier["composite"]
|
||||||
#too pixely
|
|
||||||
#im = Image.open("btv_FnQT.png")
|
|
||||||
#im = im.rotate(90, Image.NEAREST, "expand=1")
|
|
||||||
|
|
||||||
#sideways, no rotate
|
if flierPath == None:
|
||||||
im = Image.open("btv_FQT.png")
|
print ("no flier here...")
|
||||||
|
|
||||||
im.thumbnail(size, Image.BICUBIC)
|
# print composite
|
||||||
im = im.convert("1")
|
try:
|
||||||
im.save("btv.bmp")
|
result = subprocess.call('lp ' + flierPath, shell=True)
|
||||||
|
print ("printing...")
|
||||||
|
except:
|
||||||
|
print('traceback.format_exc():\n%s' % traceback.format_exc())
|
||||||
|
exit()
|
||||||
|
|
||||||
#display the weather
|
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
||||||
epd.init()
|
button_flag = "null"
|
||||||
Limage = Image.new('1', (epd4in2.EPD_HEIGHT, epd4in2.EPD_WIDTH), 255) # 255: clear the frame
|
|
||||||
bmp = Image.open("btv.bmp")
|
# chill for a bit, keep track of how long we're chilling
|
||||||
Limage.paste(bmp)
|
time.sleep(2)
|
||||||
epd.display(epd.getbuffer(Limage))
|
print("time:", timeIndex, "/", intervalTime, "index", dbIndex, "/", dbCount, "sync time:", syncIndex, "/", syncTime)
|
||||||
time.sleep(3)
|
|
||||||
timeIndex+=2
|
|
||||||
epd.sleep()
|
|
||||||
button_flag = "null"
|
|
||||||
buttonshim.set_pixel(0x00, 0x00, 0x00)
|
|
||||||
|
|||||||
14
epd4in2.py
14
epd4in2.py
@@ -227,8 +227,8 @@ class EPD:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# print "bufsiz = ",(self.width/8) * self.height
|
print ("bufsiz = ",(self.width/8) * self.height)
|
||||||
buf = [0xFF] * ((self.width/8) * self.height)
|
buf = [0xFF] * int(((self.width/8) * self.height))
|
||||||
image_monocolor = image.convert('1')
|
image_monocolor = image.convert('1')
|
||||||
imwidth, imheight = image_monocolor.size
|
imwidth, imheight = image_monocolor.size
|
||||||
pixels = image_monocolor.load()
|
pixels = image_monocolor.load()
|
||||||
@@ -247,25 +247,25 @@ class EPD:
|
|||||||
newx = y
|
newx = y
|
||||||
newy = self.height - x - 1
|
newy = self.height - x - 1
|
||||||
if pixels[x, y] == 0:
|
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
|
return buf
|
||||||
|
|
||||||
def display(self, image):
|
def display(self, image):
|
||||||
self.send_command(DATA_START_TRANSMISSION_1)
|
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_data(0xFF)
|
||||||
self.send_command(DATA_START_TRANSMISSION_2)
|
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_data(image[i])
|
||||||
self.send_command(DISPLAY_REFRESH)
|
self.send_command(DISPLAY_REFRESH)
|
||||||
self.wait_until_idle()
|
self.wait_until_idle()
|
||||||
|
|
||||||
def Clear(self, color):
|
def Clear(self, color):
|
||||||
self.send_command(DATA_START_TRANSMISSION_1)
|
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_data(0xFF)
|
||||||
self.send_command(DATA_START_TRANSMISSION_2)
|
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_data(0xFF)
|
||||||
self.send_command(DISPLAY_REFRESH)
|
self.send_command(DISPLAY_REFRESH)
|
||||||
self.wait_until_idle()
|
self.wait_until_idle()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Description=the EBB carousel
|
|||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/bin/python -u carousel.py
|
ExecStart=/usr/bin/python3 -u carousel.py
|
||||||
WorkingDirectory=/home/pi/ebb
|
WorkingDirectory=/home/pi/ebb
|
||||||
StandardOutput=inherit
|
StandardOutput=inherit
|
||||||
StandardError=inherit
|
StandardError=inherit
|
||||||
|
|||||||
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]
|
[Service]
|
||||||
ExecStart=/bin/bash run-ssb.sh
|
ExecStart=/bin/bash run-ssb.sh
|
||||||
WorkingDirectory=/home/pi/bb
|
WorkingDirectory=/home/pi/ebb
|
||||||
StandardOutput=inherit
|
StandardOutput=inherit
|
||||||
StandardError=inherit
|
StandardError=inherit
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
21
ssbpost.sh
21
ssbpost.sh
@@ -3,11 +3,26 @@
|
|||||||
#ok so this script should take an argument of an image and posts it
|
#ok so this script should take an argument of an image and posts it
|
||||||
|
|
||||||
#add blob
|
#add blob
|
||||||
blobID=$(cat $1 | ssb-server blobs.add)
|
blobID=$(cat $1 | ssb-server blobs.add) || exit 1
|
||||||
|
|
||||||
echo $blobID
|
#echo $blobID
|
||||||
|
|
||||||
#publish blob
|
#publish blob
|
||||||
#key=$(ssb-server publish --type post --text "![upload.bmp($blobID)]"
|
#key=$(ssb-server publish --type post --text "![upload.bmp($blobID)]"
|
||||||
|
|
||||||
ssb-server publish --type post --text "" --mentions.0.name photo.bmp --mentions.0.type image/bmp
|
#ssb-server publish --type post --text "a new photo from #dweb-camp 2022! " --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! ",
|
||||||
|
"mentions": [
|
||||||
|
{
|
||||||
|
"name": "photo.jpg",
|
||||||
|
"type": "image/jpeg",
|
||||||
|
"link": "$blobID"
|
||||||
|
},
|
||||||
|
{"link":"#dweb-camp"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|||||||
Reference in New Issue
Block a user