def on_clicked(self, widget): """Callback when `Record` button is clicked. This will be called on whenever the Record button is clicked First will communicate with rpi_out to see if a clip is being record or not and will set the self.recording flag accordingly If recording still, do nothing If not record, send signal to record clip and set self.recording accordingly. """ # Sets button to yellow while rpi_in tries communicating with rpi_out set_button_property(self, "yellow", "Spooling up camera...") # Check if not recording if not self.recording: self.logger.info("Sending record ON message to rpi_out...") self.pub.publish(json.dumps(["record", True])) try: # wait for rpi_out to send true msg back self.recording = wait_msg("record", self.logger, self.msg_q)[1] except IndexError: # no message received self.recording = False if self.recording: # Since rpi_out sent back true it should be recording now self.logger.info("rpi_out is recording now...") # turn button to red if not already red set_button_property(self, "red", "Recording...") # waiting for rpi_out to send youtube playlist link try: # wait for rpi_out to send msg back. # Set timeout longer than video length self.yt_playlist_link = wait_msg( "yt_playlist_link", self.logger, self.msg_q, timeout=self.video_length + 30, )[1] except IndexError: # no message received self.recording = False # Does not catch if junk str was sent back if type(self.yt_playlist_link) == str and self.recording: self.logger.info("rpi_out recorded a video succesfully...") else: # Something wrong with mqtt or the recording failed self.logger.error( f"The camera is running, Mqtt broke or the YouTube Api broke. No video was recorded! Recording status: rpi_in = {self.recording}" ) # display message box with error ######################### # Missing code # ######################### set_button_property(self, "blue", "Record") self.recording = False
def test_wait_msg_timeout(mqtt_out, button, logger): """Test timeout functionality of wait_msg().""" out_pub, out_msg_q, out_listen_proc = mqtt_out empty_queues(out_msg_q, button.msg_q) in_received_list = wait_msg("test_2", logger, button.msg_q, timeout=1) sleep(2) assert in_received_list == []
def test_wait_msg_normal(mqtt_out, button, logger): """Essentially, we are testing message sent from out to in.""" out_pub, out_msg_q, out_listen_proc = mqtt_out empty_queues(out_msg_q, button.msg_q) out_pub.publish(json.dumps(["test_1", True])) in_received_list = wait_msg("test_1", logger, button.msg_q) assert in_received_list[0] == "test_1" and in_received_list[1]
def test_wait_msg_wrong_id(mqtt_out, button, logger): """ Test situation where the message id sent from out is not the one currently being expected from in. We should not receive anything and the in_msg_q should still contain the unmatched message """ out_pub, out_msg_q, out_listen_proc = mqtt_out empty_queues(out_msg_q, button.msg_q) sent_list = ["foo", True] out_pub.publish(json.dumps(sent_list)) in_received_list = wait_msg("test_3", logger, button.msg_q, timeout=1) sleep(2) remain_list = json.loads(button.msg_q.get()) assert in_received_list == [] and sent_list == remain_list
def on_clicked(self, widget): """Callback when `Alarm` button is clicked First will communicate with rpi_out to see if sound is being played and will set the self.alarm_sounding flag accordingly If sound alarm is active, do nothing If not active, send signal to sound alarm and set self.alarm_sounding accordingly """ # user wants to set off alarm on rpi_out if not self.alarm_sounding and not self.alarm_sounding_out: # turn button yellow, but with message "Acitvating" set_button_property(self, "yellow", "Activating...") # let rpi_in know intent to sound alarm on rpi_out self.logger.info("Activating alarm on rpi_out...") self.alarm_sounding = True self.logger.info("Sending alarm SOUND message to rpi_out...") self.pub.publish(json.dumps(["alarm", True])) try: # wait for rpi_out to send msg back self.alarm_sounding_out = wait_msg("alarm", self.logger, self.msg_q)[1] except IndexError: # no message received # this is assuming rpi_out did not change state self.alarm_sounding = False # If message from rpi_out was recieved if self.alarm_sounding_out: # buzzer is playing on rpi_out: turn button to red self.logger.info("Alarm SOUNDING on rpi_out") set_button_property(self, "red", "Silence Alarm") else: # A message from rpi_out was not recieved self.logger.error( f"Alarm status: rpi_in = {self.alarm_sounding}, rpi_out = {self.alarm_sounding_out}" ) # display message box with error message = message_box.MessageBox("title", "message") message.run() set_button_property(self, "blue", "Sound Alarm") self.alarm_sounding = False # Alarm is sounding. Silence Alarm. elif self.alarm_sounding and self.alarm_sounding_out: # turn button yellow, but with message "Silencing" set_button_property(self, "yellow", "Silencing...") self.logger.info("Silencing rpi_out alarm...") self.alarm_sounding = False # Send silence signal self.logger.info("Sending alarm SILENCE message to rpi_out...") self.pub.publish(json.dumps(["alarm", False])) try: # wait for rpi_out to send msg back self.alarm_sounding_out = wait_msg("alarm", self.logger, self.msg_q)[1] except IndexError: # no message received # this is assuming rpi_out did not change state self.alarm_sounding = True if not self.alarm_sounding: # rpi_out message recieved, Alarm sound is off, turn button to blue self.logger.info("Alarm is SILENCED on rpi_out") set_button_property(self, "blue", "Sound Alarm") self.alarm_sounding = False else: # A message from rpi_out was not recieved self.logger.error( f"Alarm status: rpi_in = {self.alarm_sounding}, rpi_out = {self.alarm_sounding_out}" ) # display message box with error message = message_box.MessageBox("title", "message") message.run() set_button_property(self, "red", "Silence") self.alarm_sounding = True
def on_clicked(self, widget): """Callback when `Arm` button is clicked. Inbetween changing motion detector state, the button will be yellow with 'Arming' and 'Disarming' messages to notify that the change has not taken place yet. If the alarm is not set, sets text to 'Disarm' and color to red along with sending a message to rpi_out activing armed flag. If the alarm is set, sets text to 'Arm' and color to blue along with sending a message to rpi_out disactiving armed flag. """ # user wants to turn on motion_sensor for rpi_out if not self.armed and not self.armed_out: # turn button yellow, but with message "Arming" set_button_property(self, "yellow", "Arming...") # let rpi_in know to arm motion detector self.logger.info("Arming rpi_out motion sensor...") self.armed = True self.logger.info( "Sending motion detection ON message to rpi_out...") self.pub.publish(json.dumps(["motion", True])) try: # wait for rpi_out to send msg back self.armed_out = wait_msg("motion", self.logger, self.msg_q)[1] except IndexError: # no message received # this is assuming rpi_out did not change state self.armed = False # If message from rpi_out was recieved if self.armed_out: # motion_sensor is 'armed' on rpi_out: turn button to red self.logger.info("Motion sensor ARMED on rpi_out") set_button_property(self, "red", "Disarm") else: # A message from rpi_out was not recieved self.logger.error( f"Motion status: rpi_in = {self.armed}, rpi_out = {self.armed_out}" ) # display message box with error ######################### # Missing code # ######################### set_button_property(self, "blue", "Arm") self.armed = False # motion detection active. Turn off sensor. elif self.armed and self.armed_out: # turn button yellow, but with message "Disarming" set_button_property(self, "yellow", "Disarming...") self.logger.info("Disarming rpi_out motion sensor...") self.armed = False # Send disarm signal self.logger.info("Sending armed OFF message to rpi_out...") self.pub.publish(json.dumps(["motion", False])) try: # wait for rpi_out to send msg back self.armed_out = wait_msg("motion", self.logger, self.msg_q)[1] except IndexError: # no message received # this is assuming rpi_out did not change state self.armed = True if not self.armed_out: # rpi_out message recieved, motion detection is off, turn button to blue self.logger.info("Motion sensor is OFF on rpi_out") set_button_property(self, "blue", "Arm") self.armed = False else: # A message from rpi_out was not recieved self.logger.error( f"Motion status: rpi_in = {self.armed}, rpi_out = ?") # display message box with error ######################### # Missing code # ######################### set_button_property(self, "red", "Disarm") self.armed = True
def on_clicked(self, widget) -> None: """Callback when `Talk` button is clicked. This will be called on whenever the Talk button is clicked First will communicate with rpi_out to see if intercom is active on both parties and will set the self.intercom flag accordingly. If intercom is active, turn off intercom and set color to blue with 'Talk' text for button. If intercom is not active, send signal to activate intercom and set self.intercom_active accordingly Intercom will reset if error message is received when trying to active intercom. :param widget: Pointing to this button. Not used in the function. """ # Always turn button to yellow whenever button is clicked set_button_property(self, "yellow", "Configuring...") # user wants to turn on intercom for both rpi_in and rpi_out if not self.rpi_in_intercom_on and not self.rpi_out_intercom_on: # Turn on Mumble for rpi_in mumble.turn_on(self.intercom_config, "rpi_in", self.logger) self.rpi_in_intercom_on = mumble.is_on(self.logger) # Only signal to rpi_out if rpi_in's Mumble client is on if self.rpi_in_intercom_on: self.logger.info("Sending intercom ON message to rpi_out...") self.pub.publish(json.dumps(["intercom", True])) try: # wait for rpi_out to send msg back self.rpi_out_intercom_on = wait_msg("intercom", self.logger, self.msg_q, timeout=15)[1] except IndexError: # no message received self.rpi_out_intercom_on = False if self.rpi_out_intercom_on and self.rpi_in_intercom_on: # intercom is on for both sides, turn button to red self.logger.info("Intercom ON on both devices") set_button_property(self, "red", "End Talk") else: # at least one of the intercom is not on self.logger.error( (f"Intercom status: rpi_in = {self.rpi_in_intercom_on}," f"rpi_out = {self.rpi_out_intercom_on}")) # display message box with error ######################### # Missing code # ######################### self.rpi_in_intercom_on = not mumble.turn_off(self.logger) self.rpi_out_intercom_on = False set_button_property(self, "blue", "Talk") # intercom active for both devices. Turn off both elif self.rpi_in_intercom_on and self.rpi_out_intercom_on: self.rpi_in_intercom_on = not mumble.turn_off(self.logger) # OFF # Only signal to rpi_out if rpi_in's Mumble client is off if not self.rpi_in_intercom_on: self.logger.info("Sending intercom OFF message to rpi_out...") self.pub.publish(json.dumps(["intercom", False])) try: # wait for rpi_out to send msg back self.rpi_out_intercom_on = wait_msg( "intercom", self.logger, self.msg_q)[1] except IndexError: # no message received self.rpi_out_intercom_on = False if not self.rpi_out_intercom_on and not self.rpi_in_intercom_on: # intercom is off for both sides, turn button to red self.logger.info("Intercom OFF on both devices") set_button_property(self, "blue", "Talk") self.rpi_in_intercom_on = False self.rpi_out_intercom_on = False
def on_clicked(self, widget): """Callback when `Live Stream` button is clicked. This will be called on whenever the Live Stream button is clicked First will communicate with rpi_out to see if a clip is being recorded or the livestream is already on and will set the self.livestream flag accordingly. If livestreaming still, turn off livestream and close window If not livestreaming, send signal to livestream, open window and set self.livestream accordingly. """ if not self.camera_flags["recording_on"]: self.camera_flags["livestream_on"] = True self.logger.info("Sending livestream ON message to rpi_out...") self.pub.publish(json.dumps(["livestream", True])) try: # wait for rpi_out to send true msg back self.livestream = wait_msg("livestream", self.logger, self.msg_q)[1] # True sent back if self.livestream: # Since rpi_out sent back true it should be livestreaming self.logger.info("rpi_out is livestreaming now...") # turn button to red if not already red set_button_property(self, "red", "Livestreaming...") try: # waiting for rpi_out to send youtube playlist link self.yt_livestream_link = wait_msg( "yt_livestream_link", self.logger, self.msg_q, timeout=30, )[1] # Does not catch if junk str was sent back if type(self.yt_livestream_link) == str: # display window with livestream # yt_window = embedded_yt.EmbeddedYT( # self.yt_livestream_link, "Livestream" # ) # yt_window.run() webbrowser.open(self.yt_livestream_link) except IndexError: # no message received self.logger.error( f"The camera is running, Mqtt broke or the YouTube Api broke. Live Stream status: rpi_in = {self.livestream}" ) # Change flags self.camera_flags["livestream_on"] = False self.livestream = False # Turn livestream off self.pub.publish(json.dumps(["livestream", True])) # Reset button to blue set_button_property(self, "blue", "Livestream") # Log event self.logger.info("Livestream is off...") # display message to try again later message = message_box.MessageBox( "Sorry, something broke...", "Please try again later.", ) message.run() elif self.livestream is None: self.logger.error( f"The camera is running, Mqtt broke or the YouTube Api broke. Live Stream status: rpi_in = {self.livestream}" ) # Change flag self.camera_flags["livestream_on"] = False self.livestream = False # display message to wait for recording to be done message = message_box.MessageBox( "Sorry, but...", "A video is being recorded, please try again later.", ) message.run() else: # Change flags self.camera_flags["livestream_on"] = False # Log event self.logger.info("Turned off rpi_out livestream...") # Reset button to blue set_button_property(self, "blue", "Livestream") # close livestream window ######################### # Missing code # ######################### except IndexError: # no message received # Log event self.logger.error( f"The camera is running, Mqtt broke or the YouTube Api broke. Live Stream status: rpi_in = {self.livestream}" ) # Change flags self.livestream = False self.camera_flags["livestream_on"] = False # Reset button to blue set_button_property(self, "blue", "Livestream") # Log event self.logger.info("Livestream is off...") # display message saying to try again later message = message_box.MessageBox("Sorry, something broke...", "Please try again later.") message.run()