Ver la Versión Completa : [ IDEA ] Tarea para llamar por voz PLUS con Autovoice o como widget sin Autovoice
cace0353
04/04/15, 13:52:43
Bueno, os presento parte de mi último proyecto, una tarea para llamar por voz (ya hay algunas publicadas en el foro) pero que tiene un "plus": permite escoger entre varios contactos que tienen coincidencia de patrón con el nombre que se diga.
REQUERIMIENTOS
- Necesitamos tener instalado el plugin Autocontacts
- Tener conexión de Red en 3G, WiFi o haber bajado los archivos de reconocimiento de voz offline desde Google http://www.htcmania.com/showthread.php?t=611741&highlight=offline
ANTECEDENTES Y PREPARACIÓN DE LA LISTA DE CONTACTOS
a) En principio tenia una lista de contactos con más de 500 entradas que he revisado para pulirla (eliminando contactos que ni recuerdo, añadiendo el oficio/profesión después del nombre, estableciendo el nº de teléfono predeterminado, etc.) quedando finalmente en 430 (2 horas de trabajo en los contactos de mi cuenta en el ordenador)
Pues bién, la búsqueda con Autocontacts usando la variable %acname te devuelve el primer contacto encontrado pero prescinde de los otros. Así se plantea en la mayoria de tareas publicadas en el foro para llamar por voz. Esto es generalmente suficiente con una base de 20 o 30 contactos, pero en mi caso, y supongo que en el de otros muchos, no sirve. A veces el que necesito es otro José Sánchez u otro Juan Garcia, o simplemente recuerdo el nombre y tengo 10 contactos con el mismo...
b) He planteado la tarea tanto para poder ejecutarla desde un widget (el reconocimiento de voz dentro de la tarea se hace con el Captar voz y no precisamos tener Autovoice), como para activarla mediante un perfil con un comando de voz si tenemos AV instalado. Además todas la variables de uso en la propia tarea son locales.
c) He añadido a mis contactos la profesión o cualquier texto identificativo del contacto (abogado, ingeniero, electricista, tendero de la esquina,...). Esto nos permite hacer la búsqueda por cualquier palabra que figure en el nombre del contacto, y la tarea me devolverá la lista de abogados, electricistas, etc.. En fin, una especie de Páginas Amarillas de mis contactos.
d) He eliminado los Nicknames que no eran nombres del diccionario (p.e. Mei, Mian, Jep,...) ya que AC no los encuentra.
LA TAREA: DESCRIPCIÓN FUNCIONAL
- Desactiva el reconocimiento de voz por AVcontinuous por si venimos desde un perfil.
- Empieza preguntando el nombre del contacto y guardándolo en la variable local %nom
- Busca el nombre con AC y, entonces, Pueden darse 3 situaciones:
1) Si no lo encuentra me pide que repita y vuelve a esperar respuesta
2) Si encuentra 1 contacto solamente, nos lee el contacto completo indicando el tipo de teléfono (casa, móvil o trabajo) y nos pide confirmación para llamar.
3) Si encuentra más de uno nos dice el número de contactos encontrados y nos los lee asignando un número a cada uno. Cuando termina, nos da la opción de repetir la lista o decir el número del contacto al que queremos llamar, nos lo lee y actúa como en el caso anterior.
- Activa el altavoz y llama al contacto con marcado automático
- Finalmente vuelve a poner AV continuous en su estado inicial si estaba activado al iniciar la tarea (caso de venir de un perfil)
La tarea está depurada funcionalmente (no se queda colgada) aunque no me he entretenido en repasar si se puede "pulir" el código, si hay acciones prescindibles. En cambio se pueden simplificar las acciones Decir, por ejemplo eliminando la confirmación final (acciones A41..A46 ambas inclusive).
Salvo los nombres de las variables, la he traducido al castellano.
LA TAREA: EL TEXTO CON COMENTARIOS
Llamar_contacto_plus (191)
Esta primera parte es para desactivar AV si ejecutamos la tarea desde un perfil de reconocimiento de voz con AV. La acción A4 introduce una espera de 1 seg. porque si no, se me cortaba el principio de A5: Decir
A1: Si (if) [ %AVactivat ~ 1 ]
A2: AutoVoice Continuous [ Configuración: Stopping continuous voice recognition Paquete:com.joaomgcd.autovoice Nombre:AutoVoice Continuous Cuenta atrás (segundos):0 ]
A3: Fin si (End if)
A4: Esperar [ MS:0 Segundos:1 Minutos:0 Horas:0 Días:0 ]
Nos pide el nombre del contacto, profesión, apellido,... que queremos buscar y lo ponemos en la variable %nom
A5: Decir [ Texto:Di el nombre del contacto Motor: Voz:default:default Stream:3 Tono:5 Velocidad:5 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
A6: Esperar [ MS:0 Segundos:1 Minutos:0 Horas:0 Días:0 ]
A7: Anchor
A8: Captar Voz [ Título:NOMBRE DEL CONTACTO? Modelo Lenguaje:Forma libre Resultados Máximos:1 Cuenta atrás (segundos):30 ]
cace0353
04/04/15, 14:18:33
(Continuo con la tarea ya que me habia quedado cortada en A8)
A9: Establecer variable [ Nombre:%nom A:%VOICE Calcular:Apagado Añadir:Apagado ]
Le pedimos a AC que busque %nom en nuestros contactos (puede ser el nombre solo, el apellido, la profesión, el nombre y la profesión, etc)
A10: AutoContacts [ Configuración:Contact Name or Nickname: %nom Name as Nickname: true Paquete:com.joaomgcd.autocontacts Nombre:AutoContacts Cuenta atrás (segundos):1000 ]
Ahí viene el Plus: en lugar de usar %acname usamos %acnames() que es la matriz que contiene TODAS las coincidencias y guardamos en la variable %num_coincidencies el nº de contactos encontrados = %acnames(#)...
A11: Establecer variable [ Nombre:%num_coincidencies A:%acnames(#) Calcular:Encendido Añadir:Apagado ]
Si no hay coincidencias, nos lo comunica y nos devuelve a la etiqueta "coger contacto"
A12: Si (if) [ %num_coincidencies ~ 0 | %num_coincidencies ~ %* ]
A13: Decir [ Texto:Contacto no encontrado. Repite por favor Motor: Voz:default:default Stream:3 Tono:5 Velocidad:4 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
A14: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:coger contacto ]
A15: Fin si (End if)
Si sólo hay una coincidencia nos manda directamente a la etiqueta "resultado" para confirmar si queremos llamar
A16: Si (if) [ %num_coincidencies ~ 1 ]
A17: Establecer variable [ Nombre:%opcio A:1 Calcular:Encendido Añadir:Apagado ]
A18: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:resultado ]
A19: Fin si (End if)
Peeero, si hay varios elementos en la matriz %acnames (si AC ha encontrado más de un contacto), establece un bucle para extraerlos todos hasta que se acaben...
A20: Establecer variable [ Nombre:%contador A:1 Calcular:Encendido Añadir:Apagado ]
<bucle>
A21: Anchor
A22: Si (if) [ %contador < %num_coincidencies | %contador ~ %num_coincidencies ]
Coge cada contacto (elemento de la matriz) y empieza a escribir la variable %contactes con el nombre del contacto junto con el nº de orden dentro de la lista. A cada vuelta del bucle la variable es la misma (ya que tenemos Añadir:Encendido) pero va creciendo de manera que, si ha encontrado 3 JOSE, la variable %contactes al final quedará: "José Alcázar fontanero:1:José Madera vecino de la suegra:2:Luis Sanjosé:3:" Los ":" són para hacer pausas cuando me los lea...
A23: Establecer variable [ Nombre:%contactes A:%acnames(%contador): %contador: Calcular:Apagado Añadir:Encendido ]
A24: Sumar a variable [ Nombre:%contador Valor:1 Módulo (wrap around):0 ]
A25: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:bucle ]
A26: Fin si (End if)
<repetir>
A27: Anchor
Cuando ya ha acabado de componer la variable %contactes me la lee, acabando cada nombre completo del contacto con un nº que es EL ÍNDICE DEL CONTACTO dentro de la matriz %acnames()
A28: Decir [ Texto:%num_coincidencies contactos encontrados: %contactes . Opciones: número del contacto o repetir Motor: Voz:default:default Stream:3 Tono:5 Velocidad:4 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
<repetir opcion>
A29: Anchor
Espera que le diga que nº del contacto elegido entre los que me ha dicho o si necesito volver a oir la lista...
A30: Captar Voz [ Título:ELIGE EL Nº DEL CONTACTO O DI REPETIR Modelo Lenguaje:Forma libre Resultados Máximos:1 Cuenta atrás (segundos):30 ]
A31: Establecer variable [ Nombre:%opcio A:%VOICE Calcular:Apagado Añadir:Apagado ]
A32: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:repetir ] Si (if) [ %opcio ~ repetir ]
<resultado>
A33: Anchor
Asigna nombre y nº de teléfono al contacto, y me pedirá si quiero llamar. Si no me ha entendido o le he dicho un número superior me pide que repita la respuesta y me manda a la etiqueta "repetir opcion"
A34: Establecer variable [ Nombre:%contacte A:%acnames(%opcio) Calcular:Apagado Añadir:Apagado ]
A35: Establecer variable [ Nombre:%telefon A:%acnumbers(%opcio) Calcular:Apagado Añadir:Apagado ]
A36: Si (if) [ %contacte ~ %* ]
A37: Decir [ Texto:Disculpa, no te he entendido. Puedes repetir por favor? Motor: Voz:default:default Stream:3 Tono:5 Velocidad:4 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
A38: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:repetir opcion ]
A39: Fin si (End if)
<final>
Me dice el nombre del contacto, si es el móvil, casa, trabajo, etc y me pregunta si quiero llamar o salir...
A40: Anchor
A41: Flash [ Texto:%contacte . %telefon %acnumbertype Largo:Apagado ]
A42: Decir [ Texto:%contacte: telèfon %acnumbertype. Quieres llamar? . Opciones : llamar salir Motor: Voz:default:default Stream:3 Tono:5 Velocidad:4 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
A43: Captar Voz [ Título: ELIGE UNA OPCIÓN Modelo Lenguaje:Forma libre Resultados Máximos:1 Cuenta atrás (segundos):15 ]
A44: Si (if) [ %VOICE ~R llamar|llama ]
A45: Llamar [ Número:%telefon Automarcado:Encendido ]
A46: Esperar [ MS:0 Segundos:3 Minutos:0 Horas:0 Días:0 ]
A47: Altavoz [ Establecer:Encendido ] Si (if) [ %Altaveu_Activat ~ 0 ]
A48: Fin si (End if)
Para volver a activar AV si al empezar la tarea estaba activado porque veniamos de un perfil...
A49: AutoVoice Continuous [ Configuración: Starting continuous voice recognition without headset Paquete:com.joaomgcd.autovoice Nombre:AutoVoice Continuous Cuenta atrás (segundos):0 ] Si (if) [ %AVactivat ~ 1 ]
COMPLEMENTOS Y MEJORAS
1.- Puede incluirse un grupo de acciones al principio para, como en los teléfonos de botones haciendo pulsación larga, guardar unos nnúmeros de marcado directo. Los números de teléfono se añaden separados por , (coma) a la variable %cont_direct y podemos acceder a ellos diciendo su número de posición dentro de la variable. En este caso al decir en número (1, 2, 3, ...) se llama directamente al contacto asociado segun la lista de números. Así nos ahorramos toda la conversación con el smartphone.
Las acciones que se proponen se colocan al principio (substituyendo las acciones A1..A9) y deberá añadirse la etiqueta "directe" al final, justo antes de la acción "Llamar":
A1: Si (if) [ %AVactivat ~ 1 ]
A2: AutoVoice Continuous [ Configuración: Stopping continuous voice recognition Paquete:com.joaomgcd.autovoice Nombre:AutoVoice Continuous Cuenta atrás (segundos):0 ]
A3: Fin si (End if)
A4: Establecer variable [ Nombre:%num_direct A:93xxxxxxx,636xxxxxx,679xxxxxx, 641xxxxxx,618xxxxxx,93xxxxxxx Calcular:Apagado Añadir:Apagado ]
A5: Separar variable [ Nombre:%num_direct Separador:, Eliminar base:Apagado ]
A6: Establecer variable [ Nombre:%num_preferits A:%num_direct(#) Calcular:Apagado Añadir:Apagado ]
A7: Decir [ Texto:DI EL NOMBRE DEL CONTACTO Motor: Voz:default:default Stream:3 Tono:5 Velocidad:5 Respetar Foco Audio:Encendido Red:Apagado Continuar tarea inmediatamente:Apagado ]
A8: Esperar [ MS:0 Segundos:1 Minutos:0 Horas:0 Días:0 ]
<agafar contacte>
A9: Anchor
A10: Captar Voz [ Título:Nombre del contacto? 1-CASA 2-MUJER 3-HIJO1 4-HIJO2 5-HIJO3 6-TRABAJO Modelo Lenguaje:Forma libre Resultados Máximos:1 Cuenta atrás (segundos):30 ]
A11: Establecer variable [ Nombre:%nom A:%VOICE Calcular:Apagado Añadir:Apagado ]
A12: Establecer variable [ Nombre:%contador A:1 Calcular:Apagado Añadir:Apagado ]
<Bucle preferits>
A13: Anchor
A14: Si (if) [ %nom ~ %contador ]
A15: Establecer variable [ Nombre:%telefon A:%num_direct(%contador) Calcular:Apagado Añadir:Apagado ]
A16: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:directe ]
A17: Else
A18: Establecer variable [ Nombre:%contador A:%contador+1 Calcular:Encendido Añadir:Apagado ]
A19: Ir a acción [ Tipo:Etiqueta Acción Número: Etiqueta:Bucle preferits ] Si (if) [ %contador < %num_preferits | %contador ~ %num_preferits ]
A20: Fin si (End if)
Aquí ya vendria A21: Autocontacts ...
2.- Finalmente, podria hacerse que, una vez encontrado el contacto y si tiene varios números de teléfono, la tarea nos ofreciera la posibilidad de elegir a cual llamar. Yo no lo necesito porque tengo como primer teléfono puesto el del móvil. Además añadiria "conversación" con el aparato y al final (podria ocurrir) cuando marcara el número y tuviera el contacto al habla, haber olvidado el motivo de la llamada!
3.- Como opción, podeis cambiar el tono de la voz de mujer en las acciones "Decir", si lo bajamos la voz se convierte en masculina (o casi). También se puede bajar (y así lo he hecho) la velocidad de reproducción a 4 para entender mejor los recados...
Disfrutad de estos dias de vacaciones, que yo ya lo estoy haciendo... je, je
Y, como siempre, atento a vuestros comentarios.
Juanmiwow
05/04/15, 11:34:43
Muy buen aporte compañero!
Has hecho un buen curro, desde luego!
Muchas gracias!
Cosas que encuentro mejorables:
1 Los bucles creo que lo suyo seria usar un For. Con la expresión "%Array()" te va a ir metiendo todos los valores de ese array empezando por el uno.
2 El establecer un contador a uno con calcular encendido se puede sustituir por sumar a variable 1. Cuandocuna variable no esta iniciada tasker entiende a efectos de calculo q vale 0.
3 Usando AVoice no tendrías que estar encendiendo y apagando el reconocimiento. Bastaría añadir un contexto al de reconocimiento de valor de variable %Interruptor = 1. Poniéndolo a 0 no se dispara el reconocimiento cuando tasker "dice" algo pero no apagas la escucha.
4 Lo de eliminar los alias, sabras tu mas que yo, pero en general son mas fáciles de recordar y al ser únicos evitan q nos confundamos de José por ejemplo. No entiendo muy bien pq dices q AC no los reconoce. Claro esta q tienen q ser alias q estén en el diccionario eso si.
Por lo demás, salvo esto que no son mas que cuestiones de "estilo", lo veo todo muy correcto.
La única gran pega que le veo es que veo el sistema muy lento. Pero claro yo no tengo ni de lejos 400 contactos y tampoco estoy seguro de que se pudiese hacer mas rápido sin renunciar a los pluses.
Muy ingenioso lo de numerar las opciones para luego solo tener que referirse a ellas con el numero!
Por ultimo la cuestión de disparar la tarea con un widget no la veo. Supongo que esto lo haces cuando vas en el coche entonces tienes que encender/desbloquear la pantalla no? Si llevas la pantalla encendida entonces gasto de batería. Siempre que tengas un coche que te lo permita yo lo haría vía Autovoice q te detecta la pulsación del botón bluetooth y con el modo continuo que te permite la escucha con pantalla apagada y/o bloqueada.
De lo malo malo con el sensor de proximidad haz que se active la escucha no?
EDITO: una sugerencia, lo de confirmar la llamada podrías hacerlo opcional de manera que si tasker detecta que la frase acaba en "confirmar" efectivamente pida la confirmación y si no, no.
cace0353
08/04/15, 17:42:30
Gracias por tus comentarios mlesir
Paso a valorarlos
1 Los bucles creo que lo suyo seria usar un For. Con la expresión "%Array()" te va a ir metiendo todos los valores de ese array empezando por el uno.En realidad, si te refieres a la acción A22, aunque me lo planteé, no lo necesito. Como he de acabar leyendo con "Decir" el contenido de la variable %contactes, me parece que es más práctico leerla entera ya que la he construido añadiendo "en continuo" (Añadir: Encendido) cada valor encontrado y el número %contador correspondiente a la misma variable. Luego sólo voy a usar el número que diga como índice para extraer los datos del contacto de la matriz %acnames().
En general, no obstante, me he acostumbrado a usar los bucles con IF en lugar de los FOR (que es lo que tocaria como tú dices) desde que una vez leí por ahí que consumian más recursos.
2 El establecer un contador a uno con calcular encendido se puede sustituir por sumar a variable 1. Cuando una variable no está iniciada tasker entiende a efectos de calculo que vale 0.Muy buena, no sabia esto. Me la apunto...
3 Usando AVoice no tendrías que estar encendiendo y apagando el reconocimiento. Bastaría añadir un contexto al de reconocimiento de valor de variable %Interruptor = 1. Poniéndolo a 0 no se dispara el reconocimiento cuando tasker "dice" algo pero no apagas la escucha.La idea era hacer la tarea como un widget (sin AV), de manera que si no tienes Autovoice funcione igual.
4 Lo de eliminar los alias, sabras tu mas que yo, pero en general son mas fáciles de recordar y al ser únicos evitan q nos confundamos de José por ejemplo. No entiendo muy bien pq dices q AC no los reconoce. Claro esta q tienen q ser alias q estén en el diccionario eso si.Por esto lo dije, por lo del diccionario. Al principio no me funcionaban algunos hasta que caí en la cuenta de que no eran entradas de diccionario... Así que al final añadí lo de los números "perferidos" que funciona muy bién (són los mismos que tengo en el inalámbrico de mi casa excepto el "1" que allí és el buzón de voz y en el móvil no lo uso).
Por lo demás, salvo esto que no son mas que cuestiones de "estilo", lo veo todo muy correcto.
La única gran pega que le veo es que veo el sistema muy lento. Pero claro yo no tengo ni de lejos 400 contactos y tampoco estoy seguro de que se pudiese hacer mas rápido sin renunciar a los pluses.
Muy ingenioso lo de numerar las opciones para luego solo tener que referirse a ellas con el numero!
Por ultimo la cuestión de disparar la tarea con un widget no la veo. Supongo que esto lo haces cuando vas en el coche entonces tienes que encender/desbloquear la pantalla no? Si llevas la pantalla encendida entonces gasto de batería. Siempre que tengas un coche que te lo permita yo lo haría vía Autovoice q te detecta la pulsación del botón bluetooth y con el modo continuo que te permite la escucha con pantalla apagada y/o bloqueada.
De lo malo malo con el sensor de proximidad haz que se active la escucha no?A mí me funciona rápido, a pesar de manejar una base de contactos amplia. En el coche uso casi siempre una aplicación de navegación. En estos casos el perfil cuando se carga la aplicación me activa GPS, Radardroid, volúmenes al máximo,... también activa AV en modo continuous ya que en el coche normalmente conecto el móvil al cargador.
Ya te he leido en otros post lo del botón del Bluetooth (desde que Pent lo arregló para que funcionara) y creo que me voy a comprar unos auriculares sencillitos para esto. Cuáles me recomiendas? Cómo no uso el Bluetooth (ni mi coche ni mi radio tienen) tengo todos los servicios donde pone algo de BT desactivados con Titanium para ahorrar bateria. Debería activarlos?
EDITO: una sugerencia, lo de confirmar la llamada podrías hacerlo opcional de manera que si tasker detecta que la frase acaba en "confirmar" efectivamente pida la confirmación y si no, no. Tienes razón. No me lo planteé porque inicialmente era una tarea sin AV lanzada desde un widget. Desde luego acortaria la "conversación"... Ya la he modificado en el sentido de que cuando te ha dicho el nombre del contacto llama sin más!
Lo del bucle te lo decía por eso, es mas una cuestión de estilo. Lo de los recursos pudiera ser la verdad es que ni idea.
Otro acierto que has tenido es lo de usar variables locales. Esto que a mi me enseño GraphicAdventure es la leche. Con variables locales las tareas pesadas con arrays tienen una velocidad que si que se nota.
Respecto a lo que dices del bluetooth. Te refieres a un manos libres o a un auricular?
Y si, creo que tendrás que activar los servicios de bluetooth.
De todos modos ya te digo que me parece que es tan bueno tu proyecto que .... te lo voy a copiar sin piedad!!! jeje Creo que lo implementare en mi proyecto de asistente de voz total para tasker.
La única duda que me surge es que creo que Google Now ya permite esto no? La verdad es que no lo he probado pero es probable que claro no sea tan funcional ni tenga los pluses q tiene el tuyo.
cace0353
08/04/15, 21:50:59
mlesir, puedes disponer de lo que quieras. Es mas, me enorgullece que un experto taskero como tú diga que va a copiar algo que he publicado. Yo también he bebido en otras fuentes del foro y gracias a ello y a la afición, vamos aprendiendo.
Al grano:
Efectivamente, las variables globales se escriben, a cada cambio de valor, en la memoria física (la SD interna) y su consulta se hace leyendo también la SD. En cambio las locales se manejan en la ram solamente y, por tanto, mas velozmente.
Lo del manos libres era referido a unos auriculares baratillos, para usar la funcionalidad de activar perfiles solamente con el botón. Te he leido en otro post que los usas.
No uso Google Now y lamento no poder aclararte nada relativo a tu duda final…
Si solo lo quieres para tener la posibilidad de apretar el botón y que tasker lo detecte unos de estos pienso podrian funcionarar pero no lo se seguro. En todo caso serán dos euros:
http://www.aliexpress.com/snapshot/6552241099.html?orderId=66306827073181
Por nueve pavos yo tengo un auricular bluetooth. Tiene su boton de llamada, puedes oir y hablar por el micro.
Supongo que en el cualquier tienda ( los mios son de mediamarkt) tienen algo barato y que te valga. En principio para oír y escuchar lo que le mande tasker si tiene el protocolo a2dp valdría. Pero como yo a tanto no llego, creo q lo mejor es que te vayas a la tienda con el móvil y los perfiles de prueba listos, y les digas si puedes probarlo.
Si el tamaño no te importa mucho yo creo q es mejor pillar el auricular: no es mucho mas grande y en un futuro puedes encontrarle mas utilidades.
Si lo pruebas ojo con que le estés hablando al auricular, pienses que va y en realidad es el movil el que capta la voz.
Por otro lado no se si te lo he comentado ya pero si eres de los que llevas el móvil en el coche a la vista también te puede servir el contexto de sensor de proximidad que no gasta casi nada. Si lo tapas activas la escucha y listo.
vBulletin® v3.8.1, Copyright ©2000-2025, Jelsoft Enterprises Ltd.