如何让我每天早上读到天气?

How do I get the weather read to me each morning?

我想在我的 Android phone 上创建一个应用程序来告诉我每天早上的天气已经有一段时间了,并且找到了很多很多网站告诉你如何去做,但是其中 none 确实使编辑任务变得容易 - 没有真正的文档。此外,有些链接有下载任务或配置文件的链接,但它们要么是死链接,要么按原样提供,没有任何解释。

所以我已经做到了。

好的,经过数小时的搜索、挖掘和 Tasker 游戏,更不用说构建正则表达式以使其正常工作了……我做到了,让它正常工作。

第 1 步:从 http://openweathermap.org/ 获取免费的 API 密钥。他们限制您每 10 分钟只能使用一次 window,但由于我们每天只使用一次,这远远超出了我们的需要。

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>

好的,保存以上内容后,将其复制到 phone 上容易找到的位置。

启动 Tasker 并长按 "Profiles" 选项卡。松开后,select 导入并找到 XML 文件。

它现在的工作方式是它会在早上 8 点启动,并且只有在插入充电器时才会启动。它只会在星期一到星期五 运行。

您可以随意更改时间,但请尽量保持在整点时间。我为它添加了一个额外的条件,只有当它也连接到我家的 wifi 时才会触发。

好的,现在让我们开始定制它以供您使用: 1:打开任务,点击第三个动作"HTTP Get" 现在我有以下内容:

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

一开始,您想要将城市从 "Cape%20Town" 更改为您的城市名称。要在 OpenWeatherMap 上查找您的城市名称,请使用此页面:http://openweathermap.org/find?q= 如果您的城市名称中包含 2 个或更多单词,请使用“%20”而不是 space 将它们分隔开。 "Los%20Angeles"

如果你是核心温度极客,如果你想让当天的最高温度以开尔文为单位读给你,你可以把 "units=metric" 去掉,否则,如果你, 在帝国方面,将 "metric" 替换为 "imperial".

现在是重要的部分;最后,输入 &APPID={key}(将 {key} 替换为您从 OpenWeatherMap 获得的 API 密钥。

好的,现在解释其余的操作:

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.

一些注意事项:
与大多数编程语言一样,Tasker 的数组编号从 1 而不是 0 开始。使用变量搜索和替换每次都会创建一个数组,因此在创建它之后,要访问它,您必须访问 %var(1),而不仅仅是 %var.

可能有一种更有效的方法可以将 max() 数组压缩为一个值以找到最高温度,但我不是计算机科学专业的学生,​​所以它已经足够好了。如果有人想用它做一个 wiki 来找到最优化的方法,请成为我的客人。

我已经设置为"Good Morning, it's now 8AM"...触发时间随意更改,只要是早上(和整点),它就可以正常工作。

很想看到您的评论和upgrades/changes您对此所做的评论。

我也用过 IVONA TTS 语音。默认的 android 不是那么令人愉快。

我还刚刚使用 Wunderground API 创建了另一个(也许更好)。 (您需要在此处获取免费的 API 密钥:www.wunderground.com/weather/api/ 并将其插入下方代码中第 281 行 "Insert-API-Key-HERE" 的位置)

从 wunderground 获得钥匙超级容易!注册一个免费帐户(他们不会打扰您)。 - LINK!(完全披露:如果你使用那个 link,我会从 wunderground 得到 "raindrops")

这一次我从网站上得到的是 JSON 而不是 XML。

另外:额外奖励!我现在使用的是地理位置,而不是硬编码的城市。

Tasker 使用 XML 到 import/export,所以这里是... XML:

代码移至 JSFiddle - XML 是 28,000 个奇数字符,然后添加解释,它使它达到 47,000 左右(反正错误就是这么说的,而 Whosebug 最多只需要 30,000 个字符在答案中 windows.

所以要获取它,请从 HTML window 复制代码。并读取 CSS window 中的指令,并忽略输出 window

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

代码开始和结束于:

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

如果您需要对操作的解释,请告诉我。

看看 AlarmPad 应用程序。它有很好的 Tasker 集成和内置天气(除其他外)检查