RaspberryPiでnetdata

提供: ディーズガレージ wiki
移動先: 案内検索

IoT MONITOR 別窓

Iot-monitor.jpg Iot-monitor-iphone.jpg Iot-monitor-ipad.jpg

環境

ボード Raspberry Pi 2 Model B
OS Raspbian Stretch with desktop 2019-04-08
ストレージ SanDisk Ultra microSDHC 16GB
LAN 標準搭載の有線LAN

具合

  • rebootでnginxが停止してる sudo service nginx restartで起動はする
  • rebootでTSL2561が動かないことがある python tsl2561.pyをたたけば動き出す
  • DashboardがFirefoxで重い
  • Dashboardのeasy-pie-chartをレスポンシブなリサイズに対応させていない
GPIO 50mAまで
BME280 3.6μA
TSL2561 0.5mA
PocketGeiger 10mA

準備

OS

省略

IP固定

$ sudo nano /etc/dhcpcd.conf

末尾に追記

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

保存: Ctrl + o > リターン
終了: Ctrl + x

再起動

$ sudo reboot

ホスト名

Menu > 設定 > Raspberry Piの設定 > システムタブ > ホスト名
iot
OK > 再起動

遠隔操作

運用にモニター、マウス、キーボードは必要ないので遠隔操作にする
標準で入っているRealVNCを使用

VNC有効

Menu > 設定 > Raspberry Piの設定 > インターフェイスタブ > VNC有効 > OK

解像度の変更

Menu > 設定 > Raspberry Piの設定 > システムタブ > 解像度 > 1280x960程度 > OK > 再起動

シャットダウンし、モニター、マウス、キーボードを取り外して電源入れ直し
WindowsPCなどのVNCクライアントから接続を試す
成功していれば、以降はVNCクライアントの窓の中で作業

Install

参考: Installation - Netdata Documentation

