import os
import random
import threading
import time
import socket
import sys
# from bluepy.btle import Scanner, DefaultDelegate
import paho.mqtt.client as mqtt
#import cv2
import struct
import imghdr
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
# customize before using!
brokeraddress = "test.mosquitto.org" # you can use this as a test broker, or setup msoquitto on a rpi as an internal broker
mqttclient = "dynaframe1" # must be unique for each frame...
brokerport = 1883
subscriptionname = "jfarro/house/makerspace/display" # this should be a string that is unique and describes where your frame is
viewcount = 0
# initial variables
refresh = False # controls when the frame needs to close aps and start over
imagePath = "" # path to the current folder of images
webpageEnd = "" # the 'footer' of the webpage
refreshInterval = 10 # number of seconds between images in a slideshow
# webpageBody is the main template for the http served webpage. This is where you can make that page..prettier
webpageBody = '''
Dynamic Screen Config
'''
webpage = webpageBody
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
qs = {}
refreshfolders()
path = self.path
# print("Path is: " + path)
qs = parse_qs(path)
for key, value in qs.items():
print ("- " + key, value)
if "/?dir" in qs :
print("Dir is.....! " + qs['/?dir'][0])
if qs['/?dir'][0] == "exit" :
os.system("killall -9 feh");
os.system("killall -9 omxplayer.bin")
global imagePath
imagePath = ""
sys.exit()
imagePath = qs['/?dir'][0]
global refresh
refresh = True
os.system("killall -9 omxplayer.bin")
print("HTTPHandler - ImagePath set to: " + imagePath)
self.send_response(200)
self.end_headers()
self.wfile.write(webpage.encode('UTF-8'))
self.wfile.write(b"
ImagePath is now: " +
imagePath.encode('UTF-8')
+ b"")
def refreshfolders():
global webpageEnd
webpageEnd = ""
# add dirs to webpage as links
folders = os.listdir()
for folder in folders:
if os.path.isdir(folder) and ("log" not in folder):
print("folder found: " + folder)
webpageEnd += "" + folder + "
"
global webpage
webpageEnd += "Exit
"
webpage = webpageBody + webpageEnd
def getrandomfolder():
global imagePath
folders = os.listdir()
validfolder = False
while validfolder is False:
imagePath = random.choice(folders)
if os.path.isdir(imagePath) and imagePath != "logs":
validfolder = True
break
def MQTTSubscribe():
client = mqtt.Client(mqttclient) # create new instance
client.connect(brokeraddress,brokerport) # connect to broker
client.subscribe(subscriptionname) # subscribe
client.on_message=on_message
client.on_log=on_log
client.loop_start()
def on_log(client, userdata, level, buf):
print("log: ", buf)
def on_message(client, userdata, message):
print("message received ", str(message.payload.decode("utf-8")))
print("message topic=", message.topic)
print("message qos=", message.qos)
print("message retain flag=", message.retain)
global imagePath
imagePath = str(message.payload.decode("utf-8"))
global refresh
refresh = True
os.system("killall -9 omxplayer.bin");
print("Imagepath set to: " + imagePath);
getrandomfolder()
print("ImagePath is: " + imagePath)
time.sleep(10.0)
# get local machine ip
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
print("Starting server at: " + ip + ":8000")
httpd = HTTPServer((ip, 8000), SimpleHTTPRequestHandler)
thread = threading.Thread(target=httpd.serve_forever)
thread.daemon = True
thread.start()
refreshfolders()
imageCheck = ""
dirs = os.listdir(imagePath)
def test_jpeg(h, f):
# SOI APP2 + ICC_PROFILE
if h[0:4] == '\xff\xd8\xff\xe2' and h[6:17] == b'ICC_PROFILE':
print("A")
return 'jpeg'
# SOI APP14 + Adobe
if h[0:4] == '\xff\xd8\xff\xee' and h[6:11] == b'Adobe':
return 'jpeg'
# SOI DQT
if h[0:4] == '\xff\xd8\xff\xdb':
return 'jpeg'
imghdr.tests.append(test_jpeg)
def get_image_size(fname):
'''Determine the image type of fhandle and return its size.
from draco'''
with open(fname, 'rb') as fhandle:
head = fhandle.read(24)
if len(head) != 24:
return
what = imghdr.what(None, head)
if what == 'png':
check = struct.unpack('>i', head[4:8])[0]
if check != 0x0d0a1a0a:
return
width, height = struct.unpack('>ii', head[16:24])
elif what == 'gif':
width, height = struct.unpack('H', fhandle.read(2))[0] - 2
# We are at a SOFn block
fhandle.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', fhandle.read(4))
except Exception: #IGNORE:W0703
return
else:
return
return width, height
def refreshPath():
global dirs
del dirs
dirs = os.listdir(imagePath)
global imageCheck
imageCheck = imagePath
refreshPath()
# init...clean up any other running instances
os.system("killall -9 feh")
os.system("killall -9 omxplayer.bin")
MQTTSubscribe()
while True:
print("Mainloop : Imagepath is:" + imagePath + "and has " + str(len(dirs)) + "files")
for file in dirs:
file = "./" + imagePath + "/" + file
print ("File is:" + file )
if imageCheck != imagePath:
print("imageCheck " + imageCheck)
print("imagePath " + imagePath)
refreshPath()
break
if imagePath == "":
quit()
#os.system("killall -9 feh")
#os.system("killall -9 omxplayer.bin")
if file.upper().endswith(".MOV"):
os.system('omxplayer ' + file)
if file.upper().endswith(".MP4"):
os.system('omxplayer ' + file)
if file.upper().endswith(".JPG"):
#checking picture is portrait
width = get_image_size(file)[0]
height = get_image_size(file)[1]
#print("Image Size - H: " + str(height) + " W: " + str(width))
if width > height:
print("Skipping Landscape Picture")
else:
print("Displaying file")
os.system("DISPLAY=:0.0 feh -qYzF \"" + file + "\" &")
#kill previous processes of feh
old = 2 * refreshInterval
os.system("killall" + " -9 -o " + str(old) + "s feh")
count = 0
while refresh is False:
time.sleep(1.0)
#print("refresh is: " + str(refresh) + " and count is: " + str(count))
#print("refreshInterval is: " + str(refreshInterval))
count = count + 1
if count > refreshInterval:
break
refresh = False