在新版谷歌協作平台嵌入edimax或lass空氣盒子讀取數值並視覺化

URL Link //n.sfs.tw/13258

2019-04-24 10:16:50 By jung

為了解決谷歌協作平台無法像一般網頁自由嵌入及編輯javascript,css樣式的問題找了很久

最近終於試出來了~幸好新版協作平台可以嵌入html語法

一開始發現台中市公發的空氣盒子位置被G0V政府公開資訊網空氣品質監測數據列表拿掉了??!!

原本用他們的js做資料讀取視覺化的方式就失效了~因為沒有對應的位置

只好開始爬文,後來發現,LASS官網有定期蒐集空氣盒子的數據並可以公開查詢

https://data.lass-net.org/data/last.php?device_id=(你的空氣盒子位址例如 74DA3895CXXX)

可以傳給你一份json檔長得像這樣

{"source": "last by IIS-NRL", "feeds": [{"AirBox2": {"gps_lat": 24.267, "gps_num": 9.0, "name": "XXXXX", "s_t0": 26.62, "area": "taichung", "gps_alt": 2.0, "timestamp": "2019-04-24T01:59:05Z", "app": "AirBox2", "gps_fix": 1.0, "s_d0_hourly_num": 9, "s_d0_hourly": 39.111111111111114, "gps_lon": 120.000, "s_d2": 28.0, "time": "01:59:05", "s_d0": 40.0, "s_d1": 51.0, "date": "2019-04-24", "s_h0": 100.0, "device_id": "74DA389XXXXXA"}}], "version": "2019-04-24T02:08:38Z", "num_of_records": 1, "device_id": "74DA3895C3AA"}

就去查這些代表的意思,再想說要怎麼解析這些數值

還好,查到某小學的xoops網站有做類似的樣式,讀到網頁原始碼後修改一下,就成功了,

特別做個紀錄並分享給需要的網友,不過如果懂得css的高手應該不會有這種初級問題:P

我這邊是沒有去改css div的命名直接照抄:P

