def handle_action(self, interface_id, action_name, device_id=None): """ params: @device_id: string @action_name: string, formatted as name_param1_param2 args is a list of strings return: device if the handling was successful else None """ interface = None device = None logger.debug("Handling action with device id: {}".format(device_id)) if device_id is not None: interface, device = self.get_device(device_id, interface_id) else: interface = self.get_interface(interface_id) if interface is None: logger.info("No interface with id {} found".format(interface_id)) return # get a target for the command target = interface.get_random_target() # create a command command = DeviceCommand.command_from_api(target, action_name) logger.info("forwarding command: {} for interface id {} and device id {}".format(command, interface_id, device_id)) # delegate the command to the interface interface.command_subjects(command, device_id)
def stop_detection(self): logger.info("Stopping voice detection") self.interrupted = True self.vthread.join() self.running = False self.is_on = False logger.info("Voice detection halted")
def connect_to_hue_bridge(self, config): """ function to establish a connection to the hue bridge """ logger.info("Connecting to hue bridge") bridge = None max_connect_tries = 3 for i in range(max_connect_tries): try: #get the dridge bridge = Bridge( config['DEFAULT']['HUE_BRIDGE_IP'], config_file_path=config['DEFAULT']['HUE_CONFIG_FILE']) # actually do an api request to check whether the connection was succesfull bridge.get_light_objects() logging.info("[ INFO ] connected to hue bridge") self.connected = True self.is_on = True break except PhueRegistrationException: print( "push the button on the hue bridge, waiting 15 sec for {}:th attempt out of {}" .format(i + 1, max_connect_tries)) time.sleep(15) except PhueRequestTimeout: #actually cannot timeout because initialising bridge does not check whether hue bridge is available print("[ ERROR ] Cannot connect to HUE bridge") bridge = None break return bridge
def intialize_device_interface(device_handler, file_path): """ Initializes a correct type of interface @params: :device_handler: store reference :file_path: path to the config file of the interface """ logger.info("loading devices from {}".format(file_path)) config = configparser.ConfigParser() try: config.read(file_path) except Exception as e: logger.warn("loading devices from failed.") return None logger.info("loaded device interface config for {}".format( config['DEFAULT']['DEVICE_CLASS'])) #import the device classes with importlib DeviceInterfaceClass = getattr( importlib.import_module("homeserver.interface"), config['DEFAULT']['DEVICE_CLASS']) return DeviceInterfaceClass(device_handler, config) """This phase is done for all different configs. After this
def initialize_detector(self): logger.info("model path: {}".format(self.model)) self.detector = HotwordDetector(self.model, sensitivity=self.sensitivity) #set the path of the audio file saved self.detector.set_recording_filepath(self.recording_path) #the voicethread self.vthread = VoiceThread(target=self._start_detection, parent=self)
def record_audio(record_len, filename): """ records an audio clip from the default input device @params: length: the length of recorded audio [seconds] filename: the ouput filename """ try: CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 16000 RECORD_SECONDS = record_len WAVE_OUTPUT_FILENAME = filename p = None with no_alsa_error(): p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) logger.info("Recording {}.".format(WAVE_OUTPUT_FILENAME)) frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) logger.info("Done recording.") stream.stop_stream() stream.close() p.terminate() with wave.open(WAVE_OUTPUT_FILENAME, 'wb') as wf: wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) return WAVE_OUTPUT_FILENAME except: pass return None
def command_from_api(cls, target, command_name): """ This method creates a command for the devices from based on the given arguments. Mainly be used from the web api """ logger.info( "creating command from api with target {} and command {}".format( target, command_name)) return cls(target=target, arguments=[command_name])
def start_detector(self): """ Method to be called outside the VoiceController class to start the detection. """ self.initialize_detector() self.vthread.start() self.is_on = True self.connected = True self.running = True logger.info('Keyword detector started')
def command_subjects(self, vcommand, dev_id=None): """ A middle man to before sending command to a light. If the dev_id is not given, send command to all lights. """ super().command_subjects(vcommand) #error handling #if we are not connected we cannot command device if not self.connected: logger.info("Cannot command lights, not connected.") return False #parse command action = vcommand.arguments[0] func = None for command in self.commands: if action == command.action: func = command.action_func break if func is None: logger.debug("no command action function") return False #lights = self.bridge.get_light_objects() logger.info("got lights with ids: ".format([ (light.bridge_light_id, light.dev_id) for light in self._devices ])) lights_reachable = 0 print("devices: ", self._devices) for device in self._devices: light = device.phue_light if light.reachable: # if light id is given only control the light with matching id if dev_id is not None and not (dev_id == device.dev_id): print("continuing") continue lights_reachable += 1 print("calling func with light id {}") func(light, vargs=vcommand.arguments[1:]) else: print("light not reachable") return lights_reachable > 0
def device_action(interface_id, action, device_id=None): """ Main interface point """ interface_id = int(interface_id) if device_id is not None: device_id = int(device_id) # to string if action is not None: action = str(action) # to string logger.info("interface id: {}".format(interface_id)) logger.info("device id: {}".format(device_id)) logger.info("action: {}".format(action)) device_handler.handle_action(interface_id=interface_id, action_name=action, device_id=device_id ) status_dict =device_handler.get_status_json() return jsonify(status_dict)
def train_new_model(wav_files=[], gender=QueryParamaters.Gender.MALE, \ age_group=QueryParamaters.AgeGroups.ages[2], \ language=QueryParamaters.Languages.lang_codes[-1]): logger.info("Training new model") # get the Snowboy api token api_key = get_api_token() if not api_key: return model_name = input(""" What should the model be named? ... """) if len(wav_files) != 3: print("Training requires 3 voice samples, press Enter to start recording the first one.") wav_files = [] # record 3 samples for index in range(1,4): input("Start the recording of sample {}...".format(index)) audio_file = os.path.join(VOICE_CONTROL_DIR, 'resources', 'voiceque{}.wav'.format(index)) wav_files.append(audio_file) record_audio(VOICE_SAMPLE_LENGTH, audio_file) logger.info("Successfully recorded 3 samples") # parse the model name parsed_name = "my_model" try: parsed_name = str(model_name).strip() if parsed_name.endswith('.umdl'): parsed_name = parsed_name[0:-5] except: pass data = { "name": parsed_name, "language": language, "age_group": age_group, "gender": gender, "token": api_key, "microphone": "default", "voice_samples": [ {"wave": get_wave(wav_files[0])}, {"wave": get_wave(wav_files[1])}, {"wave": get_wave(wav_files[2])} ] } # where to put the ready model model_name = parsed_name + '.pmdl' model_dir = get_model_folder() model_file = os.path.join(model_dir, model_name) response = requests.post(SNOWBOY_API_ENDPOINT, json=data) if response.ok: with open(model_file, "wb") as outfile: outfile.write(response.content) logger.info("Created model saved to {}.".format(model_file)) else: logger.info("Creating hotword failed.") logger.info(response.text)