#!/usr/bin/python3 import pickle import os import time import sys import tm1637 import max7219 os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" import pygame from time import sleep,strftime import RPi.GPIO as GPIO import button import signal import clockyconfig import clockytracklist VERBOSE=True settings= {} looptype=0 quit=0 print("\n +----------+\n | Clocky |\n | v0.3.0 |\n +----------+\n") o_configfilename = "clocky.conf" #o_defaultalarmtime = 60*14+10 # hh*60+mm #config.settings['showalarmtime']=3 # time that the alarmtime shows after short press #config.settings['showtracktime']=2 # note that this is per track, so total time is 10 times longer #config.settings['editdelaytime']=3 # time it takes to qualify as longpress #config.settings['edittimeout']=6 # timeout to exit edit modus #config.settings['snoozetime'] = 9 # time to snooze #config.settings['timetomaxvolume'] = 150# seconds it takes to go from 0% to 100% volume #config.settings['maxalarmtime'] = 900 # seconds it to play #config.settings['soundpreviewtime']=5 #config.settings['defaultbrightness']=0 o_loopdelay=0.25 track=0 stopprogram=0 reload=False #GPIO.setmode(GPIO.BCM) # set up BCM GPIO numbering #GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP) #def signal_handler(signal,frame): # global quit # print("") # quit=1 def receive_signal(signum, stack): global stopprogram global reload if VERBOSE: print('Received signal: %d' %signum) else: print("") if signum == signal.SIGHUP: reload=True if signum == signal.SIGINT: stopprogram=1 def stamp(str): sys.stdout.write(strftime("[%Y%m%d %H%M%S] ")+str+"\n") sys.stdout.flush() def timetoval(str): return (str.split(":")[0]*60)+str.split(":")[1] # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # looptype=0 colon=0 digit=1 showtime=0 playtime=0 soundpreview=0 alarmstarted=0 silencedalarm=0 tvol=0 volume=0.0 brightness=0 snooze=0 count=0 if VERBOSE: print('My PID is %d' %os.getpid()) signal.signal(signal.SIGHUP, receive_signal) signal.signal(signal.SIGINT, receive_signal) but1=button.Button(21,verbose=VERBOSE) but2=button.Button(20,verbose=VERBOSE) but3=button.Button(26,verbose=VERBOSE) config=clockyconfig.ClockyConfig(verbose=VERBOSE) tracks=clockytracklist.ClockyTracklist("mp3",recursive=True,verbose=VERBOSE) #------------------------------------------------------------------ #------------------------------------------------------------------ while not stopprogram: if VERBOSE: print("Load config...") reload=False display=tm1637.TM1637(CLK=14, DIO=4, brightness=1) # display=max7219.MAX7219(brightness=1) display.Clear() display.SetBrightnessRaw(config.settings['defaultbrightness']) if VERBOSE: print("Reading mp3s from directory:") allmp3s=tracks.tracklist c=0 if True: # VERBOSE: print("\nTracks:") for m in allmp3s: print("%2d : %s"%(c+1,m)) c+=1 stamp("Started") # ................................................................. if not os.path.isfile(o_configfilename): print("Createconf: \""+o_configfilename+"\":") settings = {'track0':1, 'track1':2, 'track2':3, 'track3':4, 'track4':5, 'track5':6, 'track6':7, 'track7':8, 'track8':9, 'track9':10 } config.starttrack=0; config.settings['alarmdisabled']=0; with open(o_configfilename, 'wb') as handle: pickle.dump(settings, handle) handle.close() else: if VERBOSE: print("Configfile: \""+o_configfilename+"\":") with open(o_configfilename, 'rb') as handle: settings = pickle.load(handle) handle.close() a_hour=int(config.settings['alarmtime'].split(":")[0]) a_mins=int(config.settings['alarmtime'].split(":")[1]) if VERBOSE: print("Alarmtime : %02d:%02d"%(a_hour,a_mins)) print("Alarmdisable: %d"%(config.settings['alarmdisabled'])) print("Starttrack : %d"%(config.starttrack)) for i in range(0,10): if i==config.starttrack: if VERBOSE: print("=>",end='') else: if VERBOSE: print(" ",end='') if VERBOSE: print(" [T%01dM%02d] "%(i,settings["track%d"%i]),end='') if settings["track%d"%i] and (settings["track%d"%i]-1 < len(allmp3s)): if VERBOSE: print("\""+allmp3s[settings["track%d"%i]-1]+"\"") else: if VERBOSE: print("") settings["track%d"%i]=0 # ................................................................. # Main loop without reload and stuff # while not reload and not stopprogram: count+=1; sleep(o_loopdelay) mytime=time.localtime(time.time()) currenttime=mytime[3]*60 + mytime[4]; if not config.settings["alarmdisabled"]: if currenttime == timetoval(config.settings['alarmtime']): if looptype==0 and not silencedalarm: looptype=5 else: silencedalarm=0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==0: # normal time display if but1.WasPressed(): looptype=1 if but1.WasLong(): if but2.WasPressed(): if but2.WasLong(): if config.settings["alarmdisabled"]==0: config.settings["alarmdisabled"]=1 stamp("Alarm disabled") else: config.settings["alarmdisabled"]=0 stamp("Alarm enabled") looptype=1 else: looptype=2 if but2.WasPressed(): looptype=3 track=0 if but2.WasLong(): looptype=4 if but3.WasPressed(): if but3.WasLong(): if config.settings["alarmdisabled"]==0: config.settings["alarmdisabled"]=1 stamp("Alarm disabled") else: config.settings["alarmdisabled"]=0 stamp("Alarm enabled") looptype=1 if colon: tim="%02d:%02d" % (mytime[3] , mytime[4]) else: tim="%02d %02d" % (mytime[3] , mytime[4]) display.showclock(tim) if count % 4 == 0: colon=1-colon # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==1: # show alarmtime if not config.settings["alarmdisabled"]==1: a_hour=int(config.settings['alarmtime'].split(":")[1]) a_mins=int(config.settings['alarmtime'].split(":")[1]) if colon: tim="%02d:%02d" % (a_hour, a_mins) else: tim="%02d %02d" % (a_hour, a_mins) display.showclock(tim) colon=1-colon else: display.showclock(" O FF") if showtime > config.settings['showalarmtime']: if but1.WasPressed(): # drop intermediate presses {} if but2.WasPressed(): {} if but3.WasPressed(): {} showtime=0 looptype=0 else: showtime+=o_loopdelay # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==2: # edit alarmtime delta=0 dh=int(config.settings['alarmtime'][0]) sh=int(config.settings['alarmtime'][1]) dm=int(config.settings['alarmtime'][3]) sm=int(config.settings['alarmtime'][4]) if colon: tim="%0d%0d:%0d%0d" % (dh,sh,dm,sm) else: if but2.WasPressed(): delta=1 showtime=0 if but3.WasPressed(): delta=-1 showtime=0 if digit==1: if delta: dh+=delta if dh>2: dh=0 if dh<0: dh=2 tim=" %0d:%0d%0d" % ( sh,dm,sm) elif digit==2: if delta: sh+=delta if sh>9: sh=0 if dh==2 and sh>3: sh=0 if sh<0: sh=9 tim="%0d :%0d%0d" % (dh, dm,sm) elif digit==3: if delta: dm+=delta if dm>5: dm=0 if dm<0: dm=5 tim="%0d%0d: %0d" % (dh,sh, sm) elif digit==4: if delta: sm+=delta if sm>9: sm=0 if sm<0: sm=9 tim="%0d%0d:%0d " % (dh,sh,dm ) delta=0 display.showclock(tim) colon=1-colon if showtime > config.settings['edittimeout']: showtime=0 if dh==2 and sh>3: sh=3 looptype=1 else: looptype=0 if config.settings["alarmdisabled"]==1: config.settings["alarmdisabled"]=0 stamp("Alarm enabled") config.settings['alarmtime']=("%d%d:%d%d" %(dh,sh,dm,sm)) stamp("Set alarmtime = %d%d:%d%d"%(dh,sh,dm,sm)) sys.stdout.flush() digit=1 else: showtime+=o_loopdelay config.settings['alarmtime']=("%d%d:%d%d" %(dh,sh,dm,sm)) if but1.WasPressed(): showtime=0 digit+=1 if digit>4: digit=1 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==3: # show tracks mode if but1.WasPressed(): if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() soundpreview=0 looptype=1 if but1.WasLong(): looptype=2 if but2.WasPressed(): if settings["track%d"%track]>0: print (allmp3s[settings["track%d"%track]-1]) sys.stdout.flush() if not pygame.mixer.get_init(): pygame.mixer.init() if pygame.mixer.get_init(): pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1]) pygame.mixer.music.set_volume(1) pygame.mixer.music.play() soundpreview=1 tr=track tl=int(settings["track%d"%tr]%10) th=int((settings["track%d"%tr]-tl)/10) if colon: tim="%d=:%d%d" % (tr,th,tl) else: tim="%d %d%d" % (tr,th,tl) tr+=1; if tr>9: looptype=0 display.showclock(tim) colon=1-colon if soundpreview: if pygame.mixer.music.get_pos() >config.settings['soundpreviewtime']*1000: if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() soundpreview=0 showtime=0 track+=1; if track>9: looptype=0 else: if showtime > config.settings['showtracktime']: showtime=0 track+=1; if track>9: looptype=0 else: showtime+=o_loopdelay # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==4: # edit track delta=0 tr=track tl=int(settings["track%d"%tr]%10) th=int((settings["track%d"%tr]-tl)/10) if colon: tim="%d=:%d%d" % (tr,th,tl) else: if but2.WasPressed(): delta=1 showtime=0 if but3.WasPressed(): delta=-1 showtime=0 if digit==1: if delta: tr+=delta if tr>9: tr=0 delta=0 tl=settings["track%d"%tr]%10 th=(settings["track%d"%tr]-tl)/10 tim=" =:%0d%0d" % ( th,tl) elif digit==2: if delta: th+=delta if th>9: th=0 delta=0 tim="%d=: %d" % (tr, tl) elif digit==3: if delta: tl+=delta if tl>9: tl=0 delta=0 tim="%d=:%d " % (tr,th ) delta=0 display.showclock(tim) colon=1-colon settings["track%d"%tr]=th*10+tl track=tr if showtime > config.settings['edittimeout']: showtime=0 looptype=0 else: showtime+=o_loopdelay if but1.WasPressed(): digit+=1 if digit>3: digit=1 showtime=0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==5: # Alarm loop! #config.settings['timetomaxvolume'] = 60 # seconds it takes to go from 0% to 100% volume if colon: display.SetBrightnessRaw(0) tim="%02d:%02d" % (mytime[3] , mytime[4]) else: display.SetBrightnessRaw(brightness) tim="%02d:%02d" % (mytime[3] , mytime[4]) display.showclock(tim) if count % 2 == 0: colon=1-colon if not alarmstarted: track=config.starttrack; stamp("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1]))) sys.stdout.flush() if not pygame.mixer.get_init(): pygame.mixer.init() if pygame.mixer.get_init(): pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1]) pygame.mixer.music.set_volume(volume) pygame.mixer.music.play() track+=1 if track > 9: track=0 if settings["track%d"%track]==0: track=0 config.starttrack=track; playtime=0 alarmstarted=1 else: # alarmstarted if playtime < config.settings['timetomaxvolume']: brightness=int((playtime / config.settings['timetomaxvolume'])*255) volume = float(int((playtime*100) / config.settings['timetomaxvolume']))/100 # print("------> %d / %d => %f - %f [%d]"%(playtime,config.settings['timetomaxvolume'],tvol,volume,brightness)) else: volume=1 if pygame.mixer.get_init(): pygame.mixer.music.set_volume(volume) playtime+=o_loopdelay if pygame.mixer.get_init(): if not pygame.mixer.music.get_busy(): track=config.starttrack stamp("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1]))) sys.stdout.flush() pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1]) pygame.mixer.music.play() track+=1 if track > 9: track=0 if settings["track%d"%track]==0: track=0 config.starttrack=track; if playtime > config.settings['maxalarmtime']: looptype=0 playtime=0 if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() display.SetBrightnessRaw(config.settings['defaultbrightness']) alarmstarted=0 stamp("Alarmtime expired") if but1.WasPressed(): if but1.WasLong(): # Finished if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() display.SetBrightnessRaw(config.settings['defaultbrightness']) playtime=0 if but1.WasPressed(): # flush intermediate presses {} if but2.WasPressed(): {} if but3.WasPressed(): {} looptype=0 alarmstarted=0 silencedalarm=1 stamp("Silenced alarm") if but2.WasPressed(): if not but1.WasLong(): if pygame.mixer.get_init(): if pygame.mixer.music.get_busy(): pygame.mixer.music.stop() track=config.starttrack stamp("[T%02dM%02d] \"%s\""%(track,settings["track%d"%track],(allmp3s[settings["track%d"%track]-1]))) sys.stdout.flush() if pygame.mixer.get_init(): pygame.mixer.music.load(allmp3s[settings["track%d"%track]-1]) pygame.mixer.music.play() track+=1 if track > 9: track=0 if settings["track%d"%track]==0: track=0 config.starttrack=track; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if count % 40 == 0: # every 10 seconds if tracks.CheckTrackList() or config.CheckConfig(): reload = True; #------------------------------------------------------------------ if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() display.cleanup() sys.stdout.flush() stamp("Shutdown!")