$ bash <(curl -Ss https://my-netdata.io/kickstart.sh)
  It will be installed at these locations:
   - the daemon     at /usr/sbin/netdata
   - config files   in /etc/netdata
   - web files      in /usr/share/netdata
   - plugins        in /usr/libexec/netdata
   - cache files    in /var/cache/netdata
   - db files       in /var/lib/netdata
   - log files      in /var/log/netdata
   - pid file       at /var/run/netdata.pid
   - logrotate file at /etc/logrotate.d/netdata

設定

$ sudo /etc/netdata/edit-config netdata.conf

参考: Running netdata in embedded devices - Netdata Documentation

[global]
           history = 600
           memory mode = ram
         # debug log = /var/log/netdata/debug.log
         # error log = /var/log/netdata/error.log
         # access log = /var/log/netdata/access.log
           debug log = none
           error log = none
           access log = none
[web]
           enable gzip compression = no
[plugins]
           cgroups = no
           tc = no
           idlejitter = no

保存: Ctrl + o リターン
終了: Ctrl + x

温度センサー
参考: Netdata for IoT - Netdata Documentation

$ sudo /etc/netdata/edit-config charts.d.conf

#コメント消去

sensors=force

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999

Replication

参考: Streaming and replication - Netdata Documentation
Raspberry Piにはuuidgenが無い様子
APIキーは単なるランダムなGUID
デフォルトを使用 11111111-2222-3333-4444-555555555555

Master

MasterにするRaspberry Piに最低限、ホスト名、IP固定、netdataのインストールを設定

$ sudo /etc/netdata/edit-config stream.conf

設定

# [API_KEY] is [YOUR-API-KEY], i.e [11111111-2222-3333-4444-555555555555]
[11111111-2222-3333-4444-555555555555]
   enabled = yes
   allow from = *
   default history = 3600
   default memory mode = ram
   health enabled by default = auto

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999

Slave

SlaveにするRaspberry Piに最低限、ホスト名、netdataのインストールを設定
Slaveが複数台なら複数台に同じ設定

$ sudo /etc/netdata/edit-config stream.conf

設定

[stream]
    enabled = yes
    destination = 192.168.1.187:19999
    api key = 11111111-2222-3333-4444-555555555555

保存: Ctrl + o リターン
終了: Ctrl + x

$ sudo /etc/netdata/edit-config netdata.conf

設定

[global]
          history = 600
          memory mode = none
          debug log = none
          error log = none
          access log = none
[web]
          mode = none
          accept a streaming request every seconds = 0
          enable gzip compression = no
[plugins]
          cgroups = no
          tc = no
          idlejitter = no

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999

Web Server

参考: High performance netdata - Netdata Documentation
参考: Netdata via nginx - Netdata Documentation

Replication >> Master のRaspberry Piで設定
公開向け設定
/api/v1/のメトリクスにアクセス制限
8081番で設定

インストール

$ sudo apt-get install nginx

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

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

新規作成

$ sudo nano /etc/nginx/sites-available/netdata

設定

upstream backend {
    server 127.0.0.1:19999;
    keepalive 1024;
}

server {
    listen *:8081;
    server_name my.web.server.name;

    location / {
        return 403;
    }

    location ~ /api/v1/ {
        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;
        gzip on;
        gzip_proxied any;
        gzip_types *;

        # Block any HTTP requests other than GET, HEAD, and OPTIONS
        limit_except GET HEAD OPTIONS {
            deny all;
        }
    }

    # WordPress Pingback Request Denial
    if ($http_user_agent ~* "WordPress") {
        return 403;
    }

}

保存: Ctrl + o リターン
終了: Ctrl + x

シンボリックリンク

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

再起動

$ sudo service nginx restart

確認 ローカル

疎通
http://127.0.0.1:19999/api/v1/allmetrics?format=json
http://127.0.0.1:19999
http://192.168.1.187:19999/api/v1/allmetrics?format=json
http://192.168.1.187:19999
疎通
http://127.0.0.1:8081/api/v1/allmetrics?format=json
ブロック
http://127.0.0.1:8081
疎通
http://192.168.1.187:8081/api/v1/allmetrics?format=json
ブロック
http://192.168.1.187:8081

確認 WAN

疎通
http://dz.plala.jp:8081/api/v1/allmetrics?format=json
ブロック
http://dz.plala.jp:8081
疎通
http://dz.plala.jp:8081/api/v1/allmetrics?format=prometheus_all_hosts
http://dz.plala.jp:8081/api/v1/alarms?all
http://dz.plala.jp:8081/api/v1/alarms
http://dz.plala.jp:8081/api/v1/alarm_log
http://dz.plala.jp:8081/api/v1/charts
http://dz.plala.jp:8081/api/v1/data?chart=system.cpu
http://dz.plala.jp:8081/api/v1/badge.svg?chart=system.cpu
http://dz.plala.jp:8081/api/v1/registry?action=hello
ブロック
http://dz.plala.jp:8081/netdata.conf

Module

Raspberry Piの電力不足を検出
Replication >> Master Slave 全てのRaspberry Piに設定

video

netdataをグループvideoに追加

$ sudo adduser netdata video

再起動

$ sudo reboot

vcgencmd

確認

$ vcgencmd get_throttled
throttled=0x50005
0x0 正常
0x50000 過去 低電圧状態になったが現在は正常
0x50005 現在 低電圧状態
0x80000 過去 熱によりクロックダウン
0x80008 現在 熱によりクロックダウン

0x50005または0x80008をtrue=1, false=0に振り分けてみる

Plugin

参考: python.d.plugin - Netdata Documentation

PowerStatus.chart.py

$ sudo nano /usr/libexec/netdata/python.d/PowerStatus.chart.py

ソース

# -*- coding: utf-8 -*-

from bases.FrameworkServices.ExecutableService import ExecutableService

# update_every = 1
# priority = 60000
# retries = 60

ORDER = ["powerstatus"]

CHARTS = {
    "powerstatus": {
        "options": [
            None,
            "under-voltage",
            "",
            "under-voltage",
            "powerstatus",
            "line",
        ],
        "lines": [["voltage", "under-voltage", "absolute", 1]],
    }
}


class Service(ExecutableService):
    def __init__(self, configuration=None, name=None):
        ExecutableService.__init__(self,
                                   configuration=configuration,
                                   name=name)
        self.command = "vcgencmd get_throttled"
        self.order = ORDER
        self.definitions = CHARTS

    def _get_data(self):
        try:
            raw = self._get_raw_data()
            str = raw[0].split("=")[1].encode()
        except AttributeError:
            return None

        try:
            if str == "0x50005\n" or str == "0x80008\n":
                return {"voltage": 1}
            else:
                return {"voltage": 0}
        except (ValueError, AttributeError):
            return None

保存: Ctrl + o リターン
終了: Ctrl + x

PowerStatus.conf

$ sudo nano /usr/lib/netdata/conf.d/python.d/PowerStatus.conf

ソース

# netdata python.d.plugin configuration for example
#
# This file is in YaML format. Generally the format is:
#
# name: value
#
# There are 2 sections:
#  - global variables
#  - one or more JOBS
#
# JOBS allow you to collect values from multiple sources.
# Each source will have its own set of charts.
#
# JOB parameters have to be indented (using spaces only, example below).

# ----------------------------------------------------------------------
# Global Variables
# These variables set the defaults for all JOBs, however each JOB
# may define its own, overriding the defaults.

# update_every sets the default data collection frequency.
# If unset, the python.d.plugin default is used.
update_every: 1

# priority controls the order of charts at the netdata dashboard.
# Lower numbers move the charts towards the top of the page.
# If unset, the default for python.d.plugin is used.
priority: 60000

# retries sets the number of retries to be made in case of failures.
# If unset, the default for python.d.plugin is used.
# Attempts to restore the service are made once every update_every
# and only if the module has collected values in the past.
retries: 60

# ----------------------------------------------------------------------
# JOBS (data collection sources)
#
# The default JOBS share the same *name*. JOBS with the same name
# are mutually exclusive. Only one of them will be allowed running at
# any time. This allows autodetection to try several alternatives and
# pick the one that works.
#
# Any number of jobs is supported.
#
# All python.d.plugin JOBS (for all its modules) support a set of
# predefined parameters. These are:
#
# job_name:
#     name: myname     # the JOB's name as it will appear at the
#                      # dashboard (by default is the job_name)
#                      # JOBs sharing a name are mutually exclusive
#     update_every: 1  # the JOB's data collection frequency
#     priority: 60000  # the JOB's order on the dashboard
#     retries: 5       # the JOB's number of restoration attempts
#
# Additionally to the above, example also supports the following:
#
# - none
#
# ----------------------------------------------------------------------
# AUTO-DETECTION JOBS
# only one of them will run (they have the same name)

保存: Ctrl + o リターン
終了: Ctrl + x

debug

$ sudo su -s /bin/bash netdata
$ /usr/libexec/netdata/plugins.d/python.d.plugin PowerStatus debug trace

登録

$ sudo /etc/netdata/edit-config python.d.conf

末尾に追記

PowerStatus: yes

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999

Module2

Replication >> Master のRaspberry Piに取り付ける設定

I2C

有効化

メニュー→設定→Raspberry Piの設定→インターフェイスタブ→I2C有効にチェック
再起動

netdataをグループi2cに追加

$ sudo adduser netdata i2c

再起動

$ sudo reboot

BME280

BME280使用 温湿度・気圧センサモジュールキット
GPIO 引用:BMOW

BME280使用 温湿度・気圧センサモジュールキット: 秋月電子通商

配線

J3の半田付けなし
BME280 Raspberry Pi
VDD Pin1 3.3V Pin1
GND Pin2 GND Pin6
CSB Pin3 3.3V Pin1
SDI Pin4 GPIO2 Pin3
SDO Pin5 GND Pin6
SCK Pin6 GPIO3 Pin5

確認

$ sudo i2cdetect -y 1
76番があればOK

新規作成

$ cd ~
$ sudo nano bme280.py

ソース

#coding: utf-8

#from smbus2 import SMBus
from smbus import SMBus
import time

bus_number = 1
i2c_address = 0x76

bus = SMBus(bus_number)

digT = []
digP = []
digH = []

t_fine = 0.0


def writeReg(reg_address, data):
    bus.write_byte_data(i2c_address, reg_address, data)


def get_calib_param():
    calib = []

    for i in range(0x88, 0x88 + 24):
        calib.append(bus.read_byte_data(i2c_address, i))
    calib.append(bus.read_byte_data(i2c_address, 0xA1))
    for i in range(0xE1, 0xE1 + 7):
        calib.append(bus.read_byte_data(i2c_address, i))

    digT.append((calib[1] << 8) | calib[0])
    digT.append((calib[3] << 8) | calib[2])
    digT.append((calib[5] << 8) | calib[4])
    digP.append((calib[7] << 8) | calib[6])
    digP.append((calib[9] << 8) | calib[8])
    digP.append((calib[11] << 8) | calib[10])
    digP.append((calib[13] << 8) | calib[12])
    digP.append((calib[15] << 8) | calib[14])
    digP.append((calib[17] << 8) | calib[16])
    digP.append((calib[19] << 8) | calib[18])
    digP.append((calib[21] << 8) | calib[20])
    digP.append((calib[23] << 8) | calib[22])
    digH.append(calib[24])
    digH.append((calib[26] << 8) | calib[25])
    digH.append(calib[27])
    digH.append((calib[28] << 4) | (0x0F & calib[29]))
    digH.append((calib[30] << 4) | ((calib[29] >> 4) & 0x0F))
    digH.append(calib[31])

    for i in range(1, 2):
        if digT[i] & 0x8000:
            digT[i] = (-digT[i] ^ 0xFFFF) + 1

    for i in range(1, 8):
        if digP[i] & 0x8000:
            digP[i] = (-digP[i] ^ 0xFFFF) + 1

    for i in range(0, 6):
        if digH[i] & 0x8000:
            digH[i] = (-digH[i] ^ 0xFFFF) + 1


def readData():
    data = []
    for i in range(0xF7, 0xF7 + 8):
        data.append(bus.read_byte_data(i2c_address, i))
    pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
    temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
    hum_raw = (data[6] << 8) | data[7]

    t = compensate_T(temp_raw)
    p = compensate_P(pres_raw)
    h = compensate_H(hum_raw)
    return t, h, p


def compensate_P(adc_P):
    global t_fine
    pressure = 0.0

    v1 = (t_fine / 2.0) - 64000.0
    v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]
    v2 = v2 + ((v1 * digP[4]) * 2.0)
    v2 = (v2 / 4.0) + (digP[3] * 65536.0)
    v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8) +
          ((digP[1] * v1) / 2.0)) / 262144
    v1 = ((32768 + v1) * digP[0]) / 32768

    if v1 == 0:
        return 0
    pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125
    if pressure < 0x80000000:
        pressure = (pressure * 2.0) / v1
    else:
        pressure = (pressure / v1) * 2
    v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096
    v2 = ((pressure / 4.0) * digP[7]) / 8192.0
    pressure = pressure + ((v1 + v2 + digP[6]) / 16.0)
    pressure = pressure / 100.0
    return pressure


