From bd70c3ef64dc2f4ad8fbff5a6a2a50e821f1d3dc Mon Sep 17 00:00:00 2001 From: trav Date: Fri, 5 Aug 2022 04:54:58 +0100 Subject: [PATCH] python 2 to 3 --- .git_ignore | 2 + addtoDB.py | 2 +- addtoDB.py.bak | 52 ++++++ carousel.py | 40 ++--- carousel.py.bak | 407 +++++++++++++++++++++++++++++++++++++++++++++++ config.txt | 2 +- epd4in2.py | 4 +- epd4in2.py.bak | 279 ++++++++++++++++++++++++++++++++ refreshdb.py | 20 +-- refreshdb.py.bak | 125 +++++++++++++++ 10 files changed, 899 insertions(+), 34 deletions(-) create mode 100644 .git_ignore create mode 100644 addtoDB.py.bak create mode 100755 carousel.py.bak create mode 100644 epd4in2.py.bak create mode 100644 refreshdb.py.bak diff --git a/.git_ignore b/.git_ignore new file mode 100644 index 0000000..3984257 --- /dev/null +++ b/.git_ignore @@ -0,0 +1,2 @@ +config.txt + diff --git a/addtoDB.py b/addtoDB.py index 1c3a5c8..249a4cd 100644 --- a/addtoDB.py +++ b/addtoDB.py @@ -42,7 +42,7 @@ def addFile(pathToImage, pathToDB, SSBidentify): try: result = subprocess.call('./ssbpost.sh ' + pathToImage, shell=True) except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() return pathToImage diff --git a/addtoDB.py.bak b/addtoDB.py.bak new file mode 100644 index 0000000..1c3a5c8 --- /dev/null +++ b/addtoDB.py.bak @@ -0,0 +1,52 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- + +#this script takes a file as an option and adds that file to the db and posts the file to scuttlebutt + +import optparse +import traceback +import os, sys +import subprocess +from tinydb import TinyDB, Query + + + +def main(): + #get options and arguments + p = optparse.OptionParser() + p.add_option('--file', '-f', action='store', dest='file', help='this needs to be a file path') + + options, arguments = p.parse_args() + + if options.file: + pathToImage=options.file + else: + print("you need to provide a file path") + exit(1) + + + +def addFile(pathToImage, pathToDB, SSBidentify): + #init db + db = TinyDB(pathToDB) + + #add to db + db.insert({'path': pathToImage, 'date': 4, 'ssb': SSBidentify}) + print("all done, added to db") + #print("heres the whole db") + #print(db.all()) + + #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) + except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + + return pathToImage + + +if __name__ == '__main__': + main() diff --git a/carousel.py b/carousel.py index af1c127..cd94eb9 100755 --- a/carousel.py +++ b/carousel.py @@ -15,7 +15,7 @@ import subprocess import buttonshim import addtoDB import refreshdb -import ConfigParser +import configparser from tinydb import TinyDB, Query from PIL import Image,ImageDraw,ImageFont @@ -37,7 +37,7 @@ flierPath = "noneyet" button_flag = "null" #pull some vals from the config -configParser = ConfigParser.RawConfigParser() +configParser = configparser.RawConfigParser() configFilePath = r'config.txt' configParser.read(configFilePath) imagesPath = configParser.get('ebb-config', 'imagesPath') @@ -49,7 +49,7 @@ howmany = Query() dbCount = 0 for item in db: dbCount = item.doc_id -print dbCount +print(dbCount) #initialize display and display boot image #grab the entry at dbIndex, newFlier is a dict @@ -69,7 +69,7 @@ try: time.sleep(2) epd.sleep() except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() ## button press contingencies ## @@ -113,7 +113,7 @@ buttonshim.set_pixel(0x00, 0x00, 0x00) 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 + print("time:", timeIndex, "/", intervalTime, "index", dbIndex, "/", dbCount, "sync time:", syncIndex, "/", syncTime) #iterate through syncTime and image time syncIndex+=2 @@ -126,8 +126,8 @@ while True: refreshdb.fresh() #db count may have changed for item in db: - dbCount = item.doc_id - syncIndex = 0 + dbCount = item.doc_id + syncIndex = 0 buttonshim.set_pixel(0x00, 0x00, 0x00) #time to iterate through images @@ -165,7 +165,7 @@ while True: epd.sleep() except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() #in case the LED was on because we're buttoning through images buttonshim.set_pixel(0x00, 0x00, 0x00) @@ -190,7 +190,7 @@ while True: try: result = subprocess.call(['raspistill', '-o', jpgpath, '-vf', '-hf', '-w', '300', '-h', '400', '-t', '1000']) except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() #convert to bmp @@ -254,8 +254,8 @@ while True: #add the photo to the db/ssb addtoDB.addFile(bmpath,dbPath,0) #update dbCount - for item in db: - dbCount = item.doc_id + for item in db: + dbCount = item.doc_id exitPhotoMode = True #display the image to clear the menu (also display text "posted") @@ -273,8 +273,8 @@ while True: #add that file to the db. -1 tells addtoDB not to post to ssb. addtoDB.addFile(bmpath,dbPath,-1) #update dbCount - for item in db: - dbCount = item.doc_id + for item in db: + dbCount = item.doc_id 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) @@ -308,16 +308,16 @@ while True: #move to the next image elif button_flag == "button_2": - print ("next image") - timeIndex = intervalTime - button_flag = "null" + print ("next image") + timeIndex = intervalTime + button_flag = "null" #go back to the previous image elif button_flag == "button_3": print ("previous image") #we go back 2 because we have to account for calling timeIndex = intervalTime iterates forward by 1 - dbIndex-=2 + dbIndex-=2 if dbIndex < 2: dbIndex = dbCount-1 timeIndex = intervalTime @@ -328,7 +328,7 @@ while True: elif button_flag == "button_4": button_flag = "null" - #can't delete the default image + #can't delete the default image if dbIndex != 1: #CONFIRM WITH USER THEY WANT TO DELETE @@ -360,7 +360,7 @@ while True: db.remove(Fruit.path == flierPath) #update dbCount for item in db: - dbCount = item.doc_id + dbCount = item.doc_id #ok so it's deleted, let's force display of next image timeIndex = intervalTime else: @@ -379,7 +379,7 @@ while True: #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() + (out, err) = proc.communicate() #convert size = 400, 300 diff --git a/carousel.py.bak b/carousel.py.bak new file mode 100755 index 0000000..af1c127 --- /dev/null +++ b/carousel.py.bak @@ -0,0 +1,407 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- + +# This is the main program of the EBB: E-Paper Bulletin Board. More info at https://git.laboratoryb.org/trav/ebb +# +# carousel iterates through all posts in posts.json + +import os +import epd4in2 +import traceback +import time +import signal +import uuid +import subprocess +import buttonshim +import addtoDB +import refreshdb +import ConfigParser +from tinydb import TinyDB, Query +from PIL import Image,ImageDraw,ImageFont + +## INITIALIZE ## + +#Let the user know we're booting: with a PURPLE led +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 +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 +syncIndex = 0 +dbIndex = 1 +flierPath = "noneyet" +button_flag = "null" + +#pull some vals from the config +configParser = ConfigParser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) +imagesPath = configParser.get('ebb-config', 'imagesPath') +dbPath = configParser.get('ebb-config', 'dbPath') + +#initialize db and our place going through the db. We want dbCount instead of len(db) because len(db) doesn't account for the vacant holes in the db that I can't figure out how to get rid of... +db = TinyDB(dbPath) +howmany = Query() +dbCount = 0 +for item in db: + dbCount = item.doc_id +print dbCount + +#initialize display and display boot image +#grab the entry at dbIndex, newFlier is a dict +newFlier = db.get(doc_id=dbIndex) +flierPath = "/home/pi/images/" + newFlier["path"] +Limage = Image.new('1', (epd4in2.EPD_HEIGHT, epd4in2.EPD_WIDTH), 255) # 255: clear the frame +try: + font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 36) + epd = epd4in2.EPD() + epd.init() + 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) + epd.display(epd.getbuffer(Limage)) + time.sleep(2) + epd.sleep() +except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + +## button press contingencies ## +@buttonshim.on_press(buttonshim.BUTTON_A) +def button_a(button, pressed): + global button_flag + 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) + button_flag = "button_2" + + +@buttonshim.on_press(buttonshim.BUTTON_C) +def button_c(button, pressed): + global button_flag + buttonshim.set_pixel(0x00, 0x00, 0xFF) + button_flag = "button_3" + +@buttonshim.on_press(buttonshim.BUTTON_D) +def button_d(button, pressed): + global button_flag + buttonshim.set_pixel(0xFF, 0x00, 0x00) + button_flag = "button_4" + +@buttonshim.on_press(buttonshim.BUTTON_E) +def button_e(button, pressed): + global button_flag + buttonshim.set_pixel(0x00, 0x00, 0xFF) + button_flag = "button_5" + +buttonshim.set_pixel(0x00, 0x00, 0x00) + +buttonshim.set_pixel(0x00, 0x00, 0x00) + +## 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 + + #time to sync db with ssb + if syncIndex >= syncTime: + #light up red while syncing db + buttonshim.set_pixel(0xFF, 0x00, 0x00) + refreshdb.fresh() + #db count may have changed + for item in db: + dbCount = item.doc_id + syncIndex = 0 + buttonshim.set_pixel(0x00, 0x00, 0x00) + + #time to iterate through images + if timeIndex >= intervalTime: + #reset the index + timeIndex = 0 + + # iterate where we are in the db + dbIndex+=1 + + # if dbIndex is now out of range, reset to beginning (skipping 1 because that's the boot image) + if dbIndex > dbCount: + dbIndex=2 + + #grab the entry at dbIndex, newFlier is a dict + print ("getting db at") + print (dbIndex) + newFlier = db.get(doc_id=dbIndex) + + #if that's an empty spot in the db we gotta keep lookin + while newFlier == None: + dbIndex+=1 + newFlier = db.get(doc_id=dbIndex) + + flierPath = newFlier["path"] + + #display the image + try: + epd.init() + bmp = Image.open(flierPath) + Limage.paste(bmp) + epd.display(epd.getbuffer(Limage)) + time.sleep(2) + timeIndex+=2 + epd.sleep() + + except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + #in case the LED was on because we're buttoning through images + buttonshim.set_pixel(0x00, 0x00, 0x00) + +#take pic + if button_flag == "button_1": + + #generate unique file_name + unique = uuid.uuid4() + unique = str(unique) + jpgpath = imagesPath + unique + '.jpg' + + #generate unique bmp name + bmpath = imagesPath + unique + '.bmp' + + + #loop in case we wanna re-take it + exitPhotoMode = False + while exitPhotoMode == False: + + #take photo + try: + result = subprocess.call(['raspistill', '-o', jpgpath, '-vf', '-hf', '-w', '300', '-h', '400', '-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 + epd.init() + bmp = Image.open(bmpath) + Limage.paste(bmp) + epd.display(epd.getbuffer(Limage)) + + #wait for user decision on photo + waited = 0 + 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) + 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) + + #led to thinking mode + buttonshim.set_pixel(0x00, 0x00, 0xFF) + + #post to ssb + if button_flag == "button_1": + button_flag == "null" + #add the photo to the db/ssb + addtoDB.addFile(bmpath,dbPath,0) + #update dbCount + for item in db: + dbCount = item.doc_id + 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) + bmp = Image.open(bmpath) + 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) + epd.display(epd.getbuffer(Limage)) + + #post only locally + if button_flag == "button_2": + button_flag == "null" + #add that file to the db. -1 tells addtoDB not to post to ssb. + addtoDB.addFile(bmpath,dbPath,-1) + #update dbCount + for item in db: + dbCount = item.doc_id + 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) + bmp = Image.open(bmpath) + Limage.paste(bmp) + draw = ImageDraw.Draw(Limage) + 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)) + + #reshoot the picture + if button_flag == "button_3": + 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" + exitPhotoMode = True + os.remove(bmpath) + os.remove(jpgpath) + + #led off + buttonshim.set_pixel(0x00, 0x00, 0x00) + time.sleep(3) + timeIndex+=2 + epd.sleep() + button_flag = "null" + + + +#move to the next image + elif button_flag == "button_2": + print ("next image") + timeIndex = intervalTime + button_flag = "null" + + +#go back to the previous image + elif button_flag == "button_3": + print ("previous image") + #we go back 2 because we have to account for calling timeIndex = intervalTime iterates forward by 1 + dbIndex-=2 + if dbIndex < 2: + dbIndex = dbCount-1 + timeIndex = intervalTime + button_flag = "null" + + +#delete current image + elif button_flag == "button_4": + button_flag = "null" + + #can't delete the default image + if dbIndex != 1: + + #CONFIRM WITH USER THEY WANT TO DELETE + epd.init() + #Limage = Image.new('1', (epd4in2.EPD_HEIGHT, epd4in2.EPD_WIDTH), 255) # 255: clear the frame + draw = ImageDraw.Draw(Limage) + font18 = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24) + 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, 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) + epd.display(epd.getbuffer(Limage)) + epd.sleep() + + + while button_flag == "null": + buttonshim.set_pixel(0xFF, 0x00, 0x00) + time.sleep(.1) + buttonshim.set_pixel(0x00, 0x00, 0x00) + time.sleep(.05) + + #sounds like delete time + if button_flag == "button_4": + Fruit = Query() + #results = db.search(Fruit.path == flierPath) + db.remove(Fruit.path == flierPath) + #update dbCount + for item in db: + dbCount = item.doc_id + #ok so it's deleted, let's force display of next image + timeIndex = intervalTime + else: + #stay on same image and refresh to get rid of delete text + dbIndex-=1 + timeIndex = intervalTime + + button_flag = "null" + buttonshim.set_pixel(0x00, 0x00, 0xFF) + +#weather button! + elif button_flag == "button_5": + + #ACTUALLY PARSE THE JSON DUH, THIS IS BROKEN + + #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() + + #convert + size = 400, 300 + #too pixely + #im = Image.open("btv_FnQT.png") + #im = im.rotate(90, Image.NEAREST, "expand=1") + + #sideways, no rotate + im = Image.open("btv_FQT.png") + + im.thumbnail(size, Image.BICUBIC) + im = im.convert("1") + im.save("btv.bmp") + + #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) diff --git a/config.txt b/config.txt index f1b61ae..97399ae 100644 --- a/config.txt +++ b/config.txt @@ -1,4 +1,4 @@ [ebb-config] imagesPath = /home/pi/images/ dbPath = /home/pi/posts.json -ssbme = @0KQ9D7Sbkg4F6qBBg90/CRT5K1wW/b2mWwl4GJWd6MA=.ed25519 +ssbme = @eFLm0W3hiQGaT3W5EvVj8DXTe5t1/WfmmHu/gKvkUAU=.ed25519 diff --git a/epd4in2.py b/epd4in2.py index 567ae25..65b69fc 100644 --- a/epd4in2.py +++ b/epd4in2.py @@ -234,14 +234,14 @@ class EPD: pixels = image_monocolor.load() # print "imwidth = %d, imheight = %d",imwidth,imheight if(imwidth == self.width and imheight == self.height): - print "Horizontal" + print("Horizontal") for y in range(imheight): for x in range(imwidth): # Set the bits for the column of pixels at the current position. if pixels[x, y] == 0: buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8)) elif(imwidth == self.height and imheight == self.width): - print "Vertical" + print("Vertical") for y in range(imheight): for x in range(imwidth): newx = y diff --git a/epd4in2.py.bak b/epd4in2.py.bak new file mode 100644 index 0000000..567ae25 --- /dev/null +++ b/epd4in2.py.bak @@ -0,0 +1,279 @@ +# /***************************************************************************** +# * | File : EPD_1in54.py +# * | Author : Waveshare team +# * | Function : Electronic paper driver +# * | Info : +# *---------------- +# * | This version: V3.0 +# * | Date : 2018-11-06 +# * | Info : python2 demo +# * 1.Remove: +# digital_write(self, pin, value) +# digital_read(self, pin) +# delay_ms(self, delaytime) +# set_lut(self, lut) +# self.lut = self.lut_full_update +# * 2.Change: +# display_frame -> TurnOnDisplay +# set_memory_area -> SetWindow +# set_memory_pointer -> SetCursor +# get_frame_buffer -> getbuffer +# set_frame_memory -> display +# * 3.How to use +# epd = epd2in7.EPD() +# epd.init(epd.lut_full_update) +# image = Image.new('1', (epd1in54.EPD_WIDTH, epd1in54.EPD_HEIGHT), 255) +# ... +# drawing ...... +# ... +# epd.display(getbuffer(image)) +# ******************************************************************************/ +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documnetation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + + +import epdconfig +from PIL import Image +import RPi.GPIO as GPIO + +# Display resolution +EPD_WIDTH = 400 +EPD_HEIGHT = 300 + +# GDEW042T2 commands +PANEL_SETTING = 0x00 +POWER_SETTING = 0x01 +POWER_OFF = 0x02 +POWER_OFF_SEQUENCE_SETTING = 0x03 +POWER_ON = 0x04 +POWER_ON_MEASURE = 0x05 +BOOSTER_SOFT_START = 0x06 +DEEP_SLEEP = 0x07 +DATA_START_TRANSMISSION_1 = 0x10 +DATA_STOP = 0x11 +DISPLAY_REFRESH = 0x12 +DATA_START_TRANSMISSION_2 = 0x13 +LUT_FOR_VCOM = 0x20 +LUT_WHITE_TO_WHITE = 0x21 +LUT_BLACK_TO_WHITE = 0x22 +LUT_WHITE_TO_BLACK = 0x23 +LUT_BLACK_TO_BLACK = 0x24 +PLL_CONTROL = 0x30 +TEMPERATURE_SENSOR_COMMAND = 0x40 +TEMPERATURE_SENSOR_SELECTION = 0x41 +TEMPERATURE_SENSOR_WRITE = 0x42 +TEMPERATURE_SENSOR_READ = 0x43 +VCOM_AND_DATA_INTERVAL_SETTING = 0x50 +LOW_POWER_DETECTION = 0x51 +TCON_SETTING = 0x60 +RESOLUTION_SETTING = 0x61 +GSST_SETTING = 0x65 +GET_STATUS = 0x71 +AUTO_MEASUREMENT_VCOM = 0x80 +READ_VCOM_VALUE = 0x81 +VCM_DC_SETTING = 0x82 +PARTIAL_WINDOW = 0x90 +PARTIAL_IN = 0x91 +PARTIAL_OUT = 0x92 +PROGRAM_MODE = 0xA0 +ACTIVE_PROGRAMMING = 0xA1 +READ_OTP = 0xA2 +POWER_SAVING = 0xE3 +class EPD: + def __init__(self): + self.reset_pin = epdconfig.RST_PIN + self.dc_pin = epdconfig.DC_PIN + self.busy_pin = epdconfig.BUSY_PIN + self.width = EPD_WIDTH + self.height = EPD_HEIGHT + + lut_vcom0 = [ + 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x17, 0x17, 0x00, 0x00, 0x02, + 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + lut_ww = [ + 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, + 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, + 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + lut_bw = [ + 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, + 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, + 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + lut_wb = [ + 0x80, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, + 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, + 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + lut_bb = [ + 0x80, 0x17, 0x00, 0x00, 0x00, 0x02, + 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, + 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, + 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + + # Hardware reset + def reset(self): + epdconfig.digital_write(self.reset_pin, GPIO.HIGH) + epdconfig.delay_ms(200) + epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset + epdconfig.delay_ms(200) + epdconfig.digital_write(self.reset_pin, GPIO.HIGH) + epdconfig.delay_ms(200) + + def send_command(self, command): + epdconfig.digital_write(self.dc_pin, GPIO.LOW) + epdconfig.spi_writebyte([command]) + + def send_data(self, data): + epdconfig.digital_write(self.dc_pin, GPIO.HIGH) + epdconfig.spi_writebyte([data]) + + def wait_until_idle(self): + while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy + epdconfig.delay_ms(100) + + def set_lut(self): + self.send_command(LUT_FOR_VCOM) # vcom + for count in range(0, 44): + self.send_data(self.lut_vcom0[count]) + self.send_command(LUT_WHITE_TO_WHITE) # ww -- + for count in range(0, 42): + self.send_data(self.lut_ww[count]) + self.send_command(LUT_BLACK_TO_WHITE) # bw r + for count in range(0, 42): + self.send_data(self.lut_bw[count]) + self.send_command(LUT_WHITE_TO_BLACK) # wb w + for count in range(0, 42): + self.send_data(self.lut_bb[count]) + self.send_command(LUT_BLACK_TO_BLACK) # bb b + for count in range(0, 42): + self.send_data(self.lut_wb[count]) + + def init(self): + if (epdconfig.module_init() != 0): + return -1 + # EPD hardware init start + self.reset() + + self.send_command(POWER_SETTING) + self.send_data(0x03) # VDS_EN, VDG_EN + self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0] + self.send_data(0x2b) # VDH + self.send_data(0x2b) # VDL + self.send_command(BOOSTER_SOFT_START) + self.send_data(0x17) + self.send_data(0x17) + self.send_data(0x17) + self.send_command(POWER_ON) + self.wait_until_idle() + self.send_command(PANEL_SETTING) + self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f + self.send_data(0x0d) + self.send_command(PLL_CONTROL) + self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ + + self.send_command(0x61); # resolution setting + self.send_data(0x01); + self.send_data(0x90); # 128 + self.send_data(0x01); + self.send_data(0x2c); + + self.send_command(0x82); # vcom_DC setting + self.send_data(0x28); + + self.send_command(0X50); # VCOM AND DATA INTERVAL SETTING + self.send_data(0x97); # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 + + self.set_lut() + # EPD hardware init end + return 0 + + def getbuffer(self, image): + # print "bufsiz = ",(self.width/8) * self.height + buf = [0xFF] * ((self.width/8) * self.height) + image_monocolor = image.convert('1') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + # print "imwidth = %d, imheight = %d",imwidth,imheight + if(imwidth == self.width and imheight == self.height): + print "Horizontal" + for y in range(imheight): + for x in range(imwidth): + # Set the bits for the column of pixels at the current position. + if pixels[x, y] == 0: + buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8)) + elif(imwidth == self.height and imheight == self.width): + print "Vertical" + for y in range(imheight): + for x in range(imwidth): + newx = y + newy = self.height - x - 1 + if pixels[x, y] == 0: + buf[(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): + self.send_data(0xFF) + self.send_command(DATA_START_TRANSMISSION_2) + for i in range(0, 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): + self.send_data(0xFF) + self.send_command(DATA_START_TRANSMISSION_2) + for i in range(0, self.width * self.height / 8): + self.send_data(0xFF) + self.send_command(DISPLAY_REFRESH) + self.wait_until_idle() + + def sleep(self): + self.send_command(POWER_OFF) + self.wait_until_idle() + self.send_command(DEEP_SLEEP) + self.send_data(0XA5) +### END OF FILE ### + diff --git a/refreshdb.py b/refreshdb.py index 5b468b3..e40ccd4 100644 --- a/refreshdb.py +++ b/refreshdb.py @@ -3,7 +3,7 @@ # call this to sync any new bitmaps in SSB from our friends into our posts.json EBB DB -import ConfigParser +import configparser import json import re import subprocess @@ -21,9 +21,9 @@ def main(): def fresh(): - print 'refreshing db from ssb' + print('refreshing db from ssb') #get our ssb pub key and db location from config - configParser = ConfigParser.RawConfigParser() + configParser = configparser.RawConfigParser() configFilePath = r'config.txt' configParser.read(configFilePath) ssbme = configParser.get('ebb-config', 'ssbme') @@ -34,7 +34,7 @@ def fresh(): #get time of last db-to-ssb sync from db root_entry = db.get(doc_id=1) last_run = root_entry["date"] - print 'looking for posts since: ', last_run + print('looking for posts since: ', last_run) #if last run is never ran then only look back 1 month (new installs don't need EVERY old post...) if last_run==4: @@ -49,7 +49,7 @@ def fresh(): try: proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() # get the ssb json from the bash command we just ran @@ -77,7 +77,7 @@ def fresh(): #so now theblob[0] should be THE blob dablob = theblob[0] - print dablob, 'at', timestamp + print(dablob, 'at', timestamp) #check to make sure we haven't already added this one Fruit = Query() @@ -89,15 +89,15 @@ def fresh(): try: proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() #tru/false whether we have the blob: newssb=proc.stdout.read() - print 'do we have the blob? ', newssb + print('do we have the blob? ', newssb) # if we have it, add it! if (str(newssb)=='true\n'): - print "yep, we have the blob" + print("yep, we have the blob") #generate unique file_name unique = uuid.uuid4() unique = str(unique) @@ -108,7 +108,7 @@ def fresh(): try: proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) except: - print 'traceback.format_exc():\n%s' % traceback.format_exc() + print('traceback.format_exc():\n%s' % traceback.format_exc()) exit() #add to db diff --git a/refreshdb.py.bak b/refreshdb.py.bak new file mode 100644 index 0000000..5b468b3 --- /dev/null +++ b/refreshdb.py.bak @@ -0,0 +1,125 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- + +# call this to sync any new bitmaps in SSB from our friends into our posts.json EBB DB + +import ConfigParser +import json +import re +import subprocess +import datetime +import time +import traceback +import iterparse +import uuid +import addtoDB +from tinydb import TinyDB, Query + + +def main(): + nonspace = re.compile(r'\S') + + +def fresh(): + print 'refreshing db from ssb' + #get our ssb pub key and db location from config + configParser = ConfigParser.RawConfigParser() + configFilePath = r'config.txt' + configParser.read(configFilePath) + ssbme = configParser.get('ebb-config', 'ssbme') + dbPath = configParser.get('ebb-config', 'dbPath') + imgpath = configParser.get('ebb-config', 'imagesPath') + db = TinyDB(dbPath) + + #get time of last db-to-ssb sync from db + root_entry = db.get(doc_id=1) + last_run = root_entry["date"] + print 'looking for posts since: ', last_run + + #if last run is never ran then only look back 1 month (new installs don't need EVERY old post...) + if last_run==4: + whatever=time.time() + whatever-=2700000 + last_run=int(whatever) + + newssb="nada" + newssbcmd = 'ssb-server createLogStream --reverse 1 --gt ' + str(last_run) + + #get the latest posts from ssb + try: + proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) + except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + + # get the ssb json from the bash command we just ran + newssb=proc.stdout.read() + + + # iterate through new ssb posts + for decoded in iterparse.parsy(newssb): + # get the timestamp + timestamp = decoded['timestamp'] + # get the value part of the ssb post + value = decoded['value'] + #get the content part within value... + content = value['content'] + + #check that type is post + if(content['type'] == 'post'): + #check that we are not the author + if (value['author']!=ssbme): + + #gotta pull out the non blob shiz + bigblobstring = content['text'] + halfblob = bigblobstring.split("(") + theblob = halfblob[1].split(")") + + #so now theblob[0] should be THE blob + dablob = theblob[0] + print dablob, 'at', timestamp + + #check to make sure we haven't already added this one + Fruit = Query() + isitthere=db.search(Fruit.ssb == dablob) + if (bool(isitthere)==False): + + #make sure we actually have the blob + newssbcmd = 'ssb-server blobs.has "' + theblob[0] + '"' + try: + proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) + except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + #tru/false whether we have the blob: + newssb=proc.stdout.read() + print 'do we have the blob? ', newssb + + # if we have it, add it! + if (str(newssb)=='true\n'): + print "yep, we have the blob" + #generate unique file_name + unique = uuid.uuid4() + unique = str(unique) + bmpath = imgpath + unique + '.bmp' + + #get the blob out of .ssb/blobs and put into imgages folder + newssbcmd = 'touch ' + bmpath + ' && sbot blobs.get "' + theblob[0] + '" >> ' + bmpath + try: + proc=subprocess.Popen(newssbcmd, shell=True, stdout=subprocess.PIPE, ) + except: + print 'traceback.format_exc():\n%s' % traceback.format_exc() + exit() + + #add to db + addtoDB.addFile(bmpath,dbPath,dablob) + + #update last_run (so that we don't have to search through ALL ssb posts everytime, this keeps track of oldest + Fruit = Query() + if timestamp>last_run: + db.update({'date': timestamp}, Fruit.ssb == 'default') + + + +if __name__ == '__main__': + main()