Last active
December 11, 2015 17:58
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 "tmp_read:", tmp_read | |
print "tmp_v:", tmp_v | |
print "tmp_temp:", tmp_temp | |
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) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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