RaspberryPiでリソースの可視化(NetData版)

提供: ディーズガレージ wiki
2017年8月10日 (木) 01:21時点におけるShogooda (トーク | 投稿記録)による版 (InfluxDB)

(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

NetData使ってみます。

主電源供給維持活動限界監視モニター

Iot-monitor.jpg

開発環境

ボード Raspberry Pi 2 Model B
OS Raspbian Jessie with PIXEL 2017-04-10
microSDHC SanDisk Ultra microSDHC Class10 8GB
LAN 標準搭載の有線LAN

ファームウェア更新

$ sudo rpi-update

再起動

$ sudo reboot

最新状態にアップデート

$ sudo apt-get update
$ sudo apt-get upgrade

再起動

$ sudo reboot

ホスト名

ホスト名変更

$ sudo leafpad /etc/hostname

変更

iot

ホスト名変更

$ sudo leafpad /etc/hosts

変更

127.0.1.1 iot

再起動

$ sudo reboot

IP固定

以降の遠隔操作でIPアドレスで接続したい場合必要な設定です。

$ sudo leafpad /etc/dhcpcd.conf

末尾に追記(設定内容は各ネットワーク環境により異なります。「Raspberry Pi Jessie IP固定」などで検索してみてください。)

interface eth0
static ip_address=192.168.1.187/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

再起動

$ sudo reboot

遠隔操作

運用にはモニター、マウス、キーボードは必要ないので、この段階で遠隔操作にしてしまいます。
Raspbian Jessie with PIXEL にはRealVNCが標準で入ってます。これを使用してみます。

デフォルトで有効になってないので

Menu→設定→RaspberryPiの設定→インターフェイスタブ→VNC有効→OK→再起動

何も考えずディスプレイを取り外しVNCに接続すると画面サイズが656x416となってしまいます。おまじないがあるようなので設定しておきます。

$ sudo leafpad /boot/config.txt
#hdmi_mode=1の下に以下を追加
hdmi_ignore_edid=0xa5000080
hdmi_group=2
hdmi_mode=47

参考: config.txt - Raspberry Pi Documentation

RaspberryPiをシャットダウン

モニター、マウス、キーボードを取り外して電源入れ直し

VNCクライアントから接続してみる
ホスト名で接続する場合、クライアントパソコンにはavahiかBonjourがインストールされている必要があります。
Windowsパソコンだけ問題になりやすく、簡単な方法はiTunesをインストールすることです。
ネット検索で「Raspberry avahi Bonjour」辺りで調べると詳しい事情が出てきます。

RealVNC Viewerの場合
VNC Server: iot.local または 192.168.1.187
Username: pi
Password: raspberry
Confirm: raspberry

成功していれば、以降はVNCクライアントの窓の中で作業できます。

インストール

NetData

参考: Installation · firehol/netdata Wiki · GitHub

$ sudo apt-get update
$ sudo apt-get install zlib1g-dev uuid-dev libmnl-dev gcc make git autoconf autoconf-archive autogen automake pkg-config curl
$ git clone https://github.com/firehol/netdata.git --depth=1
$ cd netdata
$ sudo ./netdata-installer.sh
$ sudo cp system/netdata.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable netdata
$ sudo service netdata start

設定
参考: netdata for IoT · firehol/netdata Wiki · GitHub

$ sudo leafpad /etc/netdata/netdata.conf

RPi1向け (RPi2とRP3のnetdataのチューニングは必要ないとなってます)

[global]
    history = 600
    update every = 1
    memory mode = ram
    debug log = none
    error log = none
    access log = none
[web]
    enable gzip compression = no
    gzip compression level = 1
[plugins]
    tc = no
    idlejitter = no
    cgroups = no
    apps = no
    node.d = no
    #enable running new plugins = no

sensorsプラグインを有効に(python版は動きませんでしたbash版で対応)

$ sudo leafpad /etc/netdata/charts.d.conf

アンコメント

sensors=force

再起動

$ sudo reboot

動作確認

http://127.0.0.1:19999
またはローカルネット内の他のPCから http://192.168.1.187:19999

設定項目の確認

http://127.0.0.1:19999/netdata.conf
またはローカルネット内の他のPCから http://192.168.1.187:19999/netdata.conf

nginx

参考: Running behind nginx · firehol/netdata Wiki · GitHub
参考: netdata/python.d at master · firehol/netdata · GitHub

$ sudo apt-get install nginx
$ sudo /etc/init.d/nginx start

デフォルトのシンボリックリンク削除

$ sudo unlink /etc/nginx/sites-enabled/default

設定作成 ※ /etc/nginx/nginx.confでincludeになっているのでhttp{…}ディレクティブは必要無し

$ sudo leafpad /etc/nginx/sites-available/netdata
log_format netdata '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '$request_length $request_time '
                '"$http_referer" "$http_user_agent"';

access_log /var/log/nginx/access.log netdata;

upstream backend {
    # the netdata server
    server 127.0.0.1:19999;
    keepalive 64;
}

server {
    # nginx listens to this
    listen 8081;
    
    # the virtual host name of this
    server_name netdata.example.com;

    location / {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
    }
    location /stub_status {
        stub_status on;
        access_log off;
        allow 192.168.1.0/24;
        allow 127.0.0.1;
        deny all;
    }
}

シンボリックリンク

$ sudo ln -s /etc/nginx/sites-available/netdata /etc/nginx/sites-enabled/

再起動

$ sudo reboot

動作確認

http://127.0.0.1
またはローカルネット内の他のPCから http://192.168.1.187

アップデートの自動化

インストール

$ sudo apt-get install unattended-upgrades
$ sudo dpkg-reconfigure -plow unattended-upgrades
GUIがでるので「はい」を選択

設定

$ sudo leafpad /etc/apt/apt.conf.d/50unattended-upgrades

変更箇所(セキュリティーアップデートのみ自動アップデート設定)

//      "o=Raspbian,a=stable";"o=Raspbian,a=stable";
に

//Unattended-Upgrade::Automatic-Reboot "false";
を
Unattended-Upgrade::Automatic-Reboot "true";
に

//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
を
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

再起動

$ sudo reboot

カスタマイズ

RaspberryPiでリソースの可視化(NetData版)付録参照

複数台集約

参考: Replication Overview · firehol/netdata Wiki · GitHub
参考: Monitoring ephemeral nodes · firehol/netdata Wiki · GitHub
参考: netdata のレプリケーション設定(stream) - biaxident’s blog

マスターの設定

マスターにするRaspberryPiに最低限、ホスト名IP固定NetDataのインストールnginxのインストールを設定

$ sudo leafpad /etc/netdata/stream.conf

末尾に追記

[11111111-2222-3333-4444-555555555555]
enabled = yes
default history = 600
default memory = ram
health enabled by default = auto
メモ: api keyは何でもOKとなってますがapi keyとIPアドレスが外部に漏れた場合、NetDataの脆弱を攻撃できる状況が成立すると思います。11111111-2222-3333-4444-555555555555は使わないほうが安全と思います。

再起動

$ sudo reboot

スレーブの設定

スレーブにするRaspberryPiに最低限、ホスト名NetDataのインストールを設定
スレーブが複数台なら複数台に同じ設定でOK

$ sudo leafpad /etc/netdata/stream.conf

末尾に追記(destinationはマスターの固定IPアドレス)

[stream]
enabled = yes
destination = 192.168.1.187:19999
api key = 11111111-2222-3333-4444-555555555555
$ sudo leafpad /etc/netdata/netdata.conf

書き換え

[global]
    history = 300
    update every = 1
    memory mode = none
    debug log = none
    error log = none
    access log = none
[web]
    enable gzip compression = no
    gzip compression level = 1
    mode = none
[health]
    enabled = no

再起動

$ sudo reboot

確認
マスターのIPアドレス

http://192.168.1.187

左上から機器の切り替え

IoT Monitor

主電源供給維持活動限界監視モニター

Iot-monitor.jpg

設置場所はどこでも構わないがマスターのjsonが取れる位置に居る必要あり。
スレーブのjsonはマスターのプロキシで到達できるので、マスター・スレーブ間が開通していれば考慮する必要無し。

ソースコード index.php

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png?<?php echo date("YmdHis");?>">
<link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png?<?php echo date("YmdHis");?>">
<link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png?<?php echo date("YmdHis");?>">
<link rel="manifest" href="favicon/manifest.json?<?php echo date("YmdHis");?>">
<link rel="mask-icon" href="favicon/safari-pinned-tab.svg?<?php echo date("YmdHis");?>" color="#5bbad5">
<link rel="shortcut icon" href="favicon/favicon.ico?<?php echo date("YmdHis");?>">
<meta name="msapplication-config" content="favicon/browserconfig.xml?<?php echo date("YmdHis");?>">
<meta name="theme-color" content="#ffffff">
<title>主電源供給維持活動限界監視モニター</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css?<?php echo date("YmdHis");?>" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
@font-face {
 font-family: 'AyatoNumA_eot?<?php echo date("YmdHis");?>';
 src: url('AyatoNumA.eot?<?php echo date("YmdHis");?>');
}
@font-face {
 font-family: 'AyatoNumA_ttf?<?php echo date("YmdHis");?>';
 src: url('AyatoNumA.ttf?<?php echo date("YmdHis");?>') format("truetype");
}
* {
	margin: 0;
	padding: 0;
}
html, body {
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	height: 100%;
	width: 100%;
	background-color: #262626;
	color: #fff;
	text-align: center;
}
a, a:focus, a:hover {
	outline: none;
}
.close {
	font-size: 26px;
}
.clear {
	clear: both;
}
.dummy {
	height: 40px;
}
.navbar {
	min-height:28px !important;
	margin-right: auto;
	margin-left: auto;
	background: #ffa020;
	background: -moz-linear-gradient(left,  #ffa020 0%, #fcfa2c 19%, #ffa020 100%);
	background: -webkit-linear-gradient(left,  #ffa020 0%,#fcfa2c 19%,#ffa020 100%);
	background: linear-gradient(to right,  #ffa020 0%,#fcfa2c 19%,#ffa020 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffa020', endColorstr='#528a27',GradientType=1 );
}
.navbar-nav {
	margin-top: 0;
	margin-bottom: 0;
}
.brand {
	float: left;
    height: 30px;
	padding: 7px 0 0 5px !important;
	color: #333 !important;
	font-style: normal;
	font-size: 12px;
}
.nav {
	float: right;
    height: 30px;
	font-style: normal;
	font-size: 12px;
}
.nav>li {
	float: right;
}
.nav>li>span {
	display: block;
	padding: 8px 12px 0 15px !important;
	cursor: pointer;
	color: #333 !important;
}
#smoke {
	position: fixed;
	top: 0;
	left: 0;
	opacity: 0.6;
}
.wrapper {
	display: table;
	width: 100%;
	height: 100%;
	min-height: 100%;
	opacity: 0;
	background: #0a0807;
	background: -moz-linear-gradient(top,  #0a0807 20%, #1e1b16 50%, #38352c 100%);
	background: -webkit-linear-gradient(top,  #0a0807 20%,#1e1b16 50%,#38352c 100%);
	background: linear-gradient(to bottom,  #0a0807 20%,#1e1b16 50%,#38352c 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0a0807', endColorstr='#38352c',GradientType=0 );
}
.wrapper-inner {
	display: table-cell;
	vertical-align: middle;
}
.wrapper-container, .navbar-container {
	width: 945px;
	margin-right: auto;
	margin-left: auto;
}
.brand, .hard, .hardSub, .gauge-container, .gauge, .title, .label, .units, .alert {
	-ms-user-select: none;
	-webkit-user-select: none;
	-moz-user-select: none;
	cursor: default;
	position: relative;
	z-index: 10;
}
.hardSub, .title, .units {
	/*opacity: 0.5;*/
}
.gauge-container {
	width: 105px;
	height: 105px;
	float: left;
}
.gauge {
	position: relative;
	width: 105px;
	height: 105px;
}
canvas {
	position: absolute;
	top: 0;
	left: 0;
}
.title, .label, .units {
	position: absolute;
	left: 0;
	right: 0;
}
.title {
	top: 26px;
	font-size: 11px;
	color: #907171;
}
.label {
	top: 40px;
	font-family: 'AyatoNumA_eot?<?php echo date("YmdHis");?>', 'AyatoNumA_ttf?<?php echo date("YmdHis");?>';
	font-style: normal;
	font-weight: normal;
	font-size: 20px;
	color: #ebd311;
}
.units {
	top: 66px;
	font-size: 11px;
	color: #907171;
}
.alert {
	position: absolute;
	left: 9px;
	top: 9px;
	width: 88px;
	height: 88px;
	opacity: 0;
	-webkit-border-radius: 50%;
	-moz-border-radius: 50%;
	border-radius: 50%;
	background-color: red;
}
.back {
	position: absolute;
	left: 9px;
	top: 9px;
	width: 88px;
	height: 88px;
	opacity: 0.1;
	-webkit-border-radius: 50%;
	-moz-border-radius: 50%;
	border-radius: 50%;
	background-color: gray;
}
.hard {
	float: left;
	margin-left: 5px;
	font-family: "游明朝", YuMincho, "ヒラギノ明朝 ProN W3", "Hiragino Mincho ProN", "HG明朝E", "MS P明朝", "MS 明朝", serif;
	font-style: normal;
	font-weight: bold;
	font-size: 22px;
	color: #ebd311;
}
.hardSub {
	float: left;
	margin-left: 5px;
	padding-top: 20px;
	font-style: normal;
	font-size: 14px;
	color: #907171;
}
#fullscreen {
	position: absolute;
	right: 6px;
	top: 6px;
	z-index: 10000;
	cursor: pointer;
}
.modal-content {
	font-size: 12px;
}
.modal-header {
	border-bottom: 0px solid #e5e5e5;
	padding-bottom: 0px;
}
.modal-body {
	padding: 0 20px 20px 20px;
	text-align: left;
	color: #000;
}
.modal-dialog {
	padding-top: 6%;
}
.href {
	cursor: pointer;
	color: blue;
}
.modal-body .href{
	font-weight: bold;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js?<?php echo date("YmdHis");?>"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js?<?php echo date("YmdHis");?>"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bowser/1.7.0/bowser.min.js?<?php echo date("YmdHis");?>"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/screenfull.js/3.2.2/screenfull.min.js?<?php echo date("YmdHis");?>"></script>
<script src="jquery.easypiechart.js?<?php echo date("YmdHis");?>"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js?<?php echo date("YmdHis");?>" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<script>
$(function() {
	var gaugeList = [
		{title:	'CPU',			max:	100,	from:	80,		to:	100},
		{title:	'TEMP',			max:	85,		from:	70,		to:	80},
		{title:	'Free RAM',		max:	1024,	from:	0,		to:	256},
		{title:	'IPv4 IN',		max:	100000,	from:	80000,	to:	100000},
		{title:	'IPv4 OUT',		max:	100000,	from:	80000,	to:	100000},
		{title:	'Used DISK',	max:	8,		from:	6,		to:	8},
		{title:	'Disk READ',	max:	100,	from:	80,		to:	100},
		{title:	'Disk WRITE',	max:	100,	from:	80,		to:	100},
		{title:	'SWAP',			max:	100,	from:	10,		to:	100},
		{title:	'CPU',			max:	100,	from:	80,		to:	100},
		{title:	'TEMP',			max:	85,		from:	70,		to:	80},
		{title:	'Free RAM',		max:	1024,	from:	0,		to:	256},
		{title:	'IPv4 IN',		max:	100000,	from:	80000,	to:	100000},
		{title:	'IPv4 OUT',		max:	100000,	from:	80000,	to:	100000},
		{title:	'Used DISK',	max:	8,		from:	6,		to:	8},
		{title:	'Disk READ',	max:	100,	from:	80,		to:	100},
		{title:	'Disk WRITE',	max:	100,	from:	80,		to:	100},
		{title:	'SWAP',			max:	100,	from:	10,		to:	100},
		{title:	'CPU',			max:	100,	from:	80,		to:	100},
		{title:	'TEMP',			max:	85,		from:	70,		to:	80},
		{title:	'Free RAM',		max:	512,	from:	0,		to:	128},
		{title:	'IPv4 IN',		max:	100000,	from:	80000,	to:	100000},
		{title:	'IPv4 OUT',		max:	100000,	from:	80000,	to:	100000},
		{title:	'Used DISK',	max:	8,		from:	6,		to:	8},
		{title:	'Disk READ',	max:	100,	from:	80,		to:	100},
		{title:	'Disk WRITE',	max:	100,	from:	80,		to:	100},
		{title:	'SWAP',			max:	100,	from:	10,		to:	100},
		{title:	'CPU',			max:	100,	from:	80,		to:	100},
		{title:	'TEMP',			max:	85,		from:	70,		to:	80},
		{title:	'Free RAM',		max:	1024,	from:	0,		to:	256},
		{title:	'IPv4 IN',		max:	100000,	from:	80000,	to:	100000},
		{title:	'IPv4 OUT',		max:	100000,	from:	80000,	to:	100000},
		{title:	'Used DISK',	max:	8,		from:	6,		to:	8},
		{title:	'Disk READ',	max:	100,	from:	80,		to:	100},
		{title:	'Disk WRITE',	max:	100,	from:	80,		to:	100},
		{title:	'SWAP',			max:	100,	from:	10,		to:	100}
	];
	for (var i = 0; i < gaugeList.length; i++) {
		$('#gauge' + i).easyPieChart({
			size: 105,
			maxValue: gaugeList[i].max,
			barColor: '#ebd311',
			trackColor: '#222',
			scaleColor: 'rgba(0,0,0,0)',
			scaleLength: 2,
			lineWidth: 3,
			rotate: 270,
			animate: ({
				duration: 1000,
				enabled: true
			}),
			onStep: function(from, to, currentValue) {
				$(this.el).find('.label').text(currentValue.toFixed(2));
			}
		});
	};
	var testTimer;

	function startTimer() {
		testTimer = setInterval(function() {
			$.ajax({
				url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
				type: 'GET',
				cache: false,
				dataType: 'json',
				timeout: 4000
			}).done(function(obj) {
				var checkValue = [];
				checkValue[0] = 100 - obj["system.cpu"]["dimensions"]["idle"]["value"];
				checkValue[1] = obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"];
				checkValue[2] = obj["system.ram"]["dimensions"]["free"]["value"];
				checkValue[3] = obj["system.ipv4"]["dimensions"]["InOctets"]["value"];
				checkValue[4] = Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]);
				checkValue[5] = obj["disk_space._"]["dimensions"]["used"]["value"];
				checkValue[6] = obj["system.io"]["dimensions"]["in"]["value"];
				checkValue[7] = Math.abs(obj["system.io"]["dimensions"]["out"]["value"]);
				checkValue[8] = obj["system.swap"]["dimensions"]["used"]["value"];
				$('#gauge0').data('easyPieChart').update(checkValue[0]);
				$('#gauge1').data('easyPieChart').update(checkValue[1]);
				$('#gauge2').data('easyPieChart').update(checkValue[2]);
				$('#gauge3').data('easyPieChart').update(checkValue[3]);
				$('#gauge4').data('easyPieChart').update(checkValue[4]);
				$('#gauge5').data('easyPieChart').update(checkValue[5]);
				$('#gauge6').data('easyPieChart').update(checkValue[6]);
				$('#gauge7').data('easyPieChart').update(checkValue[7]);
				$('#gauge8').data('easyPieChart').update(checkValue[8]);
				for (var i = 0; i < 9; i++) {
					if ((i == 6 || i == 7) && checkValue[i] > gaugeList[i].from) {
						//only Disk READ/WRITE
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else if (checkValue[i] > gaugeList[i].from && checkValue[i] <= gaugeList[i].to) {
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else {
						$('#gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': '#907171'
						}, 600);
						$('#gauge' + i + ' .label').animate({
							'color': '#ebd311'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = '#ebd311';
					}
				}
				checkValue.length = 0;
			});
			$.ajax({
				url: 'http://dz.plala.jp:8081/host/seti/api/v1/allmetrics?format=json',
				type: 'GET',
				cache: false,
				dataType: 'json',
				timeout: 4000
			}).done(function(obj) {
				var checkValue = [];
				checkValue[9] = 100 - obj["system.cpu"]["dimensions"]["idle"]["value"];
				checkValue[10] = obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"];
				checkValue[11] = obj["system.ram"]["dimensions"]["free"]["value"];
				checkValue[12] = obj["system.ipv4"]["dimensions"]["InOctets"]["value"];
				checkValue[13] = Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]);
				checkValue[14] = obj["disk_space._"]["dimensions"]["used"]["value"];
				checkValue[15] = obj["system.io"]["dimensions"]["in"]["value"];
				checkValue[16] = Math.abs(obj["system.io"]["dimensions"]["out"]["value"]);
				checkValue[17] = obj["system.swap"]["dimensions"]["used"]["value"];
				$('#gauge9').data('easyPieChart').update(checkValue[9]);
				$('#gauge10').data('easyPieChart').update(checkValue[10]);
				$('#gauge11').data('easyPieChart').update(checkValue[11]);
				$('#gauge12').data('easyPieChart').update(checkValue[12]);
				$('#gauge13').data('easyPieChart').update(checkValue[13]);
				$('#gauge14').data('easyPieChart').update(checkValue[14]);
				$('#gauge15').data('easyPieChart').update(checkValue[15]);
				$('#gauge16').data('easyPieChart').update(checkValue[16]);
				$('#gauge17').data('easyPieChart').update(checkValue[17]);
				for (var i = 9; i < 18; i++) {
					if ((i == 15 || i == 16) && checkValue[i] > gaugeList[i].from) {
						//only Disk READ/WRITE
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else if (checkValue[i] > gaugeList[i].from && checkValue[i] <= gaugeList[i].to) {
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else {
						$('#gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': '#907171'
						}, 600);
						$('#gauge' + i + ' .label').animate({
							'color': '#ebd311'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = '#ebd311';
					}
				}
				checkValue.length = 0;
			});
			$.ajax({
				url: 'http://dz.plala.jp:8081/host/fr24/api/v1/allmetrics?format=json',
				type: 'GET',
				cache: false,
				dataType: 'json',
				timeout: 4000
			}).done(function(obj) {
				var checkValue = [];
				checkValue[18] = 100 - obj["system.cpu"]["dimensions"]["idle"]["value"];
				checkValue[19] = obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"];
				checkValue[20] = obj["system.ram"]["dimensions"]["free"]["value"];
				checkValue[21] = obj["system.ipv4"]["dimensions"]["InOctets"]["value"];
				checkValue[22] = Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]);
				checkValue[23] = obj["disk_space._"]["dimensions"]["used"]["value"];
				checkValue[24] = obj["system.io"]["dimensions"]["in"]["value"];
				checkValue[25] = Math.abs(obj["system.io"]["dimensions"]["out"]["value"]);
				checkValue[26] = obj["system.swap"]["dimensions"]["used"]["value"];
				$('#gauge18').data('easyPieChart').update(checkValue[18]);
				$('#gauge19').data('easyPieChart').update(checkValue[19]);
				$('#gauge20').data('easyPieChart').update(checkValue[20]);
				$('#gauge21').data('easyPieChart').update(checkValue[21]);
				$('#gauge22').data('easyPieChart').update(checkValue[22]);
				$('#gauge23').data('easyPieChart').update(checkValue[23]);
				$('#gauge24').data('easyPieChart').update(checkValue[24]);
				$('#gauge25').data('easyPieChart').update(checkValue[25]);
				$('#gauge26').data('easyPieChart').update(checkValue[26]);
				for (var i = 18; i < 27; i++) {
					if ((i == 24 || i == 25) && checkValue[i] > gaugeList[i].from) {
						//only Disk READ/WRITE
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else if (checkValue[i] > gaugeList[i].from && checkValue[i] <= gaugeList[i].to) {
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else {
						$('#gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': '#907171'
						}, 600);
						$('#gauge' + i + ' .label').animate({
							'color': '#ebd311'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = '#ebd311';
					}
				}
				checkValue.length = 0;
			});
			$.ajax({
				url: 'http://dz.plala.jp:8081/host/livebot3/api/v1/allmetrics?format=json',
				type: 'GET',
				cache: false,
				dataType: 'json',
				timeout: 4000
			}).done(function(obj) {
				var checkValue = [];
				checkValue[27] = 100 - obj["system.cpu"]["dimensions"]["idle"]["value"];
				checkValue[28] = obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"];
				checkValue[29] = obj["system.ram"]["dimensions"]["free"]["value"];
				checkValue[30] = obj["system.ipv4"]["dimensions"]["InOctets"]["value"];
				checkValue[31] = Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]);
				checkValue[32] = obj["disk_space._"]["dimensions"]["used"]["value"];
				checkValue[33] = obj["system.io"]["dimensions"]["in"]["value"];
				checkValue[34] = Math.abs(obj["system.io"]["dimensions"]["out"]["value"]);
				checkValue[35] = obj["system.swap"]["dimensions"]["used"]["value"];
				$('#gauge27').data('easyPieChart').update(checkValue[27]);
				$('#gauge28').data('easyPieChart').update(checkValue[28]);
				$('#gauge29').data('easyPieChart').update(checkValue[29]);
				$('#gauge30').data('easyPieChart').update(checkValue[30]);
				$('#gauge31').data('easyPieChart').update(checkValue[31]);
				$('#gauge32').data('easyPieChart').update(checkValue[32]);
				$('#gauge33').data('easyPieChart').update(checkValue[33]);
				$('#gauge34').data('easyPieChart').update(checkValue[34]);
				$('#gauge35').data('easyPieChart').update(checkValue[35]);
				for (var i = 27; i < 36; i++) {
					if ((i == 33 || i == 34) && checkValue[i] > gaugeList[i].from) {
						//only Disk READ/WRITE
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else if (checkValue[i] > gaugeList[i].from && checkValue[i] <= gaugeList[i].to) {
						$('#gauge' + i + ' .label, #gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': 'red'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0.5'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = 'red';
					} else {
						$('#gauge' + i + ' .title, #gauge' + i + ' .units').animate({
							'color': '#907171'
						}, 600);
						$('#gauge' + i + ' .label').animate({
							'color': '#ebd311'
						}, 600);
						$('#gauge' + i + ' .alert').animate({
							'opacity': '0'
						}, 600);
						$('#gauge' + i).data('easyPieChart').options.barColor = '#ebd311';
					}
				}
				checkValue.length = 0;
			});
		}, 1000);
	};

	function stopTimer() {
		clearInterval(testTimer);
	};
	// Page Visibility API
	// https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
	// Set the name of the hidden property and the change event for visibility
	var hidden, visibilityChange;
	if (typeof document.hidden !== "undefined") {
		hidden = "hidden";
		visibilityChange = "visibilitychange";
	} else if (typeof document.msHidden !== "undefined") {
		hidden = "msHidden";
		visibilityChange = "msvisibilitychange";
	} else if (typeof document.webkitHidden !== "undefined") {
		hidden = "webkitHidden";
		visibilityChange = "webkitvisibilitychange";
	};
	if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
		console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
	} else {
		document.addEventListener(visibilityChange, handleVisibilityChange, false);
	};

	function handleVisibilityChange() {
		for (var i = 0; i < 36; i++) {
			$('#gauge' + i).data('easyPieChart').update(0);
		}
		if (document[hidden]) {
			stopTimer();
		} else {
			startTimer();
		}
	};

	function resize() {
		var windowWidth = $(window).innerWidth();
		var windowHeight = $(window).innerHeight();
		var split;
		var regulation;
		if (bowser.mobile) {
			if (windowWidth < windowHeight) {
				split = 3;
				regulation = 0;
			} else {
				split = 9;
				regulation = 18;
			}
		} else if (bowser.tablet) {
			if (windowWidth < windowHeight) {
				split = 5;
				regulation = 0;
			} else {
				split = 9;
				regulation = 18;
			}
		} else {
			split = 9;
			regulation = 18;
		}
		$(".wrapper-container, .navbar-container").css("width", $(window).innerWidth() * 0.85);
		var conatinerWidth = $(".wrapper-container").width();
		$(".gauge-container, .gauge, canvas").css({
			"width": Math.floor(conatinerWidth / split),
			"height": Math.floor(conatinerWidth / split)
		});
		$(".hard").css("font-size", Math.floor(30 * conatinerWidth / split / 105));
		$(".hardSub").css({
			"font-size": Math.floor(14 * conatinerWidth / split / 105),
			"padding-top": Math.floor(regulation * conatinerWidth / split / 105)
		});
		$(".title").css({
			"font-size": Math.floor(11 * conatinerWidth / split / 105),
			"top": Math.floor(26 * conatinerWidth / split / 105)
		});
		$(".label").css({
			"font-size": Math.floor(20 * conatinerWidth / split / 105),
			"top": Math.floor(40 * conatinerWidth / split / 105)
		});
		$(".units").css({
			"font-size": Math.floor(11 * conatinerWidth / split / 105),
			"top": Math.floor(66 * conatinerWidth / split / 105)
		});
		$(".alert, .back").css({
			"left": Math.floor(7 * conatinerWidth / split / 105),
			"top": Math.floor(8 * conatinerWidth / split / 105),
			"width": Math.floor(92 * conatinerWidth / split / 105),
			"height": Math.floor(92 * conatinerWidth / split / 105)
		});
	};
	$(window).on('resize', function() {
		resize();
	});
	$("#fullscreen").on('click', function() {
		if (screenfull.isFullscreen) {
			$(this).attr('src', $(this).attr('src').replace('_off', '_on'));
			screenfull.exit();
		} else {
			$(this).attr('src', $(this).attr('src').replace('_on', '_off'));
			screenfull.request($('html')[0]);
		}
	});
	$(".href").on('click', function() {
		if (screenfull.isFullscreen) {
			$("#fullscreen").attr('src', $("#fullscreen").attr('src').replace('_off', '_on'));
			screenfull.exit();
		}
		if ($(this).attr('id') == "wiki") {
			window.open("http://dz.plala.jp/wiki/index.php/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8", "_blank");
		} else if ($(this).attr('id') == "netdata") {
			window.open("https://my-netdata.io/", "_blank");
		} else if ($(this).attr('id') == "nginx") {
			window.open("https://nginx.org/", "_blank");
		} else if ($(this).attr('id') == "grafana") {
			window.open("https://grafana.com/", "_blank");
		} else if ($(this).attr('id') == "ayatoweb") {
			window.open("http://www.ayatoweb.com/download/down01.html", "_blank");
		}
	});
	function init() {
		if (bowser.mobile || bowser.tablet) {
			$("#fullscreen").remove();
			$(".nav").remove();
		}
		startTimer();
		resize();
		$(".wrapper").css("opacity", "1.0");
	};
	init();
	if (!bowser.mobile && !bowser.tablet) {
		// https://codepen.io/teolitto/pen/KwOVvL
		var camera, scene, renderer, geometry, material, mesh;
		threeInit();
		animate();
		function threeInit() {
			clock = new THREE.Clock();
			renderer = new THREE.WebGLRenderer({
				alpha: true
			});
			renderer.setSize(window.innerWidth, window.innerHeight);
			scene = new THREE.Scene();
			camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
			camera.position.y = 330;
			camera.position.z = 1000;
			scene.add(camera);
			
			geometry = new THREE.CubeGeometry(200, 1000, 200);
			material = new THREE.MeshLambertMaterial({
				color: 0xaa9071716,
				wireframe: false
			});
			mesh = new THREE.Mesh(geometry, material);
			
			cubeSineDriver = 0;
			light = new THREE.DirectionalLight(0xffffff, 0.9);
			light.position.set(-1.8, 0, 1);
			scene.add(light);
			
			smokeTexture = THREE.ImageUtils.loadTexture('images/Smoke-Element.png');
			smokeMaterial = new THREE.MeshLambertMaterial({
				color: 0xff6060,
				map: smokeTexture,
				transparent: true
			});
			smokeGeo = new THREE.PlaneGeometry(300, 300);
			smokeParticles = [];
			for (p = 0; p < 300; p++) {
				var particle = new THREE.Mesh(smokeGeo, smokeMaterial);
				particle.position.set(Math.random() * 1200 - 600, Math.random() * 400 - 200, Math.random() * 1000 - 100);
				particle.rotation.z = Math.random() * 360;
				scene.add(particle);
				smokeParticles.push(particle);
			}
			$("#smoke").append(renderer.domElement);
		}
		function animate() {
			delta = clock.getDelta();
			requestAnimationFrame(animate);
			evolveSmoke();
			render();
		}
		function evolveSmoke() {
			var sp = smokeParticles.length;
			while (sp--) {
				smokeParticles[sp].rotation.z -= (delta * 0.2);
			}
		}
		function render() {
			mesh.rotation.x += 0.005;
			mesh.rotation.y += 0.01;
			cubeSineDriver += .01;
			mesh.position.z = 100 + (Math.sin(cubeSineDriver) * 500);
			renderer.render(scene, camera);
		}
		$(window).resize(function() {
			windowWidth = $(window).innerWidth();
			windowHeight = $(window).innerHeight();
			camera.aspect = windowWidth / windowHeight;
			camera.updateProjectionMatrix();
			renderer.setSize(windowWidth, windowHeight);
		});
	}
});
</script>
</head>
<body>
<div id="smoke"></div>
<div class="wrapper">
	<div class="wrapper-inner">
		<div class="wrapper-container">
			<nav class="navbar navbar-fixed-top">
				<div class="navbar-container">
					<div class="brand">主電源供給維持活動限界監視モニター</div>
					<ul class="nav navbar-nav">
						<li><span id ="wiki" class="href">WIKI</span></li>
						<li><span data-toggle="modal" data-target="#myModal">FEATURES</span></li>
					</ul>
				</div>
			</nav>
			<div class="dummy"></div>
			<div class="hard">指令本部中央制御装置</div>
			<div class="hardSub">Raspberry Pi 2 Model B v1.1 a01041 (Sony, UK)</div>
			<div class="clear"></div>
			<div class="gauge-container">
				<div id="gauge0" class="gauge"> <span class="title">CPU</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge1" class="gauge"> <span class="title">TEMP</span> <span class="label"></span> <span class="units">°C</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge2" class="gauge"> <span class="title">Free RAM</span> <span class="label"></span> <span class="units">MB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge3" class="gauge"> <span class="title">IPv4 IN</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge4" class="gauge"> <span class="title">IPv4 OUT</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge5" class="gauge"> <span class="title">Used DISK</span> <span class="label"></span> <span class="units">GB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge6" class="gauge"> <span class="title">Disk READ</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge7" class="gauge"> <span class="title">Disk WRITE</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge8" class="gauge"> <span class="title">SWAP</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="clear"></div>
			<div class="hard">地球外知的生命体探査装置</div>
			<div class="hardSub">Raspberry Pi 2 Model B v1.1 a01041 (Sony, UK)</div>
			<div class="clear"></div>
			<div class="gauge-container">
				<div id="gauge9" class="gauge"> <span class="title">CPU</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge10" class="gauge"> <span class="title">TEMP</span> <span class="label"></span> <span class="units">°C</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge11" class="gauge"> <span class="title">Free RAM</span> <span class="label"></span> <span class="units">MB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge12" class="gauge"> <span class="title">IPv4 IN</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge13" class="gauge"> <span class="title">IPv4 OUT</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge14" class="gauge"> <span class="title">Used DISK</span> <span class="label"></span> <span class="units">GB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge15" class="gauge"> <span class="title">Disk READ</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge16" class="gauge"> <span class="title">Disk WRITE</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge17" class="gauge"> <span class="title">SWAP</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="clear"></div>
			<div class="hard">航空機追跡非常事態検出装置</div>
			<div class="hardSub">Raspberry Pi 1 Model B+ 0010</div>
			<div class="clear"></div>
			<div class="gauge-container">
				<div id="gauge18" class="gauge"> <span class="title">CPU</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge19" class="gauge"> <span class="title">TEMP</span> <span class="label"></span> <span class="units">°C</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge20" class="gauge"> <span class="title">Free RAM</span> <span class="label"></span> <span class="units">MB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge21" class="gauge"> <span class="title">IPv4 IN</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge22" class="gauge"> <span class="title">IPv4 OUT</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge23" class="gauge"> <span class="title">Used DISK</span> <span class="label"></span> <span class="units">GB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge24" class="gauge"> <span class="title">Disk READ</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge25" class="gauge"> <span class="title">Disk WRITE</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge26" class="gauge"> <span class="title">SWAP</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="clear"></div>
			<div class="hard">映像送出装置</div>
			<div class="hardSub">Raspberry Pi 3 Model B a02082 (Sony, UK)</div>
			<div class="clear"></div>
			<div class="gauge-container">
				<div id="gauge27" class="gauge"> <span class="title">CPU</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge28" class="gauge"> <span class="title">TEMP</span> <span class="label"></span> <span class="units">°C</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge29" class="gauge"> <span class="title">Free RAM</span> <span class="label"></span> <span class="units">MB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge30" class="gauge"> <span class="title">IPv4 IN</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge31" class="gauge"> <span class="title">IPv4 OUT</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge32" class="gauge"> <span class="title">Used DISK</span> <span class="label"></span> <span class="units">GB</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge33" class="gauge"> <span class="title">Disk READ</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge34" class="gauge"> <span class="title">Disk WRITE</span> <span class="label"></span> <span class="units">Kbps</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
			<div class="gauge-container">
				<div id="gauge35" class="gauge"> <span class="title">SWAP</span> <span class="label"></span> <span class="units">%</span> <span class="alert"></span> <span class="back"></span></div>
			</div>
		</div>
	</div>
</div>
<img id="fullscreen" src="images/fullscreen_on.png">
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
	<div class="modal-dialog" role="document">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
			</div>
			<div class="modal-body">
				<div style="line-height:14px;margin-top:0;"> <span class="glyphicon glyphicon-th-large" aria-hidden="true" style="margin-right:2px;margin-bottom:6px;"></span>主電源供給維持活動限界監視システム<br />
					IoT機器を<span id ="netdata" class="href">NetData</span>で監視、<span id ="nginx" class="href">nginx</span>で集約ビジュアル化、<span id ="grafana" class="href">Grafana</span>で記録管理解析するシステムです。<br />
					<br />
					Code licensed MIT, docs CC BY 4.0.<br />
					Copyright © 2017 shogooda (shogo.gfx@gmail.com) All rights reserved.
				</div>
			</div>
		</div>
	</div>
</div>
</body>
</html>

ファビコン

http://dz.plala.jp/wiki_data/favicons.zip

その他

http://dz.plala.jp/iot-monitor/jquery.easypiechart.js
http://dz.plala.jp/iot-monitor/images/fullscreen_off.png
http://dz.plala.jp/iot-monitor/images/fullscreen_on.png
http://dz.plala.jp/iot-monitor/images/Smoke-Element.png

Grafana

複数台集約したマスターにGrafanaをインストールしてみます。

NetData

参考: netdata backends · firehol/netdata Wiki · GitHub

$ sudo leafpad /etc/netdata/netdata.conf
[backend]
    enabled = yes
    data source = average
    type = opentsdb
    destination = localhost:4242
    prefix = netdata
    hostname = iot
    update every = 10
    buffer on failures = 10
    timeout ms = 20000

再起動

$ sudo reboot

InfluxDB

参考: InfluxData | Documentation | Installation

$ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
$ source /etc/os-release
$ test $VERSION_ID = "7" && echo "deb https://repos.influxdata.com/debian wheezy stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
$ test $VERSION_ID = "8" && echo "deb https://repos.influxdata.com/debian jessie stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
$ sudo apt-get update && sudo apt-get install influxdb
$ sudo service influxdb start
$ sudo leafpad /etc/influxdb/influxdb.conf

末尾に追記

[[opentsdb]]
    enabled = true
    bind-address = ":4242"
    database = "netdata"

再起動

$ sudo reboot

保存期間の設定

$ influx
# 作成済みのデータベース確認
> SHOW DATABASES

# ポリシーtrafficを設定(1週間保存し古いものは自動的に削除)
> CREATE RETENTION POLICY traffic ON netdata DURATION 1w REPLICATION 1 DEFAULT

# ポリシーの確認
> SHOW RETENTION POLICIES ON "netdata"

# ポリシー変更
> ALTER RETENTION POLICY traffic ON netdata DURATION 2h

# 終了
> exit

再起動

$ sudo reboot

Grafana

参考: fg2it/grafana-on-raspberry Wiki · GitHub

For raspberry pi 1, use

$ sudo apt-get install adduser libfontconfig
$ sudo apt-get install apt-transport-https curl

$ curl https://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add -
$ echo "deb https://dl.bintray.com/fg2it/deb-rpi-1b jessie main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
$ sudo apt-get update
$ sudo apt-get install grafana
$ sudo systemctl enable grafana-server
$ sudo systemctl start grafana-server

For raspberry pi 2 and pi 3, use

$ sudo apt-get install adduser libfontconfig
$ sudo apt-get install apt-transport-https curl

$ curl https://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add -
$ echo "deb https://dl.bintray.com/fg2it/deb jessie main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
$ sudo apt-get update
$ sudo apt-get install grafana
$ sudo systemctl enable grafana-server
$ sudo systemctl start grafana-server

再起動

$ sudo reboot

Grafana起動

http://127.0.0.1:3000
またはローカルネット内の他のPCから http://192.168.1.187:3000
User: admin
Password: admin

Home Dashboardが表示されます。
Grafana左上アイコン→Data Sources→Add data source

Grafana-002.jpg

Dashboard for netdataのインポート

https://grafana.com/dashboards/1295
Dashboard for netdata. Netdata used as collector and InfluxDB as data source.
Just change yourhostname in json file and you ready to go!

NetDataのダッシュボード。Netdataはコレクタとして使用され、InfluxDBはデータソースとして使用されます。
jsonファイルのyourhostnameを変更するだけで準備が整っています。

jsonの書き換えがややこしい部分があるので書き換え済jsonはこちら

http://dz.plala.jp/wiki_data/yourhostname_rev1.json

iotというホスト名にしてるのでテキストエディターなどで全て置換してしまえば他の名前でも使用できると予想します。

Grafana左上アイコン→Dashboards→Import
Upload .json Fileでファイル選択
InfluxDBにnetdata指定しImportボタン Grafana-005.jpg

InfluxDBに全てのスレーブのデータも登録されてます。
yourhostname_rev1.jsonのiotを他のスレーブ名に書き換え全てインポート

消費電力の設定

参考: Raspberry Pi 3 Model B の消費電力削減 - Rabbit Note

USB電源をOFF(VNCで操作すると接続が切れてしまいます。ご注意。)

$ sudo sh -c "echo 0 > /sys/devices/platform/soc/20980000.usb/buspower"
または
$ sudo sh -c "echo 0 > /sys/devices/platform/soc/3f980000.usb/buspower"
ONにする場合は0を1に

HDMI電源をOFF

$ sudo /opt/vc/bin/tvservice -o
ONにする場合
$ sudo /opt/vc/bin/tvservice -p

再起動

$ sudo reboot

メモリの節約

参考: Raspberry メモリ 節約 - Google

デーモンの停止

$ sudo apt-get install chkconfig
$ #sudo chkconfig dbus off
$ sudo chkconfig triggerhappy off
$ sudo chkconfig alsa-utils off
$ sudo chkconfig lightdm off
$ sudo chkconfig motd off
$ sudo chkconfig plymouth off

topコマンド見るとXorg(デスクトップ環境)がいちばんメモリを消費しています。停止してみます。
※この操作するとVNCが機能しないように見えます。復帰にはモニター、マウス、キーボード必要です。

Menu→設定→RaspberryPiの設定→システムタブ→ブート→CLIにチェック→再起動

Xorg(デスクトップ環境)復帰方法

電源OFF
モニター、マウス、キーボードを取り付け
電源ON
コマンドプロンプトの状態
$ sudo startx
デスクトップ環境起動
Menu→設定→RaspberryPiの設定→システムタブ→ブート→デスクトップにチェック→シャットダウン
モニター、マウス、キーボード取り外し
電源ON
VNCなどで接続

アップデート

参考: Installation · firehol/netdata Wiki · GitHub

$ cd ~
$ cd netdata
$ sudo ./netdata-updater.sh

このスクリプトを使用すると、最初にインストールしたのと同じオプションで更新できます。だそうです。

再起動

$ sudo reboot

参考