Skip to content

Instantly share code, notes, and snippets.

@jareware

jareware/README.md

Last active Aug 10, 2018
Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@dpc32 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
You can’t perform that action at this time.