Skip to content

Commit

Permalink
Version 1.3.3a
Browse files Browse the repository at this point in the history
  • Loading branch information
KenT2 committed Sep 27, 2017
1 parent f3f6efc commit 8e83916
Show file tree
Hide file tree
Showing 68 changed files with 2,342 additions and 3,729 deletions.
14 changes: 9 additions & 5 deletions README.md
Expand Up @@ -69,22 +69,26 @@ Pi Presents MUST have the latest version of omxplayer and of Raspbian, get this
sudo apt-get update
sudo apt-get upgrade

Install required applications
Install required packages
-----------------------------
sudo apt-get install python-pexpect

sudo apt-get install python-imaging
sudo apt-get install python-imaging-tk
sudo apt-get install unclutter
sudo apt-get install mplayer
sudo apt-get install uzbl
sudo apt-get install python-pexpect
Install optional packages
------------------------------
sudo pip install evdev (if you are using the input device I/O plugin)

Download Pi Presents
--------------------
Requirements:

* must use the latest version of Raspbian Stretch
* must use the latest version of Raspbian Stretch with Desktop (not the Lite version)
* must be run from the PIXEL desktop.
* must be installed and run from user Pi

Expand Down Expand Up @@ -162,7 +166,7 @@ Lastly you will need to do some manual updating of some of the field values as s

Requirements
============
Pi Presents was developed on Raspbian using Python 2.7. It is now being developed on Stretch and will not work on Wheezy or Jessie. While it will run on a Pi 1, a Pi2 or Pi3 gives much better performance for the starting of videos and images.
Pi Presents was developed on Raspbian using Python 2.7. It is now being developed on Jessie and will not work on Wheezy. While it will run on a Pi 1, a Pi2 or Pi3 gives much better performance for the starting of videos and images.

If you want to play videos omxplayer requires 256MB of GPU memory.

Expand Down
71 changes: 71 additions & 0 deletions ReleaseNotes.txt
@@ -1,4 +1,75 @@
Version 1.3.3a

Version 1.3.3a introduce I/O plugins and quiz counters. There is a fix to liveshows and other smaller enhancements and fixes.

You will need to update your profiles using the editor.

I/O Plugins
-----------
input/output is now implemented as plugins so people can write their own. The following changes are required to introduce configuration files:

If you have a modified gpio.cfg or keys.cfg in /pipresents/pp_config then these should be moved to /pipresents/pp_io_config

gpio.cfg and keys.cfg in a profile remain in /pp_io_config

Any keys.cfg file you have created will require moodification to add the following section

[DRIVER]
title = Tkinter Keys
enabled = yes
bind-printing = yes
module= pp_kbddriver

See updated /pipresents/pp_io_config/keys.cfg

Any gpio.cfg file you have created yourself will require moodification to add the following section

[DRIVER]
title = GPIO
enabled = yes
tick-interval = 50
module= pp_gpiodriver

See updated /pipresents/pp_resources/pp_templates/gpio.cfg


/dev/input I/O plugin
---------------------
There is a new I/O plugin pp_inputdevicedriver.py which suppports devices such as wireless remote controls
To use this it will be necessary to install evdev (sudo apt-get install evdev)


Shutting Down the RPi from Pi Presents
-----------------------------------------
The method of achieving this has changed. The delay is now implemented by the I/O plugin so gpio.cfg requires change to any pin used for shutdown:

# shutdown the Rpi after 5 seconds
# changed for version 1.3.3a
[P1-12]
direction = in
rising-name =
falling-name =
one-name =
#event is sent after the button is pressed fo 5 seconds NOTE CHANGE OF SYMBOLIC NAME
zero-name = pp-shutdownnow
# 50mS*100
repeat = 100
threshold = 8
pull-up-down = up

See updated /pipresents/pp_resources/pp_templates/gpio.cfg


Liveshows
---------
Liveshows have been improved to cope with a lockup condition when an empty liveshow was a subshow. It was not possible to return to the parent show.
There is a new field in the profile called an Escape Track
The List Empty Track is now mandatory. The Escape Track is now esential if the List Empty track is a show, it must not be a show. See updated example pp_liveshowempty_1p3



Version 1.3.2a
=================

Version 1.3.2a continues the improvements to Remote Management including a revamp of the look and feel of the Manager and Web Editor. Otherwise there is a large number of enhancements to the core show/player.

