#!/usr/bin/python3 import pickle import os import time import sys import tm1637 import max7219 import pygame from time import sleep,strftime import RPi.GPIO as GPIO import button import signal import clockytracklist settings= {} looptype=0 quit=0 print("\n +----------+\n | Clocky |\n | v0.2.5 |\n +----------+\n") o_configfilename = "clocky.conf" o_defaultalarmtime = 60*14+10 # hh*60+mm o_showalarmtime=3 # time that the alarmtime shows after short press o_showtracktime=2 # note that this is per track, so total time is 10 times longer o_editdelaytime=3 # time it takes to qualify as longpress o_showtimeout=6 # timeout to exit edit modus o_snoozetime = 9 # time to snooze o_timetomaxvol = 150# seconds it takes to go from 0% to 100% volume o_maxplaytime = 900 # seconds it to play o_soundpreviewtime=5 o_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 print('Received signal: %d' %signum) if signum == signal.SIGHUP: reload=True if signum == signal.SIGINT: stopprogram=1 def stamp(): sys.stdout.write(strftime("[%Y%m%d %H%M%S] ")) def writesettings(): "write settings to conf file" with open(o_configfilename, 'wb') as handle: pickle.dump(settings, handle) handle.close() # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 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 print('My PID is %d' %os.getpid()) signal.signal(signal.SIGHUP, receive_signal) signal.signal(signal.SIGINT, receive_signal) but1=button.Button(21) but2=button.Button(20) but3=button.Button(26) #------------------------------------------------------------------ #------------------------------------------------------------------ while not stopprogram: print("Load config...") reload=False # display=tm1637.TM1637(CLK=14, DIO=4, brightness=1) display=max7219.MAX7219(brightness=1) display.Clear() display.SetBrightnessRaw(o_defaultbrightness) print("reading mp3s from directory:") tracks=clockytracklist.ClockyTracklist("mp3",recursive=True,verbose=True) allmp3s=tracks.tracklist c=0 for m in allmp3s: print(" %2d : %s"%(c+1,m)) c+=1 stamp() print("Started") sys.stdout.flush() # ................................................................. 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 } settings['alarmtime']=o_defaultalarmtime; settings['starttrack']=0; settings['alarmdisabled']=0; with open(o_configfilename, 'wb') as handle: pickle.dump(settings, handle) handle.close() else: print("Configfile: \""+o_configfilename+"\":") with open(o_configfilename, 'rb') as handle: settings = pickle.load(handle) handle.close() a_mins=int(settings['alarmtime']%60) a_hour=int((settings['alarmtime']-a_mins)/60) print("Alarmtime : %02d:%02d"%(a_hour,a_mins)) print("Alarmdisable: %d"%(settings['alarmdisabled'])) print("Starttrack : %d"%(settings['starttrack'])) for i in range(0,10): if i==settings['starttrack']: print("=>",end='') else: print(" ",end='') print(" [T%01dM%02d] "%(i,settings["track%d"%i]),end='') if settings["track%d"%i] and (settings["track%d"%i]-1 < len(allmp3s)): print("\""+allmp3s[settings["track%d"%i]-1]+"\"") else: print("") settings["track%d"%i]=0 writesettings() # ................................................................. while not reload and not stopprogram: count+=1; sleep(o_loopdelay) mytime=time.localtime(time.time()) currenttime=mytime[3]*60 + mytime[4]; if not settings["alarmdisabled"]: if currenttime == 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 settings["alarmdisabled"]==0: settings["alarmdisabled"]=1 stamp() print("Alarm disabled") writesettings() else: settings["alarmdisabled"]=0 stamp() print("Alarm enabled") writesettings() looptype=1 else: looptype=2 if but2.WasPressed(): looptype=3 track=0 if but2.WasLong(): looptype=4 if but3.WasPressed(): if but3.WasLong(): if settings["alarmdisabled"]==0: settings["alarmdisabled"]=1 stamp() print("Alarm disabled") writesettings() else: settings["alarmdisabled"]=0 stamp() print("Alarm enabled") writesettings() 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 settings["alarmdisabled"]==1: a_mins=int(settings['alarmtime']%60) a_hour=int((settings['alarmtime']-a_mins)/60) 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 > o_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 sm=int(settings['alarmtime']%10) dm=int(((settings['alarmtime']-sm)/10)%6) sh=int((settings['alarmtime']-dm)/60%10) dh=int((settings['alarmtime']-sh)/600) 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 > o_showtimeout: showtime=0 if dh==2 and sh>3: sh=3 looptype=1 else: looptype=0 if settings["alarmdisabled"]==1: settings["alarmdisabled"]=0 stamp() print("Alarm enabled") settings['alarmtime']=dh*600+sh*60+dm*10+sm writesettings() stamp() print("Set alarmtime = %d%d:%d%d"%(dh,sh,dm,sm)) sys.stdout.flush() digit=1 else: showtime+=o_loopdelay settings['alarmtime']=dh*600+sh*60+dm*10+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() >o_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 > o_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 > o_showtimeout: showtime=0 looptype=0 writesettings() else: showtime+=o_loopdelay if but1.WasPressed(): digit+=1 if digit>3: digit=1 showtime=0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if looptype==5: # Alarm! #o_timetomaxvol = 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=settings['starttrack']; stamp() print("[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 settings['starttrack']=track; writesettings() playtime=0 alarmstarted=1 else: # alarmstarted if playtime < o_timetomaxvol: brightness=int((playtime / o_timetomaxvol)*255) volume = float(int((playtime*100) / o_timetomaxvol))/100 # print("------> %d / %d => %f - %f [%d]"%(playtime,o_timetomaxvol,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=settings['starttrack'] stamp() print("[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 settings['starttrack']=track; writesettings() if playtime > o_maxplaytime: looptype=0 playtime=0 if pygame.mixer.get_init(): pygame.mixer.music.set_volume(0) pygame.mixer.music.stop() pygame.mixer.quit() display.SetBrightnessRaw(o_defaultbrightness) alarmstarted=0 stamp() print("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(o_defaultbrightness) playtime=0 if but1.WasPressed(): # flush intermediate presses {} if but2.WasPressed(): {} if but3.WasPressed(): {} looptype=0 alarmstarted=0 silencedalarm=1 stamp() print("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=settings['starttrack'] stamp() print("[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 settings['starttrack']=track; writesettings() # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if count % 40 == 0: # every 10 seconds if tracks.CheckTrackList(): 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() print("Shutdown!")