PDA

Ver la Versión Completa : [ CONSULTA ] Juntar varias condiciones del mismo contexto en una sola


darkopro
23/01/14, 08:02:59
Quiero saber si se pueden juntar varias condiciones del mismo contexto en una sola, concretamente tengo una condición que se activa si varios perfiles están activos y quería saber si la podría juntar en una sola
Vendría a ser algo así
Si (if) %PACTIVE ~ perfil1|
perfil2|perfil3

Muchas gracias de antemano ;)

darkopro
23/01/14, 08:05:35
Perdón no me deja editar el post, la condición se activa si varios perfiles están activos «al mismo tiempo» para que no haya confusión, no que si cualquiera de esos perfiles está activo ;)

maid450
23/01/14, 11:12:04
Pues me ha picado la curiosidad, porque se han planteado bastantes veces preguntas de este tipo, y las respuestas habituales siempre son:

Crear un perfil con varios contextos de estado de tipo variable así:
%PACTIVE ~ *,perfil1,*
%PACTIVE ~ *,perfil2,*
%PACTIVE ~ *,perfil3,*

Este perfil solo se activaría cuando las 3 condiciones se cumplieran, y tiene la limitación de que solo valdría para comprobar máximo 3 perfiles, o, ya que solo se pueden poner 3 contextos de estado, no se podrían hacer cosas como que los 3 perfiles estuvieran activos y además estuviese enchufado a la corriente, o tuviese la pantalla encendida o algo así...

Otra posibilidad, en los casos en que una tarea deba ejecutarse según otras condiciones varias pero la ejecución deba ser diferente en funcion de si hay uno o varios perfiles activos se podría hacer así dentro de la tarea:

variable %resultado = 0;
Sumar 1 a %resultado Si %PACTIVE ~ *,perfil1,*
Sumar 1 a %resultado Si %PACTIVE ~ *,perfil2,*
Sumar 1 a %resultado Si %PACTIVE ~ *,perfil3,*
Si %resultado = 0 ... (ninguno de esos perfiles activo)
Si %resultado = 3 ... (todos activos)
Esto permite también hacer cosas de lo más raras como

Si %resultado = 1 ... (uno solo de los perfiles activos)
Si %resultado = 2 ... (solo 2 de los 3 perfiles activos)
Si %resultado > 0 (uno o más activo)
...
Sin embargo, tu intento me ha despertado la curiosidad de si se podría hacer algo más flexible que los metodos anteriores mediante expresiones regulares, y tras varias pruebas he sacado esta:
((?<=,)(perfil1|perfil2|perfil3),.*?){3}Entre los paréntesis del medio se pone una lista de los perfiles que se deben comprobar separados por "|" en cualquier orden (sin espacios que no formen parte de los nombres de los perfiles) y entre las llaves del final hay que poner un numero ("3" en el ejemplo) que indica que deben estar activos al menos ese número de perfiles de la lista (si pones la cantidad total de perfiles que hay en la lista, como en el ejemplo, equivale a que deben estar todos ellos activos, si se pusiese por ejemplo un 2 indicaría que deben estar activos al menos 2 de los 3 perfiles puestos en la lista)

Con lo que, volviendo a tu pregunta, se podría hacer lo que quieres con un contexto de tipo "Valor de variable" en que %PACTIVE cumpla la regex ((?<=,)(perfil1|perfil2|perfil3),.*?){3}

edito: corrijo un fallo en la expresión regular que saqué en un principio.

Jusss
23/01/14, 13:36:20
lo que, volviendo a tu pregunta, se podría hacer lo que quieres con un contexto de tipo "Valor de variable" en que %PACTIVE cumpla la regex ((?<=,)(perfil1|perfil2|perfil3),){3} Poniendo un uno indicaría que se cumpla con cualquiera de las tres condiciones?

maid450
23/01/14, 13:56:01
Poniendo un uno indicaría que se cumpla con cualquiera de las tres condiciones?
Exacto

tito_chua
23/01/14, 15:29:51
Se me ocurre una opción enrevesada pero que puede cumplir el propósito...
Si asignamos un número primo mayor que 3 a cada una de las tareas, podemos elegir cual de ellas o que grupo de ellas ejercutar...
Por ejemplo
Tarea 1 = 3
Tarea 2 = 5
Tarea 3 = 7

Ahora en función de la tarea o tareas que quieras ejecutar pones la suma...
Tarea 1 y 3 y no 2 = 10
Tarea 1 y 3 (me da igual 2) > 3