Expand Down
43 changes: 43 additions & 0 deletions changelog.txt
@@ -1,3 +1,46 @@
CHANGES FOR 1.3.3a 27/09/2017
====================
enhanced - io_plugins. Users can write their own I/O device driver
enhanced - input_device.py utility assists configuration of devices in /dev/input that use evdev
enhanced - new i/o plugin (pp_inputdevicedriver.py) for devices in /dev/input that use evdev
enhanced - new .cfg file which configures pp_inputdevicedriver.py specifically for OSMC official remote control.
enhanced - Pi Presents - New method of programming the shutdown pin in gpio.cfg. Allows other device drivers to do shutdown
enhanced - videoplayer, more real time controls added
enhanced - liveshow, added 'escape' track to allow use of stop command when the 'empty' track is a show.
enhanced - Pi Presents - detect there is no user and object
enhanced - players, x,y,colour, font and justify for Track Text is now in show profile track default tab
enhanced - radiobuttonshow, profile option to allow controls in subshows
enhanced - web editor, improved layout of track/show editor to reduce its height
enhanced - web editor, track has a menu entry to copy a track
enhanced - counters, new feature to define, increment, and disply counters.
enhanced - new example pp_counters_1p3
enhanced - new example pp_quiz_1p3 - shows how a hyperlinkshow and counters can be used in a multiple choice quiz,

deleted - the ability to validate a profile from Pi Presents using the -v command line option
deleted - the retired original editor pp_editor.py

fixed - manager, can now run a profile from other than /home/pi/pp_home
fixed - manager, download profile
fixed - radiobuttonshow, if first track is not specified then an anonymous track is not played
fixed - web editor, background is not grey on vga monitors
fixed - web editor, track, add directory now works
fixed - web editor, backups of profile are now stored in the correct directory in pp_profiles.bak
fixed - web editor, running the editor without a network is now possible
fixed - validate, blank track text x,y shown not as error
fixed - animate, remove crash if there was an error in animate at end command
fixed - image track and background images, if an image is corrupt objects properly instead of throwing a python exception
fixed - show control begin now happens after show control end for the previous track when changing tracks
fixed - track plugins and show control re-ordered to allow counters to work.
fixed - track plugin text is deleted at the end of a track if no redraw
modified - track plugin API simplified by removal of 'draw(). code in draw() now in show().
fixed - time of day scheduler, when using the time of day scheduler with with simulated time, log now shows simulated time of day
fixed - gain of local channel in pp_audioplayer.py increased by 40 to compensate for changes in Raspbian Stretch
fixed - import ptyprocess error fixed by alternative method of installing pexpect (see readme.md)
fixed - typo corrections profile for pp_openclose_1p3 close/closed
fixed - pp_videoplayout_1p3 example profile, added pause and mute to radiobuttonshow
fixed - removed extraneous osc.cfg from pp_showcontrol_1p3 and pp_showcontrolevent_1p3 example profile


CHANGES FOR 1.3.2a 1/4/2017
====================
enhanced - Manager,delete and rename media, livetracks, profile, download log and stats, reboot and shutdown Pi
Expand Down
2 changes: 2 additions & 0 deletions examples.sh
Expand Up @@ -38,6 +38,8 @@ while [ $RET -eq 0 ]; do
pp_plugin_1p3 "Demonstration of Track Plugins" \
pp_shutdown_1p3 "Shutdown the Raspberry Pi from Pi Presents" \
pp_videoplayout_1p3 "Using Pi Presents as a simple video playout system" \
pp_counters_1p3 "Demonstraation od Counters" \
pp_quiz_1p3 "A simple quiz using a hyperlinkshow and counters" \
website "pipresents.wordpress.com")
RET=$?
echo $RET
Expand Down
168 changes: 168 additions & 0 deletions input_device.py
@@ -0,0 +1,168 @@
import evdev
from select import select
from Tkinter import Tk, StringVar, Menu,Frame,Label,Button,Scrollbar,Listbox,Entry,Text
from Tkinter import Y,END,TOP,BOTH,LEFT,RIGHT,VERTICAL,SINGLE,NONE,W,NORMAL,DISABLED

class InputDevice(object):

def __init__(self):
# root is the Tkinter root widget
self.root = Tk()
self.root.title("Input Device Utility")

# self.root.configure(background='grey')

self.root.resizable(False,False)

# define response to main window closing
self.root.protocol ("WM_DELETE_WINDOW", self.app_exit)

self.my_device =''
self.my_device_display = StringVar()
self.device_list=[]
self.matches=0