def compensate_T(adc_T):
    global t_fine
    v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1]
    v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 -
                                                  digT[0] / 8192.0) * digT[2]
    t_fine = v1 + v2
    temperature = t_fine / 5120.0
    return temperature


def compensate_H(adc_H):
    global t_fine
    var_h = t_fine - 76800.0
    if var_h != 0:
        var_h = (adc_H - (digH[3] * 64.0 + digH[4] / 16384.0 * var_h)) * (
            digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h *
                                 (1.0 + digH[2] / 67108864.0 * var_h)))
    else:
        return 0
    var_h = var_h * (1.0 - digH[0] * var_h / 524288.0)
    if var_h > 100.0:
        var_h = 100.0
    elif var_h < 0.0:
        var_h = 0.0
    return var_h


def setup():
    osrs_t = 1  # Temperature oversampling x 1
    osrs_p = 1  # Pressure oversampling x 1
    osrs_h = 1  # Humidity oversampling x 1
    mode = 3  # Normal mode
    t_sb = 5  # Tstandby 1000ms
    filter = 0  # Filter off
    spi3w_en = 0  # 3-wire SPI Disable

    ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode
    config_reg = (t_sb << 5) | (filter << 2) | spi3w_en
    ctrl_hum_reg = osrs_h

    writeReg(0xF2, ctrl_hum_reg)
    writeReg(0xF4, ctrl_meas_reg)
    writeReg(0xF5, config_reg)


