webradio.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/python3
  2. from gpiozero import Button, LED
  3. from signal import pause
  4. from threading import Thread
  5. import serial
  6. import time
  7. from sys import argv
  8. import subprocess
  9. from math import ceil
  10. if len(argv) > 1:
  11. serial_port = argv[1]
  12. else:
  13. serial_port = "/dev/ttyUSB0"
  14. with open("zenders.csv") as file:
  15. ZENDERLIJST = [("Uitschakelen", None), ("AirPlay", None)] + [tuple(line.strip().split("\t")) for line in file.readlines()]
  16. class NoritakeDisplay:
  17. def __init__(self, port, baudrate=19200, parity=serial.PARITY_EVEN, **kwargs):
  18. self._serial = serial.Serial(port, baudrate=baudrate, parity=parity, **kwargs)
  19. def reset(self):
  20. self._serial.write(bytes([0x1B]))
  21. time.sleep(0.01)
  22. self._serial.write(bytes([0x49]))
  23. time.sleep(0.01)
  24. def clear(self):
  25. self._serial.write(bytes([0x0E]))
  26. time.sleep(0.01)
  27. def goto_begin(self):
  28. self._serial.write(bytes([0x0C]))
  29. time.sleep(0.01)
  30. def block_cursor(self):
  31. self._serial.write(bytes([0x15]))
  32. time.sleep(0.01)
  33. def line_cursor(self):
  34. self._serial.write(bytes([0x14]))
  35. time.sleep(0.01)
  36. def cursor_off(self):
  37. self._serial.write(bytes([0x16]))
  38. time.sleep(0.01)
  39. def print_text(self, text):
  40. # self.clear()
  41. self.goto_begin()
  42. self._serial.write(text.encode('ascii'))
  43. def center_text(self, text):
  44. # self.clear()
  45. self.goto_begin()
  46. start = ceil((20 - len(text))/2)
  47. self._serial.write((" "*start).encode('ascii'))
  48. self._serial.write(text.encode('ascii'))
  49. self._serial.write((" "*(20 - start - len(text))).encode('ascii'))
  50. def type_text(self, text):
  51. self.clear()
  52. self.goto_begin()
  53. for letter in text:
  54. self._serial.write(letter.encode('ascii'))
  55. time.sleep(.02)
  56. class WebRadio:
  57. knop = Button(14)
  58. links = Button(15)
  59. rechts = Button(18)
  60. zenderfile = "laatste_zender.txt"
  61. laatst_gedraaid = None
  62. def __init__(self, display):
  63. # Voeg display toe aan onze radio
  64. self.display = display
  65. # Stel interrupts in voor de knoppen
  66. self.knop.when_pressed = self.button_pressed
  67. self.links.when_pressed = self.dial_turned
  68. # Start een thread om de staat van het display te controleren
  69. self.thread = Thread(target=self.check_display)
  70. self.thread.start()
  71. self.mplayer = None
  72. with open(WebRadio.zenderfile, "r") as file:
  73. self.zender = int(file.read().strip())
  74. self.gekozen_zender = self.zender
  75. print(ZENDERLIJST[self.zender][0])
  76. self.display.center_text(ZENDERLIJST[self.zender][0])
  77. self.switch_zender()
  78. def button_pressed(self):
  79. self.gekozen_zender = self.zender
  80. if self.zender == 0:
  81. self.afsluiten()
  82. else:
  83. self.switch_zender()
  84. with open(self.zenderfile, "w") as file:
  85. file.write(str(self.gekozen_zender))
  86. def afsluiten(self):
  87. self.mplayer.terminate()
  88. self.display.center_text("Doei!!")
  89. self.thread.join()
  90. time.sleep(2)
  91. self.display.clear()
  92. subprocess.call(["sudo", "shutdown", "-h", "now"])
  93. quit(0)
  94. def switch_zender(self):
  95. if self.mplayer:
  96. self.mplayer.terminate()
  97. if self.zender == 1:
  98. self.mplayer = subprocess.Popen(["/home/pi/projects/airplay-audio-project/shairport/shairport", "-a", "RaspberryPi"], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
  99. else:
  100. self.mplayer = subprocess.Popen(["mplayer", *ZENDERLIJST[self.zender][1:]], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
  101. def dial_turned(self):
  102. if self.rechts.is_pressed:
  103. self.zender = self.zender + 1 if self.zender < len(ZENDERLIJST) - 1 else 0
  104. else:
  105. self.zender = self.zender - 1 if self.zender > 0 else len(ZENDERLIJST) - 1
  106. print(ZENDERLIJST[self.zender][0])
  107. self.display.center_text(ZENDERLIJST[self.zender][0])
  108. self.laatst_gedraaid = time.time()
  109. def check_display(self):
  110. while True:
  111. time.sleep(0.5)
  112. if self.gekozen_zender == 0:
  113. break
  114. if self.laatst_gedraaid and time.time() - self.laatst_gedraaid > 5 and self.zender != self.gekozen_zender:
  115. self.zender = self.gekozen_zender
  116. print(ZENDERLIJST[self.zender][0])
  117. self.display.center_text(ZENDERLIJST[self.zender][0])
  118. self.laatst_gedraaid = None
  119. display = NoritakeDisplay(serial_port)
  120. webradio = WebRadio(display=display)
  121. pause()