Login
Register
Forum
Kontakt
Bitmania
2014-04-21 11:46
by bitman
RFM12 Mehrzweck Funknetz
RFM12 Network

neues vom Projekt 'RFM12 Mehrzweck Funknetz'

Die Funk-Node hat nun einen Bewegungssensor bekommen



Der PIR Bewegungs Sensor hat einen geringen Stromverbrauch und einen weiten Versorgungs-Spannungsbereich (0,8V bis 9V, Leistungsaufnahme 50 Mikroampere).
Dadruch kann ich ihn einfach parallel zur RFM12-Funknode anschließen und den Ausgang auf den Externen INT1 Pin legen
Den Sensor (DYP ME003DD) findet man bei Ebay per Suche nach '2x IR Sensor Melder Module PIR Low Voltage' und kostet ca 3,41 € pro Stück.


Link zu Projektbeschreibung (./index.php?page=252)
Hier die neueste Version zum Download (Eagle Files für das Board und die Software): file

Ich habe den Sleep Mode durch Abschalten von weiteren Komponenten und vor allem des RFM12 verbessert.
Der Stromverbrauch sinkt im Schlafzustand von 24.46 mA auf 276 uA

Hier sieht man den Spannungsverlauf der Test-Node.
Die Node ist noch direkt an zwei NiMH Zellen in Reihe angeschlossen.

Man sieht beim Ersten Versuch wie die Spannung im Verlaufe eines Tages schnell absinkt.
Beim anschließenden Versuch mit dem gefixten Sleep Mode hält der Akku nun schon fast 5 Tage.



Hier muß ich aber noch weiter verbessern.
Der DHT22 liefert hier zum Beispiel keine vernünftigen Luftfeuchte Werte da er weit unter seinem Spannungsbereich von 3.3V liegt.
In der nächsten Version spendiere ich daher erstmal einen 3.3V Spannungsregler und drei NiMH Zellen



An meinem Heimserver (Debian-Linux) habe ich dieses kleine Script erstellt, welches die seriellen Ports nach dem RFM12-Gateway Master absucht und das erste gefundene dann periodisch liest, mitloggt und Aktionen anstößt.

Das Logfile zeigt was so im Funknetz los ist, z.B. die erkannte Bewegung vom Sensor 2222:
:::
2014-04-21 10:50:54.142 31288 rfm12_gateway.py aaaa: M-- 01 0073 00ab 0001 999 999 4897 07 00 00 o 1030
2014-04-21 10:51:11.166 31288 rfm12_gateway.py 2222: INT1 PD3 open
2014-04-21 10:51:11.167 31288 rfm12_gateway.py motion detected
2014-04-21 10:51:21.289 31288 rfm12_gateway.py 2222: S-S 01 0534 0031 0002 999 201 2637 07 00 00 o 1030
2014-04-21 10:51:21.290 31288 rfm12_gateway.py rrdtool update /var/www/rrd/test.rrd N:20.1:99.9:2.637
2014-04-21 10:51:23.315 31288 rfm12_gateway.py 2222: INT1 PD3 close
2014-04-21 10:51:23.316 31288 rfm12_gateway.py motion release
2014-04-21 10:51:39.431 31288 rfm12_gateway.py 1111: S-- 01 0157 00bc 0001 999 999 5073 07 00 00 o 1030
2014-04-21 10:51:53.724 31288 rfm12_gateway.py aaaa: M-- 01 0074 00b1 0001 999 999 4897 07 00 00 o 1030
2014-04-21 10:52:20.760 31288 rfm12_gateway.py 2222: S-S 01 0538 0031 0002 999 201 2637 07 00 00 c 1030
2014-04-21 10:52:20.761 31288 rfm12_gateway.py rrdtool update /var/www/rrd/test.rrd N:20.1:99.9:2.637
2014-04-21 10:52:52.835 31288 rfm12_gateway.py aaaa: M-- 01 0075 00b2 0001 999 999 4897 07 00 00 o 1030
2014-04-21 10:53:20.874 31288 rfm12_gateway.py 2222: S-S 01 0539 0031 0002 999 202 2631 07 00 00 c 1030
2014-04-21 10:53:20.876 31288 rfm12_gateway.py rrdtool update /var/www/rrd/test.rrd N:20.2:99.9:2.631
2014-04-21 10:53:21.963 31288 rfm12_gateway.py 1111: S-- 01 015c 00c1 0001 999 999 5073 07 00 00 o 1030
:::