setup()
get_calib_param()

if __name__ == '__main__':
    try:
        readData()
    except KeyboardInterrupt:
        pass

保存: Ctrl + o リターン
終了: Ctrl + x

TSL2561

Adafruit TSL2561 デジタル光センサ
GPIO 引用:BMOW

Adafruit TSL2561 デジタル光センサ - スイッチサイエンス

配線

TSL2561 Raspberry Pi
3vo Pin3 3.3V Pin1
SDA Pin6 GPIO2 Pin3
SCL Pin7 GPIO3 Pin5
GND Pin2 GND Pin6

確認

$ sudo i2cdetect -y 1
39番があればOK

新規作成

$ cd ~
$ sudo nano tsl2561.py

ソース

#! /usr/bin/python2
# coding: UTF-8

import smbus
import time
import math

bus = smbus.SMBus(1)  # I2cバス番号
address = 0x39  # I2Cアドレス
command = 0x00

# i2c データ出力 1byte
def write(regist, value):
    bus.write_byte_data(address, regist, value)


# i2c データ読み込み 1byte
def read(regist):
    value = bus.read_byte_data(address, regist)
    return value


# i2c データ読み込み ブロック
def blockread(regist, num):
    value = bus.read_i2c_block_data(address, regist, num)
    return value


def ratio_calc(ambient, ir):
    # Avoid division by zero
    if float(ambient) == 0:
        ratio = 9999
    else:
        ratio = ir / float(ambient)
    return ratio


