Added Elektro - Please check
[enigma2-plugins.git] / elektro / src / plugin.py
1 #
2 # Power Save Plugin by gutemine
3 # Rewritten by Morty (morty@gmx.net)
4 #
5 # Deep standby will be called sleep. Normal standby will be named standby!
6 # All calculations are in the local timezone, or in the relative Timezone.
7 # In the relative timezone the day starts at "nextday". If it is before nextday the last day will be used.
8 #
9 #
10
11
12 #from enigma import *
13
14
15 from Screens.InfoBarGenerics import *
16 # from RecordTimer import *
17
18
19 import calendar 
20 #################
21
22 # Plugin
23 from Plugins.Plugin import PluginDescriptor
24
25 # GUI (Screens)
26 from Screens.Screen import Screen
27 from Components.ConfigList import ConfigListScreen
28 from Screens.MessageBox import MessageBox
29 from Screens.Console import Console
30 from Screens import Standby 
31
32 # GUI (Summary)
33 # from Screens.Setup import SetupSummary
34
35 # GUI (Components)
36 from Components.ActionMap import ActionMap
37 from Components.Button import Button
38
39 # Configuration
40 from Components.config import getConfigListEntry, ConfigEnableDisable, \
41         ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \
42         config, ConfigSubsection, ConfigSubList, ConfigSubDict
43
44 # Startup/shutdown notification
45 from Tools import Notifications
46
47 import os
48 # Timer, etc
49
50 #import time
51 from time import localtime, asctime, time, gmtime
52 # import datetime
53 # import codecs
54
55
56 # Enigma system functions
57 from enigma import quitMainloop, eTimer
58
59
60 # import Wakeup?!
61 from Tools.DreamboxHardware import getFPWasTimerWakeup
62
63
64
65 # from Tools import Directories
66 import gettext
67 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
68 try:
69         _ = gettext.translation('elektro', resolveFilename(SCOPE_PLUGINS, "Extensions/Elektro/locale"), [config.osd.language.getText()]).gettext
70 except IOError:
71         print "[Elektro] Locale not found!"
72         pass
73
74 #############
75
76 # Globals
77 session = None
78 ElektroWakeUpTime = -1
79 elektro_pluginversion = "3.3.1"
80 elektro_readme = "/usr/lib/enigma2/python/Plugins/Extensions/Elektro/readme.txt"
81 elektrostarttime = 60 
82 elektrosleeptime = 5
83 elektroShutdownThreshold = 60 * 20
84
85
86 #Configuration
87 config.plugins.elektro = ConfigSubsection()
88 config.plugins.elektro.nextday = ConfigClock(default = ((6 * 60 + 0) * 60) )
89
90 config.plugins.elektro.sleep = ConfigSubDict()
91 for i in range(7):
92         config.plugins.elektro.sleep[i] = ConfigClock(default = ((1 * 60 + 0) * 60) )
93
94 config.plugins.elektro.wakeup = ConfigSubDict()
95 for i in range(7):
96         config.plugins.elektro.wakeup[i] = ConfigClock(default = ((9 * 60 + 0) * 60) )
97
98 config.plugins.elektro.standbyOnBoot = ConfigEnableDisable(default = False)
99 config.plugins.elektro.standbyOnManualBoot =  ConfigEnableDisable(default = True)
100 config.plugins.elektro.standbyOnBootTimeout = ConfigNumber(default = 60)
101 config.plugins.elektro.enable = ConfigEnableDisable(default = False)
102 config.plugins.elektro.nextwakeup = ConfigNumber(default = 0)
103 config.plugins.elektro.force = ConfigEnableDisable(default = False)
104 config.plugins.elektro.dontwakeup = ConfigEnableDisable(default = False)
105 config.plugins.elektro.holiday =  ConfigEnableDisable(default = False)
106
107
108
109 weekdays = [
110         _("Monday"),
111         _("Tuesday"),
112         _("Wednesday"),
113         _("Thursday"),
114         _("Friday"),
115         _("Saturday"),
116         _("Sunday"),
117 ]
118
119
120 #global ElektroWakeUpTime
121 ElektroWakeUpTime = -1
122
123 def autostart(reason, **kwargs):
124         global session  
125         if reason == 0 and kwargs.has_key("session"):
126                 session = kwargs["session"]
127                 session.open(DoElektro)
128
129 def getNextWakeup():
130         global ElektroWakeUpTime
131         
132         #it might happen, that session does not exist. I don't know why. :-(
133         if session is None:
134                 return ElektroWakeUpTime;
135         
136         nextTimer = session.nav.RecordTimer.getNextRecordingTime()
137         print "[Elektro] Now: " + strftime("%a:%H:%M:%S",  gmtime(time()))
138         if (nextTimer < 1) or (nextTimer > ElektroWakeUpTime):
139                 print "[Elektro] will wake up " + strftime("%a:%H:%M:%S",  gmtime(ElektroWakeUpTime))
140                 return ElektroWakeUpTime
141         
142         #We have to make sure, that the Box will wake up because of us
143         # and not because of the timer
144         print "[Elektro] will wake up due to the next timer" + strftime("%a:%H:%M:%S",  gmtime(nextTimer))
145         return nextTimer - 1
146            
147         
148         
149         
150 def Plugins(**kwargs):
151         return [
152                 PluginDescriptor(
153                         name="Elektro", 
154                         description="Elektro Power Save Plugin Ver. " + elektro_pluginversion, 
155                         where = [
156                                 PluginDescriptor.WHERE_SESSIONSTART, 
157                                 PluginDescriptor.WHERE_AUTOSTART
158                         ], 
159                         fnc = autostart, 
160                         wakeupfnc=getNextWakeup
161                 ),
162                 PluginDescriptor(
163                         name="Elektro", 
164                         description="Elektro Power Save Plugin Ver. " + elektro_pluginversion, 
165                         where = PluginDescriptor.WHERE_PLUGINMENU, 
166                         icon="elektro.png", 
167                         fnc=main
168                 )
169         ]
170
171         
172 def main(session,**kwargs):
173         try:    
174                 session.open(Elektro)
175         except:
176                 print "[Elektro] Pluginexecution failed"
177
178 class Elektro(ConfigListScreen,Screen):
179         skin = """
180                         <screen position="100,100" size="550,400" title="Elektro Power Save Ver. """ + elektro_pluginversion + """" >
181                         <widget name="config" position="0,0" size="550,360" scrollbarMode="showOnDemand" />
182                         
183                         <widget name="key_red" position="0,360" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;18" transparent="1"/> 
184                         <widget name="key_green" position="140,360" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;18" transparent="1"/> 
185                         <widget name="key_yellow" position="280,360" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;18" transparent="1"/>
186                         
187                         <ePixmap name="red"    position="0,360"   zPosition="2" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
188                         <ePixmap name="green"  position="140,360" zPosition="2" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
189                         <ePixmap name="yellow" position="280,360" zPosition="2" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> 
190                 </screen>"""
191                 
192         def __init__(self, session, args = 0):
193                 self.session = session
194                 Screen.__init__(self, session)
195         
196                 
197                 self.list = []
198                 
199                 
200                 self.list.append(getConfigListEntry(_("Enable Elektro Power Save"),config.plugins.elektro.enable))
201                 self.list.append(getConfigListEntry(_("Standby on boot"), config.plugins.elektro.standbyOnBoot ))
202                 self.list.append(getConfigListEntry(_("Standby on manual boot"), config.plugins.elektro.standbyOnManualBoot ))
203                 self.list.append(getConfigListEntry(_("Standby on boot screen timeout"), config.plugins.elektro.standbyOnBootTimeout))
204                 self.list.append(getConfigListEntry(_("Force sleep (even when not in standby)"), config.plugins.elektro.force ))
205                 self.list.append(getConfigListEntry(_("Dont wake up"), config.plugins.elektro.dontwakeup ))
206                 self.list.append(getConfigListEntry(_("Holiday mode (experimental)"), config.plugins.elektro.holiday ))
207                 
208                 self.list.append(getConfigListEntry(_("Next day starts at"), config.plugins.elektro.nextday))
209
210                 for i in range(7):
211                         self.list.append(getConfigListEntry(weekdays[i] + ": "  + _("Wakeup"), config.plugins.elektro.wakeup[i]))
212                         self.list.append(getConfigListEntry(weekdays[i] + ": "  + _("Sleep"), config.plugins.elektro.sleep[i]))
213                         
214                 ConfigListScreen.__init__(self, self.list)
215                 
216                 self["key_red"] = Button(_("Cancel"))
217                 self["key_green"] = Button(_("Ok"))
218                 self["key_yellow"] = Button(_("Help"))
219                 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
220                 {
221                         "red": self.cancel,
222                         "green": self.save,
223                         "yellow": self.help,
224                         "save": self.save,
225                         "cancel": self.cancel,
226                         "ok": self.save,
227                 }, -2)
228         
229         def save(self):
230                 #print "saving"
231                 for x in self["config"].list:
232                         x[1].save()
233                 self.close(True,self.session)
234
235         def cancel(self):
236                 #print "cancel"
237                 for x in self["config"].list:
238                         x[1].cancel()
239                 self.close(False,self.session)
240                 
241         def help(self):
242                 self.session.open(Console,_("Showing Elektro readme.txt"),["cat %s" % elektro_readme])
243
244
245 class DoElektro(Screen):
246         skin = """ <screen position="100,100" size="300,300" title="Elektro Plugin Menu" > </screen>"""
247         
248         def __init__(self,session):
249                 Screen.__init__(self,session)
250                 
251                 print "[Elektro] Starting up Version " + elektro_pluginversion
252                 
253                 self.session = session
254                 
255                 # Make sure wakeup time is set.
256                 self.setNextWakeuptime()
257                 
258                 # If we didn't wake up by a timer we don't want to go to sleep any more.
259                 # Unforturnately it is not possible to use getFPWasTimerWakeup()
260                 # Therfore we're checking wheter there is a recording starting within
261                 # the next five min             
262                 self.dontsleep = False
263                 
264                 #Let's assume we got woken up manually
265                 timerWakeup = False
266                 
267                 #Is a recording already runniong ->woken up by a timer
268                 if self.session.nav.RecordTimer.isRecording():
269                         timerWakeup = True
270                 # Is the next timer within 5 min -> woken up by a timer 
271                 if abs(self.session.nav.RecordTimer.getNextRecordingTime() - time()) <= 360:
272                         timerWakeup = True
273                         
274                 # Did we wake up by Elektro?
275                 # Let's hope this get's run early enaugh, and this get's run
276                 # before the requested wakeup-time (should be the case)
277                 #
278                 if abs(ElektroWakeUpTime - time()) <= 360:
279                         timerWakeup = True      
280                         
281                 # If the was a manual wakeup: Don't go to sleep 
282                 if timerWakeup == False:
283                         self.dontsleep = True
284                 
285                 
286                 #Check whether we should try to sleep:
287                 trysleep = config.plugins.elektro.standbyOnBoot.value
288                 
289                 #Don't go to sleep when this was a manual wakeup and the box shouldn't go to standby
290                 if timerWakeup == False and     config.plugins.elektro.standbyOnManualBoot.value == False:
291                         trysleep = False
292                         
293         
294                 #if waken up by timer and configured ask whether to go to sleep.
295                 if trysleep:
296                         self.TimerStandby = eTimer()
297                         self.TimerStandby.callback.append(self.CheckStandby)
298                         self.TimerStandby.startLongTimer(elektrosleeptime)
299                         print "[Elektro] Set up standby timer"
300
301                 self.TimerSleep = eTimer()
302                 self.TimerSleep.callback.append(self.CheckElektro)
303                 self.TimerSleep.startLongTimer(elektrostarttime)
304                 print "[Elektro] Set up sleep timer"
305                 print "[Elektro] Translation test: " + _("Standby on boot")
306                 
307         def clkToTime(self, clock):
308                 return ( (clock.value[0]) * 60 + (int)(clock.value[1]) )  * 60
309                 
310         def getTime(self):
311                 ltime = localtime();
312                 return ( (int)(ltime.tm_hour) * 60 + (int)(ltime.tm_min) ) * 60
313         
314         def getPrintTime(self, secs):
315                 return strftime("%H:%M:%S", gmtime(secs))
316
317         
318         # This function converts the time into the relative Timezone where the day starts at "nextday"
319         # This is done by substracting nextday from the current time. Negative times are corrected using the mod-operator
320         def getReltime(self, time):
321                 nextday = self.clkToTime(config.plugins.elektro.nextday)
322                 return (time - nextday) %  (24 * 60 * 60)
323                 
324         
325         def CheckStandby(self):
326                 print "[Elektro] Showing Standby Sceen "
327                 try:
328                         self.session.openWithCallback(self.DoElektroStandby,MessageBox,_("Go to Standby now?"),type = MessageBox.TYPE_YESNO,
329                                         timeout = config.plugins.elektro.standbyOnBootTimeout.value)            
330                 except:
331                         # Couldn't be shown. Restart timer.
332                         print "[Elektro] Failed Showing Standby Sceen "
333                         self.TimerStandby.startLongTimer(elektrostarttime)
334
335
336         def DoElektroStandby(self,retval):
337                 if (retval):
338                         #Yes, go to sleep
339                         Notifications.AddNotification(Standby.Standby)
340                 
341
342                         
343         def setNextWakeuptime(self):
344                 # Do not set a wakeup time if
345                 #  - Elektro isn't enabled
346                 #  - Elektro shouldn't wake up
347                 #  - Holiday mode is turned on
348                 if ((config.plugins.elektro.enable.value == False) 
349                       or (config.plugins.elektro.dontwakeup.value == True)
350                       or config.plugins.elektro.holiday.value == True): 
351                         global ElektroWakeUpTime
352                         ElektroWakeUpTime = -1
353                         return
354                         
355                 time_s = self.getTime()
356                 ltime = localtime()
357                 
358                 #print "Nextday:" + time.ctime(self.clkToTime(config.plugins.elektro.nextday))
359                 # If it isn't past next-day time we need yesterdays settings
360                 if time_s < self.clkToTime(config.plugins.elektro.nextday):
361                         day = (ltime.tm_wday - 1) % 7
362                 else:
363                         day = ltime.tm_wday
364                 
365                 #Check whether we wake up today or tomorrow
366                 # Relative Time is needed for this
367                 time_s = self.getReltime(time_s)
368                 wakeuptime = self.getReltime(self.clkToTime(config.plugins.elektro.wakeup[day]))
369                 
370                 # Lets see if we already woke up today
371                 if wakeuptime < time_s:
372                         #yes we did -> Next wakeup is tomorrow
373                         #print "Elektro: Wakeup tomorrow"
374                         day = (day + 1) % 7
375                         wakeuptime = self.getReltime(self.clkToTime(config.plugins.elektro.wakeup[day]))
376                 
377                 # Tomorrow we'll wake up erly-> Add a full day.
378                 if wakeuptime < time_s:
379                         wakeuptime = wakeuptime + 24 * 60 * 60
380                 
381                 # The next wakeup will be in wakupin seconds
382                 wakeupin = wakeuptime - time_s
383                 
384                 # Now add this to the current time to get the wakeuptime
385                 wakeuptime = (int)(time()) + wakeupin
386                 
387                 #Write everything to the global variable
388                 ElektroWakeUpTime = wakeuptime
389                         
390                         
391         def CheckElektro(self):
392                 # first set the next wakeuptime - it would be much better to call that function on sleep. This will be a todo!
393                 self.setNextWakeuptime()
394         
395                 #convert to seconds
396                 time_s = self.getTime()
397                 ltime = localtime()
398                 
399                 print "[Elektro] Testtime; " + self.getPrintTime(2 * 60 * 60)
400                 
401                 #Which day is it? The next day starts at nextday
402                 print "[Elektro] wday 1: " + str(ltime.tm_wday)
403                 if time_s < self.clkToTime(config.plugins.elektro.nextday):
404                         day = (ltime.tm_wday - 1) % 7
405                 else:
406                         day = ltime.tm_wday
407                         
408                 print "[Elektro] wday 2: " + str(day)
409                 
410                 #Let's get the day
411                 wakeuptime = self.clkToTime(config.plugins.elektro.wakeup[day])
412                 sleeptime = self.clkToTime(config.plugins.elektro.sleep[day])
413                 print "[Elektro] Current time: " + self.getPrintTime(time_s)
414                 print "[Elektro] Wakeup time: " + self.getPrintTime(wakeuptime)
415                 print "[Elektro] Sleep time: " + self.getPrintTime(sleeptime)
416                 
417                 #convert into relative Times
418                 time_s = self.getReltime(time_s)
419                 wakeuptime  = self.getReltime(wakeuptime)
420                 sleeptime = self.getReltime(sleeptime)
421                 
422                 print "[Elektro] Current Rel-time: " + self.getPrintTime(time_s)
423                 print "[Elektro] Wakeup Rel-time: " + self.getPrintTime(wakeuptime)
424                 print "[Elektro] Sleep Rel-time: " + self.getPrintTime(sleeptime)
425                 
426                 
427                 #let's see if we should be sleeping
428                 trysleep = False
429                 if time_s < (wakeuptime - elektroShutdownThreshold): # Wakeup is in the future -> sleep!
430                         trysleep = True
431                         print "[Elektro] Wakeup!" + str(time_s) + " < " + str(wakeuptime)
432                 if sleeptime < time_s : #Sleep is in the past -> sleep!
433                         trysleep = True
434                         print "[Elektro] Sleep: " + str(sleeptime) + " < " + str(time_s)
435                 
436                 #We are not tying to go to sleep anymore -> maybe go to sleep again the next time
437                 if trysleep == False:
438                         self.dontsleep = False
439                 
440                 #The User aborted to got to sleep -> Don't go to sleep.
441                 if self.dontsleep:
442                         trysleep = False
443                         
444                 # If we are in holydaymode we should try to got to sleep anyway
445                 # This should be set after self.dontsleep has been handled
446                 if config.plugins.elektro.holiday.value:
447                         trysleep = True
448                 
449                 # We are not enabled -> Dont go to sleep (This could have been catched earlier!)
450                 if config.plugins.elektro.enable.value == False:
451                         trysleep = False
452                 
453                 # Only go to sleep if we are in standby or sleep is forced by settings
454                 if  not ((Standby.inStandby) or (config.plugins.elektro.force.value == True) ):
455                         trysleep = False
456                 
457                 # No Sleep while recording
458                 if self.session.nav.RecordTimer.isRecording():
459                         trysleep = False
460                 
461                 # Will there be a recording in a short while?
462                 nextRecTime = self.session.nav.RecordTimer.getNextRecordingTime()
463                 if  (nextRecTime > 0) and (nextRecTime - (int)(time()) <  elektroShutdownThreshold):
464                         trysleep = False
465                         
466                 # Looks like there really is a reason to go to sleep -> Lets try it!
467                 if trysleep:
468                         #self.();
469                         try:
470                                 self.session.openWithCallback(self.DoElektroSleep, MessageBox, _("Go to sleep now?"),type = MessageBox.TYPE_YESNO,timeout = 60) 
471                         except:
472                                 #reset the timer and try again
473                                 self.TimerSleep.startLongTimer(elektrostarttime) 
474                                 
475                 #set Timer, which calls this function again.
476                 self.TimerSleep.startLongTimer(elektrostarttime) 
477                 
478                 
479
480
481         def DoElektroSleep(self,retval):
482                 if (retval):
483                         # os.system("wall 'Powermanagent does Deepsleep now'")
484                         #  Notifications.AddNotification(TryQuitMainloop,1)
485                         # 1 = Deep Standby -> enigma2:/doc/RETURNCODES
486                         
487                         global inTryQuitMainloop
488                         if Standby.inTryQuitMainloop == False:
489                                 self.session.open(Standby.TryQuitMainloop, 1) # <- This might not work reliably
490                                 #quitMainloop(1)
491                 else:
492                         # Dont try to sleep until next wakeup
493                         self.dontsleep = True
494                         #Start the timer again
495                         self.TimerSleep.startLongTimer(elektrostarttime) 
496