No Description

main.py 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import functools
  2. import wx
  3. import wx.lib.newevent
  4. import paho.mqtt.client as paho
  5. import threading
  6. import json
  7. #import subprocess
  8. import printing
  9. import gi
  10. gi.require_version('Notify', '0.7')
  11. from gi.repository import Notify
  12. MqttMessageWaiting, EVT_MQTT_MESSAGE_WAITING = wx.lib.newevent.NewEvent()
  13. NAMES = ("Rechner", "Barkley", "Odysseus", "Adam", "Robyn", "Spritz", "Melonball")
  14. class NamePanel(wx.Panel):
  15. def __init__(self, *args, **kwargs):
  16. wx.Panel.__init__(self, *args, **kwargs)
  17. self.SetBackgroundColour("black")
  18. self.buttons = []
  19. vsizer = wx.BoxSizer(wx.VERTICAL)
  20. bold = wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.BOLD, False)
  21. sizer0 = wx.BoxSizer(wx.HORIZONTAL)
  22. self.closeBtn = wx.Button(self, wx.ID_ANY, "< Main Menu")
  23. self.closeBtn.SetFont(bold)
  24. self.closeBtn.SetBackgroundColour("red")
  25. sizer0.Add(self.closeBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 5)
  26. if len(NAMES) >= 1:
  27. btn = wx.Button(self, wx.ID_ANY, NAMES[0])
  28. sizer0.Add(btn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 5)
  29. self.buttons.append(btn)
  30. vsizer.Add(sizer0, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 5)
  31. for n in range(1, len(NAMES), 2):
  32. sizer = wx.BoxSizer(wx.HORIZONTAL)
  33. btn = wx.Button(self, wx.ID_ANY, NAMES[n])
  34. self.buttons.append(btn)
  35. sizer.Add(btn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 5)
  36. try:
  37. btn = wx.Button(self, wx.ID_ANY, NAMES[n+1])
  38. self.buttons.append(btn)
  39. sizer.Add(btn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 5)
  40. except IndexError:
  41. pass
  42. vsizer.Add(sizer, -1, wx.ALL|wx.EXPAND, 0)
  43. self.SetSizer(vsizer)
  44. self.SetSize((800, 480))
  45. self.Layout()
  46. class Controls(wx.Frame):
  47. def __init__(self, *args, **kwargs):
  48. wx.Frame.__init__(self, *args, **kwargs)
  49. self.Bind(wx.EVT_CLOSE, self.close)
  50. self.Bind(EVT_MQTT_MESSAGE_WAITING, self.processMqtt)
  51. self.namePanel = NamePanel(self)
  52. self.namePanel.Hide()
  53. self._bindNameButtons()
  54. sizer = wx.BoxSizer(wx.VERTICAL)
  55. bold = wx.Font(20, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.BOLD, False)
  56. self.snipsBtn = wx.Button(self, wx.ID_ANY, "Idle")
  57. self.snipsBtn.Bind(wx.EVT_BUTTON, self.close)
  58. self.dateBtn = wx.Button(self, wx.ID_ANY, "Date Label")
  59. self.dateBtn.SetFont(bold)
  60. self.dateBtn.Bind(wx.EVT_BUTTON, self.print_date)
  61. self.outsideBtn = wx.Button(self, wx.ID_ANY, "Outside Label")
  62. self.outsideBtn.SetFont(bold)
  63. self.outsideBtn.Bind(wx.EVT_BUTTON, self.print_outside)
  64. self.nameBtn = wx.Button(self, wx.ID_ANY, "Name Label")
  65. self.nameBtn.SetFont(bold)
  66. self.nameBtn.Bind(wx.EVT_BUTTON, self.show_name_menu)
  67. self.kitchenBtn = wx.Button(self, wx.ID_ANY, "Kitchen Lights")
  68. self.kitchenBtn.SetFont(bold)
  69. self.kitchenBtn.Bind(wx.EVT_BUTTON, self.toggle_kitchen)
  70. self.kitchenBtn.SetBackgroundColour("#275DAD")
  71. self.kitchenBtn.SetForegroundColour("white")
  72. self.diningBtn = wx.Button(self, wx.ID_ANY, "Dining Lights")
  73. self.diningBtn.SetFont(bold)
  74. self.diningBtn.Bind(wx.EVT_BUTTON, self.toggle_dining)
  75. self.diningBtn.SetBackgroundColour("#C1292E")
  76. self.diningBtn.SetForegroundColour("white")
  77. self.SetBackgroundColour("black")
  78. self.ShowFullScreen(True)
  79. vsizer_left = wx.BoxSizer(wx.VERTICAL)
  80. vsizer_left.Add(self.dateBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  81. vsizer_left.Add(self.outsideBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  82. hsizer_top = wx.BoxSizer(wx.HORIZONTAL)
  83. hsizer_top.Add(vsizer_left, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  84. hsizer_top.Add(self.nameBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  85. sizer.Add(self.snipsBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  86. sizer.Add(hsizer_top, 2, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 10)
  87. hsizer = wx.BoxSizer(wx.HORIZONTAL)
  88. sizer.Add(hsizer, 1, wx.ALL|wx.EXPAND, 10)
  89. hsizer.Add(self.kitchenBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  90. hsizer.Add(self.diningBtn, -1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE, 0)
  91. self.SetSizer(sizer)
  92. self.printer = printing.Main(False)
  93. Notify.init("Snips")
  94. self.mqtt = paho.Client()
  95. self.mqtt.connect("10.0.10.11")
  96. self.mqtt.on_publish = Controls.on_publish
  97. self.MQTT_EXIT = threading.Event()
  98. self.thread = threading.Thread(target=self._mqttWorkerThread)
  99. self.thread.start()
  100. self.mqtt.subscribe("homeassistant/light/kitchen/state")
  101. self.mqtt.subscribe("homeassistant/light/dining_room/state")
  102. self.mqtt.subscribe("hermes/dialogueManager/#")
  103. self.buttons = {
  104. 'homeassistant/light/kitchen/state' : self.kitchenBtn,
  105. 'homeassistant/light/dining_room/state' : self.diningBtn
  106. }
  107. #self.mqtt.loop_start()
  108. def print_date(self, event):
  109. self.printer.nametag(theme='date')
  110. self.printer.printout(printer='Zebra_2824')
  111. #self.printer.preview()
  112. print(self.printer.pdf)
  113. wx.CallLater(4000, self.printer.cleanup, [self.printer.pdf,])
  114. def show_name_menu(self, event):
  115. self.namePanel.Show()
  116. def hide_name_menu(self, event):
  117. self.namePanel.Enable()
  118. self.namePanel.Hide()
  119. def _bindNameButtons(self):
  120. self.namePanel.closeBtn.Bind(wx.EVT_BUTTON, self.hide_name_menu)
  121. for btn in self.namePanel.buttons:
  122. label = btn.GetLabel()
  123. func = functools.partial(self.print_name, label=label)
  124. btn.Bind(wx.EVT_BUTTON, func)
  125. def print_name(self, event, label):
  126. print(label)
  127. self.printer.nametag(theme='name', name=label)
  128. self.printer.printout(printer='Zebra_2824')
  129. #self.printer.preview()
  130. print(self.printer.pdf)
  131. wx.CallLater(4000, self.printer.cleanup, [self.printer.pdf,])
  132. self.hide_name_menu(event=None)
  133. #self.namePanel.Disable()
  134. #wx.CallLater(4000, self.hide_name_menu)
  135. def print_outside(self, event):
  136. self.printer.nametag(theme='outside')
  137. self.printer.printout(printer='Zebra_2824')
  138. wx.CallLater(4000, self.printer.cleanup, [self.printer.pdf,])
  139. @staticmethod
  140. def on_publish(client, userdata, result):
  141. print("Published: {0}: {1}".format(userdata, result))
  142. def send_notification(self, title, text, icon="dialog-information"):
  143. pass
  144. #subprocess.check_call(['/usr/bin/notify-send', str(title), str(text)])
  145. #self.notification = Notify.Notification.new(title, text)
  146. #self.notification.show()
  147. # Since we might not be on the main thread (?)
  148. #wx.CallAfter(self.queue_close_notifiaction)
  149. def queue_close_notifiaction(self, event=None):
  150. wx.CallLater(20000, self.close_notification)
  151. def close_notification(self, event=None):
  152. self.notification.close()
  153. def toggle_kitchen(self, event):
  154. print("Kitchen light toggle")
  155. self.mqtt.publish("house/switch/kitchen", "toggle")
  156. def toggle_dining(self, event):
  157. print("Dining light toggle")
  158. self.mqtt.publish("house/switch/dining_room", "toggle")
  159. def snips_idle(self):
  160. self.snipsBtn.SetBackgroundColour("white")
  161. self.snipsBtn.SetForegroundColour("black")
  162. self.snipsBtn.SetLabelText("Idle...")
  163. def processHermes(self, event):
  164. try:
  165. payload = json.loads(event.payload)
  166. except:
  167. payload = {}
  168. if event.topic == "hermes/dialogueManager/sessionStarted":
  169. self.snipsBtn.SetBackgroundColour("green")
  170. self.snipsBtn.SetForegroundColour("white")
  171. self.snipsBtn.SetLabelText("Listening...")
  172. if event.topic == "hermes/dialogueManager/sessionEnded":
  173. if 'termination' in payload.keys():
  174. if payload['termination']['reason'] in ('timeout', 'intentNotRecognized'):
  175. self.send_notification("Snips", "Sorry, I didn't quite catch that")
  176. self.snips_idle()
  177. if event.topic == "hermes/dialogueManager/endSession":
  178. if 'text' in payload.keys():
  179. print(payload['text'])
  180. self.send_notification("Snips", payload['text'])
  181. def processMqtt(self, event):
  182. if event.topic.startswith("hermes"):
  183. self.processHermes(event)
  184. return
  185. try:
  186. button = self.buttons[event.topic]
  187. except KeyError:
  188. print("No matching button for registered event topic: {0}".format(event.topic))
  189. return
  190. if event.payload == "on":
  191. button.SetBackgroundColour("green")
  192. elif event.payload == "off":
  193. button.SetBackgroundColour("red")
  194. def _mqttWorkerThread(self):
  195. def on_message(client, userdata, msg):
  196. print(msg.topic, msg.payload)
  197. event = MqttMessageWaiting(topic=msg.topic, payload=msg.payload)
  198. self.GetEventHandler().ProcessEvent(event)
  199. self.mqtt.on_message = on_message
  200. while True:
  201. self.mqtt.loop()
  202. if self.MQTT_EXIT.isSet():
  203. return None
  204. def close(self, event):
  205. Notify.uninit()
  206. self.MQTT_EXIT.set()
  207. self.thread.join()
  208. self.mqtt.disconnect()
  209. self.Destroy()
  210. if __name__ == '__main__':
  211. app = wx.App()
  212. frame = Controls(None, title="Kitchen", size=(480, 320))
  213. frame.Show()
  214. app.MainLoop()