def init():
    # device enable
    write(0x80, 0x03)
    power = 0x03
    while power != 0x03:
        power = read(0x80) & 0x03
        print("{0:02x}".format(power))
    write(0x81, 0x11)


def read_lux():
    value0 = blockread(0xAC, 2)
    ch0 = 256 * value0[1] + value0[0]
    value1 = blockread(0xAE, 2)
    ch1 = 256 * value1[1] + value1[0]
    ratio = ratio_calc(ch0, ch1)
    if (ratio >= 0) & (ratio <= 0.52):
        lux = (0.0315 * ch0) - (0.0593 * ch0 * (ratio ** 1.4))
    elif ratio <= 0.65:
        lux = (0.0229 * ch0) - (0.0291 * ch1)
    elif ratio <= 0.80:
        lux = (0.0157 * ch0) - (0.018 * ch1)
    elif ratio <= 1.3:
        lux = (0.00338 * ch0) - (0.0026 * ch1)
    elif ratio > 1.3:
        lux = 0
    return lux


def main():
    init()
    counter = 0
    lux = read_lux()
    print("lux={0:f}".format(lux))


if __name__ == "__main__":
    main()

保存: Ctrl + o リターン
終了: Ctrl + x

Plugin

参考: python.d.plugin - Netdata Documentation

EnvSensors.chart.py

$ sudo nano /usr/libexec/netdata/python.d/EnvSensors.chart.py

ソース

# -*- coding: utf-8 -*-
# Description: example netdata python.d module
# Author: Pawel Krupa (paulfantom)

import sys

sys.path.append("/home/pi/")
import bme280
import tsl2561
from bases.FrameworkServices.ExecutableService import ExecutableService

# update_every = 1
# priority = 60000
# retries = 60

ORDER = ["temperature", "humidity", "pressure", "lux"]

CHARTS = {
    "temperature": {
        "options": [
            None,
            "temperature",
            "℃",
            "temperature",
            "environment.temperature",
            "line",
        ],
        "lines": [["temp", "temperature", "absolute", 1, 100]],
    },
    "humidity": {
        "options": [None, "humidity", "%", "humidity", "environment.humidity", "line"],
        "lines": [["hum", "humidity", "absolute", 1, 100]],
    },
    "pressure": {
        "options": [
            None,
            "pressure",
            "hPa",
            "pressure",
            "environment.pressure",
            "line",
        ],
        "lines": [["press", "pressure", "absolute", 1, 100]],
    },
    "lux": {
        "options": [None, "lux", "lux", "lux", "environment.lux", "line"],
        "lines": [["lux", "lux", "absolute", 1, 100]],
    },
}


class Service(ExecutableService):
    def __init__(self, configuration=None, name=None):
        ExecutableService.__init__(self, configuration=configuration, name=name)
        self.order = ORDER
        self.definitions = CHARTS

    def check(self):
        return True

    def _get_data(self):
        try:
            raw01 = bme280.readData()
            raw02 = tsl2561.read_lux()
            return {
                "temp": raw01[0] * 100,
                "hum": raw01[1] * 100,
                "press": raw01[2] * 100,
                "lux": raw02 * 100,
            }
        except (ValueError, AttributeError):
            return None

保存: Ctrl + o リターン
終了: Ctrl + x

EnvSensors.conf

$ sudo nano /usr/lib/netdata/conf.d/python.d/EnvSensors.conf

ソース

# netdata python.d.plugin configuration for example
#
# This file is in YaML format. Generally the format is:
#
# name: value
#
# There are 2 sections:
#  - global variables
#  - one or more JOBS
#
# JOBS allow you to collect values from multiple sources.
# Each source will have its own set of charts.
#
# JOB parameters have to be indented (using spaces only, example below).

# ----------------------------------------------------------------------
# Global Variables
# These variables set the defaults for all JOBs, however each JOB
# may define its own, overriding the defaults.