Y así las combinaciones que se te ocurran...

darkopro
23/01/14, 17:23:32
Muchas gracias a todos por las respuestas.
Maid como siempre has dado en el clavo, además es para un perfil que no quiero gastar los 3 contextos de estado usando los 3 «Perfil activos». Además también me va a servir para no poner tantas condiciones en algunas tareas, que crack eres.

darkopro
23/01/14, 18:59:14
Bueno solo añadir que la expresión regular de Maid va genial para una tarea pero no para un perfil, me explico:
Lo he probado en un perfil me ha pasado usa cosa muy extraña, el problema es que me ejecutaba la tarea de entrada continuamente, es como si cada X tiempo comprobara el valor de la variable y volviera a lanzar la tarea de entrada, al menos eso me ha ocurrido a mi, si alguien lo puede corroborar salimos de dudas.

maid450
23/01/14, 19:03:59
Se me ocurre una opción enrevesada pero que puede cumplir el propósito...
Si asignamos un número primo mayor que 3 a cada una de las tareas, podemos elegir cual de ellas o que grupo de ellas ejercutar...
Por ejemplo
Tarea 1 = 3
Tarea 2 = 5
Tarea 3 = 7

Ahora en función de la tarea o tareas que quieras ejecutar pones la suma...
Tarea 1 y 3 y no 2 = 10
Tarea 1 y 3 (me da igual 2) > 3

Y así las combinaciones que se te ocurran...

Una aproximación muy ingeniosa :-)
Algo enrevesada y laboriosa de poner en práctica como dices, pero muy interesante

Bueno solo añadir que la expresión regular de Maid va genial para una tarea pero no para un perfil, me explico: Lo he probado en un perfil me ha pasado usa cosa muy extraña, el problema es que me ejecutaba la tarea de entrada continuamente, es como si cada X tiempo comprobara el valor de la variable y volviera a lanzar la tarea de entrada, al menos eso me ha ocurrido a mi, si alguien lo puede corroborar salimos de dudas.

En las pruebas rápidas que he hecho esta mañana no he notado nada raro, pero tal vez haya algun bug en tasker o se me escape algo...

Entiendo que la variable %PACTIVE se modificará a menudo si se tienen muchas tareas de varios tipos, y la comprobación se hará cada vez que ésta cambie.
Sin embargo, lo que supongo que hará Tasker es que si tras esa compobación el perfil sigue en el mismo estado (se cumplía antes de la modificación y sigue cumpliéndose después, o no se cumplía y sigue sin cumplirse) no hace nada, si pasa de no cumplirse a cumplirse ejecuta la tarea de entrada, y si pasa de cumplirse a no cumplirse ejecuta la tarea de salida (si tiene).

A ver si puedo hacer más pruebas

Caravantes
24/01/14, 04:17:56
concretamente tengo una condición que se activa si varios perfiles están activos y quería saber si la podría juntar en una sola

Hay otro método pedestre para resolver ese problema. Se trata de usar una variable global para controlar el número de perfiles activos. Esa variable será incementada o decrementada en las tareas de entrada y salida de los respectivos perfiles. Así: Perfil1, Tarea de entrada: Sumar 1 a la variable %NumPerfiles
Perfil1, Tarea de salida: Restar 1 a la variable %NumPerfiles
Perfil2, Tarea de entrada: Sumar 1 a la variable %NumPerfiles
Perfil2, Tarea de salida: Restar 1 a la variable %NumPerfiles
Perfil3, Tarea de entrada: Sumar 1 a la variable %NumPerfiles
Perfil3, Tarea de salida: Restar 1 a la variable %NumPerfiles
Luego puedes usar un contexto de estado de variable
%NumPerfiles = 3
o bien %NumPerfiles > 1 , etc.

En mi opinión, el mayor problema de este método es que la variable se descontrole en algún momento por un fallo de Tasker o por otro motivo, como por ejemplo que al comenzar con este método ya hubiera varios perfiles activos y la variable no comenzase con ese valor. En caso de que la variable sume o reste un punto indebidamente, esa diferencia se mantendía indefinidamente a lo largo del tiempo y las cosas nunca volverían a funciona bien.

