Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 1-Wire sensor monitoring #3822

Merged
merged 1 commit into from Jun 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions conf.d/Makefile.am
Expand Up @@ -79,6 +79,7 @@ dist_pythonconfig_DATA = \
python.d/traefik.conf \
python.d/unbound.conf \
python.d/varnish.conf \
python.d/w1sensor.conf \
python.d/web_log.conf \
$(NULL)

Expand Down
1 change: 1 addition & 0 deletions conf.d/python.d.conf
Expand Up @@ -82,3 +82,4 @@ nginx_log: no
unbound: no
# varnish: yes
# web_log: yes
# w1sensor: yes
74 changes: 74 additions & 0 deletions conf.d/python.d/w1sensor.conf
@@ -0,0 +1,74 @@
# netdata python.d.plugin configuration for w1sensor
#
# 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: 5

# 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

# autodetection_retry sets the job re-check interval in seconds.
# The job is not deleted if check fails.
# Attempts to start the job are made once every autodetection_retry.
# This feature is disabled by default.
# autodetection_retry: 0

# ----------------------------------------------------------------------
# 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: 5 # the JOB's data collection frequency
# priority: 60000 # the JOB's order on the dashboard
# retries: 60 # the JOB's number of restoration attempts
# autodetection_retry: 0 # the JOB's re-check interval in seconds
#
# Additionally to the above, example also supports the following:
#
# name_<1-Wire id>: '<human readable name>'
# This allows associating a human readable name with a sensor's 1-Wire
# identifier. Example:
# name_00000022276e: 'Machine room'
# name_00000022298f: 'Rack 12'
#
# ----------------------------------------------------------------------
# AUTO-DETECTION JOBS
# only one of them will run (they have the same name)
1 change: 1 addition & 0 deletions python.d/Makefile.am
Expand Up @@ -67,6 +67,7 @@ dist_python_DATA = \
traefik.chart.py \
unbound.chart.py \
varnish.chart.py \
w1sensor.chart.py \
web_log.chart.py \
$(NULL)

Expand Down
14 changes: 14 additions & 0 deletions python.d/README.md
Expand Up @@ -2522,6 +2522,20 @@ No configuration is needed.

---

# w1sensor

Data from 1-Wire sensors.
On Linux these are supported by the wire, w1_gpio, and w1_therm modules.
Currently temperature sensors are supported and automatically detected.

Charts are created dynamically based on the number of detected sensors.

### configuration

For detailed configuration information please read [`w1sensor.conf`](https://github.com/firehol/netdata/blob/master/conf.d/python.d/w1sensor.conf) file.

---

# web_log

Tails the apache/nginx/lighttpd/gunicorn log files to collect real-time web-server statistics.
Expand Down
103 changes: 103 additions & 0 deletions python.d/w1sensor.chart.py
@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
# Description: 1-wire temperature monitor netdata python.d module
# Author: Diomidis Spinellis <http://www.spinellis.gr>

import os
import re
from bases.FrameworkServices.SimpleService import SimpleService

# default module values (can be overridden per job in `config`)
update_every = 5

# Location where 1-Wire devices can be found
W1_DIR = '/sys/bus/w1/devices/'

# Lines matching the following regular expression contain a temperature value
RE_TEMP = re.compile(r' t=(\d+)')

ORDER = ['temp']

# id: {
# 'options': [name, title, units, family (heading 2), context, charttype],
# 'lines': [
# [unique_dimension_name, name, algorithm, multiplier, divisor]
# ]}
CHARTS = {
'temp': {
'options': [
None,
'1-Wire Temperature Sensor',
'Celsius',
'Temperature',
'w1sensor.temp',
'line'
],
# lines are constructed from check
}
}

# Known and supported family members
# Based on linux/drivers/w1/w1_family.h and w1/slaves/w1_therm.c
THERM_FAMILY = {
'10': 'W1_THERM_DS18S20',
'22': 'W1_THERM_DS1822',
'28': 'W1_THERM_DS18B20',
'3b': 'W1_THERM_DS1825',
'42': 'W1_THERM_DS28EA00',
}

class Service(SimpleService):
"""Provide netdata service for 1-Wire sensors"""
def __init__(self, configuration=None, name=None):
SimpleService.__init__(self, configuration=configuration, name=name)
self.order = ORDER
self.definitions = CHARTS
self.probes = []

def check(self):
"""Auto-detect available 1-Wire sensors, setting line definitions
and probes to be monitored."""
try:
file_names = os.listdir(W1_DIR)
except OSError as err:
self.error(err)
return False

lines = []
for file_name in file_names:
if file_name[2] != '-':
continue
if not file_name[0:2] in THERM_FAMILY:
continue

self.probes.append(file_name)
identifier = file_name[3:]
name = identifier
config_name = self.configuration.get('name_' + identifier)
if config_name:
name = config_name
lines.append(['w1sensor_temp_' + identifier, name, 'absolute',
1, 10])
self.definitions['temp']['lines'] = lines
return len(self.probes) > 0

def get_data(self):
"""Return data read from sensors."""
data = dict()

for file_name in self.probes:
file_path = W1_DIR + file_name + '/w1_slave'
identifier = file_name[3:]
try:
with open(file_path, 'r') as device_file:
for line in device_file:
matched = RE_TEMP.search(line)
if matched:
# Round to one decimal digit to filter-out noise
value = round(int(matched.group(1)) / 1000., 1)
value = int(value * 10)
data['w1sensor_temp_' + identifier] = value
except (OSError, IOError) as err:
self.error(err)
continue
return data or None
10 changes: 10 additions & 0 deletions web/dashboard_info.js
Expand Up @@ -384,6 +384,12 @@ netdataDashboard.menu = {
title: 'BOINC',
icon: '<i class="fas fa-microchip"></i>',
info: 'Provides task counts for <b><a href="http://boinc.berkeley.edu/">BOINC</a></b> distributed computing clients.'
},

'w1sensor': {
title: '1-Wire Sensors',
icon: '<i class="fas fa-thermometer-half"></i>',
info: 'Data derived from <a href="https://en.wikipedia.org/wiki/1-Wire">1-Wire</a> sensors. Currently temperature sensors are automatically detected.'
}
};

Expand Down Expand Up @@ -2142,6 +2148,10 @@ netdataDashboard.context = {

'boinc.process': {
info: 'Counts of active tasks in each process state. <code>Executing</code> tasks are running right now. <code>Suspended</code> tasks have an associated process, but are not currently running (either because the system isn\'t processing any tasks right now, or because they have been preempted by higher priority tasks). <code>Quit</code> tasks are exiting gracefully. <code>Aborted</code> tasks exceeded some resource limit, and are being shut down. code>Copy Pending</code> tasks are waiting on a background file transfer to finish. <code>Uninitialized</code> tasks do not have an associated process yet.'
},

'w1sensor.temp': {
info: 'Temperature derived from 1-Wire temperature sensors.'
}

// ------------------------------------------------------------------------
Expand Down