Ich lasse mir im Testbetrieb nun eine Email zuschicken wenn sich was bewegt.

Eine andere Aktion wäre z.B. eine Email, wenn der Spannungswert einer Node einen Schwellwert unterschreitet.
Dadurch bekommt man dann frühzeitig mit das man die Akkus wechseln sollte.

Hier das Script: rfm12_gateway.py
#!/usr/bin/python
# coding=utf-8

# Script: rfm12_gateway.py
#
# Author: bitman (a) bitmania.de
#
# Date: 2014-04-21
#
# Projekt: RFM12 Network (https//www.bitmania.de/index.php?page=252)
#
# Purpose: Scan currently present ttyUSB devices for RFM12-Gateway
# Connect to the first found ttyUSB device and scan for RFM12 Network messages
# Log incoming data pakets and trigger actions
#
#
#
#

import os, sys, string, time, serial, socket, struct, datetime, re, urllib, urllib2, urlparse, MySQLdb, math, random



# rrdtool create test.rrd --step 300 DS:TEMP:GAUGE:600:U:U DS:HREL:GAUGE:600:U:U DS:U:GAUGE:600:U:U RRA:AVERAGE:0.5:1:525600

hour = int(time.strftime("%H",time.localtime()))
minute = int(time.strftime("%M",time.localtime()))
random.seed()
data_interval = 300 # intervall (sec) for check and process new files

pid = os.getpid()
script_name = os.path.basename(__file__) # the name of this script (ommiting path)

path_rrd = '/var/www/rrd'
log_dir = '/my-data/log/rfm_gateway'

log_file = 'rfm_gateway.log.'


def str2milliseconds(s):
s = s.replace('.', '-')
s = s.replace('_', ' ')
dt = time.mktime(time.strptime(s,'%Y-%m-%d %H:%M:%S'))
return dt



