def __init__(self): self.pipresents_issue="1.2" self.nonfull_window_width = 0.6 # proportion of width self.nonfull_window_height= 0.6 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y=0 # position of top left corner StopWatch.global_enable=False #**************************************** # Initialisation # *************************************** # get command line options self.options=command_options() # get pi presents code directory pp_dir=sys.path[0] self.pp_dir=pp_dir if not os.path.exists(pp_dir+"/pipresents.py"): tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit() #Initialise logging Monitor.log_path=pp_dir self.mon=Monitor() self.mon.on() if self.options['debug']==True: Monitor.global_enable=True else: Monitor.global_enable=False self.mon.log (self, "Pi Presents is starting") self.mon.log (self," OS and separator:" + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: "+sys.path[0]) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # optional other classes used self.ppio=None self.tod=None #get profile path from -p option if self.options['profile']<>"": self.pp_profile_path="/pp_profiles/"+self.options['profile'] else: self.pp_profile_path = "/pp_profiles/pp_profile" #get directory containing pp_home from the command, if self.options['home'] =="": home = os.path.expanduser('~')+ os.sep+"pp_home" else: home = self.options['home'] + os.sep+ "pp_home" self.mon.log(self,"pp_home directory is: " + home) #check if pp_home exists. # try for 10 seconds to allow usb stick to automount # fall back to pipresents/pp_home self.pp_home=pp_dir+"/pp_home" found=False for i in range (1, 10): self.mon.log(self,"Trying pp_home at: " + home + " (" + str(i)+')') if os.path.exists(home): found=True self.pp_home=home break time.sleep (1) if found==True: self.mon.log(self,"Found Requested Home Directory, using pp_home at: " + home) else: self.mon.log(self,"FAILED to find requested home directory, using default to display error message: " + self.pp_home) #check profile exists, if not default to error profile inside pipresents self.pp_profile=self.pp_home+self.pp_profile_path if os.path.exists(self.pp_profile): self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.pp_profile=pp_dir+"/pp_home/pp_profiles/pp_profile" self.mon.log(self,"FAILED to find requested profile, using default to display error message: pp_profile") if self.options['verify']==True: val =Validator() if val.validate_profile(None,pp_dir,self.pp_home,self.pp_profile,self.pipresents_issue,False) == False: tkMessageBox.showwarning("Pi Presents","Validation Failed") exit() # open the resources self.rr=ResourceReader() # read the file, done once for all the other classes to use. if self.rr.read(pp_dir,self.pp_home,self.pp_profile)==False: self.end('error','cannot find resources.cfg') #initialise and read the showlist in the profile self.showlist=ShowList() self.showlist_file= self.pp_profile+ "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self,"showlist not found at "+self.showlist_file) self.end('error','showlist not found') # check profile and Pi Presents issues are compatible if float(self.showlist.sissue())<>float(self.pipresents_issue): self.mon.err(self,"Version of profile " + self.showlist.sissue() + " is not same as Pi Presents, must exit") self.end('error','wrong version of profile') # get the 'start' show from the showlist index = self.showlist.index_of_show('start') if index >=0: self.showlist.select(index) self.starter_show=self.showlist.selected_show() else: self.mon.err(self,"Show [start] not found in showlist") self.end('error','start show not found') # ******************** # SET UP THE GUI # ******************** #turn off the screenblanking and saver if self.options['noblank']==True: call(["xset","s", "off"]) call(["xset","s", "-dpms"]) self.root=Tk() self.title='Pi Presents - '+ self.pp_profile self.icon_text= 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg='black') # get size of the screen self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() # set window dimensions and decorations if self.options['fullscreen']==True: self.root.attributes('-fullscreen', True) os.system('unclutter &') self.window_width=self.screen_width self.window_height=self.screen_height self.window_x=0 self.window_y=0 self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) self.root.attributes('-zoomed','1') else: self.window_width=int(self.screen_width*self.nonfull_window_width) self.window_height=int(self.screen_height*self.nonfull_window_height) self.window_x=self.nonfull_window_x self.window_y=self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) #canvas covers the whole window self.canvas_height=self.screen_height self.canvas_width=self.screen_width # make sure focus is set. self.root.focus_set() #define response to main window closing. self.root.protocol ("WM_DELETE_WINDOW", self.exit_pressed) #setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg='black') self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) # self.canvas.pack() self.canvas.place(x=0,y=0) self.canvas.focus_set() # **************************************** # INITIALISE THE INPUT DRIVERS # **************************************** # looks after bindings between symbolic names and internal operations controlsmanager=ControlsManager() if controlsmanager.read(pp_dir,self.pp_home,self.pp_profile)==False: self.end('error','cannot find or error in controls.cfg.cfg') else: controlsmanager.parse_defaults() # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs/ # use keyboard driver to bind keys to symbolic names and to set up callback kbd=KbdDriver() if kbd.read(pp_dir,self.pp_home,self.pp_profile)==False: self.end('error','cannot find or error in keys.cfg') kbd.bind_keys(self.root,self.input_pressed) self.sr=ScreenDriver() # read the screen click area config file if self.sr.read(pp_dir,self.pp_home,self.pp_profile)==False: self.end('error','cannot find screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes reason,message = self.sr.make_click_areas(self.canvas,self.input_pressed) if reason=='error': self.mon.err(self,message) self.end('error',message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required=False #kick off GPIO if enabled by command line option if self.options['gpio']==True: from pp_gpio import PPIO # initialise the GPIO self.ppio=PPIO() # PPIO.gpio_enabled=False if self.ppio.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,50,self.gpio_pressed)==False: self.end('error','gpio error') # and start polling gpio self.ppio.poll() #kick off the time of day scheduler self.tod=TimeOfDay() self.tod.init(pp_dir,self.pp_home,self.canvas,500) self.tod.poll() # Create list of start shows initialise them and then run them self.run_start_shows() #start tkinter self.root.mainloop( )
def __init__(self): self.pipresents_issue = "1.2" self.pipresents_minorissue = '1.2.3f' self.nonfull_window_width = 0.5 # proportion of width self.nonfull_window_height = 0.6 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y = 0 # position of top left corner StopWatch.global_enable = False #**************************************** # Initialisation # *************************************** # get command line options self.options = command_options() # get pi presents code directory pp_dir = sys.path[0] self.pp_dir = pp_dir if not os.path.exists(pp_dir + "/pipresents.py"): tkMessageBox.showwarning("Pi Presents", "Bad Application Directory") exit() #Initialise logging Monitor.log_path = pp_dir self.mon = Monitor() self.mon.on() # 0 - errors only # 1 - errors and warnings # 2 - everything if self.options['debug'] == True: Monitor.global_enable = 2 else: Monitor.global_enable = 0 # UNCOMMENT THIS TO LOG WARNINGS AND ERRORS ONLY # Monitor.global_enable=1 self.mon.log( self, "\n\n\n\n\n*****************\nPi Presents is starting, Version:" + self.pipresents_minorissue) self.mon.log(self, "Version: " + self.pipresents_minorissue) self.mon.log(self, " OS and separator:" + os.name + ' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: " + sys.path[0]) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # optional other classes used self.ppio = None self.tod = None #get profile path from -p option if self.options['profile'] <> "": self.pp_profile_path = "/pp_profiles/" + self.options['profile'] else: self.pp_profile_path = "/pp_profiles/pp_profile" #get directory containing pp_home from the command, if self.options['home'] == "": home = os.path.expanduser('~') + os.sep + "pp_home" else: home = self.options['home'] + os.sep + "pp_home" self.mon.log(self, "pp_home directory is: " + home) #check if pp_home exists. # try for 10 seconds to allow usb stick to automount # fall back to pipresents/pp_home self.pp_home = pp_dir + "/pp_home" found = False for i in range(1, 10): self.mon.log(self, "Trying pp_home at: " + home + " (" + str(i) + ')') if os.path.exists(home): found = True self.pp_home = home break time.sleep(1) if found == True: self.mon.log( self, "Found Requested Home Directory, using pp_home at: " + home) else: self.mon.log( self, "FAILED to find requested home directory, using default to display error message: " + self.pp_home) #check profile exists, if not default to error profile inside pipresents self.pp_profile = self.pp_home + self.pp_profile_path if os.path.exists(self.pp_profile): self.mon.log( self, "Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.pp_profile = pp_dir + "/pp_home/pp_profiles/pp_profile" self.mon.log( self, "FAILED to find requested profile, using default to display error message: pp_profile" ) if self.options['verify'] == True: val = Validator() if val.validate_profile(None, pp_dir, self.pp_home, self.pp_profile, self.pipresents_issue, False) == False: tkMessageBox.showwarning("Pi Presents", "Validation Failed") exit() # open the resources self.rr = ResourceReader() # read the file, done once for all the other classes to use. if self.rr.read(pp_dir, self.pp_home, self.pp_profile) == False: self.end('error', 'cannot find resources.cfg') #initialise and read the showlist in the profile self.showlist = ShowList() self.showlist_file = self.pp_profile + "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self, "showlist not found at " + self.showlist_file) self.end('error', 'showlist not found') # check profile and Pi Presents issues are compatible if float(self.showlist.sissue()) <> float(self.pipresents_issue): self.mon.err( self, "Version of profile " + self.showlist.sissue() + " is not same as Pi Presents, must exit") self.end('error', 'wrong version of profile') # get the 'start' show from the showlist index = self.showlist.index_of_show('start') if index >= 0: self.showlist.select(index) self.starter_show = self.showlist.selected_show() else: self.mon.err(self, "Show [start] not found in showlist") self.end('error', 'start show not found') # ******************** # SET UP THE GUI # ******************** #turn off the screenblanking and saver if self.options['noblank'] == True: call(["xset", "s", "off"]) call(["xset", "s", "-dpms"]) self.root = Tk() self.title = 'Pi Presents - ' + self.pp_profile self.icon_text = 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg='black') # get size of the screen self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() # set window dimensions and decorations if self.options['fullscreen'] == True: self.root.attributes('-fullscreen', True) os.system('unclutter &') self.window_width = self.screen_width self.window_height = self.screen_height self.window_x = 0 self.window_y = 0 self.root.geometry("%dx%d%+d%+d" % (self.window_width, self.window_height, self.window_x, self.window_y)) self.root.attributes('-zoomed', '1') else: self.window_width = int(self.screen_width * self.nonfull_window_width) self.window_height = int(self.screen_height * self.nonfull_window_height) self.window_x = self.nonfull_window_x self.window_y = self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width, self.window_height, self.window_x, self.window_y)) #canvas covers the whole window self.canvas_height = self.screen_height self.canvas_width = self.screen_width # make sure focus is set. self.root.focus_set() #define response to main window closing. self.root.protocol("WM_DELETE_WINDOW", self.exit_pressed) #setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg='black') self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) # self.canvas.pack() self.canvas.place(x=0, y=0) self.canvas.focus_set() # **************************************** # INITIALISE THE INPUT DRIVERS # **************************************** # looks after bindings between symbolic names and internal operations controlsmanager = ControlsManager() if controlsmanager.read(pp_dir, self.pp_home, self.pp_profile) == False: self.end('error', 'cannot find or error in controls.cfg.cfg') else: controlsmanager.parse_defaults() # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs/ # use keyboard driver to bind keys to symbolic names and to set up callback kbd = KbdDriver() if kbd.read(pp_dir, self.pp_home, self.pp_profile) == False: self.end('error', 'cannot find or error in keys.cfg') kbd.bind_keys(self.root, self.input_pressed) self.sr = ScreenDriver() # read the screen click area config file if self.sr.read(pp_dir, self.pp_home, self.pp_profile) == False: self.end('error', 'cannot find screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes reason, message = self.sr.make_click_areas(self.canvas, self.input_pressed) if reason == 'error': self.mon.err(self, message) self.end('error', message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required = False #kick off GPIO if enabled by command line option if self.options['gpio'] == True: from pp_gpio import PPIO # initialise the GPIO self.ppio = PPIO() # PPIO.gpio_enabled=False if self.ppio.init(pp_dir, self.pp_home, self.pp_profile, self.canvas, 50, self.gpio_pressed) == False: self.end('error', 'gpio error') # and start polling gpio self.ppio.poll() #kick off the time of day scheduler self.tod = TimeOfDay() self.tod.init(pp_dir, self.pp_home, self.canvas, 500) self.tod.poll() # Create list of start shows initialise them and then run them self.run_start_shows() #start tkinter self.root.mainloop()