import datetime import time import sys import echo_serial.serial_controller as EchoSerial import echo_db.database as EchoDB import _thread class Blinds: @staticmethod def handle_action(device, action, data): actionData = device['actions'][action] # Check if we send action too fast after last issued action actionNow = datetime.datetime.now() actionLast = device['last_used'] lastIssued = (actionNow - actionLast).total_seconds() if lastIssued < 2.0: return {'status': 'failed', 'message': 'Issued action too fast after last issued action!'}, 200 # Check if a thread is using the blinds, if so return. if device['status'] == "busy": return {'status': 'failed', 'message': 'Blinds are being controlled by Echo, Please wait till finished.'}, 200 # Check if we issued stop command and check if we are moving # Stop blinds if we are moving if action == "stop": if device['status'] == "go_down" or device['status'] == "go_up": return Blinds.stopActiveBlinds(device, action, data) else: return {'status': 'failed', 'message': 'Blinds are not moving!'}, 200 # Check if we are already going up or down # If we are, stop that action if device['status'] == "go_down" or device['status'] == "go_up": return Blinds.stopActiveBlinds(device, action, data) # If we are requesting specific preset if action == "preset": selected_preset = data if selected_preset == {}: return {'status': 'failed', 'message': 'Please select a preset!'}, 200 if selected_preset not in device['presets']: return {'status': 'failed', 'message': 'Preset does not exist!'}, 200 # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'busy' }}) # Start thread because this action has waiting functions _thread.start_new_thread(Blinds.handleBlindsPreset, ("Main Serial Thread", 2, device, selected_preset)) return {'status': 'success', 'message': actionData['message']}, 200 # If we are requesting action if action == "up" or action == "down": # Send Serial Command EchoSerial.EchoSerial.send_commmand(device, action) # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'go_' + action }}) return {'status': 'success', 'message': actionData['message']}, 200 # If we are requesting to set automatic time if action == "set_automatic_time": selected_auto_time = data if selected_auto_time == {}: return {'status': 'failed', 'message': 'Please select a time!'}, 200 if selected_auto_time == "--:--": # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'automatic_open': False, 'automatic_open_time': '--:--' }}) else: # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'automatic_open': True, 'automatic_open_time': selected_auto_time }}) return {'status': 'success', 'message': actionData['message']}, 200 @staticmethod def stopActiveBlinds(device, action, data): if device['status'] == "go_down": EchoSerial.EchoSerial.send_commmand(device, "down") # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'custom' }}) return {'status': 'success', 'message': 'Stopped blinds.'}, 200 if device['status'] == "go_up": EchoSerial.EchoSerial.send_commmand(device, "up") # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'custom' }}) return {'status': 'success', 'message': 'Stopped blinds.'}, 200 @staticmethod def handleBlindsPreset(threadname, delay, device, preset): print('Started Blinds Preset Thread!') presetData = device['presets'][preset] # Check if we are already in preset position if device['status'] == "preset": if device['current_preset'] == preset: # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'custom' }}) print('Exiting Blinds Preset Thread!') sys.exit() # If custom goto open position if device['status'] == "custom": Blinds.setBlindsOpen(device) # If device is already in preset position, check if we need to go to open position first # Or if we can skip that if device['status'] == "preset": if device['current_preset'] != "open": Blinds.setBlindsOpen(device) if preset == "closed_ventilated": # Go down for 11 seconds EchoSerial.EchoSerial.send_commmand(device, 'down') time.sleep(17) EchoSerial.EchoSerial.send_commmand(device, 'down') if preset == "open_ventilated": # Go down for 11 seconds EchoSerial.EchoSerial.send_commmand(device, 'down') time.sleep(11) EchoSerial.EchoSerial.send_commmand(device, 'down') if preset == "open": # We already went to open position, no need to do it again pass if preset == "closed": EchoSerial.EchoSerial.send_commmand(device, 'down') time.sleep(19) EchoSerial.EchoSerial.send_commmand(device, 'down') # Update Database collection = EchoDB.EchoDB.database['Devices'] collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'preset', 'current_preset': preset }}) print('Exiting Blinds Preset Thread!') @staticmethod def setBlindsOpen(device): EchoSerial.EchoSerial.send_commmand(device, 'up') time.sleep(25) EchoSerial.EchoSerial.send_commmand(device, 'up') time.sleep(2)