Por tanto yo trataría de comprobar/ajustar el valor de esa variable en alguna tarea, por ejemplo en la propia tarea de entrada del perfil afectado, del modo siguiente (se supone que esa tarea de entrada solo se ejecuta cuando la variable es 3): Restar 1 a la variable %NumPerfiles, si %PACTIVE no coincide con *Perfil1*
Restar 1 a la variable %NumPerfiles, si %PACTIVE no coincide con *Perfil2*
Restar 1 a la variable %NumPerfiles, si %PACTIVE no coincide con *Perfil3*
Con eso aseguramos que la variable no se descontrole por exceso, pero también convendría controlarla por defecto; se haría creando otro perfil similar que se active cuando esa variable es cero y en la tarea de entrada pondríamos tres acciones (esta tarea se ejecutaría cuando la variable vale cero): Sumar 1 a la variable %NumPerfiles, si %PACTIVE coincide con *Perfil1*
Sumar 1 a la variable %NumPerfiles, si %PACTIVE coincide con *Perfil2*
Sumar 1 a la variable %NumPerfiles, si %PACTIVE coincide con *Perfil3*
Todo esto es un poco tedioso, soy consciente.
El método de Maid450 parece mucho más eficiente y simple de manejar, si funciona. Tiene una pinta bárbara.

Respecto al método de Tito... Es muy ingenioso pero... ¿cómo se implementa eso en un contexto?

tito_chua
25/01/14, 22:54:14
No si he entendido bien lo que preguntas Caravantes, voy a intentar responder (si me voy por las ramas avisa).

Yo organizo tasker mediante variables. Si se conecta a cierta wifi, si estoy en un horario, etc pongo un valor en cierta variable. De forma que si estoy en casa, es horario de dormir y no es fin de semana hace cierto perfil.
O si me desconecto de una ubicación y no estoy en el coche, haz otra acción
Y como tenía dificultades para negar eventos y estados se me ocurrió organizarlos de este modo y usar el evento cuando variable cambia para lanzar los perfiles.

El único problema puede venir si tasker deja de controlar las variables que restablezco en ciertas circunstancias. Por ejemplo todos los días al levantarme. Se que no es el método más eficiente, pero no tengo muchas tareas y me va muy bien.

Espero haber respondido la duda.
Saludos

Jusss
26/01/14, 00:14:05
Exacto
En el caso que uno le de lo mismo cualquiera de los dos perfiles tienen alguna ventaja usar regex ((?<=,)(perfil1|perfil2),){1} al método "si pactive coincide con *,perfil 1,*/*,perfil 2,*

maid450
26/01/14, 03:02:44
En el caso que uno le de lo mismo cualquiera de los dos perfiles tienen alguna ventaja usar regex ((?<=,)(perfil1|perfil2),){1} al método "si pactive coincide con *,perfil 1,*/*,perfil 2,*

Supongo que internamente será más eficiente con la expresión regular, pero la diferencia a nivel usuario debe ser tan mínima (algunos milisegundos) que para ese caso sencillo puedes usar el que te resulte más natural sin problema

maid450
26/01/14, 03:08:10
Bueno solo añadir que la expresión regular de Maid va genial para una tarea pero no para un perfil, me explico:
Lo he probado en un perfil me ha pasado usa cosa muy extraña, el problema es que me ejecutaba la tarea de entrada continuamente, es como si cada X tiempo comprobara el valor de la variable y volviera a lanzar la tarea de entrada, al menos eso me ha ocurrido a mi, si alguien lo puede corroborar salimos de dudas.

He hecho algunas pruebas y efectivamente he notado un comportamiento raro, como que se cumple cuando no debe e inmediatamente deja de cumplirse (pero la tarea ya se ejecutado) o cosas así, y estoy casi seguro de que es un bug en tasker, así que cuando tenga tiempo lo expondré en el foro oficial

darkopro
26/01/14, 07:51:43
He hecho algunas pruebas y efectivamente he notado un comportamiento raro, como que se cumple cuando no debe e inmediatamente deja de cumplirse (pero la tarea ya se ejecutado) o cosas así, y estoy casi seguro de que es un bug en tasker, así que cuando tenga tiempo lo expondré en el foro oficial

Pues la verdad que sería de gran utilidad, para perfiles. En algunas tareas lo he implementado y es un lujo para simplificar condiciones.





No si he entendido bien lo que preguntas Caravantes, voy a intentar responder (si me voy por las ramas avisa).

Yo organizo tasker mediante variables. Si se conecta a cierta wifi, si estoy en un horario, etc pongo un valor en cierta variable. De forma que si estoy en casa, es horario de dormir y no es fin de semana hace cierto perfil.
O si me desconecto de una ubicación y no estoy en el coche, haz otra acción
Y como tenía dificultades para negar eventos y estados se me ocurrió organizarlos de este modo y usar el evento cuando variable cambia para lanzar los perfiles.

