|
||
|
![]() |
![]() |
Tasker Para hablar de todo lo relacionado con la aplicación tasker |
![]() |
|
Herramientas |
#1
|
||||
|
||||
Procesar los XML de AEMET (versión Código>JavaScriptlet)
- - ADVERTENCIA - - En este tutorial se explica cómo procesar los XML de la predicción meteorológica de AEMET usando código JavaScript ... pero mucho código. - - - - Hace unos días el compañero @Mitrhandir me lanzó el "reto", como a él le gusta decir, de hacer una tarea para procesar el XML de la "Predicción por horas" de AEMET, pero sin usar nada más que Tasker. ![]() No es la primera vez que se toca el tema de procesar los datos de AEMET en el foro... Tarea que te dice el tiempo y temperatura Cómo hacer una tarea para saber el tiempo que hace o va a hacer ...pero después de revisar esas conversaciones me decidí por un nuevo enfoque. Tras unas vueltas al asunto, y descartar un par de ideas por inviables o exceso de complejidad (convertir el XML a JSON en local o mediante un webservice), terminé por escribir un JavaScriptlet que se encargase de procesar ese XML directamente. Lo podía haber dejado aquí pero resulta que AEMET también publica una "Predicción 7 días" y el código JS que tenía sólo procesaba la "Predicción por horas" (de 3 días). Me puse a ello y no me quedó más remedio que escribir otro JavaScriptlet para procesar ese otro XML. El siguiente paso estaba cantado, unirlo todo en un único JavaScriptlet capaz de procesar los dos XML (por horas y 7 días) de la "Predicción por Municipios" que publica AEMET. Estos son los pasos que he ido dando hasta llegar a la solución final... ![]() Los XML de AEMET Tenemos estas dos fuente de datos: Código:
Predicción por horas http://www.aemet.es/xml/municipios_h/localidad_h_INE.xml Predicción 7 días (Interpretación) http://www.aemet.es/xml/municipios/localidad_INE.xml Ejemplos: "Predicción por horas" de Alegría-Dulantzi en Álava "Predicción 7 días" de Alegría-Dulantzi en Álava El valor INE es un código de cinco dígitos que identifica cada municipio de España. Están disponibles en la web del Instituto Nacional de Estadística y aunque lo parezca no es el Código Postal que usa Correos. La forma más fácil de conseguir el código INE de un lugar concreto es buscarlo en la web de la "Predicción por Municipios" y fijarte en el número que aparece al final de la URL (...-idxxxxx). A primera vista ambos XML parecen iguales, pero un análisis detallado pone de manifiesto unas pocas "particularidades":
Obtener un XML y pasarlo al JavaScriptlet para "parsearlo" Cualquiera de los XML se pueden obtener fácilmente poniendo su URL en una acción "HTTP Get" de Tasker. El resultado de esa acción queda almacenado en la variable global %HTTPD y lo tenemos que pasar al JavaScriplet para poder procesarlo. Eso es fácil con este código JS... Código:
httpd = global("HTTPD"); dom = new DOMParser(); xml = dom.parseFromString(httpd,"text/xml"); Solución al problema de la "fecha" Además de generar el formato adecuado (aaaa-mm-dd) está el tema de saber qué fecha es dentro de 2 días o de 3 horas, algo imprescindible en el caso que nos ocupa. Para resolver eso he creado esta función JS... Código:
function fecha(_nd=0,_nh=0){ _x=new Date(); _a=_x.getFullYear(); _m=_x.getMonth(); _d=_x.getDate(); _h=_x.getHours(); _x=new Date(_a,_m,_d+_nd,_h+_nh); _a=_x.getFullYear(); _m=_x.getMonth()+1; _d=_x.getDate(); _x=_a+"-"+("0"+_m).slice(-2)+"-"+("0"+_d).slice(-2); return _x; } Sintaxis: cadena = fecha([número días[, número horas]]) Ejemplos: //fecha de hoy dia = fecha(); //fecha de pasado mañana dia = fecha(2); //fecha dentro de tres horas dia = fecha(0,3); //fecha dentro de día y medio (o 36 horas) dia = fecha(1,12); dia = fecha(0,36); La dificultad en este caso está en conseguir un determinado formato de "periodo" para ahora o para dentro de X horas. He creado esta función JS para eso... Código:
function periodo(_nh=0,_fmt="h0"){ _x=new Date(); _a=_x.getFullYear(); _m=_x.getMonth(); _d=_x.getDate(); _h=_x.getHours(); _x=new Date(_a,_m,_d,_h+_nh); _h=_x.getHours(); if(_fmt=="h0"){ _x=("0"+_h).slice(-2); } if(_fmt=="h6"){ _t=Math.floor(_h/6);_t=_t*6+6; _x=("0"+_t).slice(-2); } if(_fmt=="r6"){ _to=_x.getTimezoneOffset()/60; _it=Math.floor(_h/6);_it=_it*6-_to; _xx=new Date(_a,_m,_d,_it+6); _ft=_xx.getHours(); _x=("0"+_it).slice(-2)+("0"+_ft).slice(-2); } if(_fmt=="r6-"){ _it=Math.floor(_h/6);_it=_it*6; _ft=_it+6; _x=("0"+_it).slice(-2)+"-"+("0"+_ft).slice(-2); } if(_fmt=="r12-"){ _x=(_h<12)?"00-12":"12-24"; } if(_fmt=="r24-"){ _x="00-24"; } return _x; } Sintaxis: cadena = periodo([número horas[, "formato"]]) Donde "formato" puede ser: h0 devuelve "00" a "23" [formato por defecto] h6 devuelve "06", "12", "18", "24" r6 devuelve "0006", "0612", "1218", "1824" más la diferencia horaria con UTC r6- devuelve "00-06", "06-12", "12-18", "18-24" r12- devuelve "00-12" o "12-24" r24- devuelve "00-24" Ejemplos: //hora actual con dos dígitos per = periodo(); //dentro de tres horas con dos dígitos per = periodo(3); //rango de doce horas de la hora actual en formato "hh-hh" per = periodo(0,"r12-"); //rango de seis horas para dentro de dos horas en formato "hh-hh" per = periodo(2,"r6-"); Al principio de ambos XML aparecen unos pocos datos genéricos que se pueden sacar casi directamente. Para este caso concreto he creado esta sencilla función JS... Código:
function valornodo(_elem){ _res=xml.getElementsByTagName(_elem)[0].childNodes[0].nodeValue; return _res; } Sintaxis: cadena = valornodo("nombre nodo") Ejemplos: //enlace a la página de la predicción enlace = valornodo("enlace"); //fecha y hora de elaboración elaborado = valornodo("elaborado"); //municipio municipio = valornodo("nombre"); municipio = municipio.split("/"); municipio = municipio[municipio.length-1]; Extraer los datos de la predicción del XML Esta es la parte que más trabajo me ha dado, principalmente por usar instrucciones básicas de JavaScript en vez de otras técnicas más directas, como las expresiones "XPath", pero quería hacer algo que se "entendiera" y que pudiera funcionar en cualquier dispositivo. Esta es la función JS que lo hace posible... Código:
function prediccion(_fecha,_periodo,_elem1,_elem2,_attr){ _xmlres=xml.getElementsByTagName("prediccion")[0]; _xmlres=_xmlres.getElementsByTagName("dia"); for(_i=0;_i<_xmlres.length;_i++){ _attfecha=_xmlres[_i].getAttribute("fecha"); if(_attfecha==_fecha){break;} } if(_i==_xmlres.length){return null;} _xmlres=_xmlres[_i]; if(_attr=="fecha" || _attr=="orto" || _attr=="ocaso"){ _res=_xmlres.getAttribute(_attr); return _res; } _xmlres=_xmlres.getElementsByTagName(_elem1); if(_xmlres.length==0){return null;} if(_xmlres.length==1){ //sin periodos _xmlres=_xmlres[0]; }else{ for(_i=0;_i<_xmlres.length;_i++){ _attperiodo=_xmlres[_i].getAttribute("periodo"); if(_attperiodo==_periodo){break;} } if(_i==_xmlres.length){return null;} _xmlres=_xmlres[_i]; } if(_xmlres.childNodes.length>1){ //con subnodos _xmlres=_xmlres.getElementsByTagName(_elem2); if(_xmlres.length==0){return null;} if(_xmlres.length==1){ _xmlres=_xmlres[0]; }else{ //en 7d: dato for(_i=0;_i<_xmlres.length;_i++){ _atthora=_xmlres[_i].getAttribute("hora"); if(_atthora==_periodo){break;} } if(_i==_xmlres.length){return null;} _xmlres=_xmlres[_i]; } } if(_attr){ _res=_xmlres.getAttribute(_attr); }else{ if(_xmlres.childNodes.length==0){ _res=null; }else{ _res=_xmlres.childNodes[0].nodeValue; } } return _res; } Sintaxis: cadena = prediccion("fecha", "periodo", "nodo1"[, "nodo2"[, "atributo"]]) Los nombres de los parámetros son bastante aclaratorios, pero la mejor forma de entender su funcionamiento es con ejemplos. Ejemplos: //datos de la próxima hora (XML por horas) dia = fecha(); hh = periodo(1); orto = prediccion(dia,"","","","orto"); ocaso = prediccion(dia,"","","","ocaso"); cielo = prediccion(dia,hh,"estado_cielo","","descripcion"); temp = prediccion(dia,hh,"temperatura"); dirviento = prediccion(dia,hh,"viento","direccion"); velviento = prediccion(dia,hh,"viento","velocidad"); //datos de mañana (XML de 7 días) dia = fecha(1); h24 = "00-24"; cielo = prediccion(dia,h24,"estado_cielo","","descripcion"); dirviento = prediccion(dia,h24,"viento","direccion"); velviento = prediccion(dia,h24,"viento","velocidad"); uvmax = prediccion(dia,"","uv_max"); La subtarea TiempoAEMET Llegados a este punto ya podemos abordar la creación de una tarea para procesar cualquiera de los XML de AEMET. Me ha parecido que lo más interesante es hacerla como una subtarea que reciba un código INE en %par1 y devuelva el texto de la predicción para mostrarlo o decirlo, a gusto del consumidor. La subtarea tiene esta pinta... Código:
TiempoAEMET (999) A1: Establecer variable [ Nombre:%par1 A:01001 ] Si (if) [ %caller1 ~ ui ] A2: HTTP Get [ Servidor:http://www.aemet.es Ruta:xml/municipios_h/localidad_h_%par1.xml ] A3: JavaScriptlet [ Código://** parser ** httpd = global("HTTPD"); dom = new DOMParser(); xml = dom.parseFromString(httpd,"text/xml"); //** funciones ** function valornodo(){...} function prediccion(){...} function fecha(){...} function periodo(){...} //** datos xml ** dia = fecha(); per = periodo(); var ... var ... var ... ...Librerías: Salida Automática:Encendido Cuenta atrás (segundos):45 ] A4: Establecer variable [ Nombre:%texto A:El cielo en %nombre está %descielo, la temperatura es de %temp grados Añadir:Apagado ] A5: Establecer variable [ Nombre:%texto A: con sensación de %senter Añadir:Encendido ] Si (if) [ %temp nig %senter ] A6: Establecer variable [ Nombre:%texto A:, el viento es de %velviento kilómetros por hora Añadir:Encendido ] A7: Establecer variable [ Nombre:%texto A: con rachas máximas de %rachamax Añadir:Encendido ] Si (if) [ %rachamax > 0 ] A8: Establecer variable [ Nombre:%texto A:. La probabilidad de lluvia es del %problluvia por ciento. Añadir:Encendido ] Si (if) [ %problluvia > 10 ] A9: Decir [ Texto:%texto ] Si (if) [ %caller1 ~ ui ] A10: Devolver [ Valor:%texto Detener:Encendido ]
![]()
Código:
Decir el tiempo (888) A1: Realizar tarea [ Nombre:TiempoAEMET Prioridad:%priority Parámetro 1 (%par1):10001 Parámetro 2 (%par2): Devolver Valor de Variable:%resultado ] A2: Decir [ Texto:%resultado ] Al explicar cada función he puesto dos o tres ejemplos de cómo se usa cada una de ellas, pero puede que no sea tan evidente cómo se usan en conjunto. A continuación os dejo unos casos prácticos que sacan TODOS los valores de cada tipo de predicción. Todos los valores para la hora actual del XML de la "Predicción por horas" Código:
//** datos xml ** dia = fecha(); h0 = periodo(); r6 = periodo(0,"r6"); var enlace = valornodo("enlace"); var elaborado = valornodo("elaborado"); var nombre = valornodo("nombre"); nombre=nombre.split("/"); nombre=nombre[nombre.length-1]; var provincia = valornodo("provincia"); provincia=provincia.split("/"); provincia=provincia[provincia.length-1]; var orto = prediccion(dia,"","","","orto"); var ocaso = prediccion(dia,"","","","ocaso"); var descielo = prediccion(dia,h0,"estado_cielo","","descripcion"); var estcielo = prediccion(dia,h0,"estado_cielo"); var lluvia = prediccion(dia,h0,"precipitacion"); var problluvia = prediccion(dia,r6,"prob_precipitacion"); var probtorm = prediccion(dia,r6,"prob_tormenta"); var nieve = prediccion(dia,h0,"nieve"); var probnieve = prediccion(dia,r6,"prob_nieve"); var temp = prediccion(dia,h0,"temperatura"); var senter = prediccion(dia,h0,"sens_termica"); var humrel = prediccion(dia,h0,"humedad_relativa"); var dirviento = prediccion(dia,h0,"viento","direccion"); var velviento = prediccion(dia,h0,"viento","velocidad"); var rachamax = prediccion(dia,h0,"racha_max"); Código:
//** datos xml ** dia = fecha(); r6 = periodo(0,"r6-"); h6 = periodo(0,"h6"); var enlace = valornodo("enlace"); var elaborado = valornodo("elaborado"); var nombre = valornodo("nombre"); nombre=nombre.split("/"); nombre=nombre[nombre.length-1]; var provincia = valornodo("provincia"); provincia=provincia.split("/"); provincia=provincia[provincia.length-1]; var problluvia = prediccion(dia,r6,"prob_precipitacion"); var cotanieve = prediccion(dia,r6,"cota_nieve_prov"); var descielo = prediccion(dia,r6,"estado_cielo","","descripcion"); var estcielo = prediccion(dia,r6,"estado_cielo"); var dirviento = prediccion(dia,r6,"viento","direccion"); var velviento = prediccion(dia,r6,"viento","velocidad"); var rachamax = prediccion(dia,r6,"racha_max"); var temp = prediccion(dia,"","temperatura","maxima"); var tempmin = prediccion(dia,"","temperatura","minima"); var dtem = prediccion(dia,h6,"temperatura","dato"); var senter = prediccion(dia,"","sens_termica","maxima"); var sentermin = prediccion(dia,"","sens_termica","minima"); var dster = prediccion(dia,h6,"sens_termica","dato"); var humrel = prediccion(dia,"","humedad_relativa","maxima"); var humrelmin = prediccion(dia,"","humedad_relativa","minima"); var dhrel = prediccion(dia,h6,"humedad_relativa","dato"); var uvmax = prediccion(dia,"","uv_max"); Código:
//** datos xml ** var diapred=[]; var problluvia=[];var cotanieve=[]; var descielo=[];var estcielo=[]; var dirviento=[];var velviento=[];var rachamax=[]; var tempmax=[];var tempmin=[]; var sentermax=[];var sentermin=[]; var hummax=[];var hummin=[]; var uvmax=[]; for(xd=-1;xd!=7;xd++){ dia=fecha(xd); xfecha=prediccion(dia,"","","","fecha"); if(xfecha){ diapred.push(prediccion(dia,"","","","fecha")); problluvia.push(prediccion(dia,"00-24","prob_precipitacion")); cotanieve.push(prediccion(dia,"00-24","cota_nieve_prov")); descielo.push(prediccion(dia,"00-24","estado_cielo","","descripcion")); estcielo.push(prediccion(dia,"00-24","estado_cielo")); dirviento.push(prediccion(dia,"00-24","viento","direccion")); velviento.push(prediccion(dia,"00-24","viento","velocidad")); rachamax.push(prediccion(dia,"00-24","racha_max")); tempmax.push(prediccion(dia,"","temperatura","maxima")); tempmin.push(prediccion(dia,"","temperatura","minima")); sentermax.push(prediccion(dia,"","sens_termica","maxima")); sentermin.push(prediccion(dia,"","sens_termica","minima")); hummax.push(prediccion(dia,"","humedad_relativa","maxima")); hummin.push(prediccion(dia,"","humedad_relativa","minima")); uvmax.push(prediccion(dia,"","uv_max")); } } Código:
//** máximos y mínimos ** var problluvia0,mpll=0; var cotanieve0,mcn=0; var velviento0,mvv=0; var rachamax0,mrx=0; var tempmax0,mtx=0; var tempmin0,mtm=999; var senterpmax0,mstx=0; var sentermin0,mstm=999; var hummax0,mhx=0; var hummin0,mhm=999; var uvmax0,mux=0; for(i=0;i<diapred.length;i++){ if(problluvia[i]>mpll){mpll=problluvia[i]/1;problluvia0=i+1;} if(cotanieve[i]>mcn){mcn=cotanieve[i]/1;cotanieve0=i+1;} if(velviento[i]>mvv){mvv=velviento[i]/1;velviento0=i+1;} if(rachamax[i]>mrx){mrx=rachamax[i]/1;rachamax0=i+1;} if(tempmax[i]>mtx){mtx=tempmax[i]/1;tempmax0=i+1;} if(tempmin[i]<mtm){mtm=tempmin[i]/1;tempmin0=i+1;} if(sentermax[i]>mstx){mstx=sentermax[i]/1;sentermax0=i+1;} if(sentermin[i]<mstm){mstm=sentermin[i]/1;sentermin0=i+1;} if(hummax[i]>mhx){mhx=hummax[i]/1;hummax0=i+1;} if(hummin[i]<mhm){mhm=hummin[i]/1;hummin0=i+1;} if(uvmax[i]>mux){mux=uvmax[i]/1;uvmax0=i+1;} } En la web de AEMET tienen unos pequeños iconos para el estado del cielo, la dirección del viento y el índice ultravioleta que os podrían venir bien para vuestra tarea. Añadiendo el siguiente código JS justo después del bloque ** datos xml ** también dispondréis en la tarea de Tasker de unas variables locales con las URLs de las imágenes correspondientes a esos valores. Código:
//** iconos ** var icocielo = (estcielo) ? "http://www.aemet.es/imagenes_gcd/_iconos_municipios/"+estcielo+".png" : null; var icoviento = (dirviento) ? "http://www.aemet.es/imagenes_gcd/_iconos_municipios/"+dirviento+".png" : null; var icouvmax = (uvmax) ? "http://www.aemet.es/imagenes_gcd/_iconos_localidades/uvi_c"+uvmax+"_pred.gif" : null;
La dirección del viento Otra cosa que os puede interesar, sobre todo si queréis "Decir" el tiempo, es la versión "pronunciable" de las letras de la dirección del viento. Añadiendo este código JS después del bloque ** datos xml ** tendréis en la tarea una variable local más con esa conversión. Código:
//** viento ** vd = {N:"norte",NE:"nordeste",E:"este",SE:"sudeste",S:"sur",SO:"suroeste",O:"oeste",NO:"noroeste",C:"calma"}; var vientodel = (dirviento) ? vd[dirviento] : null;
Y eso es todo. Ya tenéis entretenimiento. ![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) Última edición por WillyWeb Día 18/11/17 a las 22:43:31. Razón: Ver los mensajes #4, #6, #10 y #24 |
Los siguientes 5 usuarios han agradecido a WillyWeb su comentario: | ||
|
#2
|
||||
|
||||
Impresionante, genial. Muchas gracias.
Me ha gustado especialmente las condiciones que hay al final de algunas acciones A4: Establecer variable [ Nombre:%texto A:El cielo en %nombre está %descielo, la temperatura es de %temp grados Añadir:Apagado ] A5: Establecer variable [ Nombre:%texto A: con sensación de %senter Añadir:Encendido ] Si (if) [ %temp nig %senter ] A6: Establecer variable [ Nombre:%texto A:, el viento es de %velviento kilómetros por hora Añadir:Encendido ] A7: Establecer variable [ Nombre:%texto A: con rachas máximas de %rachamax. Añadir:Encendido ] Si (if) [ %rachamax > 0 ] A8: Establecer variable [ Nombre:%texto A: La probabilidad de lluvia es del %problluvia por ciento. Añadir:Encendido ] Si (if) [ %problluvia > 10 ] Por cierto, siempre he creído que, en estas acciones de ESTABLECER VARIABLE, la opción de AÑADIR ENCENDIDO solo era aplicable en variables con contenido numérico, nunca pensé que también sirviese para concatenar textos. Yo hubiera escrito, por ejemplo A5: Establecer variable [ Nombre:%texto A: %texto con sensación de %senter Añadir:Apagado ] O sea que aquí también he aprendido algo sencillo y útil para otras muchas tareas. Gracias también por esto. Añado enlaces a otros tres hilos muy relacionados: [HILO ESPECÍFICO] Integración de JavaScript en Tasker http://www.htcmania.com/showthread.php?t=1148751 [Tutorial] Creación, uso y manipulación de variables con javascript http://www.htcmania.com/showthread.php?t=631165 [Idea] Usar Javascript en Tasker escribiendo el código desde el PC http://www.htcmania.com/showthread.php?p=26899943
__________________
Firmado: Caravantes, miembro del equipo que promueve el Subforo de Tasker
|
Gracias de parte de: | ||
#3
|
||||
|
||||
Buenos días.
Lo primero: Quiero dar las gracias a WillyWeb por haberme atendido de una manera tan generosa y altruista. La idea que se persigue con esta tarea es que, ajustando bien los parámetros, podemos conseguir cosas cosas muy interesantes. A saber: imaginad que os levantáis por la mañana y al encender vuestro dispositivo, os sale un pop-up, flash o escena alertando de que la previsión de lluvia en el INE que tú estás hay una probabilidad de lluvia superior a un 50%. Dependiendo de tu trabajo, circunstancias y/o lugar de residencia, esta información es muy valiosa, puesto que nos condiciona a coger o no el paraguas. O simplemente que nos salga un pop-up, flash y/o escena avisando de que va a haber una bajada drástica de temperaturas. Para mí esta tarea es muy útil y muy productiva. Por muchos motivos: ya no necesitas una web y/o app del tiempo. No necesitas la app Autotools para parsear el xml. Y además, después de haber estado testeando durante unos cuantos meses si los valores que arroja AEMET son o no fidedignos, puedo aseguraros que estoy gratamente sorprendido de la fiabilidad que arrojan nuestros meteorólog@s. Sin más, quiero dar las gracias otra vez a @WillyWeb por su paciencia ante mi supina y atrevida ignorancia. Un saludo.
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
Gracias de parte de: | ||
#4
|
||||
|
||||
He añadido un poco de JS más para disponer de una nueva variable local con la versión "pronunciable" de la dirección del viento.
![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
Los siguientes 2 usuarios han agradecido a WillyWeb su comentario: | ||
#5
|
||||
|
||||
La idea que se persigue con esta tarea es que, ajustando bien los parámetros, podemos conseguir cosas cosas muy interesantes. A saber: imaginad que os levantáis por la mañana y al encender vuestro dispositivo, os sale un pop-up, flash o escena alertando de que la previsión de lluvia en el INE que tú estás hay una probabilidad de lluvia superior a un 50%. Dependiendo de tu trabajo, circunstancias y/o lugar de residencia, esta información es muy valiosa, puesto que nos condiciona a coger o no el paraguas.
O simplemente que nos salga un pop-up, flash y/o escena avisando de que va a haber una bajada drástica de temperaturas. ![]()
(Click para mostrar/ocultar)
Visualmente preferiría no mostrar la temperatura actual y los mínimos/máximos, pero me resulta útil mostrarlos ahí, porque siempre puedo ver si las temperaturas van a bajar considerablemente al día siguiente, incluso sin la gráfica, y puedo ver si hay probabilidad de lluvia mayor que cero, porque incluso aunque sea un 10-20% no me puedo arriesgar a no llevar ropa de lluvia cuando coja la moto y llegar completamente calado por haberme pillado la lluvia durante un par de minutos. Todo lo relativo al tiempo lo tengo hecho con KLWP, porque resulta mucho más sencillo, cómodo y rinde muchísimo mejor a la hora de presentar algo visualmente comparado con Tasker. Pero si se desean avisos por voz (p.e.) se puede con este y enviar los datos del tiempo a mostrar a KLWP (como hago con las noticias o el calendario) para la parte visual, quedando Tasker para la parte sonora u otras cosas que queramos hacer con la información. Y digo KLWP, pero creo que para estas cosas lo mejor es, o esto u otra app de crear widgets que siempre esté a la vista en el escritorio. Y puedes añadir que bajo ciertas condiciones (p.e. probabilidad de lluvia superior a x%) se muestren con efectos que las resalten o avisos adicionales en pantalla. Y bueno, ya sé que en el fondo es publicidad gratuita de KLWP pero lo mismo hago con Tasker en otras zonas del foro XDD. Sin esta app, solo con Tasker, algo muy sencillo sería cuando se de la condición que citas cambiar el fondo de pantalla por algo como una foto de un paisaje lluvioso o de entre una lista de fotos con ese tema. No te va a pasar desapercibido. |
Gracias de parte de: | ||
#6
|
||||
|
||||
He dado con una situación poco deseable ocasionada por la forma en la que se pasan/reciben variables locales entre Tasker y JS.
Para entender el problema se debe tener en cuenta lo siguiente...
Está claro que entre los puntos 1/2 y 3/4 existe una gran posibilidad de conflicto. Es relativamente fácil "machacar" una variable local de una tarea Tasker desde un JavaScriptlet, sobre todo si este es muy largo o si has usado nombres de variable poco "imaginativos" susceptibles de ser repetidos en distintos procesos (%fecha, %hora, %nombre, etc...). Si quieres evitar "interferencias" entre funciones deberías declarar las variables con var ..., pero entonces las conviertes en variables de Tasker. He cambiado todas las funciones del JavaScriptlet de esta tarea para poner nombres poco "evidentes" que eviten interferencias con Tasker y entre diferentes partes del propio JS. Tampoco es nada del otro mundo. Simplemente he añadido un guión bajo delante del nombre de la variable. Espero que eso evite futuros problemas. ![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
Gracias de parte de: | ||
#7
|
||||
|
||||
Buenas!
Una pregunta: ¿Cómo hago para tener todos los valores más sobresalientes del XML de 7 días en variables de Tasker? Lo tengo hecho sacando los valores de uno (un faenón) en uno pero seguro que se puede hacer más fácil y rápido. Cada vez me gusta más este perfil!
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
#8
|
||||
|
||||
![]() Eso no es una pregunta. Eso es un dardo envenenado. ![]() Una cosa es pasar TODOS los datos del XML a Tasker y otra es, sabiendo lo que pretendes, pasar los "más sobresalientes". Si el objetivo es sacar TODOS los datos el JS "debería" ser relativamente sencillo... Código:
var dirviento=[]; var velviento=[], ... for(d=0;d<=6;d++){ dia=fecha(d) dirviento[d]=prediccion(dia, ... velviento[d]=prediccion(dia, ... ... } Pero ... al hacer eso me he dado cuenta de que el séptimo día no siempre tiene datos porque su fecha no siempre aparece en el XML. Eso pasa durante las primeras horas de cada día hasta que AEMET actualiza la predicción, elimina los datos del día anterior y añade los de uno nuevo. Si el objetivo es sacar TODOS los datos el JS anterior no lo hace. Así que necesito que me aclares tus intenciones...
![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) Última edición por WillyWeb Día 25/10/17 a las 11:17:07. |
Gracias de parte de: | ||
#9
|
||||
|
||||
Claro, el tema es que la web de AEMET si mal no recuerdo, actualiza cada 6 horas a saber: a las 6:45, a las 12:45, a las 18:45 y a las 00:45. Partiendo de esa base o premisa, podemos agilizar las cosas. Me falta averiguar a qué hora "desaparece" el día anterior del xml.
Por otra parte, cuando digo datos más sobresalientes, me refiero a por ejemplo, a la probabilidad de lluvia, o una velocidad de viento muy por encima de lo normal. Vamos, todos aquellos fenómenos meteorológicos que se salgan de la gráfica o de lo normal. Otra alerta interesante puede ser una brusca caída de las temperaturas o una subida. La idea es que la tarea lance un pop-up, escena y/o flash avisando de un fenómeno meteorilógico anormal a 7 días vista. Cómo último dato, date cuenta de que al final del xml de la predicción de los 7 días arroja menos datos. La tarea de por horas es interesante porque la predicción está más afinada y es más concreta. Pero la de los 7 días tiene su visión más "generalista", que también es interesante. He contestado a tu pregunta? ![]()
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
#10
|
||||
|
||||
![]() Pues la verdad es que no. ![]() A la primera pregunta sólo tenías que responder "todos" o "desde hoy". Y a la segunda si con eso de "más sobresalientes" te referías a los valores máximos y mínimos o a otra cosa. En vez de eso te has salido por peteneras y has escrito la carta a los Reyes Magos para que te traigan una tarea que te alerte cuando "algo" no sea "normal" ... nada más. ![]() Bueno, tú a lo tuyo y yo a mis cosas ... El siguiente código JS crea varios arrays con TODOS los valores de la predicción del XML de 7 días. Si sólo quieres los datos desde hoy en adelante (por el tema que comenté en mi post anterior) sólo tienes que cambiar el -1 (en rojo) por un 0 ... no te lo puedo poner más fácil. Código:
//** todos los datos de la predicción del xml de 7 días ** var diapred=[] var problluvia=[];var cotanieve=[] var descielo=[];var estcielo=[] var dirviento=[];var velviento=[];var rachamax=[] var tempmax=[];var tempmin=[] var sentermax=[];var sentermin=[] var hummax=[];var hummin=[] var uvmax=[] for(xd=-1;xd!=7;xd++){ dia=fecha(xd) xfecha=prediccion(dia,"","","","fecha") if(xfecha){ diapred.push(prediccion(dia,"","","","fecha")) problluvia.push(prediccion(dia,"00-24","prob_precipitacion")) cotanieve.push(prediccion(dia,"00-24","cota_nieve_prov")) descielo.push(prediccion(dia,"00-24","estado_cielo","","descripcion")) estcielo.push(prediccion(dia,"00-24","estado_cielo")) dirviento.push(prediccion(dia,"00-24","viento","direccion")) velviento.push(prediccion(dia,"00-24","viento","velocidad")) rachamax.push(prediccion(dia,"00-24","racha_max")) tempmax.push(prediccion(dia,"","temperatura","maxima")) tempmin.push(prediccion(dia,"","temperatura","minima")) sentermax.push(prediccion(dia,"","sens_termica","maxima")) sentermin.push(prediccion(dia,"","sens_termica","minima")) hummax.push(prediccion(dia,"","humedad_relativa","maxima")) hummin.push(prediccion(dia,"","humedad_relativa","minima")) uvmax.push(prediccion(dia,"","uv_max")) } } Si has usado la variante que sólo carga los datos desde hoy y quieres/necesitas saber de cuántos días has podido sacar del XML simplemente tienes que ver el número de elementos del array %diapred() con este valor %diapred(#). Para saber qué días se dan los valores máximos y mínimos de la predicción tienes que añadir este otro JS justo detrás del anterior... Código:
//** máximos y mínimos ** var problluvia0,mpll=0 var cotanieve0,mcn=0 var velviento0,mvv=0 var rachamax0,mrx=0 var tempmax0,mtx=0 var tempmin0,mtm=999 var senterpmax0,mstx=0 var sentermin0,mstm=999 var hummax0,mhx=0 var hummin0,mhm=999 var uvmax0,mux=0 for(i=0;i<diapred.length;i++){ if(problluvia[i]>mpll){mpll=problluvia[i]/1;problluvia0=i+1} if(cotanieve[i]>mcn){mcn=cotanieve[i]/1;cotanieve0=i+1} if(velviento[i]>mvv){mvv=velviento[i]/1;velviento0=i+1} if(rachamax[i]>mrx){mrx=rachamax[i]/1;rachamax0=i+1} if(tempmax[i]>mtx){mtx=tempmax[i]/1;tempmax0=i+1} if(tempmin[i]<mtm){mtm=tempmin[i]/1;tempmin0=i+1} if(sentermax[i]>mstx){mstx=sentermax[i]/1;sentermax0=i+1} if(sentermin[i]<mstm){mstm=sentermin[i]/1;sentermin0=i+1} if(hummax[i]>mhx){mhx=hummax[i]/1;hummax0=i+1} if(hummin[i]<mhm){mhm=hummin[i]/1;hummin0=i+1} if(uvmax[i]>mux){mux=uvmax[i]/1;uvmax0=i+1} } ![]() Veamos... Si quieres saber qué día de la previsión tendrá la temperatura máxima más alta tienes que consultar el valor de %tempmax0. El número que contenga esa variable indica qué elemento del array %tempmax() tiene el dato que buscas. Si quieres el valor de esa temperatura sólo tienes que mirar en %tempmax(%tempmax0). Y (atento que esto es para nota) si quieres saber qué día se dará esa temperatura ¿...? pues consultas este otro valor %diapred(%tempmax0) y ya lo tienes. Para probar todo esto tienes que usar las funciones que aparecen ahora mismo en el primer post. No lo hagas con las que tenías hasta ahora que no te funcionará. El resto ya es cosa tuya. ![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) Última edición por WillyWeb Día 25/10/17 a las 22:32:27. Razón: Corrección de error tipográfico |
Gracias de parte de: | ||
#11
|
||||
|
||||
Incluso mirando por meses y obteniendo los valores "medios", de ese mes (en los años anteriores), hay anomalías. Por ejemplo, este mes de octubre, en España llevamos casi todo el mes con temperaturas más altas de lo previsto y lluvias menores de lo previsto... Sin embargo sería muy tonto que estén saltando varias alertas diarias por un fenómeno "anormal" que se mantiene constante durante todo el mes. Desde este punto de vista, quizá interese definir como "especial" (o "anormal") aquella medición que cumple dos condiciones: A) se sale de lo previsto en la época del año, y además B) también supone un cambio relevante respecto a lo que ha ocurrido en días precedentes. Computerizar todo esto no es fácil, y menos aún si quieres aplicarlo a diferentes mediciones (temperatura, lluvia, viento, etc) por las complicaciones concretas de cada medición. Me refiero, por ejemplo, a que las temperaturas "máximas" son más o menos constantes, varían ligeramente hacia arriba o hacia abajo, pero el caso es que todos los días hay una temperatura máxima. En cambio, en España la lluvia es un fenómeno muy intermitente o esporádico: para un lugar concreto, incluso en un mes muy lluvioso, la mayoría de los días no llueve. Así pues, no veo nada claro cómo considerar si una probabilidad de lluvia del 50% es algo que deba llamarnos la atención (durante un mes lluvioso). De forma similar, el viento tiene sus propias peculiaridades. En fin, tras esta primera aproximación al problema... me parece que necesitarías definir de una forma mucho más concreta lo que quieres obtener... y cómo obtenerlo. En el CÓMO no me refiero a las instrucciones de Tasker o de Javascript, sino al método que emplearía un humano para hacer la misma tarea. Mira las predicciones de mañana para un lugar concreto, y decide cuáles se salen de la normalidad. Mira la predicción para otro pueblo a 500 kms, y decide qué se sale de la normalidad. Mira las predicciones de otro día y decide lo mismo. Tras haber hecho esto en unos cuantos días y lugares distintos quizá ya empieces a tener un método, un modelo que sirva para cualquier predicción, y que por tanto podríamos intentar informatizar... o quizá descubras que no eres capaz de crear un método que funcione para cualquier predicción porque es demasiado complicado e intervienen demasiados detalles que no son fáciles de controlar.
__________________
Firmado: Caravantes, miembro del equipo que promueve el Subforo de Tasker
|
#12
|
||||
|
||||
Buenas! Me siento muy holgado de hablar contigo Mr. @Caravantes
A ver. Yo no lo veo tan complicado como expones. Tendrías razón en el hipotético caso de que yo viajara asiduamente a Groenlandia, pero no es el caso. ![]() Yo vivo la provincia de Castellón a un tiro de piedra del mar Mediterráneo, lo cual se traduce que, como norma general, disfrutamos de unas temperaturas suaves. Por ejemplo, unas temperaturas inferiores a 10 grados por estos lares sería un fenómeno anormal, de la misma forma, unas temperaturas superiores a digamos, 35 grados, también se salen de lo normal. Lo bueno que tiene este perfil, es que los foreros que viven en España, dependiendo de la zona en la que vivan, podrán ajustar sus parámetros a la climatología característica de su zona, pero es que además, si se desplaza a otra zona asiduamente más fría, cálida o con cotas más bajas de nieve, lo podrá ajustar para que en esa zona concreta le salten alertas. Entiendo perfectamente tu postura y hasta cierto punto, la suscribo. Pero no olvides, mon ami, que estamos hablando de predicciones meteorológicas, que son cosas que escapan a nuestro control. En meteorología, muy pocas veces se da lo de A+B=C. Hay muchísimas variables a tener en cuenta, por lo tanto, por desgracia, tenemos que generalizar un poco. Para que éste perfil fuera mucho más completo y útil, ojalá AEMET añadiera los niveles de polen. Para los alérgicos como yo sería muy de agradecer. Sin más, recibe un afectuoso saludo. ![]()
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
Gracias de parte de: | ||
#13
|
||||
|
||||
¿Puedes definir algo similar para lluvia y viento, como indicabas en tu anterior mensaje?
__________________
Firmado: Caravantes, miembro del equipo que promueve el Subforo de Tasker
|
#14
|
||||
|
||||
El tema de lluvia empezaría con un 50% y a partir de ahí, ir ajustando la "sensibilidad". Con el viento es distinto: imagino que si ponemos un valor de 70, se referirá a un valor de 70 Km/h.
Con la sensación térmica es un poco más complicado. Sólo le veo utilidad cuando son temperaturas bajas. La humedad relativa no sé cómo interpretarla, sinceramente. Tendré que estudiar un poco más sobre este tema. El estado del cielo es un poco indiferente, puesto que para que haya lluvia, tienen que haber nubes, pero sin embargo, no es necesario que esté nublado para que sople un aire muy fuerte. La dirección del viento tampoco sé cómo jugar con ese valor. Sé que por ejemplo si sopla del sur y viene del norte de África, tenemos lo que aquí llamamos una "ponientá". Lo de los Rayos Uva puede ser interesante, pero como en la lluvia, habría que ajustar el valor, puesto que siempre está en 3 no sé su máximo. Espero haber contestado a tu pregunta.
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
#15
|
||||
|
||||
Es que todo este tema es bastante personal en cuanto que parámetros quiero utilizar.
Por ejemplo el tema del pronostico a partir desde 40% ya me empiezo a interesar ya que empieza a ser un valor a tener en cuenta. La sensación térmica pues es interesante tanto en frío como en calor ya que esta va a depender tanto de la humedad como del viento. En invierno por el tema del viento principalmente y en verano por si hay mucha humedad en el aire. La humedad del aire relativa es facil de entender y a groso modo te dice la cantidad de 'agua' que puede contener la atmósfera y es relativa porque el aire nunca podría tener 100% no relativa ya que si no un 100% estarías debajo el agua ![]() Los vientos pues depende de cada zona concreto. En mi zona tenemos el cierzo NE seco y frio que en verano viene muy bien pero en invierno te llega hasta los huesos y la sensación térmica aumenta en cuanto al frio o el bochorno SE que suele ser muy húmedo que en invierno provoca bancos de niebla intensos y calor sofocante en verano al ser muy húmedo y no poder transpirar bien donde la sensación térmica aumenta en cuanto al calor. Aparte en mi caso concreto sirve además para ver que pista del aeropuerto está activa ![]() Los UV de aquí puedes sacar el index UV y su valoración: https://es.wikipedia.org/wiki/Radiac...n_ultravioleta El punto de rocío también es interesante ya que de ese valor se puede extrapolar a que altura mínima se van a formar las nubes. Una regla generalista para saber si va haber niebla es multiplicar la diferencia de temperatura entre el valor actual y el punto de rocío por 125 y te da la altura de la "niebla" corriente ya que hay varios tipos de niebla. Y lo dicho para que halla este tipo de niebla el aire tiene que estar saturado de humedad, si el aire es seco no habrá este tipo de niebla que podemos definirlo de nubes muy bajas, que es lo que es, una nube extremadamente baja. Entonces si alguno os saca la frase a que huelen las nubes... pues a humedad a que va a oler ;) Añado: Por ejemplo en cuanto al viento, y como voy en moto, si hay mucho viento y viene racheado o con ráfagas fuertes variables me lo pienso antes de usar la moto porque parece que vas en barco en lugar de ir en moto. Un saludo. Última edición por Xcso Día 26/10/17 a las 18:13:02. Razón: Añadir viento + |
Gracias de parte de: | ||
#16
|
||||
|
||||
Buenas! @Xcso, interesante valoración la tuya.
Yo creo que con esto no es necesario ser tan "tisquismiquis". Pretender conjugar unos valores meteorológicos con Tasker lo veo rizar el rizo demasiado. Esto me recuerda poderosamente a cierta historia de la NASA y un lápiz que escribía en el espacio. Y su moraleja creo yo que debemos aplicarla aquí. Tenemos unos datos que nos arroja AEMET y podemos usarlos de una manera práctica y eficaz en nuestro beneficio. Otra cosa es que queráis jugar a ser meteorólogos. ![]() Voy a ver si consigo que funcionen los últimos cambios de @WillyWeb, que no sé qué hago mal! ![]() Un saludo
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
#17
|
||||
|
||||
![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
#18
|
||||
|
||||
Tendrías que empezar definiendo qué consideras como rango "normal", para que luego la tarea pueda chequear si un valor concreto se sale de la normalidad. Para cualquier medición (temperatura, lluvia, viento, etc), definir el rango normal es complicado porque los valores "normales" son distintos en cada época.
![]() ¿Seguro?, porque entonces la moraleja es que las soluciones baratas y simples pueden ser mucho más peligrosas e inadecuadas frente a las complejas y caras. Los rusos terminaron comprando bolígrafos al proveedor de la NASA XDD. |
#19
|
||||
|
||||
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
|
#20
|
||||
|
||||
__________________
Si la educación te parece cara, prueba con la ignorancia.
|
![]() |
![]() |
||||||
|