class Slave: host: str port: int passwd: str width: int height: int v_flip: bool h_flip: bool quality: int com_port: str baud_rate: int spl_rate: int ch_num: int ssl_ctx: ssl.SSLContext = None def __post_init__(self): self.eye_node = Node(self.host, self.port, self.passwd, 'slave_eye', 'master_eye', self.ssl_ctx) self.body_node = Node(self.host, self.port, self.passwd, 'slave_body', 'master_body', self.ssl_ctx) self.mouth_node = Node(self.host, self.port, self.passwd, 'slave_mouth', 'master_ear', self.ssl_ctx) self.eye = Eye(self.width, self.height, self.v_flip, self.h_flip, self.quality) self.body = Body(self.com_port, self.baud_rate) self.mouth = Mouth(self.spl_rate, self.ch_num) def mainloop(self): # create and start all threads # modern computer is really powerful # and it's ok to run so many thread eye_thread = Thread(target=self.handle_eye) body_thread = Thread(target=self.handle_body) mouth_thread = Thread(target=self.handle_mouth) # make sure to close all threads # after exiting the application self.eye_node.setDaemon(True) self.body_node.setDaemon(True) self.mouth_node.setDaemon(True) self.eye.setDaemon(True) self.body.setDaemon(True) self.mouth.setDaemon(True) eye_thread.setDaemon(True) body_thread.setDaemon(True) mouth_thread.setDaemon(True) self.eye_node.start() self.body_node.start() self.mouth_node.start() self.eye.start() self.body.start() self.mouth.start() eye_thread.start() body_thread.start() mouth_thread.start() self.hang_by() @tricks.new_game_plus def handle_eye(self): width, height, img = self.eye.send_q.get() temp = base64.b64encode(img.tobytes()) data = ujson.dumps((width, height, temp)) self.eye_node.send_data(data) @tricks.new_game_plus def handle_body(self): data = self.body_node.recv_data() act, det, val = ujson.loads(data) temp = '{0} {1} {2}\n'.format(act, det, val) self.body.recv_q.put(temp) @tricks.new_game_plus def handle_mouth(self): data = self.mouth_node.recv_data() temp = base64.b64decode(data) temp = np.fromstring(temp, np.float32) # make sure the shape is correct audio = temp.reshape((-1, self.ch_num)) self.mouth.recv_q.put(audio) @staticmethod @tricks.vow_of_silence(KeyboardInterrupt) @tricks.new_game_plus def hang_by(): time.sleep(3600)
class Master(App): def __init__(self, host: str, port: int, passwd: str, api_key: str, api_sec: str, spl_rate: int, ch_num: int, ssl_ctx: ssl.SSLContext = None, **kwargs): super().__init__(**kwargs) self.window = MasterWin(self) self.eye_node = Node(host, port, passwd, 'master_eye', 'slave_eye', ssl_ctx) self.body_node = Node(host, port, passwd, 'master_body', 'slave_body', ssl_ctx) self.ear_node = Node(host, port, passwd, 'master_ear', 'slave_mouth', ssl_ctx) self.sight = Sight(api_key, api_sec) self.ear = Ear(spl_rate, ch_num) def mainloop(self): # create and start all threads # modern computer is really powerful # and it's ok to run so many thread eye_thread = Thread(target=self.handle_eye) sight_thread = Thread(target=self.handle_sight) ear_thread = Thread(target=self.handle_ear) # make sure to close all threads # after exiting the application self.eye_node.setDaemon(True) self.body_node.setDaemon(True) self.ear_node.setDaemon(True) self.sight.setDaemon(True) self.ear.setDaemon(True) eye_thread.setDaemon(True) sight_thread.setDaemon(True) ear_thread.setDaemon(True) self.eye_node.start() self.body_node.start() self.ear_node.start() self.sight.start() self.ear.start() eye_thread.start() sight_thread.start() ear_thread.start() self.run() @tricks.new_game_plus def handle_eye(self): data = self.eye_node.recv_data() width, height, temp = ujson.loads(data) temp = base64.b64decode(temp) img_jpg = np.fromstring(temp, np.uint8) img = cv2.imdecode(img_jpg, cv2.IMREAD_COLOR) # update sight with JPEG encoded img # and update img with bitmap self.sight.recv_q.put_anyway((width, height, img_jpg)) self.window.update_img(width, height, img) @tricks.new_game_plus def handle_sight(self): width, height, rects = self.sight.send_q.get() self.window.update_rects(width, height, rects) @tricks.new_game_plus def handle_ear(self): audio = self.ear.send_q.get() data = base64.b64encode(audio.tobytes()) self.ear_node.send_data(data) def build(self): return self.window