# update_every sets the default data collection frequency.
# If unset, the python.d.plugin default is used.
update_every: 1

# priority controls the order of charts at the netdata dashboard.
# Lower numbers move the charts towards the top of the page.
# If unset, the default for python.d.plugin is used.
priority: 60000

# retries sets the number of retries to be made in case of failures.
# If unset, the default for python.d.plugin is used.
# Attempts to restore the service are made once every update_every
# and only if the module has collected values in the past.
retries: 60

# ----------------------------------------------------------------------
# JOBS (data collection sources)
#
# The default JOBS share the same *name*. JOBS with the same name
# are mutually exclusive. Only one of them will be allowed running at
# any time. This allows autodetection to try several alternatives and
# pick the one that works.
#
# Any number of jobs is supported.
#
# All python.d.plugin JOBS (for all its modules) support a set of
# predefined parameters. These are:
#
# job_name:
#     name: myname     # the JOB's name as it will appear at the
#                      # dashboard (by default is the job_name)
#                      # JOBs sharing a name are mutually exclusive
#     update_every: 1  # the JOB's data collection frequency
#     priority: 60000  # the JOB's order on the dashboard
#     retries: 5       # the JOB's number of restoration attempts
#
# Additionally to the above, example also supports the following:
#
# - none
#
# ----------------------------------------------------------------------
# AUTO-DETECTION JOBS
# only one of them will run (they have the same name)

保存: Ctrl + o リターン
終了: Ctrl + x

変なので再起動

$ sudo reboot

debug

$ sudo su -s /bin/bash netdata
$ /usr/libexec/netdata/plugins.d/python.d.plugin EnvSensors debug trace

登録

$ sudo /etc/netdata/edit-config python.d.conf

末尾に追記

EnvSensors: yes

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999

Module3

Replication >> Master のRaspberry Piに取り付ける設定

I2C

省略

PocketGeiger

組込版ポケットガイガーType5
GPIO 引用:BMOW

組込版ポケットガイガーType5 - スイッチサイエンス

配線
参考: ポケットガイガーType5インタフェース仕様 RADIATION WATCH: 専門家向け資料

PocketGeiger Raspberry Pi
+V Pin1 3V3 Pin17
GND Pin2 GND Pin14
SIG Pin3 GPIO24 Pin18
NS Pin5 GPIO23 Pin16

インストール
参考: GitHub - MonsieurV/PiPocketGeiger

$ cd ~
$ git clone https://github.com/MonsieurV/PiPocketGeiger.git
$ cd PiPocketGeiger
$ python setup.py build
$ sudo python setup.py install

確認

$ cd examples
$ python console_logger.py

REST API

新規作成

$ cd ~
$ sudo nano pocketgeiger.py

ソース

import json
import threading
import time
from PiPocketGeiger import RadiationWatch
from http.server import BaseHTTPRequestHandler, HTTPServer

response = {"uSvh": 0.0, "duration": 0.0, "uSvhError": 0, "cpm": 0}


def func1():
    with RadiationWatch(24, 23) as radiationWatch:
        while 1:
            global response
            response = json.dumps(radiationWatch.status())
            time.sleep(5)


class HelloHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "application/json")
        self.end_headers()
        self.wfile.write(response.encode("utf-8"))


if __name__ == "__main__":
    thread_1 = threading.Thread(target=func1)
    thread_1.start()

    server_address = ("", 50000)
    httpd = HTTPServer(server_address, HelloHandler)
    httpd.serve_forever()

保存: Ctrl + o リターン
終了: Ctrl + x

エラーが出てるので

$ sudo pip3 install PiPocketGeiger

自動起動設定

$ sudo nano /etc/rc.local

末尾のexit 0手前に追記

python3 /home/pi/pocketgeiger.py

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo reboot

確認 192.168.1.187の場合

http://127.0.0.1:50000
http://192.168.1.187:50000

Plugin

参考: python.d.plugin - Netdata Documentation

RadiationDetector.chart.py

$ sudo nano /usr/libexec/netdata/python.d/RadiationDetector.chart.py

ソース

# -*- coding: utf-8 -*-

from bases.FrameworkServices.UrlService import UrlService
import json

# update_every = 1
# priority = 60000
# retries = 60

ORDER = ["radiation"]

CHARTS = {
    "radiation": {
        "options": [None, "radiation", "uSvh", "radiation", "radiation", "line"],
        "lines": [["uSvh", "radiation", "absolute", 1, 1000]],
    }
}


