600 lines
22 KiB
Python
Executable File
600 lines
22 KiB
Python
Executable File
#!/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!")
|