stdd 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #! /usr/bin/env python
  2. # -*- coding: utf8 -*-
  3. #
  4. # This file is part of stdd, the simple time display daemon,
  5. # written by Helmut Pozimski <helmut@pozimski.eu> 2013-2014,
  6. # licensed under the 3-clause BSD license
  7. import datetime
  8. import time
  9. import sys
  10. import signal
  11. import os
  12. import logging
  13. import logging.handlers
  14. from optparse import OptionParser
  15. import stddlib.daemon
  16. import stddlib.configuration
  17. from adafruit_7segment.Adafruit_7Segment import SevenSegment
  18. """Create the OptionParser object, define and parse all options and
  19. parameters, only 3 are currently defined:
  20. * --daemon (shall stdd be run as daemon)
  21. * --user (user to change to)
  22. * --group (group to change to)
  23. * --config (path to configuration file)
  24. """
  25. parser = OptionParser(prog="stdd", version="%prog 0.9.2", add_help_option=True)
  26. parser.add_option("-d", "--daemon", action="store_true", dest="daemon",
  27. help="run stdd as daemon")
  28. parser.add_option("-u", "--user", dest="user", help="define an unprivileged \
  29. user to run the daemon")
  30. parser.add_option("-g", "--group", dest="group", help="define an unprivileged\
  31. group to run the daemon")
  32. parser.add_option("-c", "--config", dest="config", help="define an\
  33. alternative path to the configuration file")
  34. (options, arguments) = parser.parse_args()
  35. """ define a sighandler to properly catch signals """
  36. def sighandler(signum, frame):
  37. if signum == 2:
  38. logger.info("received SIGINT, stopping daemon")
  39. elif signum == 15:
  40. logger.info("received SIGTERM, stopping daemon")
  41. display.writeDigit(0, 0)
  42. display.writeDigit(1, 0)
  43. display.writeDigit(3, 0)
  44. display.writeDigit(4, 0)
  45. if options.daemon is True:
  46. if daemon.Stop() is True:
  47. sys.exit(0)
  48. else:
  49. logger.error("stopping daemon failed, PID file was not deleted!")
  50. sys.exit(1)
  51. sys.exit(0)
  52. """ create the configuration object according to the given parameters and
  53. read the file itself
  54. """
  55. signal.signal(signal.SIGTERM, sighandler)
  56. signal.signal(signal.SIGINT, sighandler)
  57. config = stddlib.configuration.Conf()
  58. if options.config is not None:
  59. config.Read(options.config)
  60. else:
  61. config.Read()
  62. config.Analyze()
  63. """ create a logger to log errors according to configuration """
  64. logger = logging.getLogger("stdd")
  65. if config.syslog_level == "debug":
  66. logger.setLevel(logging.DEBUG)
  67. elif config.syslog_level == "error":
  68. logger.setLevel(logging.ERROR)
  69. else:
  70. logger.setLevel(logging.INFO)
  71. if config.syslog_facility == "daemon":
  72. syslog_handler = logging.handlers.SysLogHandler(
  73. "/dev/log",
  74. facility=logging.handlers.SysLogHandler.LOG_DAEMON)
  75. else:
  76. syslog_handler = logging.handlers.SysLogHandler("/dev/log")
  77. console_handler = logging.StreamHandler()
  78. formatter = logging.Formatter("%(name)s[" + str(os.getpid()) +
  79. "]: %(message)s")
  80. syslog_handler.setFormatter(formatter)
  81. console_handler.setFormatter(formatter)
  82. if options.daemon is True:
  83. logger.addHandler(syslog_handler)
  84. else:
  85. logger.addHandler(console_handler)
  86. if options.daemon is True:
  87. if os.access("/run", os.F_OK & os.W_OK) is True:
  88. daemon = stddlib.daemon.Daemon("/run/stdd", "stdd.pid")
  89. else:
  90. daemon = stddlib.daemon.Daemon("/var/run/stdd", "stdd.pid")
  91. daemon.Daemonize()
  92. daemon.Start()
  93. logger.info("daemon started")
  94. cmdline = ""
  95. cmdcounter = 0
  96. for element in sys.argv:
  97. if cmdcounter > 0:
  98. cmdline = cmdline + " " + element
  99. else:
  100. cmdline = cmdline + element
  101. cmdcounter += 1
  102. daemon.SetName("stdd", cmdline)
  103. if options.user is not None and options.group is not None:
  104. daemon.DropPriv(options.user, options.group)
  105. logger.debug("dropped privileges, now running as " + options.user +
  106. " and group" + options.group)
  107. """Initialize the display object"""
  108. display = SevenSegment(config.hw_address)
  109. logger.debug("opened hardware address")
  110. """Set the brightness according to the configuration"""
  111. if datetime.datetime.now().time() > config.set_brightness_high and \
  112. datetime.datetime.now().time() < config.set_brightness_low:
  113. logger.debug("setting display brightness high")
  114. display.setBrightness(config.brightness_high)
  115. else:
  116. logger.debug("setting display brightness low")
  117. display.setBrightness(config.brightness_low)
  118. """Define the main loop"""
  119. def main():
  120. minute_written = 61
  121. while True:
  122. date_now = datetime.datetime.now()
  123. logger.debug("got datetime: " + str(date_now))
  124. minute = date_now.minute
  125. hour = date_now.hour
  126. if config.blink_colon is True:
  127. logger.debug("blinking middle colon")
  128. display.setColon(date_now.second % 2)
  129. else:
  130. display.setColon(True)
  131. """set the display brightness high or low when the point in time
  132. defined is reached.
  133. """
  134. if config.set_brightness_low.hour == hour:
  135. if config.set_brightness_low.minute == minute:
  136. logger.debug("setting display brightness low")
  137. display.setBrightness(config.brightness_low)
  138. if config.set_brightness_high.hour == hour:
  139. if config.set_brightness_high.minute == minute:
  140. logger.debug("setting display brightness high")
  141. display.setBrightness(config.brightness_high)
  142. if minute_written != minute:
  143. try:
  144. position2 = str(hour)[1]
  145. except IndexError:
  146. position2 = str(hour)[0]
  147. position1 = "0"
  148. else:
  149. position1 = str(hour)[0]
  150. try:
  151. position4 = str(minute)[1]
  152. except IndexError:
  153. position4 = str(minute)[0]
  154. position3 = "0"
  155. else:
  156. position3 = str(minute)[0]
  157. logger.debug("writing time to display")
  158. display.writeDigit(0, int(position1))
  159. display.writeDigit(1, int(position2))
  160. display.writeDigit(3, int(position3))
  161. display.writeDigit(4, int(position4))
  162. minute_written = minute
  163. time.sleep(1)
  164. if __name__ == "__main__":
  165. main()