# overall display
root_frame=Frame(self.root)
root_frame.pack(side=LEFT)

devices_frame=Frame(root_frame,padx=5,pady=10)
devices_frame.pack(side=LEFT)

devices_label = Label(devices_frame, text="Devices in dev/input")
devices_label.pack(side=TOP)

devices_list_frame=Frame(devices_frame,padx=5,pady=10)
devices_list_frame.pack(side=TOP)

selected_device_title=Label(devices_frame,text='Selected device')
selected_device_title.pack(side=TOP)
self.selected_device_var=StringVar()
selected_device=Label(devices_frame,textvariable=self.selected_device_var,fg="red")
selected_device.pack(side=TOP)

events_frame=Frame(root_frame,padx=5,pady=10)
events_frame.pack(side=LEFT)
events_title=Label(events_frame,text='Received Events')
events_title.pack(side=TOP)
events_list_frame=Frame(events_frame,padx=5,pady=10)
events_list_frame.pack(side=TOP)


# list of devices
scrollbar = Scrollbar(devices_list_frame, orient=VERTICAL)
self.devices_display = Listbox(devices_list_frame, selectmode=SINGLE, height=20,
width = 60, bg="white",activestyle=NONE,
fg="black", yscrollcommand=scrollbar.set)
scrollbar.config(command=self.devices_display.yview)
scrollbar.pack(side=RIGHT, fill=Y)
self.devices_display.pack(side=LEFT, fill=BOTH, expand=1)
self.devices_display.bind("<ButtonRelease-1>", self.e_select_device)

# events display
scrollbar = Scrollbar(events_list_frame, orient=VERTICAL)
self.events_display = Text(events_list_frame,width=40,height=20, wrap='word', font="arial 11",padx=5,yscrollcommand=scrollbar.set)
scrollbar.config(command=self.events_display.yview)
scrollbar.pack(side=RIGHT, fill=Y)
self.events_display.pack(side=LEFT, fill=BOTH, expand=1)
self.events_display.config(state=NORMAL)
self.events_display.delete(1.0, END)
self.events_display.config(state=DISABLED)


self.selected_device_index=-1
self.matches=0

self.get_all_devices()
self.refresh_devices_display()


self.root.after(10,self.event_loop)

# and enter Tkinter event loop
self.root.mainloop()



# ***************************************
# INIT AND EXIT
# ***************************************
def app_exit(self):
self.root.destroy()
exit()

def event_loop(self):
if self.matches>0:
self.get_events()
self.root.after(10,self.event_loop)

def refresh_devices_display(self):
self.devices_display.delete(0,self.devices_display.size())
for device in self.all_devices:
self.devices_display.insert(END, device[0]+ ' ' +device[1])
if self.selected_device_index >= 0:
self.devices_display.itemconfig(self.selected_device_index,fg='red')
self.devices_display.see(self.selected_device_index)


def e_select_device(self,event):
self.selected_device_index=-1
if len(self.all_devices)>0:
self.selected_device_index=int(event.widget.curselection()[0])
selected_device=self.all_devices[self.selected_device_index]
self.selected_device_name=selected_device[0]
self.selected_device_var.set(self.selected_device_name)
self.get_matching_devices()
self.refresh_devices_display()


def get_all_devices(self):
self.all_devices=[]
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for device in devices:
self.all_devices.append([device.name,device.fn])


def get_matching_devices(self):
self.matches=0
self.matching_devices=[]
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for device in devices:
if self.selected_device_name in device.name:
device_ref = evdev.InputDevice(device.fn)
self.matching_devices.append(device_ref)
self.matches+=1


def get_events(self):
r,w,x = select(self.matching_devices, [], [],0)
if r == []:
return
for event in r[0].read():
if event.type == evdev.ecodes.EV_KEY:
key_event = evdev.categorize(event)
if key_event.keystate == 1:
key_text='Down'
else:
key_text='Up'
# print key_event.keycode,key_text
if type(key_event.keycode) is list:
code_text=', '.join(key_event.keycode)
else:
code_text=key_event.keycode

self.events_display.config(state=NORMAL)
self.events_display.insert(END,'\n'+ code_text + ' ' + key_text)
self.events_display.config(state=DISABLED)
self.events_display.see(END)


# ***************************************
# MAIN
# ***************************************


if __name__ == "__main__":
id = InputDevice()

0 comments on commit 8e83916

Please sign in to comment.