感謝台南市進學國小校網Orz

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
  <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
		
	<script type="text/javascript" src="http://ff.kis.v2.scr.kaspersky-labs.com/42829480-C370-9940-A51E-66D94F38BBC9/main.js" charset="UTF-8"></script>
	<style type="text/css">
	body{
    color:#202020;
    background-color: #FFFFFF;
    background-image: url('');
    background-position:  ;
    background-repeat:  repeat;
    background-attachment:scroll;
    font-size:11pt;
		}
	a{
    color:#005ca8;
		}

	a:hover{
    color:#a40019;
		}

	.rightBlock .blockTitle{
    font-size:1.5em;
    color:#6bbdff ;
    background-color: transparent;
	border-radius:5px;
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
    -khtml-border-radius:5px;
      }

	.rightBlock a.block_config{
    float:right;
    position:relative;
    z-index: 1;
		}
		
    .rightBlock .blockTitle{
    border:none;height:40px;line-height:40px;margin-bottom:10px;
		}
	</style>
	</head>
	<body>
	<div class="rightBlock">
        
      <h3 class="blockTitle">AirBox</h3>

	        <div class="blockContent" style="clear:both;">
              <div id="edimax" style="text-align:center;">
	        <a href="http://taqm.epa.gov.tw/taqm/tw/PsiMap.aspx" class="media" target="_blank"
	            title="http://taqm.epa.gov.tw/taqm/tw/PsiMap.aspx" rel="nofollow"><img id="avatar" src="//www.chps.tn.edu.tw/dokuwiki/_media/ajax-loader.gif"
	                alt="" width="100" /></a>
	        <p><span id="status"></span></p>
	        <p style="font-size:1.5em;">
	            PM2.5數值:<span id="pm25" style="color:blue;font-weight:bolder;font-size:1.5em;"></span>μg/m³</p>
	        <canvas id="pm25_guage" style="width:200px;"></canvas><br>
	        <p>
	            溫度:<span id="t" style="color:blue;font-weight:bolder;font-size:1.5em;"></span>°C,溼度:
	            <span id="h" style="color:blue;font-weight:bolder;font-size:1.5em;"></span>%
	        </p>
	        最後更新時間<br><span class="" id="time"></span>
	    </div>
	

	    <script type="text/javascript" src="//bernii.github.io/gauge.js/dist/gauge.min.js"></script>
	    <script type="text/javascript" src="//code.jquery.com/jquery-latest.min.js"></script>
	    <script type="text/javascript">
	        var opts = {
	            lines: 12, // The number of lines to draw
	            angle: 0.15, // The length of each line
	            lineWidth: 0.44, // The line thickness
	            pointer:
	            {
	                length: 0.9, // The radius of the inner circle
	                strokeWidth: 0.035, // The rotation offset
	                color: '#000000' // Fill color
	            },
	            limitMax: 'false', // If true, the pointer will not go past the end of the gauge
	            colorStart: '#6FADCF', // Colors
	            colorStop: '#8FC0DA', // just experiment with them
	            strokeColor: '#E0E0E0', // to see which ones work best for you
	            generateGradient: true,
	            percentColors: [
	                [0.0, "#31cf00"],
	                [0.36, "#31cf00"],
	                [0.54, "#ff9a00"],
	                [0.71, "#990000"],
	                [1.0, "#ce30ff"]
	            ]
	        };
	    </script>
	    <script type="text/javascript">
	        function update_pm25()
	        {
	            var ts = (new Date()).getTime();
	            var mac = '74DA3895C3AA'; //your device address 空氣盒子LASS對應位址
	
	            if (location.hash) {
	                mac = location.hash;
	                mac = mac.replace(/#/, '');
	            }
	
	            $.ajax(
	            {
	                url: "https://cors.io/?" + "https://pm25.lass-net.org/data/last.php?" + $.param({
	                    device_id: mac,
	                    ts: ts
	                }),
	                dataType: "json",
	                success: function(response)
	                {
	                    console.log(response);
	
	                    var j = null;
	
	                    if (response.feeds[0].AirBox)
	                    {
	                        j = response.feeds[0].AirBox;
	                    }
	
	                    if (response.feeds[0].AirBox2)
	                    {
	                        j = response.feeds[0].AirBox2;
	                    }
	
	                    if (j) {
	                        var name = j.device;
	                        var pm25 = parseInt(j.s_d0);
	                        var t = j.s_t0;
	                        var h = j.s_h0;
	                        var time = new Date(j.timestamp);
	                        time = time.toLocaleString();
	                        var baseurl = '//www.chps.tn.edu.tw';
	                        var img = '/dokuwiki/_media/psi:1.png';
	
	                        var target = document.getElementById(
	                            'pm25_guage'); // your canvas element
	                        var gauge = new Gauge(target).setOptions(
	                            opts); // create sexy gauge!
	                        gauge.maxValue = 100; // set max gauge value
	                        gauge.animationSpeed = 32; // set animation speed (32 is default value)
	                        gauge.set(pm25); // set actual value
	
	
	                        if (pm25 < 36)
	                        { // 低
	                            img = '/dokuwiki/_media/psi:1.png';
	                            status =
	                                '<span style="color:#31cf00">空品良好適合趴趴走</span>';
	                        }
	                        else if (pm25 < 54)
	                        { // 中
	                            img = '/dokuwiki/_media/psi:2.png';
	                            status =
	                                '<span style="color:#ff9a00">可正常戶外活動,若不適者請戴口罩</span>';
	                        }
	                        else if (pm25 < 71)
	                        { // 高
	                            img = '/dokuwiki/_media/psi:3.png';
	                            status =
	                                '<span style="color:#990000">不適者減少戶外活動,敏感族群建議戴口罩</span>';
	                        }
	                        else
	                        { // 非常高
	                            img = '/dokuwiki/_media/psi:4.png';
	                            status =
	                                '<span style="color:#ce30ff">不適者減少戶外活動,敏感族群避免外出</span>';
	                        }
	
	                        $('#edimax #name').text(name);
	                        $('#edimax #pm25').text(pm25);
	                        $('#edimax #t').text(t);
	                        $('#edimax #h').text(h);
	                        $('#edimax #time').text(time);
	                        $('#edimax #avatar').attr('src', baseurl +
	                            img);
	                        $('#edimax #status').html(status);
	
	                    }
	                }
	            });
	        }
	
	        $(document).ready(function()
	        {
	            update_pm25();
	            setInterval(update_pm25, 1000 * 60 * 5);
	        });
	    </script>


	</div>
	</body>
</html>