2020年11月22日 星期日

如何取得空氣品質指標(AQI)的 資料-1

  如何取得空氣品質指標(AQI)的 資料-1

把網址複製下來
http://opendata.epa.gov.tw/webapi/Data/REWIQA/?$orderby=SiteName&$skip=0&$top=1000&format=json




[{"id":"b2948675.b83368","type":"inject","z":"46b6a476.64e92c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"20","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":460,"y":200,"wires":[["c64b8198.77d79"]]},{"id":"6913086a.1f0ab8","type":"function","z":"46b6a476.64e92c","name":"","func":"var PM25,Status,PublishTime;\n\nArray.from(msg.payload).forEach(function(e,i){    \n          if(e.SiteName=='大里'){        \n              PM25 = {payload:Number(e['PM2.5'])};                    \n              Status={payload:e['Status']};        \n              PublishTime={payload:e['PublishTime']};       \n }\n});\n\nreturn [PM25,Status,PublishTime];\n","outputs":3,"noerr":0,"initialize":"","finalize":"","x":750,"y":200,"wires":[["7672ede0.cd9e34","69bab252.132a3c"],["4de6518d.692fc"],["ce2b124.c566ff"]]},{"id":"7672ede0.cd9e34","type":"debug","z":"46b6a476.64e92c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":950,"y":140,"wires":[]},{"id":"c64b8198.77d79","type":"http request","z":"46b6a476.64e92c","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://opendata.epa.gov.tw/webapi/Data/REWIQA/?$orderby=SiteName&$skip=0&$top=1000&format=json","tls":"","persist":false,"proxy":"","authType":"","x":600,"y":200,"wires":[["6913086a.1f0ab8","3ce3191a.22ed56"]]},{"id":"4de6518d.692fc","type":"ui_text","z":"46b6a476.64e92c","group":"91d3cfc5.c30bb","order":1,"width":0,"height":0,"name":"","label":"空氣品質","format":"{{msg.payload}}","layout":"row-left","x":940,"y":220,"wires":[]},{"id":"ce2b124.c566ff","type":"ui_text","z":"46b6a476.64e92c","group":"91d3cfc5.c30bb","order":2,"width":0,"height":0,"name":"","label":"發佈時間","format":"{{msg.payload}}","layout":"row-left","x":940,"y":260,"wires":[]},{"id":"69bab252.132a3c","type":"ui_gauge","z":"46b6a476.64e92c","name":"","group":"91d3cfc5.c30bb","order":0,"width":0,"height":0,"gtype":"gage","title":"細懸浮微粒PM2.5","label":"units","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":970,"y":180,"wires":[]},{"id":"3ce3191a.22ed56","type":"debug","z":"46b6a476.64e92c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":770,"y":120,"wires":[]},{"id":"91d3cfc5.c30bb","type":"ui_group","z":"","name":"IAQI","tab":"2e8eb9a2.9f45f6","order":4,"disp":true,"width":"12","collapse":false},{"id":"2e8eb9a2.9f45f6","type":"ui_tab","z":"","name":"Weather","icon":"Dashboard","disabled":false,"hidden":false}]

如何取得空氣品質指標(AQI)的 資料-2

 如何取得空氣品質指標(AQI)的 資料-2


1.把網址複製下來
http://opendata.epa.gov.tw/webapi/Data/REWIQA/?$orderby=SiteName&$skip=0&$top=1000&format=json










[{"id":"dc90cfbe.e2b6","type":"inject","z":"43607cdf.baa3c4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"20","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":140,"y":100,"wires":[["dad3bb72.537b98"]]},{"id":"dad3bb72.537b98","type":"http request","z":"43607cdf.baa3c4","name":"PM2.5網頁","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://opendata.epa.gov.tw/webapi/Data/REWIQA/?$orderby=SiteName&$skip=0&$top=1000&format=json","tls":"","persist":false,"proxy":"","authType":"","x":310,"y":100,"wires":[["d12c35f2.583118","4f03b293.3286dc"]]},{"id":"4f03b293.3286dc","type":"function","z":"43607cdf.baa3c4","name":"設定地區","func":"//var a = msg.payload;\n\n//Array.from(a).forEach (function(e,i){\n //   if(e.SiteName=='大里'){\n   //     msg.PM251 =  Number(e['PM2.5']) ;\n   //     msg.AQI1 =  e['AQI'] ;\n//        msg.Status1 = e['Status'] ;\n  //      msg.PublishTime1 = e['PublishTime'] ;\n //  }\n//} );\n//return msg;\n\nvar a = msg.payload;\n a.forEach(function(e,i){\n    if(e.SiteName=='大里'){\n        msg.PM25 = e['PM2.5'];\n        msg.AQI =  e['AQI'] ;\n        msg.Status = e['Status'] ;\n        msg.PublishTime = e['PublishTime'] ;\n    } \n});\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":260,"wires":[["8e42bc6a.2a973","966d2b54.0d01a8","c1b4d57c.161ad8","ce923dca.5b23","3a6efb72.b33a94"]]},{"id":"4b6bd135.05a34","type":"comment","z":"43607cdf.baa3c4","name":"台灣空氣品質狀況","info":"","x":140,"y":60,"wires":[]},{"id":"b60b259.2ab8cd8","type":"ui_gauge","z":"43607cdf.baa3c4","name":"","group":"5b49355a.5225bc","order":0,"width":"6","height":"3","gtype":"gage","title":"PM2.5 [0..35] 良好","label":"units","format":"{{value}}","min":0,"max":"80","colors":["#00b500","#e6e600","#ca3838"],"seg1":"35","seg2":"53","x":910,"y":240,"wires":[],"inputLabels":["msg.PM25"]},{"id":"b1fe3fad.6b864","type":"ui_text","z":"43607cdf.baa3c4","group":"5b49355a.5225bc","order":0,"width":"6","height":"2","name":"","label":"空氣品質","format":"{{msg.payload}}","layout":"row-spread","x":880,"y":360,"wires":[],"inputLabels":["msg.payload"]},{"id":"8e42bc6a.2a973","type":"function","z":"43607cdf.baa3c4","name":"PM2.5 [0..80]","func":"msg.payload=msg.PM25;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":700,"y":240,"wires":[["b60b259.2ab8cd8","fb753537.724298"]]},{"id":"966d2b54.0d01a8","type":"function","z":"43607cdf.baa3c4","name":"AQI [0..400]","func":"msg.payload= msg.AQI;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":690,"y":300,"wires":[["ea3227e4.5147a8"]]},{"id":"ea3227e4.5147a8","type":"ui_gauge","z":"43607cdf.baa3c4","name":"","group":"5b49355a.5225bc","order":0,"width":"6","height":"3","gtype":"gage","title":"AQI [0..50] 良好","label":"units","format":"{{value}}","min":0,"max":"400","colors":["#00b500","#e6e600","#ca3838"],"seg1":"50","seg2":"100","x":900,"y":300,"wires":[],"inputLabels":["msg.PM25"]},{"id":"c1b4d57c.161ad8","type":"function","z":"43607cdf.baa3c4","name":"Status","func":"msg.payload=msg.Status;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":670,"y":360,"wires":[["b1fe3fad.6b864"]]},{"id":"ce923dca.5b23","type":"function","z":"43607cdf.baa3c4","name":"PublishTime","func":"msg.payload=msg.PublishTime;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":690,"y":420,"wires":[["c17d919c.f57f8"]]},{"id":"c17d919c.f57f8","type":"ui_text","z":"43607cdf.baa3c4","group":"5b49355a.5225bc","order":0,"width":"6","height":"3","name":"","label":"發表時間","format":"{{msg.payload}}","layout":"row-spread","x":880,"y":420,"wires":[],"inputLabels":["msg.payload"]},{"id":"d12c35f2.583118","type":"debug","z":"43607cdf.baa3c4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":80,"wires":[]},{"id":"fb753537.724298","type":"debug","z":"43607cdf.baa3c4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":900,"y":180,"wires":[]},{"id":"3a6efb72.b33a94","type":"debug","z":"43607cdf.baa3c4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":180,"wires":[]},{"id":"5b49355a.5225bc","type":"ui_group","z":"","name":"空氣品質狀況","tab":"bf5462b1.4d02a","order":1,"disp":true,"width":"6","collapse":false},{"id":"bf5462b1.4d02a","type":"ui_tab","z":"","name":"Weather","icon":"dashboard","order":1}]




2020年11月3日 星期二

MQTT與Mqtt Dashboard - IoT and Node-RED controller APP設定

 MQTT與Mqtt Dashboard - IoT and Node-RED controller APP設定


載點



FRED中的litedb 無法使用SQLite

 What is FRED litedb

源自於http://noderedguide.com/tutorial-sqlite-and-node-red/

The Front End for Node-RED (FRED) manages instances of Node-RED for multiple users in the cloud. We manage and optimize your instance of Node RED so you worry about accomplishing your project, not setting up and maintaining your Node-RED instance.


About Sense Tecnic: Sense Tecnic Systems Inc have been building IoT applications and services since 2010. We provide FRED, cloud hosted Node-RED as a service to the community. We also offer a commercial version to our customers, as well as professional services. Learn more.


Create a FRED Account

To get started, create your own Node-RED instance in the cloud. Register for a free account at http://fred.sensetecnic.com.

After registering, make sure to activate your account via your email. You will not be able to login until you validate your account.

Installing the litedb node

First, you will need to ensure that you have installed the litedb node since it is not installed by default in FRED. After you register for FRED, or after you login, you will be presented with the FRED dashboard.

In the management panel, click “Add or Remove Nodes“, and find the litedb node.



Make sure the litedb node is installed for your instance. If the box beside ‘litedb’ is empty in your Nodes list, just simply check the box and restart your instance.

Make sure you start your instance by hitting the start button.  If it is already started, stop, and start it to ensure the new litedb node is available.  Create a new tab to start with an empty canvas.

Once the litedb node is installed, you should see the litedb node in your left panel. Drag a litedb node to the empty canvas, and we are ready to move on. You can also name the litedb node however you like by double clicking on the node to open the configuration dialog if you like.



For demo purposes, we are going to create a table and inject random numbers at a constant time interval. We will also look at how to view and manage this data later on.

Creating your first table

As documented on the info tab of litedb, the node takes in SQL queries in the input msg.topic, and then returns responses in the output msg.payload. To create a table to store some data, all we need to do is send the appropriate SQL command to the litedb node. A simple way to do that is to connect an inject node to the litedb node with the following settings:



where in the topic field, we have the query

CREATE TABLE RANDOMNUM( TIMESTAMP INT PRIMARY KEY NOT NULL, VALUE INT NOT NULL, BOOL INT NOT NULL)

As you can see, this demo table is called “RANDOMNUM“, and it has three columns, TIMESTAMP( Primary key column ), VALUE, and BOOL. (We will use BOOL to store an attribute which indicates if the number is larger than 50 or not) These three columns are all set to NOT NULL and with type INT.

Once you are done, connect a debug node to the litedb node, and deploy the current settings. Hit the inject button, and you should see that RANDOMNUM is created.



Inserting Data

We can use the same method to send an SQLite query to the database to inject a new value into the table.

Let’s set up another inject node that injects a new timestamp every 15 seconds simulating a sensor event. Followed by a function node, we will write a query with the input of the timestamp, and send the insertion query to the litedb node.

First, drag a new inject node, and add these settings.




then, let’s connect this timestamp node to a function node.



We name the function node “write query” and we define the code inside the function node would be as follows:

var randomNum = Math.round(Math.random()*100);
var largeBool = (randomNum > 50)?1:0;
var newMsg = {
 "topic": "INSERT INTO RANDOMNUM VALUES ( " + msg.payload + ", " + randomNum + ", " + largeBool + ")"
}

return newMsg;

In the above code, a new record is inserted into RANDOMNUM with a timestamp as its primary key, a randomly generated value (ranged from 0 to 100), and a boolean value as if the number is larger than 50. Notice that there is no actual boolean data type in SQLite, so we represented boolean as either 0 or 1.

Then, we can just connect the function node to the litedb node as follow. Once you hit deploy, the inject node will start inserting new records to the table.



Selecting from database

To see the records from our table, we can set up another new inject node, with this in the settings:




where the Topic field is

SELECT * FROM RANDOMNUM ORDER BY TIMESTAMP DESC LIMIT 100;

As you can see, we are showing the first 100 records in table RANDOMNUM ordered by the TIMESTAMP column in descending order.

After you deploy the nodes, and inject the SELECT query command, you should see something like this as the output of the debug node:

SELECT * FROM RANDOMNUM ORDER BY TIMESTAMP DESC LIMIT 100; : msg.payload : array [1][ { "TIMESTAMP": 1472684511852, "VALUE": 5, "BOOL": 0 } ]

Controlling the size of your database

If you follow this guide, you will notice how we set up an inject node that injects records in 15s intervals. In real world scenarios, the database grows in size and may eventually affect the performance of servers. In addition, and as mentioned above, the litedb node has a limit of 4Mb in size. Here we will show you an example of how to delete older records that you do not want to keep.

We will set up another new inject node, and call it ‘delete’. For this example, it will run the  delete query every minute, to remove the data that is older than 1 hour.



where the query in Topic field is

DELETE FROM RANDOMNUM WHERE TIMESTAMP <= strftime('%s','now', '-1 hours')*1000

Notice that, the timestamp generated from the inject node is UNIX epoch time in milliseconds, but the default timestamp return from the SQLite function strftime() is in seconds. That’s why we need to multiply 1000 at the end.

As you can see here, we use a modifier, ‘-1 hours’, to specify the time interval of data that we want to keep. In our case, this inject query means that we want to clean data that is one hour old every minute. We choose 1 hour in this case just for demo purpose. You can use different modifiers to suit your application, more info on the function strftime() and the modifiers can be found in: https://www.sqlite.org/lang_datefunc.html

While you are trying this deletion node, you can also set up an inject node to count the size of the table with this query

SELECT COUNT(*) FROM RANDOMNUM

Don’t forget to connect the inject nodes to the litedb node in order to send the query command into SQLite!

Now sit back and see how the node clears out the old data for you in the debug tab.

Visualizing data

Users are able to visualize the data by using the dashboard nodes. You can refer to the tutorial in A Node-RED dashboard using node-red-contrib-dashboard for more information on how to do this.  In this tutorial, we will show you another trick to visualize the data in a table form.

From the previous exercises, we know that when we send

SELECT * FROM RANDOMNUM ORDER BY TIMESTAMP DESC LIMIT 100;

into the litedb node, it returns an array of records in the response, we can simply use the ui template node to parse the information we want.

For example, we would like to have a table showing the first 20 records, just simply connect the template UI node to the litedb node:



in the template node, enter the following code:

<table style="width:100%">
  <tr>
    <th>Index</th> 
    <th>Timestamp</th>
    <th>Value</th> 
    <th>Bool</th>
  </tr>
  <tr ng-repeat="x in msg.payload | limitTo:20">
    <td>{{$index}}</td>
    <td>{{msg.payload[$index].TIMESTAMP}}</td>
    <td>{{msg.payload[$index].VALUE}}</td> 
    <td>{{msg.payload[$index].BOOL}}</td>
  </tr>
</table>

and it looks like this in the config tab:



This code simply generates a table in HTML, and places the index, TIMESTAMP, VALUE and BOOL fields from  msg.payload into the appropriate cells of the table. It then repeats for the next 19 records (using ng-repeat & limitTo). You can set up the table however you like. Once you deploy the nodes, the UI template node will update the table whenever SELECT * is sent to the litedb node, and an array of records are returned from the litedb node to the UI template node. The resulting table would look like this when you hit the URL https://{REPLACE-WITH-YOUR-USERNAME}.fred.sensetecnic.com/api/ui:



This covers basic usage of the litedb node. Although the example in this guide just stores random generated numbers into the database, you can grab data from any data source and insert it into the database, and query it any way you like. For more information on specific SQLite queries, see https://www.sqlite.org/lang.html

2020年11月2日 星期一

OPEN Data 一般天氣預報-今明36小時天氣預報 (2)

OPEN Data 一般天氣預報-今明36小時天氣預報 (2)



[{"id":"8abd1a6c.6ad2d8","type":"http request","z":"264d5d13.d975e2","name":"temp request","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://opendata.cwb.gov.tw/govdownload?dataid=F-C0032-001&authorizationkey=rdec-key-123-45678-011121314","tls":"","persist":false,"proxy":"","authType":"","x":270,"y":60,"wires":[["c28517d2.b6e0f8"]]},{"id":"fcbb2f33.46db3","type":"function","z":"264d5d13.d975e2","name":"set global temp","func":"\nglobal.set(\"tempera\",msg.payload); //global.set\nreturn msg;\n\n//flow.set('YourVariable', value);    // to store a variable (YourVariable)\n//var x = flow.get('YourVariable'); //to retrieve a variable (YourVariable)","outputs":1,"noerr":0,"initialize":"","finalize":"","x":560,"y":60,"wires":[["40b86a9f.b563f4","f723747e.27ae28"]]},{"id":"c28517d2.b6e0f8","type":"xml","z":"264d5d13.d975e2","name":"","property":"payload","attr":"","chr":"","x":410,"y":60,"wires":[["fcbb2f33.46db3"]]},{"id":"babf39d4.21fac8","type":"function","z":"264d5d13.d975e2","name":"List locationname","func":"//var rawdata=context.global.temp;\nvar rawdata = global.get(\"tempera\");\n//flow.set(\"loname\",rawdata.cwbopendata.dataset[0].location.locationName);\nvar location=rawdata.cwbopendata.dataset[0].location;\nvar citynumber=location.length;\nvar cityarray=[];\nvar i;\nfor (i=0; i<citynumber;i++)\n{\ncityarray[i]=location[i].locationName[0];\n}\n\n msg.payload=cityarray;\nflow.set(\"loname\",cityarray);\nreturn msg;\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":120,"wires":[["45b1349f.2bf14c"]]},{"id":"45b1349f.2bf14c","type":"debug","z":"264d5d13.d975e2","name":"List all locationnames ","active":true,"console":"false","complete":"payload","x":700,"y":120,"wires":[]},{"id":"c4866409.85b638","type":"debug","z":"264d5d13.d975e2","name":"report result","active":true,"console":"false","complete":"payload","x":650,"y":360,"wires":[]},{"id":"4c9b36f2.7c5ff8","type":"function","z":"264d5d13.d975e2","name":"set options","func":"var rawdata =global.get(\"tempera\");\nvar location=rawdata.cwbopendata.dataset[0].location;\nvar citynumber=location.length;\nvar i;\n\nvar cityarray=[];\nfor (i=0; i<citynumber;i++)\n{\ncityarray[i]=location[i].locationName[0];\n\n\n}\nmsg.options=cityarray;\nreturn msg;\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":290,"y":240,"wires":[["900535b7.7cc6c8","fad9a24b.5509a"]]},{"id":"420b0ab1.ea7e84","type":"function","z":"264d5d13.d975e2","name":"city to number","func":"\nvar cityname;\ncontext.global.locationnumber=0;\ntry {\n   cityname=msg.payload;\n   \n   if(cityname.indexOf('台北')!=-1 ||cityname.indexOf('臺北')!=-1 )\n{\n    context.global.locationnumber=0;\n   \n}\nelse if(cityname.indexOf('新北')!=-1)\n{\n    context.global.locationnumber=1;\n   \n}\nelse if(cityname.indexOf('桃園')!=-1) //\n{\n    context.global.locationnumber=2;\n   \n}\nelse if(cityname.indexOf('臺中')!=-1 || cityname.indexOf('台中')!=-1) \n{\n    context.global.locationnumber= 3;\n   \n}\nelse if(cityname.indexOf('臺南')!=-1 || cityname.indexOf('台南')!=-1) \n{\n    context.global.locationnumber= 4;\n   \n}\nelse if(cityname.indexOf('高雄')!=-1 ) \n{\n    context.global.locationnumber= 5 ;\n   \n}\nelse if(cityname.indexOf('基隆')!=-1 ) \n{\n    context.global.locationnumber= 6 ;\n   \n}\nelse if(cityname.indexOf('新竹縣')!=-1 ) \n{\n    context.global.locationnumber= 7 ;\n   \n}\nelse if(cityname.indexOf('新竹')!=-1 ) \n{\n    context.global.locationnumber= 8 ;\n   \n}\nelse if(cityname.indexOf('連江')!=-1 ) \n{\n    context.global.locationnumber= 21 ;\n   \n}\nelse  \n{\n    context.global.locationnumber= 0 ;\n   \n}\n   \n   \n}\ncatch(err) {\n    cityname=\"台北\";\n    context.global.locationnumber=0;\n}\n\n\n msg.payload= context.global.locationnumber;\nreturn msg;\n","outputs":1,"noerr":0,"x":300,"y":420,"wires":[[]]},{"id":"2889e479.e0982c","type":"function","z":"264d5d13.d975e2","name":"report","func":"var loc=msg.payload;\n//var rawdata=context.global.temp;\nvar rawdata = global.get(\"tempera\");\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload=locationName+starthour+\"到\"+endhour+\"點溫度最低\"+period0min+\"度最高\"+period0max+\"度\";\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":360,"wires":[["c4866409.85b638","9fc656d9.f34b58"]]},{"id":"630a9213.ad888c","type":"debug","z":"264d5d13.d975e2","name":"selected city ","active":true,"tosidebar":true,"console":false,"complete":"payload","x":670,"y":280,"wires":[]},{"id":"900535b7.7cc6c8","type":"ui_dropdown","z":"264d5d13.d975e2","name":"","label":"city options","tooltip":"","place":"Select city","group":"31745d9a.412202","order":0,"width":0,"height":0,"passthru":true,"multiple":true,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"","x":470,"y":280,"wires":[["630a9213.ad888c","c11b28f7.345f28"]]},{"id":"9fc656d9.f34b58","type":"ui_text","z":"264d5d13.d975e2","group":"31745d9a.412202","order":0,"width":0,"height":0,"name":"","label":"","format":"{{msg.payload}}","layout":"row-spread","x":650,"y":400,"wires":[]},{"id":"40b86a9f.b563f4","type":"debug","z":"264d5d13.d975e2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":60,"wires":[]},{"id":"fad9a24b.5509a","type":"debug","z":"264d5d13.d975e2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"options","targetType":"msg","x":470,"y":220,"wires":[]},{"id":"c11b28f7.345f28","type":"function","z":"264d5d13.d975e2","name":"city name to number","func":"\nvar rawdata = global.get(\"tempera\");\n\n//context.global.locationnumber=0;\nflow.set(\"locationnumber\",0);\ntry {\n   cityname=msg.payload;\n   \n   if(cityname.indexOf('台北市市')!=-1 ||cityname.indexOf('臺北市')!=-1 )\n{\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n   \n}\nelse if(cityname.indexOf('新北市')!=-1)\n{\n    //context.global.locationnumber=1;\n    flow.set(\"locationnumber\",1);\n}\nelse if(cityname.indexOf('桃園市')!=-1) //\n{\n    //context.global.locationnumber=2;\n    flow.set(\"locationnumber\",2);\n}\nelse if(cityname.indexOf('臺中市')!=-1 || cityname.indexOf('台中市')!=-1) \n{\n    //context.global.locationnumber= 3;\n    flow.set(\"locationnumber\",3);\n}\nelse if(cityname.indexOf('臺南市')!=-1 || cityname.indexOf('台南市')!=-1) \n{\n    //context.global.locationnumber= 4;\n    flow.set(\"locationnumber\",4);\n   \n}\nelse if(cityname.indexOf('高雄市')!=-1 ) \n{\n    //context.global.locationnumber= 5 ;\n    flow.set(\"locationnumber\",5);\n   \n}\nelse if(cityname.indexOf('基隆市')!=-1 ) \n{\n    //context.global.locationnumber= 6 ;\n    flow.set(\"locationnumber\",6);\n}\nelse if(cityname.indexOf('新竹縣')!=-1 ) \n{\n    //context.global.locationnumber= 7 ;\n    flow.set(\"locationnumber\",7);\n}\nelse if(cityname.indexOf('新竹市')!=-1 ) \n{\n    //context.global.locationnumber= 8 ;\n    flow.set(\"locationnumber\",8);\n}\nelse if(cityname.indexOf('苗栗縣')!=-1 ) \n{\n    //context.global.locationnumber= 9 ;\n    flow.set(\"locationnumber\",9);\n}\nelse if(cityname.indexOf('彰化縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",10);\n}\nelse if(cityname.indexOf('南投縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",11);\n}\nelse if(cityname.indexOf('雲林縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",12);\n}\nelse if(cityname.indexOf('嘉義縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",13);\n}\nelse if(cityname.indexOf('嘉義市')!=-1 ) \n{\n      flow.set(\"locationnumber\",14);\n}\nelse if(cityname.indexOf('屏東縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",15);\n}\nelse if(cityname.indexOf('宜蘭縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",16);\n}\nelse if(cityname.indexOf('花蓮縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",17);\n}\nelse if(cityname.indexOf('臺東縣')!=-1 || cityname.indexOf('台東縣')!=-1)\n{\n      flow.set(\"locationnumber\",18);\n}\nelse if(cityname.indexOf('澎湖縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",19);\n}\nelse if(cityname.indexOf('金門縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",20);\n}\nelse if(cityname.indexOf('連江')!=-1 ) \n{\n    //context.global.locationnumber= 21 ;\n    flow.set(\"locationnumber\",21);\n}\nelse  \n{\n   // context.global.locationnumber= 0 ;\n    flow.set(\"locationnumber\",0);\n}\n   \n   \n}\ncatch(err) {\n    cityname=\"台北市\";\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n}\n\nmsg.payload= flow.get(\"locationnumber\");\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":360,"wires":[["2889e479.e0982c","d30425d1.ba6148"]]},{"id":"d30425d1.ba6148","type":"debug","z":"264d5d13.d975e2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":490,"y":420,"wires":[]},{"id":"e7c0839.b79c38","type":"ui_button","z":"264d5d13.d975e2","name":"","group":"31745d9a.412202","order":2,"width":0,"height":0,"passthru":false,"label":"START","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":100,"y":60,"wires":[["8abd1a6c.6ad2d8"]]},{"id":"f723747e.27ae28","type":"function","z":"264d5d13.d975e2","name":"show raw data","func":"//flow.set('YourVariable', value);    // to store a variable (YourVariable)\n//var x = flow.get('YourVariable'); //to retrieve a variable (YourVariable)\n//var loc=msg.payload.loc;\n\nvar rawdata = global.get(\"tempera\"); //global.get\n//msg.playload=rawdata.cwbopendata.dataset[0].location;\nmsg.payload=rawdata;\nreturn msg;\n\n/*\nmsg.payload = rawdata;\nreturn msg;\n*/\n\n//msg.playload=rawdata;\n//.cwbopendata.dataset[0].location;\n\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":260,"y":120,"wires":[["babf39d4.21fac8"]]},{"id":"8af50820.b49298","type":"ui_button","z":"264d5d13.d975e2","name":"","group":"31745d9a.412202","order":2,"width":0,"height":0,"passthru":false,"label":"Inject City Option","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":110,"y":240,"wires":[["4c9b36f2.7c5ff8"]]},{"id":"31745d9a.412202","type":"ui_group","z":"","name":"Default","tab":"1d173c13.e2dc64","order":1,"disp":true,"width":"6"},{"id":"1d173c13.e2dc64","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}] 

OPEN Data 一般天氣預報-今明36小時天氣預報

 OPEN Data 一般天氣預報-今明36小時天氣預報 

https://opendata.cwb.gov.tw/dataset/forecast?page=26













Node-Red程式

[{"id":"e2a597f2.5a2028","type":"http request","z":"9e0666d0.5d85d8","name":"temp request","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://opendata.cwb.gov.tw/govdownload?dataid=F-C0032-001&authorizationkey=rdec-key-123-45678-011121314","tls":"","persist":false,"proxy":"","authType":"","x":290,"y":60,"wires":[["93225e9a.c5e85","8e7740ac.f38ae"]]},{"id":"3cab233d.9d39bc","type":"inject","z":"9e0666d0.5d85d8","name":"","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"7200","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":100,"y":40,"wires":[["e2a597f2.5a2028"]]},{"id":"93225e9a.c5e85","type":"debug","z":"9e0666d0.5d85d8","name":"temp request result","active":true,"console":"false","complete":"payload","x":489,"y":42,"wires":[]},{"id":"296f470e.a36b48","type":"debug","z":"9e0666d0.5d85d8","name":"xml to json","active":true,"console":"false","complete":"payload","x":585,"y":76,"wires":[]},{"id":"f1596a96.3702e8","type":"function","z":"9e0666d0.5d85d8","name":"set global temp","func":"\nglobal.set(\"tempera\",msg.payload); //global.set\nreturn msg;\n\n//flow.set('YourVariable', value);    // to store a variable (YourVariable)\n//var x = flow.get('YourVariable'); //to retrieve a variable (YourVariable)","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":120,"wires":[["b18aa7dc.97fa38"]]},{"id":"8e7740ac.f38ae","type":"xml","z":"9e0666d0.5d85d8","name":"","property":"payload","attr":"","chr":"","x":438,"y":100,"wires":[["f1596a96.3702e8","296f470e.a36b48"]]},{"id":"ebfbb129.bf4d9","type":"http in","z":"9e0666d0.5d85d8","name":"city","url":"/city","method":"get","upload":false,"swaggerDoc":"","x":84,"y":347,"wires":[["a9155ec8.9dfa8"]]},{"id":"26cd0e87.5ccee2","type":"http response","z":"9e0666d0.5d85d8","name":"http out","x":606,"y":347,"wires":[]},{"id":"a9155ec8.9dfa8","type":"function","z":"9e0666d0.5d85d8","name":"city name to number","func":"\nvar rawdata = flow.get(\"tempera\");\n\n//context.global.locationnumber=0;\nflow.set(\"locationnumber\",0);\ntry {\n   cityname=msg.payload.cityname;\n   \n   if(cityname.indexOf('台北')!=-1 ||cityname.indexOf('臺北')!=-1 )\n{\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n   \n}\nelse if(cityname.indexOf('新北')!=-1)\n{\n    //context.global.locationnumber=1;\n    flow.set(\"locationnumber\",1);\n}\nelse if(cityname.indexOf('桃園')!=-1) //\n{\n    //context.global.locationnumber=2;\n    flow.set(\"locationnumber\",2);\n}\nelse if(cityname.indexOf('臺中')!=-1 || cityname.indexOf('台中')!=-1) \n{\n    //context.global.locationnumber= 3;\n    flow.set(\"locationnumber\",3);\n}\nelse if(cityname.indexOf('臺南')!=-1 || cityname.indexOf('台南')!=-1) \n{\n    //context.global.locationnumber= 4;\n    flow.set(\"locationnumber\",4);\n   \n}\nelse if(cityname.indexOf('高雄')!=-1 ) \n{\n    //context.global.locationnumber= 5 ;\n    flow.set(\"locationnumber\",5);\n   \n}\nelse if(cityname.indexOf('基隆')!=-1 ) \n{\n    //context.global.locationnumber= 6 ;\n    flow.set(\"locationnumber\",6);\n}\nelse if(cityname.indexOf('新竹縣')!=-1 ) \n{\n    //context.global.locationnumber= 7 ;\n    flow.set(\"locationnumber\",7);\n}\nelse if(cityname.indexOf('新竹')!=-1 ) \n{\n    //context.global.locationnumber= 8 ;\n    flow.set(\"locationnumber\",8);\n}\nelse if(cityname.indexOf('新竹')!=-1 ) \n{\n    //context.global.locationnumber= 8 ;\n    flow.set(\"locationnumber\",8);\n}\nelse if(cityname.indexOf('苗栗')!=-1 ) \n{\n    //context.global.locationnumber= 9 ;\n    flow.set(\"locationnumber\",9);\n}\nelse if(cityname.indexOf('彰化')!=-1 ) \n{\n      flow.set(\"locationnumber\",10);\n}\nelse if(cityname.indexOf('南投')!=-1 ) \n{\n      flow.set(\"locationnumber\",11);\n}\nelse if(cityname.indexOf('雲林')!=-1 ) \n{\n      flow.set(\"locationnumber\",12);\n}\nelse if(cityname.indexOf('嘉義縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",13);\n}\nelse if(cityname.indexOf('嘉義市')!=-1 ) \n{\n      flow.set(\"locationnumber\",14);\n}\nelse if(cityname.indexOf('屏東')!=-1 ) \n{\n      flow.set(\"locationnumber\",15);\n}\nelse if(cityname.indexOf('宜蘭')!=-1 ) \n{\n      flow.set(\"locationnumber\",16);\n}\nelse if(cityname.indexOf('宜蘭')!=-1 ) \n{\n      flow.set(\"locationnumber\",16);\n}\nelse if(cityname.indexOf('花蓮')!=-1 ) \n{\n      flow.set(\"locationnumber\",17);\n}\nelse if(cityname.indexOf('臺東')!=-1 || cityname.indexOf('台東')!=-1)\n{\n      flow.set(\"locationnumber\",18);\n}\nelse if(cityname.indexOf('澎湖')!=-1 ) \n{\n      flow.set(\"locationnumber\",19);\n}\nelse if(cityname.indexOf('金門')!=-1 ) \n{\n      flow.set(\"locationnumber\",20);\n}\nelse if(cityname.indexOf('連江')!=-1 ) \n{\n    //context.global.locationnumber= 21 ;\n    flow.set(\"locationnumber\",21);\n}\nelse  \n{\n   // context.global.locationnumber= 0 ;\n    flow.set(\"locationnumber\",0);\n}\n   \n   \n}\ncatch(err) {\n    cityname=\"台北\";\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n}\n\nmsg.payload= flow.get(\"locationnumber\");\nreturn msg;\n","outputs":1,"noerr":0,"x":264,"y":347,"wires":[["b31b5479.d36c88","cd3e6364.df367"]]},{"id":"b31b5479.d36c88","type":"debug","z":"9e0666d0.5d85d8","name":"city name to number result","active":true,"console":"false","complete":"payload","x":520,"y":296,"wires":[]},{"id":"d2584f90.da37c","type":"http in","z":"9e0666d0.5d85d8","name":"tempjson","url":"/tempjson","method":"get","upload":false,"swaggerDoc":"","x":80,"y":160,"wires":[["b6bd4e75.0426a"]]},{"id":"5eb83680.9781c8","type":"http response","z":"9e0666d0.5d85d8","name":"http out","x":460,"y":160,"wires":[]},{"id":"b6bd4e75.0426a","type":"function","z":"9e0666d0.5d85d8","name":"show raw data","func":"//flow.set('YourVariable', value);    // to store a variable (YourVariable)\n//var x = flow.get('YourVariable'); //to retrieve a variable (YourVariable)\n//var loc=msg.payload.loc;\n\nvar rawdata = global.get(\"tempera\"); //global.get\n//msg.playload=rawdata.cwbopendata.dataset[0].location;\nmsg.payload=rawdata;\nreturn msg;\n\n/*\nmsg.payload = rawdata;\nreturn msg;\n*/\n\n//msg.playload=rawdata;\n//.cwbopendata.dataset[0].location;\n\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":260,"y":160,"wires":[["5eb83680.9781c8","ee08400c.2c901"]]},{"id":"ee08400c.2c901","type":"debug","z":"9e0666d0.5d85d8","name":"temp data process","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":200,"wires":[]},{"id":"88d691a1.3e90e","type":"function","z":"9e0666d0.5d85d8","name":"List locationname","func":"//var rawdata=context.global.temp;\nvar rawdata = flow.get(\"tempera\");\n//flow.set(\"loname\",rawdata.cwbopendata.dataset[0].location.locationName);\nvar location=rawdata.cwbopendata.dataset[0].location;\nvar citynumber=location.length;\nvar cityarray=[];\nvar i;\nfor (i=0; i<citynumber;i++)\n{\ncityarray[i]=location[i].locationName[0];\n}\n\n msg.payload=cityarray;\nflow.set(\"loname\",cityarray);\nreturn msg;\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"x":308,"y":255,"wires":[["f7bef722.c86c88"]]},{"id":"f7bef722.c86c88","type":"debug","z":"9e0666d0.5d85d8","name":"List all locationnames ","active":true,"console":"false","complete":"payload","x":527,"y":255,"wires":[]},{"id":"cd3e6364.df367","type":"function","z":"9e0666d0.5d85d8","name":"max min","func":"var loc=msg.payload;\nvar rawdata = flow.get(\"tempera\");\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"x":462,"y":347,"wires":[["26cd0e87.5ccee2"]]},{"id":"ec8ae7ac.285248","type":"debug","z":"9e0666d0.5d85d8","name":"report result","active":true,"console":"false","complete":"payload","x":670,"y":460,"wires":[]},{"id":"e90965f.3974498","type":"inject","z":"9e0666d0.5d85d8","name":"inject city options","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"7200","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":130,"y":420,"wires":[["11e741e8.e89aee"]]},{"id":"11e741e8.e89aee","type":"function","z":"9e0666d0.5d85d8","name":"set options","func":"var rawdata = flow.get(\"tempera\");\nvar location=rawdata.cwbopendata.dataset[0].location;\nvar citynumber=location.length;\nvar i;\n\nvar cityarray=[];\nfor (i=0; i<citynumber;i++)\n{\ncityarray[i]=location[i].locationName[0];\n\n\n}\nmsg.options=cityarray;\nreturn msg;\n\n/*\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload={\"locationName\":locationName,\"time\":starthour+\"-\"+endhour, \"max\":period0max,\n\"min\":period0min};\nreturn msg;\n*/\n\n/*if(time.getHours()<18)\n{\nmsg.payload={\"locationName\":locationName,\"todaymax\":period1max, \"todaymin\":period1min,\n             \"tonightmax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\nelse\nmsg.payload={\"locationName\":locationName,\"tonightmax\":period1max, \"tonightmin\":period1min,\n             \"todaymax\":period2max, \"tonightmin\":period2min,\"tomorrowmax\":period3max, \"tomorrowmin\":period3min};\n}\n\n*/\n\n\n\n\n//msg.payload=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[1];\n\n\n\n\n","outputs":1,"noerr":0,"x":310,"y":420,"wires":[["a18b45c8.73bea8","894c9f8e.3cd3a"]]},{"id":"70bc72e0.26993c","type":"inject","z":"9e0666d0.5d85d8","name":"inject city","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":108,"y":255,"wires":[["88d691a1.3e90e"]]},{"id":"517b0460.ee94cc","type":"function","z":"9e0666d0.5d85d8","name":"city to number","func":"\nvar cityname;\ncontext.global.locationnumber=0;\ntry {\n   cityname=msg.payload;\n   \n   if(cityname.indexOf('台北')!=-1 ||cityname.indexOf('臺北')!=-1 )\n{\n    context.global.locationnumber=0;\n   \n}\nelse if(cityname.indexOf('新北')!=-1)\n{\n    context.global.locationnumber=1;\n   \n}\nelse if(cityname.indexOf('桃園')!=-1) //\n{\n    context.global.locationnumber=2;\n   \n}\nelse if(cityname.indexOf('臺中')!=-1 || cityname.indexOf('台中')!=-1) \n{\n    context.global.locationnumber= 3;\n   \n}\nelse if(cityname.indexOf('臺南')!=-1 || cityname.indexOf('台南')!=-1) \n{\n    context.global.locationnumber= 4;\n   \n}\nelse if(cityname.indexOf('高雄')!=-1 ) \n{\n    context.global.locationnumber= 5 ;\n   \n}\nelse if(cityname.indexOf('基隆')!=-1 ) \n{\n    context.global.locationnumber= 6 ;\n   \n}\nelse if(cityname.indexOf('新竹縣')!=-1 ) \n{\n    context.global.locationnumber= 7 ;\n   \n}\nelse if(cityname.indexOf('新竹')!=-1 ) \n{\n    context.global.locationnumber= 8 ;\n   \n}\nelse if(cityname.indexOf('連江')!=-1 ) \n{\n    context.global.locationnumber= 21 ;\n   \n}\nelse  \n{\n    context.global.locationnumber= 0 ;\n   \n}\n   \n   \n}\ncatch(err) {\n    cityname=\"台北\";\n    context.global.locationnumber=0;\n}\n\n\n msg.payload= context.global.locationnumber;\nreturn msg;\n","outputs":1,"noerr":0,"x":320,"y":560,"wires":[[]]},{"id":"dc9079fa.d1aee8","type":"function","z":"9e0666d0.5d85d8","name":"report","func":"var loc=msg.payload;\n//var rawdata=context.global.temp;\nvar rawdata = flow.get(\"tempera\");\nvar locationName=rawdata.cwbopendata.dataset[0].location[loc].locationName[0];\nvar period0max=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].parameter[0].parameterName[0];\nvar period0min=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[2].time[0].parameter[0].parameterName[0];\nvar period0start=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].startTime[0];\nvar period0end=rawdata.cwbopendata.dataset[0].location[loc].weatherElement[1].time[0].endTime[0];\n\nvar  starthourtemp= period0start.split(\"T\");\nvar starthour=starthourtemp[1].split(\":\")[0];\nvar  endhourtemp= period0end.split(\"T\");\nvar endhour=endhourtemp[1].split(\":\")[0];\n\nmsg.payload=locationName+starthour+\"到\"+endhour+\"點溫度最低\"+period0min+\"度最高\"+period0max+\"度\";\nreturn msg;\n","outputs":1,"noerr":0,"x":510,"y":500,"wires":[["ec8ae7ac.285248","fe250f8d.81b3"]]},{"id":"9911ba2a.5bf128","type":"debug","z":"9e0666d0.5d85d8","name":"selected city ","active":true,"tosidebar":true,"console":false,"complete":"payload","x":670,"y":420,"wires":[]},{"id":"a18b45c8.73bea8","type":"ui_dropdown","z":"9e0666d0.5d85d8","name":"","label":"city options","tooltip":"","place":"Select city","group":"31745d9a.412202","order":0,"width":0,"height":0,"passthru":true,"multiple":true,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"","x":470,"y":420,"wires":[["9911ba2a.5bf128","facaa184.1e408"]]},{"id":"fe250f8d.81b3","type":"ui_text","z":"9e0666d0.5d85d8","group":"31745d9a.412202","order":0,"width":0,"height":0,"name":"","label":"","format":"{{msg.payload}}","layout":"row-spread","x":650,"y":520,"wires":[]},{"id":"b18aa7dc.97fa38","type":"debug","z":"9e0666d0.5d85d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":120,"wires":[]},{"id":"894c9f8e.3cd3a","type":"debug","z":"9e0666d0.5d85d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"options","targetType":"msg","x":490,"y":380,"wires":[]},{"id":"facaa184.1e408","type":"function","z":"9e0666d0.5d85d8","name":"city name to number","func":"\nvar rawdata = flow.get(\"tempera\");\n\n//context.global.locationnumber=0;\nflow.set(\"locationnumber\",0);\ntry {\n   cityname=msg.payload;\n   \n   if(cityname.indexOf('台北市市')!=-1 ||cityname.indexOf('臺北市')!=-1 )\n{\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n   \n}\nelse if(cityname.indexOf('新北市')!=-1)\n{\n    //context.global.locationnumber=1;\n    flow.set(\"locationnumber\",1);\n}\nelse if(cityname.indexOf('桃園市')!=-1) //\n{\n    //context.global.locationnumber=2;\n    flow.set(\"locationnumber\",2);\n}\nelse if(cityname.indexOf('臺中市')!=-1 || cityname.indexOf('台中市')!=-1) \n{\n    //context.global.locationnumber= 3;\n    flow.set(\"locationnumber\",3);\n}\nelse if(cityname.indexOf('臺南市')!=-1 || cityname.indexOf('台南市')!=-1) \n{\n    //context.global.locationnumber= 4;\n    flow.set(\"locationnumber\",4);\n   \n}\nelse if(cityname.indexOf('高雄市')!=-1 ) \n{\n    //context.global.locationnumber= 5 ;\n    flow.set(\"locationnumber\",5);\n   \n}\nelse if(cityname.indexOf('基隆市')!=-1 ) \n{\n    //context.global.locationnumber= 6 ;\n    flow.set(\"locationnumber\",6);\n}\nelse if(cityname.indexOf('新竹縣')!=-1 ) \n{\n    //context.global.locationnumber= 7 ;\n    flow.set(\"locationnumber\",7);\n}\nelse if(cityname.indexOf('新竹市')!=-1 ) \n{\n    //context.global.locationnumber= 8 ;\n    flow.set(\"locationnumber\",8);\n}\nelse if(cityname.indexOf('苗栗縣')!=-1 ) \n{\n    //context.global.locationnumber= 9 ;\n    flow.set(\"locationnumber\",9);\n}\nelse if(cityname.indexOf('彰化縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",10);\n}\nelse if(cityname.indexOf('南投縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",11);\n}\nelse if(cityname.indexOf('雲林縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",12);\n}\nelse if(cityname.indexOf('嘉義縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",13);\n}\nelse if(cityname.indexOf('嘉義市')!=-1 ) \n{\n      flow.set(\"locationnumber\",14);\n}\nelse if(cityname.indexOf('屏東縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",15);\n}\nelse if(cityname.indexOf('宜蘭縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",16);\n}\nelse if(cityname.indexOf('花蓮縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",17);\n}\nelse if(cityname.indexOf('臺東縣')!=-1 || cityname.indexOf('台東縣')!=-1)\n{\n      flow.set(\"locationnumber\",18);\n}\nelse if(cityname.indexOf('澎湖縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",19);\n}\nelse if(cityname.indexOf('金門縣')!=-1 ) \n{\n      flow.set(\"locationnumber\",20);\n}\nelse if(cityname.indexOf('連江')!=-1 ) \n{\n    //context.global.locationnumber= 21 ;\n    flow.set(\"locationnumber\",21);\n}\nelse  \n{\n   // context.global.locationnumber= 0 ;\n    flow.set(\"locationnumber\",0);\n}\n   \n   \n}\ncatch(err) {\n    cityname=\"台北市\";\n    //context.global.locationnumber=0;\n    flow.set(\"locationnumber\",0);\n}\n\nmsg.payload= flow.get(\"locationnumber\");\nreturn msg;\n","outputs":1,"noerr":0,"x":320,"y":500,"wires":[["dc9079fa.d1aee8","c5fefb6d.2bfa38"]]},{"id":"c5fefb6d.2bfa38","type":"debug","z":"9e0666d0.5d85d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":560,"wires":[]},{"id":"ba78b990.fb2548","type":"ui_button","z":"9e0666d0.5d85d8","name":"","group":"31745d9a.412202","order":2,"width":0,"height":0,"passthru":false,"label":"START","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":120,"y":100,"wires":[["e2a597f2.5a2028"]]},{"id":"3187f9f1.fe0816","type":"ui_button","z":"9e0666d0.5d85d8","name":"","group":"31745d9a.412202","order":2,"width":0,"height":0,"passthru":false,"label":"Inject City","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":100,"y":300,"wires":[["88d691a1.3e90e"]]},{"id":"82e61f0e.cb58f","type":"ui_button","z":"9e0666d0.5d85d8","name":"","group":"31745d9a.412202","order":2,"width":0,"height":0,"passthru":false,"label":"Inject City Option","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":130,"y":460,"wires":[["11e741e8.e89aee"]]},{"id":"31745d9a.412202","type":"ui_group","z":"","name":"Default","tab":"1d173c13.e2dc64","order":1,"disp":true,"width":"6"},{"id":"1d173c13.e2dc64","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

  清除項目編譯快取 執行 flutter clean 重新取得套件依賴 執行 flutter pub get 完整重新編譯並執行 flutter run 1. 新增專案套件 (pubspec.yaml) 在 Flutter 專案根目錄下的 pubspec.yaml 中,新增 ...