-1

I've wanted to create an app on my Android phone to tell me the weather each morning for a while now and have found many, many sites that tell you how to do it, but none of them really made it easy to edit their tasks - there was no real documentation. Also, some had links to download the tasks or profiles, but they were either dead links or given as-is with no explanation.

So I've done just that.

Jim
  • 2,243
  • 2
  • 13
  • 17

3 Answers3

2

Ok, So after many hours of searching, and digging, and playing in Tasker not to mention building the regex's required to get it working... I did just that, got it working.

Step1: Get a free API key from http://openweathermap.org/ . They limit you to using it only once per 10 minute window, but as we're only going to be using it once a day, that's way more than what we need.

The XML:

    <TaskerData sr="" dvi="1" tv="4.6u3m">
    <Profile sr="prof22" ve="2">
    <cdate>1427972769580</cdate>
    <edate>1428156514542</edate>
    <id>22</id>
    <mid0>23</mid0>
    <nme>08:00 Week Weather</nme>
    <Day sr="con0">
    <wday0>2</wday0>
    <wday1>3</wday1>
    <wday2>4</wday2>
    <wday3>5</wday3>
    <wday4>6</wday4>
    </Day>
    <Time sr="con1">
    <fh>8</fh>
    <fm>0</fm>
    <th>8</th>
    <tm>1</tm>
    </Time>
    <State sr="con2" ve="2">
    <code>10</code>
    <Int sr="arg0" val="1"/>
    </State>
    </Profile>
    <Task sr="task23">
    <cdate>1427980998336</cdate>
    <edate>1428154334252</edate>
    <id>23</id>
    <nme>Tell me the Weather</nme>
    <pri>10</pri>
    <Action sr="act0" ve="7">
    <code>590</code>
    <Str sr="arg0" ve="3">%TIME</Str>
    <Str sr="arg1" ve="3">.</Str>
    <Int sr="arg2" val="0"/>
    </Action>
    <Action sr="act1" ve="7">
    <code>547</code>
    <Str sr="arg0" ve="3">%TIME1</Str>
    <Str sr="arg1" ve="3">%TIME1</Str>
    <Int sr="arg2" val="1"/>
    <Int sr="arg3" val="0"/>
    </Action>
    <Action sr="act10" ve="7">
    <code>547</code>
    <Str sr="arg0" ve="3">%maxmax</Str>
    <Str sr="arg1" ve="3">%max(1)</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    </Action>
    <Action sr="act11" ve="7">
    <code>37</code>
    <ConditionList sr="if">
    <Condition sr="c0" ve="3">
    <lhs>%max(2)</lhs>
    <op>7</op>
    <rhs>%maxmax</rhs>
    </Condition>
    </ConditionList>
    </Action>
    <Action sr="act12" ve="7">
    <code>547</code>
    <Str sr="arg0" ve="3">%maxmax</Str>
    <Str sr="arg1" ve="3">%max(2)</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    </Action>
    <Action sr="act13" ve="7">
    <code>38</code>
    </Action>
    <Action sr="act14" ve="7">
    <code>37</code>
    <ConditionList sr="if">
    <Condition sr="c0" ve="3">
    <lhs>%max(3)</lhs>
    <op>7</op>
    <rhs>%maxmax</rhs>
    </Condition>
    </ConditionList>
    </Action>
    <Action sr="act15" ve="7">
    <code>547</code>
    <Str sr="arg0" ve="3">%maxmax</Str>
    <Str sr="arg1" ve="3">%max(3)</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    </Action>
    <Action sr="act16" ve="7">
    <code>38</code>
    </Action>
    <Action sr="act17" ve="7">
    <code>37</code>
    <ConditionList sr="if">
    <Condition sr="c0" ve="3">
    <lhs>%max(4)</lhs>
    <op>7</op>
    <rhs>%maxmax</rhs>
    </Condition>
    </ConditionList>
    </Action>
    <Action sr="act18" ve="7">
    <code>547</code>
    <Str sr="arg0" ve="3">%maxmax</Str>
    <Str sr="arg1" ve="3">%max(4)</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    </Action>
    <Action sr="act19" ve="7">
    <code>38</code>
    </Action>
    <Action sr="act2" ve="7">
    <code>118</code>
    <Str sr="arg0" ve="3">api.openweathermap.org</Str>
    <Str sr="arg1" ve="3">data/2.5/forecast?q=Cape%20Town&amp;mode=xml&amp;units=metric</Str>
    <Str sr="arg2" ve="3"/>
    <Str sr="arg3" ve="3"/>
    <Str sr="arg4" ve="3"/>
    <Int sr="arg5" val="10"/>
    <Str sr="arg6" ve="3">text/xml</Str>
    <Str sr="arg7" ve="3">jim.xml</Str>
    <Int sr="arg8" val="0"/>
    </Action>
    <Action sr="act20" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%jim</Str>
    <Str sr="arg1" ve="3">s\svalue="[\w\s]*"</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3">%clouds</Str>
    <Int sr="arg6" val="0"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act21" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%clouds(1)</Str>
    <Str sr="arg1" ve="3">s\svalue="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3">%clouds(1)</Str>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act22" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%clouds(1)</Str>
    <Str sr="arg1" ve="3">"</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3"/>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act23" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%jim</Str>
    <Str sr="arg1" ve="3">g="\d*\.\d*"\scode="\w*"\sname=[\S]*"</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%from</Str>
    <Int sr="arg6" val="0"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act24" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%from(1)</Str>
    <Str sr="arg1" ve="3">g="\d*\.\d*"\scode="\w*"\sname=</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%from(1)</Str>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act25" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%from(1)</Str>
    <Str sr="arg1" ve="3">"</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%from(1)</Str>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act26" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%jim</Str>
    <Str sr="arg1" ve="3">mps="\d*\.\d*"\sname="[\w\s]*"</Str>
    <Int sr="arg2" val="1"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%wind</Str>
    <Int sr="arg6" val="0"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act27" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%wind(1)</Str>
    <Str sr="arg1" ve="3">mps="\d*\.\d*"\sname="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3">%wind(1)</Str>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act28" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%wind(1)</Str>
    <Str sr="arg1" ve="3">"</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%wind(1)</Str>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act29" ve="7">
    <code>307</code>
    <Int sr="arg0" val="10"/>
    <Int sr="arg1" val="0"/>
    <Int sr="arg2" val="0"/>
    </Action>
    <Action sr="act3" ve="7">
    <code>417</code>
    <Str sr="arg0" ve="3">jim.xml</Str>
    <Str sr="arg1" ve="3">%jim</Str>
    </Action>
    <Action sr="act30" ve="7">
    <code>559</code>
    <Str sr="arg0" ve="3">Good morning. It is now %TIME1 AM. There will be %clouds(1) today with a maximum expected temperature of %maxmax degrees. You can expect a %wind(1)         from the %from(1).</Str>
    <Str sr="arg1" ve="3">com.ivona.tts:eng-GBR</Str>
    <Int sr="arg2" val="3"/>
    <Int sr="arg3" val="5"/>
    <Int sr="arg4" val="5"/>
    <Int sr="arg5" val="1"/>
    <Int sr="arg6" val="0"/>
    <Int sr="arg7" val="0"/>
    </Action>
    <Action sr="act4" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%jim</Str>
    <Str sr="arg1" ve="3">([\S\s]{1900}from="\d*-\d*-\d*T21:00:00")</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="1"/>
    <Int sr="arg4" val="1"/>
    <Str sr="arg5" ve="3">%jim</Str>
    <Int sr="arg6" val="0"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act5" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%jim</Str>
    <Str sr="arg1" ve="3">max="\d*</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3">%max</Str>
    <Int sr="arg6" val="0"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act6" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%max(1)</Str>
    <Str sr="arg1" ve="3">max="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3"/>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act7" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%max(2)</Str>
    <Str sr="arg1" ve="3">max="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3"/>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act8" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%max(3)</Str>
    <Str sr="arg1" ve="3">max="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3"/>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Action sr="act9" ve="7">
    <code>598</code>
    <Str sr="arg0" ve="3">%max(4)</Str>
    <Str sr="arg1" ve="3">max="</Str>
    <Int sr="arg2" val="0"/>
    <Int sr="arg3" val="0"/>
    <Int sr="arg4" val="0"/>
    <Str sr="arg5" ve="3"/>
    <Int sr="arg6" val="1"/>
    <Str sr="arg7" ve="3"/>
    </Action>
    <Img sr="icn" ve="2">
    <nme>hd_aaa_ext_rain</nme>
    </Img>
    </Task>
    </TaskerData>