class Service(UrlService):
    def __init__(self, configuration=None, name=None):
        UrlService.__init__(self, configuration=configuration, name=name)
        self.url = "http://localhost:50000"
        self.order = ORDER
        self.definitions = CHARTS

    def _get_data(self):
        try:
            raw = self._get_raw_data()
        except AttributeError:
            return None

        try:
            parsed = json.loads(raw)
            return {"uSvh": parsed["uSvh"] * 1000}
        except:
            return None

保存: Ctrl + o リターン
終了: Ctrl + x

RadiationDetector.conf

$ sudo nano /usr/lib/netdata/conf.d/python.d/RadiationDetector.conf

ソース

# netdata python.d.plugin configuration for example
#
# This file is in YaML format. Generally the format is:
#
# name: value
#
# There are 2 sections:
#  - global variables
#  - one or more JOBS
#
# JOBS allow you to collect values from multiple sources.
# Each source will have its own set of charts.
#
# JOB parameters have to be indented (using spaces only, example below).

# ----------------------------------------------------------------------
# Global Variables
# These variables set the defaults for all JOBs, however each JOB
# may define its own, overriding the defaults.

# update_every sets the default data collection frequency.
# If unset, the python.d.plugin default is used.
update_every: 1

# priority controls the order of charts at the netdata dashboard.
# Lower numbers move the charts towards the top of the page.
# If unset, the default for python.d.plugin is used.
priority: 60000

# retries sets the number of retries to be made in case of failures.
# If unset, the default for python.d.plugin is used.
# Attempts to restore the service are made once every update_every
# and only if the module has collected values in the past.
retries: 60

# ----------------------------------------------------------------------
# JOBS (data collection sources)
#
# The default JOBS share the same *name*. JOBS with the same name
# are mutually exclusive. Only one of them will be allowed running at
# any time. This allows autodetection to try several alternatives and
# pick the one that works.
#
# Any number of jobs is supported.
#
# All python.d.plugin JOBS (for all its modules) support a set of
# predefined parameters. These are:
#
# job_name:
#     name: myname     # the JOB's name as it will appear at the
#                      # dashboard (by default is the job_name)
#                      # JOBs sharing a name are mutually exclusive
#     update_every: 1  # the JOB's data collection frequency
#     priority: 60000  # the JOB's order on the dashboard
#     retries: 5       # the JOB's number of restoration attempts
#
# Additionally to the above, example also supports the following:
#
# - none
#
# ----------------------------------------------------------------------
# AUTO-DETECTION JOBS
# only one of them will run (they have the same name)

保存: Ctrl + o リターン
終了: Ctrl + x

変なので再起動

$ sudo reboot

debug

$ sudo su -s /bin/bash netdata
$ /usr/libexec/netdata/plugins.d/python.d.plugin RadiationDetector debug trace

登録

$ sudo /etc/netdata/edit-config python.d.conf

末尾に追記

RadiationDetector: yes

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service netdata restart

確認

http://127.0.0.1:19999
http://192.168.1.187:19999


Alarms

参考: Netdata alarm notifications - Netdata Documentation
Module Module2 Module3 に設定

検証中

Mail

参考: email - Netdata Documentation

Replication >> Master で設定

sSMTPを使用
Gmail(二段階認証)を設定

$ sudo apt-get install ssmtp
$ sudo apt-get install mailutils
$ sudo nano /etc/ssmtp/ssmtp.conf

全てコメントアウトし末尾に追記
アプリパスワードを発行しpasswordに貼り付け

root=xxxxx@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=xxxxx@gmail.com
AuthPass=password
UseSTARTTLS=YES

送信テスト

$ mail *****@gmail.com
Cc:
Subject:test.
This is test.
「.」もしくはCtrl+Dで送信

登録

$ sudo /etc/netdata/edit-config health_alarm_notify.conf

保存: Ctrl + o リターン
終了: Ctrl + x

確認

$ sudo su -s /bin/bash netdata
$ /usr/libexec/netdata/plugins.d/alarm-notify.sh test [ROLE]

Update

参考: netdata/UPDATE.md netdata/netdata · GitHub

Manual update to get the latest nightly build