El único problema puede venir si tasker deja de controlar las variables que restablezco en ciertas circunstancias. Por ejemplo todos los días al levantarme. Se que no es el método más eficiente, pero no tengo muchas tareas y me va muy bien.

Espero haber respondido la duda.
Saludos

La verdad que es un método muy ingenioso. De todas maneras, por si te sirve de algo, para negar estados, se puede usar la casilla invertir cuando seleccionamos el estado.

maid450
27/01/14, 11:34:58
Mirando un poco antes de poner una consulta en el foro oficial he descubierto que la expresión regular que hice tenía un fallo por el que no se cumplía algunas veces que debería.
He corregido el fallo y he hecho más pruebas y pienso que esta debería ir mejor:

((?<=,)(perfil1|perfil2|perfil3),.*?){3}

(es solo poner .*? después de la última coma).

Para probarlo he creado un perfil con la condicion condicion %PACTIVE cumple regex ((?<=,)(Home|WIFICon),.*?){2} que son los perfiles de cuando estoy en casa y cuando estoy conectado a la WIFI, que se cumplen casi siempre juntos, pero no siempre y como tarea de entrada escribe al final de un fichero: "%DATE %TIME: Se cumple %PACTIVE" y como tarea de salida, escribe al final del mismo fichero: "%DATE %TIME: No se cumple %PACTIVE"

Así puedo mirar el fichero y ver las horas cuando se ha ido cumpliendo o no y cual era el valor de %PACTIVE en ese momento a ver si es correcto.

darkopro
27/01/14, 22:04:08
Maid eres un crack, funciona perfecto. Te puedo poner a prueba otra vez?
Tengo un perfil que ha de activarse entre otras cosa con un perfil (perfil 1) obligado y con cualquiera de otros dos:
Algo así PERFIL1+(PERFIL2/PERFIL3)
Como se podría adaptar tu expresión a esto?
Mil gracias de antemano ;)

Caravantes
28/01/14, 03:44:00
Tengo un perfil que ha de activarse entre otras cosa con un perfil (perfil 1) obligado y con cualquiera de otros dos:

Usa dos contextos distintos de tipo ESTADO DE VARIABLE. En el primero pones
%PACTIVE ~ perfil1
En el segundo pones la regex de Maid aplicada a los otros dos perfiles:
%PACTIVE ~ ((?<=,)(perfil2|perfil3),.*?){2}
Con eso lo resuelves.

darkopro
28/01/14, 07:38:42
Usa dos contextos distintos de tipo ESTADO DE VARIABLE. En el primero pones
%PACTIVE ~ perfil1
En el segundo pones la regex de Maid aplicada a los otros dos perfiles:
%PACTIVE ~ ((?<=,)(perfil2|perfil3),.*?){2}
Con eso lo resuelves.

Ahora lo tengo así, lo que ocurre es que lo tengo lleno de contextos, a determinada hora + si pantalla ~ off, + si %PACTIVE ~ perfil1 + si %PACTIVE ~ perfil1/perfil2
Ya no me deja poner nada más en ese. Gracias a la expresión he conseguido en uno que tenía meter una condición más y en este quería hacer sitio por si necesito en un futuro meter otra. He pensado en una pequeña variación de la expresión pero no de si está bien o mal:
((?<=,)(perfil1),.*?){1}, ((?<=,)(perfil2|perfil3),.*?){1}

O quizás algo así:
((?<=,)(perfil1)(perfil2|perfil3),.*?){2}

maid450
28/01/14, 10:06:12
Maid eres un crack, funciona perfecto. Te puedo poner a prueba otra vez?
Tengo un perfil que ha de activarse entre otras cosa con un perfil (perfil 1) obligado y con cualquiera de otros dos:
Algo así PERFIL1+(PERFIL2/PERFIL3)

Como sabes que me gustan estos retos... X-D

Ahora lo tengo así, lo que ocurre es que lo tengo lleno de contextos, a determinada hora + si pantalla ~ off, + si %PACTIVE ~ perfil1 + si %PACTIVE ~ perfil1/perfil2
Ya no me deja poner nada más en ese. Gracias a la expresión he conseguido en uno que tenía meter una condición más y en este quería hacer sitio por si necesito en un futuro meter otra. He pensado en una pequeña variación de la expresión pero no de si está bien o mal:
((?<=,)(perfil1),.*?){1}, ((?<=,)(perfil2|perfil3),.*?){1}

