Skip to content

Instantly share code, notes, and snippets.

@jareware
Last active August 10, 2018 12:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jareware/cf0690cf7b182b8f45cf45ae215aa779 to your computer and use it in GitHub Desktop.
Save jareware/cf0690cf7b182b8f45cf45ae215aa779 to your computer and use it in GitHub Desktop.
Raspberry Pi -based sensor station

Raspberry Pi -based sensor station

This is mostly documentation for myself. Feel free to use any of it if it helps, though.

Hardware

Software

  • Image an SD card with Raspbian (LITE is fine)
  • Resize disk with sudo raspi-config (and update locales etc)
  • Set up the 1-Wire filesystem:
    • sudo apt-get install owfs
    • sudo mkdir /mnt/1wire && sudo chown pi:pi /mnt/1wire/
    • sudo vim /etc/owfs.conf (see below)
    • sudo vim /etc/init.d/owfs && sudo chmod a+x /etc/init.d/owfs && sudo update-rc.d owfs defaults (see below)
    • sudo vim /etc/fuse.conf (see below)
  • Check to see the sensors are visible on owfs (use head instead of cat): head /mnt/1wire/28.5F7CE1040000/temperature should print out something like 23.4375 (depending on the sensor address and the current temperature, of course)
  • Set up a cronjob for collecting stats: * * * * * ~/bin/collect-stats > /dev/null
  • Set up Graphite scripts:
    • ~/bin/send-stat (see below)
    • ~/bin/collect-stats (see below)
    • ~/bin/ping-rt-avg (see below)
  • Set up a cronjob for collecting counter stats: @reboot ~/bin/collect-counter.py > /dev/null
#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import datetime
from subprocess import call
REED_SWITCH_PIN = 15 # RasPi GPIO pin to use (see https://www.raspberrypi.org/documentation/usage/gpio/)
FLUSH_INTERVAL = 60 # seconds
FLUSH_SCRIPT = "/home/pi/bin/send-stat"
FLUSH_LABEL = "home.counter"
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme
GPIO.setup(REED_SWITCH_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set pin as input with pull-up
flushedAt = time.time()
counter = 0
prevState = 1
# Enter main loop
try:
while 1:
# Read current value of the switch
currentState = GPIO.input(REED_SWITCH_PIN)
# Increment counters on change
if (currentState != prevState):
prevState = currentState
if currentState == 0:
counter += 1
print datetime.datetime.now().isoformat() + " counter = " + str(counter)
# Every N seconds, flush the counter
if time.time() - flushedAt > FLUSH_INTERVAL:
print datetime.datetime.now().isoformat() + " FLUSH"
call([ FLUSH_SCRIPT, FLUSH_LABEL, str(counter) ])
counter = 0
flushedAt = time.time()
# Sample every 100 ms (reading the switch without ANY delay causes false positives)
time.sleep(0.01)
# Do GPIO cleanup on Ctrl + C
except KeyboardInterrupt:
GPIO.cleanup()
#!/bin/bash
PATH=$PATH:~/bin
send-stat hosts.$(hostname).load $(cat /proc/loadavg) # since loadavg gives space-separated values, only the first such value is sent
send-stat hosts.$(hostname).uptime $(expr $(cat /proc/uptime | sed "s/\..*//") / 86400) # convert from seconds to days
send-stat hosts.$(hostname).cputemp $(expr $(cat /sys/class/thermal/thermal_zone0/temp) / 1000)
send-stat home.temps.28_5F $(head /mnt/1wire/28.5F7CE1040000/temperature)
send-stat home.temps.28_89 $(head /mnt/1wire/28.89BBE1040000/temperature)
send-stat home.temps.28_FF $(head /mnt/1wire/28.FF9768601404/temperature)
send-stat hosts.$(hostname).pings.router $(ping-rt-avg 192.168.1.1)
send-stat hosts.$(hostname).pings.graphite $(ping-rt-avg $GRAPHITE_HOST)
send-stat hosts.$(hostname).pings.google $(ping-rt-avg google.com)
# /etc/fuse.conf - Configuration file for Filesystem in Userspace (FUSE)
# Set the maximum number of FUSE mounts allowed to non-root users.
# The default is 1000.
#mount_max = 1000
# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other
#!/bin/sh
### BEGIN INIT INFO
# Provides: owfs
# Required-Start: $remote_fs $syslog $network $named
# Required-Stop: $remote_fs $syslog $network $named
# Should-Start: owfs
# Should-Stop: owfs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: 1-wire file system mount & update daemon
# Description: Start and stop 1-wire file system mount & update daemon.
### END INIT INFO
CONFFILE=/etc/owfs.conf
DESC="1-Wire file system mount"
NAME="owfs"
DAEMON=/usr/bin/$NAME
case "$1" in
start)
echo "Starting $NAME"
$DAEMON -c $CONFFILE
;;
stop)
echo "Stopping $NAME"
killall $NAME
;;
*)
echo "Usage: $N {start|stop}" >&2
exit 1
;;
esac
exit 0
# Sample configuration file for the OWFS suite for Debian GNU/Linux.
#
#
# This is the main OWFS configuration file. You should read the
# owfs.conf(5) manual page in order to understand the options listed
# here.
######################## SOURCES ########################
#
# With this setup, any client (but owserver) uses owserver on the
# local machine...
! server: server = localhost:4304
#
# ...and owserver uses the real hardware, by default fake devices
# This part must be changed on real installation
#server: FAKE = DS18S20,DS2405
#
# USB device: DS9490
server: usb = all
#
# Serial port: DS9097
#server: device = /dev/ttyS1
#
# owserver tcp address
#server: server = 192.168.10.1:3131
#
# random simulated device
#server: FAKE = DS18S20,DS2405
#
######################### OWFS ##########################
#
mountpoint = /mnt/1wire
allow_other
#
####################### OWHTTPD #########################
http: port = 2121
####################### OWFTPD ##########################
ftp: port = 2120
####################### OWSERVER ########################
server: port = localhost:4304
#!/bin/bash
# Note: you may have to $ sudo apt-get install iputils-ping
ping -c 3 $1 | grep min/avg/max/mdev | cut -d / -f 5 # 5th field == avg
#!/bin/bash
GRAPHITE_HOST=192.168.1.2
GRAPHITE_PORT=2003
echo "$1 $2 $(date +%s)" | nc $GRAPHITE_HOST $GRAPHITE_PORT
echo "send-stat: $1=$2"
@dpc32
Copy link

dpc32 commented Aug 10, 2018

I followed your detailed instructions and I don't see the sensors as you point out in this step:
Check to see the sensors are visible on owfs (use head instead of cat): head /mnt/1wire/28.5F7CE1040000

I am using an RP3 running Stretch. I also have the same 1-Wire USB Adapter, DS9490R, and it also shows up as "Dallas Semiconductor DS1490F 2-in-1 Fob, 1-Wire adapter" on lsusb.

I am not aware of any kernal modifications I may (or may not have made). Do you have any ideas on what I am missing.

I appreciate your posting of the detailed instructions and code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment