예제 #1
0
	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)
예제 #2
0
 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")
예제 #3
0
    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
예제 #4
0
    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 
예제 #5
0
    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)
예제 #6
0
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
예제 #7
0
    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])
예제 #8
0
    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')
예제 #9
0
    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
예제 #10
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)
예제 #11
0
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)