O quizás algo así: ((?<=,)(perfil1)(perfil2|perfil3),.*?){2}

Primero que nada, entiendo que de los 2 perfiles opcionales debe cumplirse al menos uno, pero tambien se pueden cumplir ambos, sino sería mucho más complicado...
En un primer momento he estado probando cosas del estilo de lo que has puesto, pero sin exito.
Sobretodo lo complicado es que el orden de %PACTIVE es bastante arbitrario.

Tras varios intentos fallidos se me ha ocurrido otra aproximación que pintaba mucho mejor, aunque salía una expresión regular enorme, y mientras la pulía he ido vienbdo como optimizarla.
Finalmente he conseguido sacar esto:
(,Obligatorio,.*?((?<=,)(Opcional1|Opcional2),))|(,(Opcional1|Opcional2 ),.*?(?<=,)Obligatorio,)
Parece que funciona correctamente, y, aunque no es tan "simple" como la otra es bastante más sencilla que lo que había empezado haciendo :-P

El funcionamiento por encima es el siguiente:
La otra expresión se basa en que los 3 perfiles tienen el mismo "peso" (se deben cumplir más o menos de ellos a la vez, pero ninguno es "más importante" que otro) con lo que hace un grupo que consta de una coma, uno de los "x" nombres de perfil y otra coma final, y dice que este grupo se tiene que repetir al menos "y" veces, es decir, que se deben cumplir al menos "y" perfiles de los "x" de la lista (y el ".*?" que añadí despues que es para que, aparte de estos, puedan haber otros perfiles por medio que no se tengan en cuenta).

En este caso sin embargo, hay un perfil más importante que es obligatorio y otros 2 menos importantes que basta que se cumpla uno de ellos, por lo que la aproximación con la que lo he conseguido es separando 2 posibles situaciones de las que se debe cumplir una, por ello la estructura general de la expresion es "(situacion a)|(situacion b)".
La situación a es, que despues de perfiles arbitrarios, aparezca ",Obligatorio,", más perfiles arbitrarios, y después uno de los 2 opcionales (o los 2, pero al menos 1).
La situación b es lo mismo en el orden inverso, es decir que apareciera cualquiera de los 2 opcionales, y despues el obligatorio (con posibilidad de otras cosas por medio)
Con esos 2 casos cubres todos los posibles ordenes y casos

Espero haberlo explicado bien, las expresiones regulares son un hueso muy duro al principio, y, aún con práctica no es facil sacar algunas cosas

darkopro
28/01/14, 12:37:25
Como sabes que me gustan estos retos... X-D



Primero que nada, entiendo que de los 2 perfiles opcionales debe cumplirse al menos uno, pero tambien se pueden cumplir ambos

Antes que nada, reiterarme otra vez en lo dicho, menudo crack!

Diste en el clavo de los opcionales se puede cumplir uno, otro o los dos a vez, es totalmente indiferente, aunque son de localización, es imposible que se cumplan los dos.

Con mi nulo conocimiento creía que sería algo más sencillo, algún derivando de la primera expresión aunque he visto que no, no te lo he puesto fácil. A la vez me estoy dando cuenta de lo complicadas que son las expresiones regulares, no basta con empollarte la simbología, ni mucho menos.

Te explicas de maravilla Maid ha quedado muy claro ;)

tito_chua
28/01/14, 21:04:41
Veo que el hilo ha avanzado mucho, y sin duda el método de las expresiones regulares es mucho más potente.


La verdad que es un método muy ingenioso. De todas maneras, por si te sirve de algo, para negar estados, se puede usar la casilla invertir cuando seleccionamos el estado.

No todas la opciones de tasker permiten negarse, creo. ¿como negais una ubicación sin variables?

darkopro
28/01/14, 22:16:34
Veo que el hilo ha avanzado mucho, y sin duda el método de las expresiones regulares es mucho más potente.



No todas la opciones de tasker permiten negarse, creo. ¿como negais una ubicación sin variables?

Con el plugin autolocate puedes, no la he probado, pero tienes la opción de «outside» en las localizaciones. De todas maneras igual te puede valer en la tarea de salida de un perfil de localización o usar dos perfiles, uno con la localización y el otro con el estado de tasker no perfil activo "lugarX" o con la variable %PACTIVE !~ "lugarX" (si perfil activo no coincide con el lugar indicado).