#===========================================================
#
# Simple Logging Function
#
def logger(log_string):
for line in string.split(log_string, '
'):
#if(line!=''):
ts=time.time()
timestamp = time.strftime("%Y-%m-%d %H:%M:%S.",time.localtime(ts))
timestamp = timestamp+str(ts % 1)[2:5] # adding milliseconds
lstring = timestamp+" "+str(os.getpid())+" "+script_name+" "+line
fd=open(log_dir+"/"+log_file+time.strftime("%Y-%m-%d",time.localtime(time.time())),'a')
fd.write(lstring+"
")
fd.close()
print lstring

return 0


#========================================================================
#
# return the timestamp of next even interval in seconds since 01.01.1970
#
def nextrun(d_int):
ts1=time.time()
ts2= ts1-(ts1 % d_int)+d_int
return ts2



def scan_serial_rfm():
''' scan for serial devices that return valid response to the get awake command'''
devices = []
for t in range(16):
device='/dev/ttyUSB'+str(t)
if os.path.exists(device):
logger("check "+device)
ser = serial.Serial(device, baudrate=38400, bytesize=8, stopbits=1, timeout=0 )
ser.write("get awake
") #
time.sleep(.05)
data = ser.read(1000)
#print data
if(data.find('get')>=0 and data.find('[0][')>=0):
devices = devices + [device]
ser.close()

if(len(devices)>0):
logger("Devices found "+str(len(devices))+" , first is "+devices[0] )
return devices[0]
else:
logger("No device found")
return False


logger( '--< start >------------------' )
tsnext=nextrun(data_interval)
#logger(str(len(sys.argv)))
#logger(str(sys.argv[0]))


device = scan_serial_rfm()
if(device):
logger("Open "+device)
ser = serial.Serial(device, baudrate=38400, bytesize=8, stopbits=1, timeout=0 )
ser.write("
") #
time.sleep(.05)
line =''
while True:
if( time.time()>=tsnext ):
logger("Run ")
ts_now = tsnext
tsnext=nextrun(data_interval) # set time for next run

#logger(str(ser))


tmp1='rrdtool graph test.png -l 2 -r -i -t "U 24h" -v "V" -w 500 -h 220
--legend-position=south
--alt-autoscale
--right-axis 1:0
--x-grid MINUTE:10:HOUR:1:MINUTE:60:1200:%H
--watermark "`date '+%Y-%m-%d %H:%M:%S'`"
--end now --start end-24h
DEF:VAL1='+path_rrd+'/test.rrd:U:AVERAGE
DEF:VAL2='+path_rrd+'/test.rrd:U:AVERAGE:step=750
AREA:VAL1#459BFF:
LINE1:VAL1#ABC6E7:
LINE2:VAL2#2B6BB6:
GPRINT:VAL1:LAST:"Last: %3.2lf %s"
GPRINT:VAL1:AVERAGE:"Avg: %3.2lf %s"
GPRINT:VAL1:MIN:"Min: %3.2lf %s"
GPRINT:VAL1:MAX:"Max: %3.2lf %s"
COMMENT:"
"'

tmp2='rrdtool graph test.png -i -t "U 7d" -v "V" -w 500 -h 220
--legend-position=south
--alt-autoscale
--right-axis 1:0
--end now --start end-1w
--watermark "`date '+%Y-%m-%d %H:%M:%S'`"
DEF:VAL1='+path_rrd+'/test.rrd:U:AVERAGE
DEF:VAL2='+path_rrd+'/test.rrd:U:AVERAGE:step=750
AREA:VAL1#459BFF:
LINE1:VAL1#ABC6E7:
LINE2:VAL2#2B6BB6:
GPRINT:VAL1:LAST:"Last: %3.2lf %s"
GPRINT:VAL1:AVERAGE:"Avg: %3.2lf %s"
GPRINT:VAL1:MIN:"Min: %3.2lf %s"
GPRINT:VAL1:MAX:"Max: %3.2lf %s"
COMMENT:"
"'

#logger( tmp2 )
logger("rrdtool graph")
os.system(tmp2)

tmp='cp test.png /my-data/pub/'
logger( tmp )
os.system(tmp)






for c in ser.read(ser.inWaiting()):
line=line+c


if c == '
':
#logger("Line: " + line[:-1])
data=line.split(" ")
if(len(data)>1):
logger(line[:-1])
#logger(str(data))

if(data[0]=='2222:' and len(data)==4):
#logger(str(data))
if(data[1]=='INT1' and data[2]=='PD3'):
if(data[3].find("open" ) >= 0):
logger("motion detected")
if(data[3].find("close" ) >= 0):
logger("motion release")
os.system('echo "'+str(data)+'" |mailx -s "motion detected" email@email.email')

if(data[0]=='2222:' and len(data)==14):
#logger("+")
#print data

temp=float(data[7])/10
humi=float(data[6])/10
u =float(data[8])/1000
#if(temp==99.9): temp='99'
#if(humi==99.9): humi='99'
#logger("temp = "+str(temp))
#logger("humi = "+str(humi))
#logger("U = "+str(u))
tmp='rrdtool update '+path_rrd+'/test.rrd N:'+str( temp )+':'+str( humi )+':'+str( u )
logger( tmp )
os.system(tmp)

line = ''
break
time.sleep(1)
ser.close()


sys.exit()