Skip to content

Instantly share code, notes, and snippets.

@pironic
Last active December 11, 2015 17:58
Show Gist options
  • Save pironic/4638291 to your computer and use it in GitHub Desktop.
Save pironic/4638291 to your computer and use it in GitHub Desktop.
rrd-remote fetch server/client using python's SocketServer library in order to provide GPIO readouts from a raspberry pi.
#! /usr/bin/env python
import SocketServer, sys, time, os
HOST = '10.1.1.45'
PORT = 2000
DEBUG = 1
import socket
def client(string):
# SOCK_STREAM == a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#sock.setblocking(0) # optional non-blocking
sock.connect((HOST, PORT))
sock.send(string)
reply = sock.recv(16384) # limit reply to 16K
sock.close()
return reply
while True:
reading = float(client('adc 0')) # TMP36
if (reading > 0):
reading = reading * ( 3.3 / 1023.0 ) # convert reading to volts
reading = (((reading * 1000) - 100.0) / 10.0) - 40.0 # convert volts to celcius
if (DEBUG):
print "saving response for %s : %s" % ("adc 0", reading)
# save the value into the rrd file.
#os.system("rrdtool update rpi.rrd N:%s" % str(reading))
reading = float(client('adc 1')) # CdS
if (reading > 0):
# Vpr = (Vin * Rc) / (Rc + Rpr)
# Rpr = Vpr * Rc / (Vin - Vpr)
Vin = 3.3
Vpr = reading * ( 3.3 / 1023.0 ) # in volts
Rc = 10000
Rpr = Rc * ((Vin / Vpr) - 1) # convert volts to resistance in ohms
#lux = 249640-39807.4 log(Rpr) (logarithmic)
if (DEBUG):
print "saving response for %s : %s" % ("adc 1", reading)
# save the value into the rrd file.
os.system("rrdtool update rpi.rrd N:%s" % str(reading))
reading = client('dht 4').split(';') # DHT11
if (len(reading) > 0):
for x in range(len(reading)):
if (reading[x] != None and reading[x] != 'None'):
if (DEBUG):
print "saving response for dht 4[%s] : %s" % (x, reading[x])
else:
continue
# save the value into the rrd file.
#os.system("rrdtool update rpi.rrd N:%s" % str(reading))
time.sleep(8)
if __name__ == "__main__":
server = SimpleServer((HOST, PORT), SingleTCPHandler)
# terminate with Ctrl-C
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)
#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO
from math import log as log
import subprocess
import re
GPIO.setmode(GPIO.BCM)
DEBUG = 1
# tmp connected to adc #0
tmp_adc = 0;
ldr_adc = 1;
dht_pin = 4;
mcs_pin = 22;
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
def RCtime (RCpin):
# we dont use this anymore, but this is the capacitor read out method.
reading = 0
GPIO.setup(RCpin, GPIO.OUT)
GPIO.output(RCpin, GPIO.LOW)
time.sleep(.1)
GPIO.setup(RCpin, GPIO.IN)
# This takes about 1 millisecond per loop cycle
# print GPIO.input(RCpin)
# print GPIO.LOW
# print GPIO.OUT
while (GPIO.input(RCpin) == GPIO.LOW):
reading += 1
if (reading>=10000):
reading = -1
break
return reading
def readDHT(pin):
output = subprocess.check_output(["./Adafruit-Raspberry-Pi-Python-Code/Adafruit_DHT_Driver/Adafruit_DHT", "11", str(pin)]);
#print output
matches = re.search("Temp =\s+([0-9.]+)", output)
if (not matches):
#time.sleep(1)
temp = "too soon since last read!"
else :
temp = float(matches.group(1))
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
#time.sleep(1)
humidity = "too soon since last read!"
else :
humidity = float(matches.group(1))
return [temp,humidity]
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it
return adcout
def GetApproxLux(rPR, lookupTable):
approxLux = 0.0
if (lookupTable != None and len(lookupTable) > 0 and len(lookupTable[0]) > 0):
#print "debug:", lookupTable[len(lookupTable) - 1][1]
if (rPR < lookupTable[len(lookupTable) - 1][1]) :
return lookupTable[len(lookupTable) - 1][0]
if (rPR > lookupTable[0][1]) :
return lookupTable[0][0]
lowerRow = len(lookupTable) - 1
minRVal = lookupTable[len(lookupTable) - 1][1]
r = len(lookupTable) - 1
for x in range(len(lookupTable)):
r = x
if (lookupTable[r][1] < rPR):
break
minRVal = lookupTable[r][1]
lowerRow = r
maxRVal = lookupTable[r][1]
upperRow = r
percent = (rPR - minRVal) / (maxRVal - minRVal)
luxRange = lookupTable[lowerRow][0] - lookupTable[upperRow][0]
approxLux = lookupTable[lowerRow][0] - (percent * luxRange)
return approxLux
while True:
# we'll assume that the pot didn't move
trim_pot_changed = False
# read the analog pin
ldr_read = readadc(ldr_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
ldr_v = (1023 - ldr_read) * ( 3.3 / 1023.0 ))
Vin = 3.3
Vpr = ldr_v # in volts
Rc = 10000
#Vo = Vcc * ( R / (R + Photocell) )
Rpc = Rc * ((Vin / Vpr) - 1) # convert volts to resistance in ohms
lux = 1207.07-105.471 * log(Rpc)
lookupTable = [[0.1,600000],[1,70000],[10,10000],[100,1500],[1000,300]]
# tmp stuff
tmp_read = readadc(tmp_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
tmp_v = tmp_read * ( 3.3 / 1023.0 )
tmp_temp = (((tmp_v * 1000) - 100.0) / 10.0) - 40.0
#dht_read = readDHT(dht_pin)
mcs_read = RCtime(mcs_pin)
if DEBUG:
print "---------"
print "ldr_read:", ldr_read
print "ldr_v", ldr_v
print "ldr_Rpc", Rpc
print "ldr_lux", lux
print "ldr_apprx", GetApproxLux(Rpc, lookupTable)
print
print "tmp_read:", tmp_read
print "tmp_v:", tmp_v
print "tmp_temp:", tmp_temp
print
print "mcs:", mcs_read
# print "dht_temp:", dht_read[0]
# print "dht_humid:", dht_read[1]
# hang out and do nothing for a second
time.sleep(1)
#! /usr/bin/env python
import SocketServer, sys, time, os
import RPi.GPIO as GPIO
import subprocess
import re
HOST = '10.1.1.45'
PORT = 2000
DEBUG = 1
GPIO.setmode(GPIO.BCM)
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
def readDHT(pin):
output = subprocess.check_output(["./Adafruit-Raspberry-Pi-Python-Code/Adafruit_DHT_Driver/Adafruit_DHT", "11", str(pin)]);
#print output
matches = re.search("Temp =\s+([0-9.]+)", output)
if (not matches):
#time.sleep(1)
temp = None
else :
temp = float(matches.group(1))
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
#time.sleep(1)
humidity = None
else :
humidity = float(matches.group(1))
return "%s;%s" % (temp,humidity)
def RCtime (RCpin):
# we dont use this anymore, but this is the capacitor read out method.
reading = 0
GPIO.setup(RCpin, GPIO.OUT)
GPIO.output(RCpin, GPIO.LOW)
time.sleep(.1)
GPIO.setup(RCpin, GPIO.IN)
# This takes about 1 millisecond per loop cycle
while (GPIO.input(RCpin) == GPIO.LOW):
reading += 1
if (reading>=100000):
reading = -1
break
return reading
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it
return adcout
class SingleTCPHandler(SocketServer.BaseRequestHandler):
"One instance per connection. Override handle(self) to customize action."
def handle(self):
# self.request is the client connection
data = self.request.recv(1024) # clip input at 1Kb
method = data.split()[0]
pin = data.split()[1]
#reading = RCtime(int(data))
if (method == 'adc') :
reading = readadc(int(pin), SPICLK, SPIMOSI, SPIMISO, SPICS)
elif (method == 'dht') :
reading = readDHT(int(pin))
else :
reading = 0
#reading = reading * ( 3.3 / 1023.0 ) # return the reading in volts
if (DEBUG):
print "request for %s(%s) : %s" % (str(method), int(pin), reading)
reply = str(reading) + '\n'
if reply is not None:
self.request.send(reply)
self.request.close()
class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
# Ctrl-C will cleanly kill all spawned threads
daemon_threads = True
# much faster rebinding
allow_reuse_address = True
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
if __name__ == "__main__":
server = SimpleServer((HOST, PORT), SingleTCPHandler)
# terminate with Ctrl-C
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)
@pironic
Copy link
Author

pironic commented Jan 25, 2013

rrdtool create -
rpi.rrd --step 10
DS:light:GAUGE:60:0:50000
RRA:AVERAGE:0.5:1:259200
RRA:AVERAGE:0.5:6:2628000
RRA:MIN:0.5:1:259200
RRA:MIN:0.5:6:2628000
RRA:MAX:0.5:1:259200
RRA:MAX:0.5:6:2628000
RRA:LAST:0.5:1:259200
RRA:LAST:0.5:6:2628000

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