Ok, once you've saved the above, copy it to a location on your phone that's easy to find.

Fire up Tasker and long press on the "Profiles" tab. When you let go, select import and find the XML file.

The way it works right now is that it will fire at 8AM and only if it's plugged into the charger. It will only run on Monday through Friday .

Feel free to change the time, but try keep it to an on-the-hour time. I've added an extra condition of it to only fire if it's also connected to my home wifi.

Ok, now lets get started customizing it for you use: 1: Open the task and tap on the 3rd action "HTTP Get" Right now i've got the following in there:

data/2.5/forecast?q=Cape%20Town&amp;mode=xml&amp;units=metric

straight off the bat, you're going to want to change the city from "Cape%20Town" to your city name. To find your city name on OpenWeatherMap, use this page: http://openweathermap.org/find?q= If your city name has 2 or more words in it, separate them with "%20" instead of a space. "Los%20Angeles"

If you're a had-core temperature geek, you can take the "units=metric" out if you want your maximum temperature for the day to have it read to you in kelvin, otherwise, if you're, on the imperial side of things replace "metric" with "imperial".

Now the important part; At the end, enter &APPID={key} (replace {key} with the API key that you got from OpenWeatherMap.

Ok, now an explanation of the rest of the actions:

1: Changes time from "8.00" to "08" and "00"
2: Changes "08" to "8"
3: Gets the weather info and writes it to a temporary file: jim.xml (So I'm a bit vain :-p)
4: Reads that file to a variable called %jim (So I'm a bit vain, AND don't have much imagination :-p)
5: Trims that variable down from a 5-day forcast to a rest-of-the-day forcast
6: Gets the 4 maximum temps for the rest of the day and puts them in an array
7-10: Trims down the values of the array to JUST the tempratures
11: Sets the value of max(1) to a new variable "maxmax" (I know my naming sucks lack of imagination mentioned above)
12-14: If max(2) is bigger than maxmax, then sets value of max(2) to maxmax
15-17: If max(3) is bigger than maxmax, then sets value of max(3) to maxmax
18-20: If max(4) is bigger than maxmax, then sets value of max(4) to maxmax
21-23: Uses regex to pull the value of the cloud cover to variable %clouds
24-26: Uses regex to pull the value of the wind direction to variable %from
27-29: Uses regex to pull the value of the wind strength to variable %wind
30: Sets media stream volume to 10 (out of 15)
31: Reads the weather pulling the values from all the variables.

Some notes:
Tasker's array numbering starts at 1 not 0 like most programming languages. Using the Variable Search and Replace creates an array each time, so after creating it, to access it you'd have to access %var(1), not just %var.

There's probably a more efficient way of condensing the max() array down to one value to find the highest temperature, but I'm not a computer science student, so it's good enough as is. If someone else wants to make a wiki out of it to find the most optimised way of doing it, please be my guest.

I've set it to say "Good Morning, it's now 8AM"... Feel free to change the trigger time, as long as it's morning (and on the hour), it'll work fine.

Keen to see your comments and upgrades/changes you've made to this.

I've also used the IVONA TTS voice. The default android one is not as pleasant.

Jim
  • 2,243
  • 2
  • 13
  • 17
  • 1
    And I just ask my wife. No, she tells me even without asking. :-D – Wiktor Stribiżew Apr 04 '15 at 15:18
  • I appreciate the effort you've put forth, but the fact that this question and answer is too broad still applies. Why not write this up in some sort of blog post? – Jonathon Reinhart Apr 04 '15 at 15:19
  • @JonathonReinhart I wanted to share with the community where I would have expected to find it in the first place. As It wasn't here, and I managed to get it built, I felt that it would be best if i shared it here so that others who looked for it here, could find it and twist it to their weird and wonderful ways. – Jim Apr 04 '15 at 15:25
  • I've noticed that I get a "There will be clear sky today " (Poor Grammar!). So I've added the following actions in at the relevant places. `25 - IF **%clouds(1)** = _clear sky_` `26 - Variable Clear **%coulds(1)**` `27 - Variable Set **%clouds(1)** to _clear skies_` – Jim Apr 08 '15 at 10:16
1

have a look at AlarmPad app. It has great Tasker integration and a has built-in weather (among other things) check

Tomaski
  • 487
  • 3
  • 15
0

I've also just created another (and maybe an even nicer) one using the Wunderground API. (You'll need to get your free API key here: www.wunderground.com/weather/api/ and insert it in the code below where it says "Insert-API-Key-HERE" on line 281)

SUPER easy to get a key from wunderground! Sign up for a free account (they don't bug you). - LINK! (full disclosure: if you use that link, I get "raindrops" from wunderground)

This time around I'm getting the JSON instead of the XML from the site.

ALSO: ADDED BONUS! I'm now using geo-location, rather than a hard-coded city.

Tasker uses XML to import/export though, so here it is... XML:

Code moved to JSFiddle - the XML is 28,000 odd characters and then adding explanation, it brings it up to arounf 47,000 or so (that's what the error said anyway, and Stackoverflow only takes up to 30,000 characters in the answer windows.

So to take it, copy the code from the HTML window. and read the instruction in the CSS window, and ignore the output window

http://jsfiddle.net/blyzz/3os8ayo5/

Code begins and ends with:

    <TaskerData sr="" dvi="1" tv="4.6u3m">
    </TaskerData>

Let me know if you need an explanation of the actions.

Jim
  • 2,243
  • 2
  • 13
  • 17
  • 1
    Interesting although you should have posted everything as one answer, only use multiple answers if they all have a very different approach! – Trevi Awater Apr 16 '15 at 13:13