No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

display.py 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. import serial
  2. from thread import start_new_thread, allocate_lock
  3. import time
  4. import threading
  5. class Display(threading.Thread):
  6. def __init__(self,portname="/dev/ttyUSB0"):
  7. threading.Thread.__init__(self)
  8. self.serialport=None
  9. self.runme=True
  10. self.idlemessage=None
  11. self.portlock = allocate_lock()
  12. self.portname=portname
  13. self.brightness=5
  14. self.scroll_line1 = None
  15. self.scroll_line2 = None
  16. self.offset_line1 = 0
  17. self.offset_line2 = 0
  18. self.screensaver = Screensaver(self)
  19. self.open_port()
  20. def __del__(self):
  21. if (not self.screensaver == None):
  22. self.screensaver = None
  23. if (not self.serialport == None):
  24. self.serialport.close()
  25. self.serialport=None
  26. def open_port(self):
  27. try:
  28. self.serialport = serial.Serial(self.portname,9600,timeout=2,rtscts=False, dsrdtr=False)
  29. #print ("Initializing display on port:\n %s\n" % self.serialport )
  30. self.mutex_get()
  31. self.cmd_reset()
  32. self.mutex_release()
  33. except Exception as e:
  34. #print ("Exception opening serial port '%s' for display\n" % self.portname)
  35. #print ("Ignoring and trying to open it again later\n")
  36. #print (e)
  37. self.serialport = None
  38. #Helper-Function, scrolls text in a specific line.
  39. def display_scroll_text(self,line,text):
  40. if (line==1): #clear the line on invocation:
  41. self.cmd("\x1f\x24\x01%c\x18" % chr(line) )
  42. self.scroll_line1 = text
  43. self.offset_line1=0
  44. if (line==2): #clear the line on invocation:
  45. self.cmd("\x1f\x24\x01%c\x18" % chr(line) )
  46. self.scroll_line2 = text
  47. self.offset_line2=0
  48. def display_handle_scroll(self,line,text,offset):
  49. if (text):
  50. l = len(text)
  51. if (l<21):
  52. if (offset == 0):
  53. self.cmd("\x1f\x24\x01%c%s" % (chr(line),text[offset:(20+offset)]))
  54. offset=1
  55. else:
  56. self.cmd("\x1f\x24\x01%c%s" % (chr(line),text[offset:(20+offset)]))
  57. missing_chars=20+offset-l
  58. if (missing_chars>0):
  59. self.cmd(text[:missing_chars])
  60. offset=((offset+1)%l)
  61. else:
  62. offset=0 #reset offset
  63. return offset
  64. def run(self):
  65. #print "Starting Display thread"
  66. self.screensaver.start()
  67. while(self.runme):
  68. #print("display thread loop\n")
  69. self.mutex_get()
  70. #print("display got mutex and handles scroll\n")
  71. self.offset_line1 = self.display_handle_scroll(1,self.scroll_line1,self.offset_line1)
  72. self.offset_line2 = self.display_handle_scroll(2,self.scroll_line2,self.offset_line2)
  73. self.mutex_release()
  74. time.sleep(.5)
  75. print "Exiting Display thread"
  76. #Front-End Funtion to display a Screen
  77. # with heading
  78. def display_screen(self,title,message):
  79. self.mutex_get()
  80. self.offset_line1=0
  81. self.offset_line2=0
  82. self.screensaver.idle_reset();
  83. self.cmd_brightness(5)
  84. if (len(title)<21):
  85. self.scroll_line1=None
  86. self.cmd("\x1f\x24\x01%c\x18%s" % (chr(1),'\xdb'*20) )
  87. if (len(title)<20):
  88. pos=1+(20-len(title))/2
  89. else:
  90. pos=1
  91. self.cmd("\x1f\x24%c%c%s" % (chr(pos),chr(1),title) )
  92. else:
  93. self.display_scroll_text(1,title)
  94. self.display_scroll_text(2,message)
  95. self.mutex_release()
  96. def cmd_reset(self):
  97. #reset the display
  98. self.cmd("\x1b\x40")
  99. def cmd_cursor_show(self,on=True):
  100. #show or hide the cursor
  101. if (on):
  102. self.cmd("\x1f\x43\x01")
  103. else:
  104. self.cmd("\x1f\x43\x00")
  105. def cmd_blink(self,rate=127):
  106. self.cmd("\x1f\x45%c" % chr(rate))
  107. def cmd_brightness(self,level):
  108. if (self.brightness==level):
  109. return
  110. #print("setting brightness to %i \n" %level)
  111. if (level==0): #turn off:
  112. self.cmd_display_on(False)
  113. self.brightness = 0
  114. return
  115. else:
  116. if (self.brightness==0): #turn on, then set wanted brightness:
  117. self.cmd_display_on(True)
  118. self.brightness = level
  119. self.cmd("\x1F\x58%c" % chr(level-1) )
  120. def cmd_display_on(self,on=True):
  121. # blink-command:
  122. # where the last value defines the blink rate,
  123. # with 0=always on, 255=always off
  124. if (on):
  125. if (not self.brightness==0):
  126. return
  127. #print("setting display to on: %s \n" % str(on))
  128. self.cmd_blink(0)
  129. self.brightness=5
  130. else:
  131. if (self.brightness==0):
  132. return
  133. #print("setting display to on: %s \n" % str(on))
  134. self.cmd_blink(255)
  135. self.brightness=0
  136. def cmd_curmode_overwrite(self):
  137. self.cmd_curmode(1)
  138. def cmd_curmode_vscroll(self):
  139. self.cmd_curmode(2)
  140. def cmd_curmode_hscroll(self):
  141. self.cmd_curmode(3)
  142. def cmd_curmode(self,val=2):
  143. self.cmd("\x1f%c" % chr(val))
  144. def cmd_home(self):
  145. self.cmd("\x0b")
  146. def cmd_clear(self):
  147. self.cmd("\x0c")
  148. def cmd_time(self):
  149. # activate timer display in lower right corner.
  150. # actual time has to be set via display_set_timer.
  151. self.cmd("\x1f\x55")
  152. def cmd_time_set(self,h=None,m=None):
  153. if (h==None or m==None):
  154. now = time.localtime()
  155. h=now.tm_hour
  156. m=now.tm_min
  157. # configures hour and minutes of the internal clock and
  158. # displays the time in the lower right corner.
  159. # turns off when something gets written into the line.
  160. # two bytes have to follow with hour and minute
  161. self.cmd("\x1F\x54%c%c" % (chr(h),chr(m)) )
  162. self.cmd_curmode_hscroll() # makes the time more robust...
  163. def cmd(self,text): #for commands: do not reset screensaver timeout
  164. self.write(text,False)
  165. def write(self,text,idle_reset=True): #for data: reset screensaver timeout
  166. if (not self.serialport == None):
  167. if (idle_reset):
  168. self.screensaver.idle_reset();
  169. self.scroll_line1=None
  170. self.scroll_line2=None
  171. self.serialport.write(text)
  172. else:
  173. self.open_port()
  174. def setIdlemessage(self,text):
  175. self.idlemessage=text
  176. def getIdlemessage(self):
  177. return self.idlemessage
  178. def mutex_get(self):
  179. self.portlock.acquire()
  180. def mutex_release(self):
  181. self.portlock.release()
  182. def terminate(self):
  183. self.runme=False
  184. if (not self.screensaver == None):
  185. self.screensaver.terminate()
  186. self.screensaver = None
  187. import threading
  188. import time
  189. class Screensaver (threading.Thread):
  190. def __init__(self,display):
  191. threading.Thread.__init__(self)
  192. self.display=display
  193. self.runme=True
  194. self.idlecounter=0
  195. self.timeout_dim=30
  196. self.timeout_message=60
  197. self.timeout_off=300
  198. self.mutex = allocate_lock()
  199. threading.Thread.__init__(self)
  200. def run(self):
  201. #print "Starting Screensaver thread"
  202. while(self.runme):
  203. self.mutex.acquire()
  204. self._main_loop()
  205. self.mutex.release()
  206. time.sleep(.5)
  207. #print "Exiting Screensaver thread"
  208. def terminate(self):
  209. self.runme = False
  210. def idle_reset(self):
  211. self.mutex.acquire()
  212. self.idlecounter=0
  213. self.display.cmd_brightness(5)
  214. self.mutex.release()
  215. def _main_loop(self):
  216. if (self.idlecounter < self.timeout_off):
  217. self.idlecounter+=1
  218. if (self.idlecounter>=self.timeout_dim and self.idlecounter <= (self.timeout_dim+7)):
  219. x = (8-( self.idlecounter - self.timeout_dim))/2
  220. self.display.mutex_get()
  221. self.display.cmd_brightness(1+x)
  222. self.display.mutex_release()
  223. return
  224. if (self.idlecounter==self.timeout_message):
  225. self.display.mutex_get()
  226. self.display.cmd_time_set()
  227. self.display.scroll_line1 = self.display.getIdlemessage()
  228. self.display.scroll_line2 = None
  229. self.display.mutex_release()
  230. return
  231. if (self.idlecounter==self.timeout_off):
  232. self.display.mutex_get()
  233. self.display.cmd_display_on(False)
  234. self.display.mutex_release()
  235. return
  236. def __del__(self):
  237. print("bye")