$ bash <(curl -Ss https://my-netdata.io/kickstart.sh) --no-updates

Uninstall

参考: netdata/UNINSTALL.md netdata/netdata · GitHub

$ sudo /usr/libexec/netdata-uninstaller.sh --yes --env /etc/netdata/.environment

Dashboard

IoT MONITOR

参考: Custom dashboards - Netdata Documentation

ソース
http://dz.plala.jp/iot-monitor/
http://dz.plala.jp/iot-monitor/jquery.easypiechart.js

Archive

参考: Metrics long term archiving - Netdata Documentation
参考: Netdata, Prometheus, Grafana stack - Netdata Documentation
参考: Using netdata with Prometheus - Netdata Documentation

Security update

参考: RaspberryPiでupdate/upgradeを自動化する。 - Qiit

Replication >> Master にセキュリティーアップデート自動化

延命対策

nginx

設定

$ sudo nano /etc/nginx/nginx.conf

変更

       # access_log /var/log/nginx/access.log;
       # error_log /var/log/nginx/error.log;
       access_log off;
       error_log off;

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo service nginx restart

swap

Stretchの場合

$ sudo dphys-swapfile swapoff
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl disable dphys-swapfile

fstab

設定

$ sudo nano /etc/fstab

nodiratime追記と末尾に追記
参考: fstab - ArchWiki atime オプション

PARTUUID=762cd6c9-02  /               ext4    defaults,noatime,nodiratime  0       1
tmpfs    /tmp                              tmpfs    defaults,noatime,nodiratime,mode=1777  0       0
tmpfs    /run/user/1000                    tmpfs    defaults,noatime,nodiratime,mode=1777  0       0
tmpfs    /home/pi/.cache/lxsession/LXDE-pi tmpfs    defaults,noatime,nodiratime,mode=1777  0       0
tmpfs    /var/lib/netdata                  tmpfs    defaults,noatime,nodiratime,mode=1777  0       0

保存: Ctrl + o リターン
終了: Ctrl + x

再起動

$ sudo reboot

確認

$ df -h

systemctl

確認

$ systemctl list-unit-files -t service|grep enabled

rsyslog停止

$ sudo systemctl stop rsyslog.service
$ sudo systemctl disable rsyslog.service
戻すなら
$ sudo systemctl enable rsyslog.service

bluetooth停止

$ sudo systemctl stop hciuart.service
$ sudo systemctl stop bluetooth.service
$ sudo systemctl disable hciuart.service
$ sudo systemctl disable bluetooth.service
戻すなら
$ sudo systemctl enable hciuart.service
$ sudo systemctl enable bluetooth.service

再起動

$ sudo reboot

確認

$ systemctl list-unit-files -t service
$ systemctl list-unit-files -t service|grep disabled

folder2ram

参考: GitHub - bobafetthotmail/folder2ram

インストール

$ sudo wget -O /sbin/folder2ram https://raw.githubusercontent.com/bobafetthotmail/folder2ram/master/debian_package/sbin/folder2ram
$ sudo chmod +x /sbin/folder2ram
$ sudo folder2ram -configure
will now open the configuration file with your favourite text editor
write its name and press enter (nano, vim, gedit are the most common)
リターン
$ sudo nano /etc/folder2ram/folder2ram.conf

末尾に追記

tmpfs		/var/log
tmpfs		/var/tmp
tmpfs		/var/spool
tmpfs		/var/cache/samba

保存: Ctrl + o > リターン
終了: Ctrl + x

$ sudo folder2ram -mountall
$ sudo folder2ram -enablesystemd

再起動

$ sudo reboot

確認

$ df -h

journald

参考: man journald.conf の訳

$ sudo nano /etc/systemd/journald.conf

追記

Storage=none

保存: Ctrl + o > リターン
終了: Ctrl + x

再起動

$ sudo reboot

sysctl

Netdataでsoftnetの警告が必ず出る

過去10分間に、ksoftirqがsysctl net.core.netdev_budgetまたはnet.core.netdev_budget_usecsを使い果たし作業が残っている。これはパケットがドロップされる原因となる可能性があります。

参考: Red Hat Enterprise Linux Network Performance Tuning Guide
参考: Can't fix persistent 'netdev budget ran outs' with 45k alerts, need help #4624

設定

$ sudo nano /etc/sysctl.conf

末尾に追記

net.core.netdev_budget_usecs=20000

保存: Ctrl + o > リターン
終了: Ctrl + x

再起動

$ sudo reboot

更新履歴

  • 2019.05.08 IoT MONITOR (Dashboard)のiPhone・iPad対応
  • 2019.05.03 書き直し
  • 2017.08.27 書き直し
  • 2017.05.15 公開