1) Installing the DS9490 on Raspberry
2) Read the temperature
3) Update a Xively Feed
This main tutorial is from the xively web site : https://xively.com/dev/tutorials/pi/
the difference is that instead of lop cpu value, we will get the value from the sensor:
change the read_loadavg() function with the following:
def read_temperature(): if DEBUG: print "Reading Read Temperature Sensor" return subprocess.check_output(["cat /mnt/1wire/28.4543737898/temperature"],shell=True)
Of course, change the device ID (28.4543737898) with your personal device.
in the main loop, change the update interval to your need :
time.sleep(10) # 10 seconds update interval
and don't forget to change the read_loadavg() name to read_temperature() evrywhere and update the FEED_ID and the API_KEY depending on your Xively account.
A full application will be :
#!/usr/bin/env python import os import xively import subprocess import time import datetime import requests # extract feed_id and api_key from environment variables FEED_ID = os.environ["FEED_ID"] API_KEY = os.environ["API_KEY"] DEBUG = os.environ["DEBUG"] or false # initialize api client api = xively.XivelyAPIClient(API_KEY) # function to read 1 minute load average from system uptime command def read_temperature(): if DEBUG: print "Reading Temperature" return subprocess.check_output(["cat /mnt/1wire/28.45566778/temperature"], shell=True) # function to return a datastream object. This either creates a new datastream, # or returns an existing one def get_datastream(feed): try: datastream = feed.datastreams.get("temperature") if DEBUG: print "Found existing datastream" return datastream except: if DEBUG: print "Creating new datastream" datastream = feed.datastreams.create("temperature", tags="sensor_01") return datastream # main program entry point - runs continuously updating our datastream with the # current 1 minute load average def run(): print "Starting Xively tutorial script" feed = api.feeds.get(FEED_ID) datastream = get_datastream(feed) datastream.max_value = None datastream.min_value = None while True: temperature = read_temperature() if DEBUG: print "Updating Xively feed with value: %s" % temperature datastream.current_value = temperature datastream.at = datetime.datetime.utcnow() try: datastream.update() except requests.HTTPError as e: print "HTTPError({0}): {1}".format(e.errno, e.strerror)
# 60 s update interval
time.sleep(60) run()
4) Create a daemon to update the xively feed
create a script "logger.py" like his below (configure it correctly for your needs).
type : sudo python logger.py start
logger.py
#!/usr/bin/env python
import os
import xively
import subprocess
import time
import datetime
import requests
import commands
import logging
import sys
from daemon import runner
# on cree leséventuels répertoires non disponibles
os.system('mkdir -p /var/run/logger-daemon')
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("/var/log/logger-daemon.log")
handler.setFormatter(formatter)
logger.addHandler(handler)
FEED_ID = "YOUR FEED_ID"
API_KEY = "YOUR_API_KEY"
# initialize api client
api = xively.XivelyAPIClient(API_KEY)
# function to read the temperature from ds18b20 temperature sensor on i2c
def read_temperature():
try:
output = subprocess.check_output("cat /mnt/1wire/28.43BE25020000/temperature", shell=True)
temperature = round(float(output),1)
return temperature
except:
logger.error("Unexpected error: %s", sys.exc_info()[0])
# function to return a datastream object. This either creates a new datastream,
# or returns an existing one
def get_datastream(feed):
try:
datastream = feed.datastreams.get("temperature")
return datastream
except:
datastream = feed.datastreams.create("temperature", tags="temperature")
return datastream
class App():
def __init__(self):
self.stdin_path = '/dev/null'
self.stdout_path = '/dev/null'
self.stderr_path = '/dev/null'
self.pidfile_path = '/var/run/logger-daemon/logger-daemon.pid'
self.pidfile_timeout = 5
def run(self):
feed = api.feeds.get(FEED_ID)
datastream = get_datastream(feed)
datastream.max_value = None
datastream.min_value = None
while True:
try:
degreesCelcius = read_temperature()
except Exception as e:
logger.error("Exception({0}): {1}".format(e.errno, e.strerror))
datastream.current_value = degreesCelcius
datastream.at = datetime.datetime.utcnow()
try:
datastream.update()
except requests.HTTPError as e:
logger.error("HTTPError({0}): {1}".format(e.errno, e.strerror))
logger.info("Upload to Xiverly Temperature : %s " % degreesCelcius)
#logger.debug("Debug message")
#logger.info("Info message")
#logger.warn("Warning message")
#logger.error("Error message")
time.sleep(60)
app = App()
daemon_runner = runner.DaemonRunner(app)
#This ensures that the logger file handle does not get closed during daemonization
daemon_runner.daemon_context.files_preserve=[handler.stream]
daemon_runner.do_action()
5) install your daemon to start at boot
create a file 'logger-daemon' in /etc/init.d
and make "sudo chmod a+x logger-daemon"
"sudo update-rc.d logger-daemon defaults"
in the script below, takes cares to configure correctly the HOM directory which contains the script logger-daemon.py
logger-daemon
#! /bin/sh
### BEGIN INIT INFO
# Provides: logger-daemon
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: logger-daemon at boot
# Description: start logger-daemon at boot
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Logger-Daemon"
NAME=logger-daemon
HOME=/home/pi/temperature
DAEMON=/usr/bin/python2.7
DAEMON_ARGS="-m logger-daemon"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
VERBOSE=yes
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
chdir $HOME
$DAEMON $DAEMON_ARGS start
}
#
# Function that stops the daemon/service
#
do_stop()
{
chdir $HOME
$DAEMON $DAEMON_ARGS stop
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status}" >&2
exit 3
;;
esac
: