#!/usr/bin/python
# coding: iso-8859-15 
import RPi.GPIO as GPIO
import MFRC522
import signal
import collections
import os
import sys
import smbus
import subprocess
import pygame
import math
import lcddriver
import time
import datetime
import MySQLdb as mdb
from time import *
from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte
from taalmodule import *
from myconfig import *
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(sirene_pin, GPIO.OUT)
GPIO.setup(voed_relais_pin,GPIO.OUT)
#NFC modulepins worden gezet door script MFRC522
GPIO.setup(8, GPIO.IN)
GPIO.setup(10, GPIO.IN)
GPIO.setup(camptica_pin,GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_camperdeur, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_slaap, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_links, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_rechts, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_pirlinks, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(reed_pirrechts, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(slaapm_toggle, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(taalkeuze_pin, GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(sens, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(led_slaap, GPIO.OUT)
GPIO.setup(36, GPIO.OUT)
GPIO.setup(38, GPIO.OUT)

#definieer de overige variabelen die onafhankelijk zijn van de feitelijke installatie
pirlijst=[] # checklist voor defecte pirs
trillijst=[] # checklist voor defecte tril/geluidssensors
my_Triggerlist=[] #hierin staan alle triggers die in één sessie afgaan
myNegeermultilijst=[] # een geactiveerde sensor mag niet nog een keer alarm slaan voordat ie weer tot rust is gekomen
# we slaan de originele int_lijst_b (interruptlijst tril/geluidsensors) op omdat in een sessie de lijst kan worden aangepast dmv autodetect defecte sensor
# en we zo bij de start van een volgende sessie weer naar het origineel terug kunnen keren
orig_int_lijst_b=int_lijst_b 
nu=time.time()
laatste_trigger=nu # tijdstip waarop laatste tril/geluidsensor getriggerd is
laatste_pirtrigger=nu # tijdstip waarop de laatste pir getriggerd is
laatste_meting=nu-2000 #laatste meting sensors temperatuur etc.
eerste_deurreed=nu
db = mdb.connect('localhost', 'root', '1Piano%', 'sensors');
cursor = db.cursor()
eerste=0
alarmfase=0
alarmaan=0
alarm=0
piractief=0
bijzonderheden=0
slaapmodus_actief=False
tweedekeer=False
webcam_on=False
beveiligcam_on=False
alarmtype=0; # 0 is hoog, 1 is laag
wachttijd=pir_duur
laatste_camp=time.time() #we willen camptica 2 minuten laten werken en hebben daar een starttijd voor nodig
controlnfc=0
camper_domotica_on=False
GPIO.output(voed_relais_pin,GPIO.LOW) # voeding voor sensors is uit
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
nullijst=['0','0','0','0','0','0','0','0']
vatoud1=0
oudniveau=[5,5,5,5,5,5,5,5,8,8,8,8,0,0,30,5]
lcd = lcddriver.lcd()

def end_read(signal,frame):
	global alarm
	global alarmaan
	print "Ctrl+C captured, ending read."
	alarm=1
	alarmaan=0
def to_seconds(timestr):
    seconds= 0
    for part in timestr.split(':'):
        seconds= seconds*60 + int(part)
    return seconds	

signal.signal(signal.SIGINT, end_read)
MIFAREReader = MFRC522.MFRC522()
pygame.mixer.init()

def getMCP(adress,register,type):
	try:
		bin_data = '{0:08b}'.format(bus.read_byte_data(adress, register))
		if type==0:
			list_data = []
			for i in bin_data:
				list_data.append(i)
			return list_data
		else:
			return bin_data	
	except IOError:
		if type==0:
			return nullijst
		else:
			return 0b00000000
def setMCP(adress,register, list):
	str_data = ""	
	for i in list:
		str_data = str_data + str(i)
	hex_data = int(str_data.format(10), 2)
	try:
		bus.write_byte_data(adress, register, hex_data)
		return 1
	except IOError:
		return 0
		
		
def initMCP():
	try:
		# MCP[0]
		iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[0],IODIRA,iolijst) #zet alle pinnen op input
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[0],INTCONA,iolijst) # 0= interrupt als waarde wijzigt, 1= als waarde anders is dan in DEFVAL		
		time.sleep(0.1)		
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[0],DEFVALA,iolijst) # evaluatiewaarde 0;
		time.sleep(0.1)		
		iolijst=[0,0,0,0,0,1,0,0]
		setMCP(MCP[0],IOCONA,iolijst) # zet uitvoer op open drain
		time.sleep(0.1)		
		#iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[0],GPINTENA,int_lijst_a) # zet alle pinnen op interrupt
		time.sleep(0.1)
		iolijst=[1,1,1,1,1,0,1,1]
		setMCP(MCP[0],IODIRB,iolijst) #zet alle pinnen op input
		time.sleep(0.1)	
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[0],INTCONB,iolijst) # 0= interrupt als waarde wijzigt, 1= als waarde anders is dan in DEFVAL	
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[0],GPPUB,iolijst) # zet voor ongebruikte (tril)poorten de PUllUP aan 
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[0],DEFVALB,iolijst) # evaluatiewaarde hoog
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,1,0,0]
		setMCP(MCP[0],IOCONB,iolijst) # zet uitvoer op open drain
		time.sleep(0.1)
		#iolijst=[1,1,1,1,1,0,1,1]
		setMCP(MCP[0],GPINTENB,int_lijst_b) # zet alle pinnen op interrupt
		time.sleep(0.1)
		
		#MCP[1]		
		iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[1],IODIRA,iolijst) # zet alle pinnen op input
		time.sleep(0.1)		
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[1],INTCONA,iolijst) # 0= interrupt als waarde wijzigt, 1= als waarde anders is dan in DEFVAL		
		time.sleep(0.1)		
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[1],DEFVALA,iolijst) # evaluatiewaarde 0;
		time.sleep(0.1)		
		iolijst=[0,0,0,0,0,1,0,0]
		setMCP(MCP[1],IOCONA,iolijst) # zet uitvoer op open drain
		time.sleep(0.1)		
		#iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[1],GPINTENA,int_lijst_a) # zet alle pinnen op interrupt
		time.sleep(0.1)
		iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[1],IODIRB,iolijst) # zet alle pinnen op input
		time.sleep(0.1)
		iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[0],GPPUB,iolijst) # zet voor ongebruikte poorten de PUllUP aan 
		time.sleep(0.1)
		iolijst=[1,1,1,1,1,1,1,1]
		setMCP(MCP[1],INTCONB,iolijst) # bij geluid en tril alleen bij RISING
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[1],DEFVALB,iolijst)  # evaluatiewaarde 0;
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,1,0,0]
		setMCP(MCP[1],IOCONB,iolijst) # zet uitvoer op open drain
		time.sleep(0.1)
		iolijst=[0,0,0,0,0,0,0,0]
		setMCP(MCP[1],GPINTENB,iolijst) # zet de interrupt			
		time.sleep(0.1)
		
	except IOError:
		return 0
def getpin(lijst):
	list_data=getMCP(lijst[0],lijst[1],0)
	num=7-lijst[2]
	return list_data[num]
def setpin(lijst,waarde):
	if lijst[1]==20:
		list_data=getMCP(lijst[0],18,0)		
	else:
		list_data=getMCP(lijst[0],19,0)
	bit_nr=7-lijst[2]
	list_data[bit_nr]=waarde
	try:
		setMCP(lijst[0],lijst[1],list_data)
	except IOError:
		return 0	
def run_cmd(cmd):
    return subprocess.check_output(cmd, shell=True).decode('utf-8')

def get_my_ipwlan():
    val = run_cmd("/sbin/ifconfig wlan0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'")[:-1]
    if val == "":
        val = "No conn.!"
    return val
		
def sms_zend(var4):
	try:		
		msg="msg "+my_tel+" ALARM sensor nr: "+var4
		subprocess.call('telegram-cli -W -D server.pub -e '+chr(34)+msg+chr(34)+' safe quit', shell=True)
	except IOError:
		return 0	
def checkcard():
	var6=0
	(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
	(status,uid) = MIFAREReader.MFRC522_Anticoll()
	if status == MIFAREReader.MI_OK:
		key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
		MIFAREReader.MFRC522_SelectTag(uid)
		status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
		if status == MIFAREReader.MI_OK:
			code_blok = MIFAREReader.MFRC522_Read(8)			
			MIFAREReader.MFRC522_StopCrypto1()
			if code_blok == check_blok:
				if GPIO.input(sens)==0: #gevoeligheid hoog
					var6=1				
				else:
					var6=2			
	return var6

	
def vuldata(varsoort,varom,varpin,vartijd):
	try:
		SQL = "INSERT INTO alarm (soort,omschrijving,pin_nr,datum_tijd) VALUES (%s, %s,%s, %s);" # Note: no quotes
		data = (varsoort,varom,varpin,vartijd)
		cursor.execute(SQL, data)
		db.commit()		
	except IOError:
		return 0		

def vulpir(varpin,varom,vartijd,varsec,vareerste,vardelta,vartrig,varcap,varpio):
	try:
		SQL = "INSERT INTO infrarood (pir_nr,omschrijving,tijd,seconden,eerste,delta,trigdata,caplijst,gpio) VALUES (%s,%s,%s,%s,%s,%s, %s,%s,%s);" # Note: no quotes
		data = (varpin,varom,vartijd,varsec,vareerste,vardelta,vartrig,varcap,varpio)
		cursor.execute(SQL, data)
		db.commit()		
	except IOError:
		return 0			
		
def maakdatabase_leeg():
	try:		
		SQL = "TRUNCATE TABLE alarm"	
		cursor.execute(SQL)
		db.commit()	
		SQL = "TRUNCATE TABLE infrarood"	
		cursor.execute(SQL)
		db.commit()	
	except IOError:
		return 0	
		
def vultemp(vartijd,vartemp,varhum,varbaro,varkoel):
	try:
		SQL = "INSERT INTO temperatuur(datum_tijd,temp,hum,baro,koel) VALUES(%s,%s,%s,%s,%s);" # Note: no quotes
		data = (vartijd,vartemp,varhum,varbaro,varkoel)
		cursor.execute(SQL, data)
		db.commit()		
	except IOError:
		return 0			

def init_webcam():
	global webcam_on
	if webcam_on:
		clear_lcd()
		lcd.backlight(1)
		lcd.lcd_display_string("Webcam is uitgezet",1)
		subprocess.call('sudo motion stop', shell=True)
		subprocess.call('sudo service motion stop', shell=True)
		time.sleep(2)
		lcd.backlight(0)
		webcam_on=False
	else:
		clear_lcd()
		lcd.backlight(1)
		lcd.lcd_display_string("Webcam is aangezet",1)
		subprocess.call('sudo motion -c /home/pi/alarmsys/webcam.conf',shell=True)
		time.sleep(1)
		subprocess.call('sudo service motion start', shell=True)		
		time.sleep(1)
		lcd.backlight(0)
		webcam_on=True
	
def controle_pir(varlijst1,varlijst2):
	var2=False	
	for y in range (0,8):
		if (int(varlijst1[y])==1 and varlijst2[y]==1):
			var2=True
	return var2
	
def checkdefect(var): #0=pir 1=tril/sonor
	global pirlijst
	global trillijst
	global int_lijst_a
	global int_lijst_b
	global piractief
	defsensor=0
	if var==0:
		pirlijst.sort
		totaal=len(pirlijst)
		teller=int_lijst_a.count(1) # hoeveel pirs in werking?
		minfreq=3*(100/teller)+1 # significante proc frequentie voor defect
		grens=int((minfreq*totaal)/100)				
		for y in range (0,8):
			aantal=pirlijst.count(y)
			bit_nr=7-y
			if (aantal>grens):
				int_lijst_a[bit_nr]=0	
				defsensor=1
			else:
				int_lijst_a[bit_nr]=1		
		str_data = ""	
		for i in int_lijst_a:
			str_data = str_data + str(i)
		if defsensor==1:
			vulpir(0,"defect pir",datetime.datetime.now().strftime("%H:%M:%S"),0,0,0,str_data,'','')
		else:
			vulpir(0,"GEEN defecte pir",datetime.datetime.now().strftime("%H:%M:%S"),0,0,0,str_data,'','')
		pirlijst=[]
	else:
		trillijst.sort
		totaal=len(trillijst)
		teller=int_lijst_b.count(1) # hoeveel pirs in werking?
		minfreq=3*(100/teller)+1 # significante proc frequentie voor defect
		grens=int((minfreq*totaal)/100)
		for y in range (0,8):
			aantal=trillijst.count(y)
			if aantal>grens:
				bit_nr=7-y
				int_lijst_b[bit_nr]=0
				defsensor=1
		str_data = ""	
		for i in int_lijst_b:
			str_data = str_data + str(i)
		if defsensor==1:
			vulpir(0,"defecte tril",datetime.datetime.now().strftime("%H:%M:%S"),0,0,0,str_data,'','')
		else:
			vulpir(0,"GEEN defecte tril",datetime.datetime.now().strftime("%H:%M:%S"),0,0,0,str_data,'','')
		
		trillijst=[]
	initMCP()
	piractief=0
	
	
def testalarm(var1): #var1=1 slaapmodus var1=2: normale modus	
	alarmset=-1
	var6=0
	alarmset=0
	if GPIO.input(reed_rechts)==1:
		alarmset=1
		reedstring='reed rechts'
	if GPIO.input(reed_links)==1:
		alarmset=2
		reedstring='reed links'
	if var1==2:
		if GPIO.input(reed_slaap)==1:
			alarmset=3	
			reedstring='reed slaapkamer'
	if GPIO.input(reed_camperdeur)==1:
		alarmset=4				
		reedstring='reed camperdeur'
	if GPIO.input(reed_pirlinks)==1:
		alarmset=5
		reedstring='reed pir links'
	if GPIO.input(reed_pirrechts)==1:
		alarmset=6				
		reedstring='reed pir rechts'
	if alarmset>0:
		var6=1
	return var6
def clear_lcd():
	lcd.lcd_display_string("                    ",1)
	lcd.lcd_display_string("                    ",2)
	lcd.lcd_display_string("                    ",3)
	lcd.lcd_display_string("                    ",4)


def getShort(data, index):
	# return two bytes from data as a signed 16-bit value
	return c_short((data[index+1] << 8) + data[index]).value

def getUShort(data, index):
	# return two bytes from data as an unsigned 16-bit value
	return (data[index+1] << 8) + data[index]

def getChar(data,index):
	# return one byte from data as a signed char
	result = data[index]
	if result > 127:
		result -= 256
	return result

def getUChar(data,index):
	# return one byte from data as an unsigned char
	result =  data[index] & 0xFF
	return result

def readBME280ID(addr):
	# Chip ID Register Address
	REG_ID     = 0xD0
	(chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
	return (chip_id, chip_version)

def readBME280All(addr):
	# Register Addresses
	REG_DATA = 0xF7
	REG_CONTROL = 0xF4
	REG_CONFIG  = 0xF5
	REG_CONTROL_HUM = 0xF2
	REG_HUM_MSB = 0xFD
	REG_HUM_LSB = 0xFE

	# Oversample setting - page 27
	OVERSAMPLE_TEMP = 2
	OVERSAMPLE_PRES = 2
	MODE = 1

	# Oversample setting for humidity register - page 26
	OVERSAMPLE_HUM = 2
	bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)

	control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
	bus.write_byte_data(addr, REG_CONTROL, control)

	# Read blocks of calibration data from EEPROM
	# See Page 22 data sheet
	cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
	cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
	cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)

	# Convert byte data to word values
	dig_T1 = getUShort(cal1, 0)
	dig_T2 = getShort(cal1, 2)
	dig_T3 = getShort(cal1, 4)

	dig_P1 = getUShort(cal1, 6)
	dig_P2 = getShort(cal1, 8)
	dig_P3 = getShort(cal1, 10)
	dig_P4 = getShort(cal1, 12)
	dig_P5 = getShort(cal1, 14)
	dig_P6 = getShort(cal1, 16)
	dig_P7 = getShort(cal1, 18)
	dig_P8 = getShort(cal1, 20)
	dig_P9 = getShort(cal1, 22)

	dig_H1 = getUChar(cal2, 0)
	dig_H2 = getShort(cal3, 0)
	dig_H3 = getUChar(cal3, 2)

	dig_H4 = getChar(cal3, 3)
	dig_H4 = (dig_H4 << 24) >> 20
	dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)

	dig_H5 = getChar(cal3, 5)
	dig_H5 = (dig_H5 << 24) >> 20
	dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)

	dig_H6 = getChar(cal3, 6)

	# Read temperature/pressure/humidity
	data = bus.read_i2c_block_data(addr, REG_DATA, 8)
	pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
	temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
	hum_raw = (data[6] << 8) | data[7]

	#Refine temperature
	var1 = ((((temp_raw>>3)-(dig_T1<<1)))*(dig_T2)) >> 11
	var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
	t_fine = var1+var2
	temperature = float(((t_fine * 5) + 128) >> 8)-140;

	# Refine pressure and adjust for temperature
	var1 = t_fine / 2.0 - 64000.0
	var2 = var1 * var1 * dig_P6 / 32768.0
	var2 = var2 + var1 * dig_P5 * 2.0
	var2 = var2 / 4.0 + dig_P4 * 65536.0
	var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
	var1 = (1.0 + var1 / 32768.0) * dig_P1
	if var1 == 0:
		pressure=0
	else:
		pressure = 1048576.0 - pres_raw
		pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
		var1 = dig_P9 * pressure * pressure / 2147483648.0
		var2 = pressure * dig_P8 / 32768.0
		pressure = pressure + (var1 + var2 + dig_P7) / 16.0
	# Refine humidity
	humidity = t_fine - 76800.0
	humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
	humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
	if humidity > 100:
		humidity = 100
	elif humidity < 0:
		humidity = 0

	return temperature/100.0,pressure/100.0,humidity

def fetch_baro(adr):
	global warmte
	temperature,pressure,humidity = readBME280All(adr)
	warmte=temperature
	return temperature,pressure,humidity
def fetch_koel():
	temperatures=[]
	temp = 0
	for polltime in range(0,3):
		text = '';
		while text.split("\n")[0].find("YES") == -1:
			tfile = open("/sys/bus/w1/devices/"+ koel_sensor+"/w1_slave")
			text = tfile.read()
			tfile.close()
			#time.sleep(1)
			secondline = text.split("\n")[1]
			temperaturedata = secondline.split(" ")[9]
			temperature = float(temperaturedata[2:])
			temperatures.append(temperature / 1000)
	avgtemperatures=sum(temperatures) / float(len(temperatures))
	temp="{0:.1f}".format(round(avgtemperatures,1))
	return temp


def slaapmodus_toggle():
	global slaapmodus_actief
	global camper_domotica_on
	global laatste_camp
	global oudniveau
	global standaard
	if slaapmodus_actief==False:
		GPIO.output(voed_relais_pin,1) # zet voeding aan		
		initMCP()
		voeding_on=True
		time.sleep(1)
		uitkomst=testalarm(1)
		if uitkomst==0:
			oudniveau=standaard
			standaard=campingniv
			tril_high=[standaard[0],standaard[1]]
			tril_low=[standaard[2],standaard[3]]
			portier_high=[standaard[4],standaard[5]]
			portier_low=[standaard[6],standaard[7]]
			pir_high=[standaard[8],standaard[9]]
			pir_low=[standaard[10],standaard[11]]
			reed_contact=[standaard[12],standaard[13]]
			pir_duur=standaard[14]
			trigger_max=standaard[15]
			clear_lcd()
			lcd.backlight(1)
			lcd.lcd_display_string("Slaapmodus is",1)
			lcd.lcd_display_string("geactiveerd!",2)
			lcd.lcd_display_string("Dit display gaat uit",3)
			lcd.lcd_display_string("in 5 seconden",4)
			GPIO.output(led_slaap,1) #zet led slaapmodus aan				
			slaapmodus_actief=True								
			alarmaan=1
			if GPIO.input(sens)==1:
				alarmtype=0
			else:
				alarmtype=1;
			time.sleep(4)
			clear_lcd()
			lcd.backlight(0)			
			time.sleep(30)
		else:
			clear_lcd()
			lcd.backlight(1)
			lcd.lcd_display_string("Er staat nog een",1)
			lcd.lcd_display_string("deur of raam open!",2)
			lcd.lcd_display_string("Slaapmodus kan niet ",3)
			lcd.lcd_display_string("aangezet worden!",4)
			GPIO.output(voed_relais_pin,0)
			GPIO.output(led_slaap,0)
			time.sleep(5)
			clear_lcd()
			lcd.backlight(0)
			standaard=oudniveau
			slaapmodus_actief=False;
			
	else:		
		clear_lcd()
		lcd.backlight(1)
		lcd.lcd_display_string("Slaapmodus gaat uit",1)
		lcd.lcd_display_string("over 2 seconden",2)
		GPIO.output(led_slaap,0) #zet led slaapmodus uit
		GPIO.output(voed_relais_pin,0)
		slaapmodus_actief=False;
		standaard=oudniveau
		tril_high=[standaard[0],standaard[1]]
		tril_low=[standaard[2],standaard[3]]
		portier_high=[standaard[4],standaard[5]]
		portier_low=[standaard[6],standaard[7]]
		pir_high=[standaard[8],standaard[9]]
		pir_low=[standaard[10],standaard[11]]
		reed_contact=[standaard[12],standaard[13]]
		pir_duur=standaard[14]
		trigger_max=standaard[15]
		sleep(3)
		camper_domotica_on=True				
		laatste_camp=time.time()
		clear_lcd()
		lcd.lcd_display_string("Even geduld a.u.b.",1)
		toggle_backlight()
	
def init_taal():
	global sound
	global aanvullende_taal
	global standaard_taal	
	clear_lcd()
	lcd.lcd_display_string("maak een taalkeuze:",1)
	lcd.lcd_display_string("Houdt knop ingedrukt",2)
	lcd.lcd_display_string("tot gewenste taal",3)
	sleep(2)
	taalteller=0
	taalkeuze=[]
	while taalteller<2:
		while GPIO.input(taalkeuze_pin)==0:
			for z in range(0,19):
				lcd.lcd_display_string("                    ",taalteller+2)
				lcd.lcd_display_string("                    ",3)
				lcd.lcd_display_string("                    ",4)
				if z<17:
					lcd_string=taal[z]+","+taal[z+1]+", "+taal[z+2]+"                                     "					
				else:
					if z<18:
						lcd_string=taal[z]+","+taal[z+1]+", "+taal[0]+"                                        "
					else:
						lcd_string=taal[z]+", "+taal[0]+", "+taal[1]+"                                      "
				lcd_string=lcd_string[0:20]
				lcd.lcd_display_string(lcd_string,taalteller+2)
				sleep(1)
				if GPIO.input(taalkeuze_pin)==1:
					taalkeuze.append(taal[z])
					taalteller +=1
					lcd.lcd_display_string("Houdt knop opnieuw",3)
					lcd.lcd_display_string("ingedrukt",4)
					break
		if taalteller==2:
			try:	
				lcd.lcd_clear()
				lcd.lcd_display_string("even geduld a.u.b.",1)	
				f=open('taalmodule.py','w')
				f.write('standaard_taal='+chr(34)+taalkeuze[0]+chr(34)+chr(13))
				f.write('aanvullende_taal='+chr(34)+taalkeuze[1]+chr(34)+chr(13))
				f.close()
				sleep(5)							
				standaard_taal=taalkeuze[0]
				aanvullende_taal=""
				if taalkeuze[1]<>"leeg":
					aanvullende_taal=taalkeuze[1]
				sound=['sirene','alarm_zwak.mp3',standaard_taal+'.mp3',aanvullende_taal+'.mp3','eind','att','port','alarm','stil','alarmaan.mp3','alarmtest.mp3','alarmuitzonder.mp3','alarmuitmet.mp3','start.mp3']
				lcd.lcd_clear()
				lcd.lcd_display_string("taalkeuze opgeslagen",1)
				lcd.lcd_display_string("1e: "+standaard_taal,2)
				lcd.lcd_display_string("2e: "+aanvullende_taal,3)
				time.sleep(3)
				camp_gelezen=False
				camper_domotica_on=True
				laatste_camp=time.time()				
				toggle_backlight()
			except:
				clear_lcd()
				lcd.lcd_display_string("Err; probeer opnieuw",1)
				sleep(1)
				taalteller=0
				clear_lcd()
				lcd.lcd_display_string("maak een taalkeuze:",1)
				sleep(2)
	
def init_standaard():
	global tril_high
	global tril_low
	global portier_high
	global portier_low
	global pir_high
	global pir_low
	global pir_duur
	global trigger_max
	global standaard	
	clear_lcd()
	lcd.lcd_display_string("Kies niveau: houdt",1)
	lcd.lcd_display_string("taalknop ingedrukt",2)
	lcd.lcd_display_string("tot gewenste keuze",3)
	sleep(3)
	teller=0
	while teller==0:
		while GPIO.input(taalkeuze_pin)==0:
			for z in range(0,5):
				lcd.lcd_display_string("Kies niveau:       ",1)
				lcd.lcd_display_string("                    ",2)
				lcd.lcd_display_string("                    ",3)
				lcd.lcd_display_string("                    ",4)
				if z<4:
					lcd.lcd_display_string(niveau[z]+","+niveau[z+1],2)
				else:
					lcd.lcd_display_string(niveau[z],2)
				time.sleep(1)
				if GPIO.input(taalkeuze_pin)==1:
					standaard=eigenniv
					if niveau[z]=="stad":
						standaard=stadniv
					if niveau[z]=="dorp":
						standaard=dorpniv
					if niveau[z]=="platteland":
						standaard=plattelandniv
					if niveau[z]=="camping":
						standaard=campingniv					
					tril_high=[standaard[0],standaard[1]]
					tril_low=[standaard[2],standaard[3]]
					portier_high=[standaard[4],standaard[5]]
					portier_low=[standaard[6],standaard[7]]
					pir_high=[standaard[8],standaard[9]]
					pir_low=[standaard[10],standaard[11]]
					reed_contact=[standaard[12],standaard[13]]
					pir_duur=standaard[14]
					trigger_max=standaard[15]
					lcd.lcd_display_string("Je hebt gekozen voor",1)
					tekst="niveau "+niveau[z]+"             "
					tekst=tekst[0:20]
					lcd.lcd_display_string(tekst,2)
					lcd.lcd_display_string("laat de knop nu los.",3)
					time.sleep(4)
					break
		lcd.lcd_display_string("keuze opgeslagen",4)
		time.sleep(2)
		teller=1
		lcd.backlight(0)
	
def haaldatatemp():	
	for z in range(0,2):
		temp,press,hum=fetch_baro(drukmeter)	
		kktemp=fetch_koel()	
	vultemp(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),round(temp,1),round(hum),round(press),kktemp)
	
def toggle_backlight():
	global camper_domotica_on
	global now
	global laatste_camp
	global voorbij
	global camp_gelezen
	global lcd_tijd	
	global vatoud1
	global monlicht
	nu=time.time()
	now=datetime.datetime.now()
	voorbij=nu-laatste_camp
	if voorbij<monlicht:
		lcd.backlight(1)
		temp,press,hum=fetch_baro(drukmeter)
		kktemp=fetch_koel()				
		ipadr=get_my_ipwlan()
		line_1="temperatuur  "+str(round(temp,1))+chr(223)+"C       " 
		line_1=line_1[0:20]
		line_2="koelkast temp "+str(kktemp)+chr(223)+"C      "
		line_2=line_2[0:20]
		line_3="baro "+str(int(round(press,0)))+" hPa; "+now.strftime("%H:%M")+"    "
		line_3=line_3[0:20]
		line_4="hum "+str(int(round(hum)))+"% "+ipadr+"                    "
		line_4=line_4[0:20]		
		lcd.lcd_display_string(line_1,1)
		lcd.lcd_display_string(line_2,2)
		lcd.lcd_display_string(line_3,3)
		lcd.lcd_display_string(line_4,4)							
	else:
		clear_lcd()		
		lcd.backlight(0)
		camper_domotica_on=False
		vatoud1=0
		

def reset_sensors():
	try:		
		trigdata = getMCP(MCP[0],INTFA,1)		
		caplijst = getMCP(MCP[0],INTCAPA, 0)				
		alijst = getMCP(MCP[0],GPIOA, 1) # reset interrupt
		time.sleep(1)
		trigdata = getMCP(MCP[1],INTFA,1)		
		caplijst = getMCP(MCP[1],INTCAPA, 0)				
		alijst = getMCP(MCP[1],GPIOA, 1) # reset interrupt
		time.sleep(1)
		data=getMCP(MCP[1],INTFB,1)
		caplijst = getMCP(MCP[1],INTCAPB, 0)		
		blijst = getMCP(MCP[1],GPIOB, 0) #reset interrupt	
		time.sleep(1)
	except IOError:
		return 0	
	

def sound_waarschuwing(var1,varpin,var2,var3): # var1= sensor , varpin=pinnr, var2 = (0) 1e of (1) 2e keer, var 3 = duur bij sirene
	global soortdb
	if var1=="sound_only":
		geluidsnum=var2	
	if var1=="multi":
		if alarmtype==0:
			geluidsnum=reed_contact[var2]
		else:
			geluidsnum=reed_contact[var2]		
	if var1=="tril":
		if alarmtype==0:
			geluidsnum=tril_high[var2]
		else:
			geluidsnum=tril_low[var2]
	if var1=="portson" or var1=="porttril":
		if alarmtype==0:
			geluidsnum=portier_high[var2]
		else:
			geluidsnum=portier_low[var2]
	if var1=="pir":
		if alarmtype==0:
			geluidsnum=pir_high[var2]
		else:
			geluidsnum=pir_low[var2]
	if geluidsnum==0: #sirene		
		GPIO.output(sirene_pin,1) # sirene aan 
		time.sleep(var3) #gedurende var3 seconden
		GPIO.output(sirene_pin,0) # sirene uit 		
	if ((geluidsnum==1) or (geluidsnum>8)):
		try:
			geluidsfragment=path_geluid+sound[geluidsnum]			 			
			pygame.mixer.music.load(geluidsfragment)
			pygame.mixer.music.play()
			while pygame.mixer.music.get_busy() == True:
				continue
					
		except IOError:
			return 0
	if geluidsnum==2:
		try:			
			geluidsfragment=path_geluid+sound[geluidsnum]			 			
			pygame.mixer.music.load(geluidsfragment)
			pygame.mixer.music.play()
			while pygame.mixer.music.get_busy() == True:
				continue
			geluidsfragment=path_geluid+sound[geluidsnum+1]
			if os.path.isfile(geluidsfragment):
				pygame.mixer.music.load(geluidsfragment)
				pygame.mixer.music.play()
				while pygame.mixer.music.get_busy() == True:
					continue
			
		except IOError:
			return 0	
	if (geluidsnum>2 and geluidsnum<8):
		try:			
			geluidsfragment=path_geluid+sound[geluidsnum]+sound[2]			 
			pygame.mixer.music.load(geluidsfragment)
			pygame.mixer.music.play()
			while pygame.mixer.music.get_busy() == True:
				continue
			
			
		except IOError:
			return 0
	if geluidsnum>3:
		geluidsnum=geluidsnum-1
	if geluidsnum<6:
		vuldata(var1,soortdb[geluidsnum],varpin,datetime.datetime.now().strftime("%H:%M:%S"))
		
			
def trigger_alarm(pinnum,pinstr,pinwaarde):
	global actief_trigger
	global trigger_list
	if (alarmfase==2 and pinwaarde==1):
		try:
			value_index=slaapmodus_gpbcheck.index(pinnum)
		except:
			value_index=-1
		if ((slaapmodus_actief==False) or (value_index==-1)):
			seconds=to_seconds(datetime.datetime.now().strftime("%H:%M:%S"))
			if seconds-actief_trigger[pinnum]>verlooptijd:
				trigger_list[pinnum]=0				
			#controleer of deze sensor al eerder is afgegaan			
			if trigger_list[pinnum]==0:
				# eerste keer
				trigger_list[pinnum]=1	
				actief_trigger[pinnum]=seconds				
				sound_waarschuwing(sensor[pinnum],pinnum+1,0,alarm_duur1)
			else:
				# vaker					
				if ((trigger_list[pinnum]<trigger_max) or (trigger_max==0)):
					trigger_list[pinnum]=trigger_list[pinnum]+1						
					sound_waarschuwing(sensor[pinnum],pinnum+1,1,alarm_duur2)
				else:
					vuldata(pinnum+1,"tril zonder",pinnum,datetime.datetime.now().strftime("%H:%M:%S"))
			


def check_pir():	
	global alarmfase
	global piractief
	global laatste_pirtrigger
	global eerste
	global oudeerste
	global pirlijst	
	try:		
		trigdata = getMCP(MCP[bank],INTFA,1)
		triglijst=getMCP(MCP[bank],INTFA,0)
		caplijst = getMCP(MCP[bank],INTCAPA, 0)
		capbin=getMCP(MCP[bank],INTCAPA, 1) # om te testen en op te kunnen slaan in pirdata
		alijst = getMCP(MCP[bank],GPIOA, 1) # reset interrupt		
		trigstr=format(int(trigdata,2), '08b')
		capstr=format(int(capbin,2), '08b')
		astr=format(int(alijst,2), '08b')
		seconds=to_seconds(datetime.datetime.now().strftime("%H:%M:%S"))
		if (int(alijst,2)==0 and eerste>0): # als geen enkele pir meer actief				
			verschil=seconds-eerste
			eerste=0							
		if (eerste>0 and int(alijst,2)>0): 
			if seconds-eerste>pir_duur: # (één of meerdere van) de pirs zijn langer onafgebroken actief dan pir_duur
				werkend=controle_pir(caplijst,int_lijst_a) #zijn de getriggerde pirs niet defect? bij True gaan we door bij False geen waarschuwing.				
				if ((piractief<2) and werkend): #maximaal tweemaal waarschuwingsboodschap laten horen
					piractief +=1
					verschil=seconds-eerste
					if piractief==1:
						sound_waarschuwing("pir",astr,0,0)						
						eerste=to_seconds(datetime.datetime.now().strftime("%H:%M:%S"))						
					else:
						sound_waarschuwing("pir",astr,1,0)						
				else:
					eerste=to_seconds(datetime.datetime.now().strftime("%H:%M:%S"))	
		if int(trigdata,2) == 0:			
			if (int(alijst,2))==0: # nu weten we zeker geen enkele pir meer actief
				if alarmfase==2: #maar alarm staat nog in fase 2, dus
					nu= time.time()
					if nu-laatste_pirtrigger>verlooptijd: # laatste melding langer geleden dan verlooptijd
						my_Triggerlist=[] # maak triggerlijst leeg
						alarmfase=1  # schakel over naar fase 1
						piractief=0 # waarschuwing weer aan													
						eerste=0 #eerste trigger is nul
					else:
						if (nu-laatste_pirtrigger>int(verlooptijd/2) and piractief==1): # laatste waarschuwing langer geleden dan de helft van de verlooptijd
							piractief=0 # waarschuwing weer aan													
							eerste=0
		else:			
			seconds=to_seconds(datetime.datetime.now().strftime("%H:%M:%S"))
			if piractief==0:
				blijst = getMCP(MCP[0],GPIOB, 0) # reset interrupt tril- en geluidssensoren om valse alarmmeldingen te voorkomen				
			for z in range(0,8):
				if int(triglijst[7-z])==1:
					if int(alijst[7-z])==1:
						if eerste==0:
							eerste=seconds						
						alarmfase=2
						nu=time.time()
						laatste_pirtrigger=nu							
						verschil=seconds-eerste
						if int(int_lijst_a[7-z])==1:
							vulpir(z+1,"pir actief",datetime.datetime.now().strftime("%H:%M:%S"),seconds,eerste,verschil,trigstr,capstr,astr)
							if autocheck==1:
								if (int(triglijst[7-z]))==1:
									pirlijst.append(z)								
								if len(pirlijst)>50:
									checkdefect(0)					
		blijst = getMCP(MCP[bank],GPIOA, 1) # reset interrupt
	except IOError:
		return 0
	

		
def check_state():
	global bijzonderheden
	global trillijst
	try:
		if alarmfase==2: #alleen als alarmfase 2 door triggering pirs
			data=getMCP(MCP[0],INTFB,1)			
			trigdata=getMCP(MCP[0],INTFB,0)			
			if int(data,2)>0: # alleen als een bit 1 is						
				caplijst = getMCP(MCP[0],INTCAPB, 0)		
				blijst = getMCP(MCP[0],GPIOB, 0) #reset interrupt
				capbin=getMCP(MCP[0],INTCAPB, 1) # om te testen en op te kunnen slaan in pirdata
				alijst = getMCP(MCP[0],GPIOB, 1) # reset interrupt	
				trigstr=format(int(data,2), '08b')
				capstr=format(int(capbin,2), '08b')
				astr=format(int(alijst,2), '08b')				
				tijdstip=datetime.datetime.now().strftime("%H:%M:%S")				
				for z in range(0,8):
					if (int(trigdata[7-z])==1) and (int(int_lijst_b[7-z])==1):
						if (int(caplijst[7-z])==1):
							try:
								value_index=slaapmodus_gpbcheck.index(7-z)
							except:
								value_index=-1
							if ((slaapmodus_actief==False) or (value_index>-1)):
								trigger_alarm(z,trigstr,1)	
								bijzonderheden +=1
								if autocheck==1:
									if (int(trigdata[7-z]))==1:
										trillijst.append(z)								
									if len(trillijst)>25:
										checkdefect(1)
				clijst = getMCP(MCP[0],GPIOB, 1) #reset interrupt
	except IOError:
		return 0
		
def check_reed():
	global myNegeermultilijst
	global eerste_deurreed
	global tweedekeer
	global bijzonderheden
	try:		
		alarmset=0
		if GPIO.input(reed_rechts)==1:
			alarmset=1
			reedstring='reed rechts'
		if GPIO.input(reed_links)==1:
			alarmset=2
			reedstring='reed links'
		if GPIO.input(reed_slaap)==1:
			alarmset=3	
			reedstring='reed slaapkamer'
		if GPIO.input(reed_camperdeur)==1:
			alarmset=4				
			reedstring='reed camperdeur'
		if GPIO.input(reed_pirlinks)==1:
			alarmset=5
			reedstring='reed pir links'
		if GPIO.input(reed_pirrechts)==1:
			alarmset=6				
			reedstring='reed pir rechts'
		if alarmset>0:
			try:
				value_index=slaapmodus_check.index(alarmset)
			except:
				value_index=-1
			if ((slaapmodus_actief==False) or (value_index>-1)):
				try:
					value_index = myNegeermultilijst.index(alarmset)
				except:
					value_index = -1
				if value_index == -1: #eerste keer dat deze sensor wordt getriggerd
					myNegeermultilijst.append(alarmset)	
					nu= time.time()										
					if alarmset<>4:
						bijzonderheden +=1
						sound_waarschuwing("sound_only",0,7,0)
						sound_waarschuwing("multi",alarmset,0,alarm_duurreed)
						sms_zend(reedstring)
						
					else:
						eerste_deurreed=nu
				else:
					if (alarmset==4 and tweedekeer==False):
						nu= time.time()
						if nu-eerste_deurreed>uitschakeltijd: # langer dan de uitschakeltijd uit config, dus alarm af laten gaan
							sound_waarschuwing("sound_only",0,7,0)
							sound_waarschuwing("multi",alarmset,0,alarm_duurreed)
							sms_zend(reedstring)
							tweedekeer=True
	except IOError:
		return 0	

lcd_tijd=time.time()
lcd.backlight(0)
alarm=0
	
# hier begint de lees-routine
bank=0 # 0 = MCP[0] 1=MCP[1]
initMCP()
voeding_on=True
nu=time.time()
laatste_meting=nu
haaldatatemp()	
resultaat=testalarm(2)					
if resultaat==0:
	if GPIO.input(sens)==0:			
		alarmtype=0;
	else:
		alarmtype=1; #alarm gevoeligheid LAAG
	alarmaan=1		
	maakdatabase_leeg()	
	GPIO.output(voed_relais_pin,GPIO.HIGH) # zet hoofdvoeding aan
	time.sleep(30) #alarm op scherp na 30 sec
	if beveiligcam_on==False:
		subprocess.call('sudo motion -c /home/pi/alarmsys/motion.conf', shell=True)
		time.sleep(1)
		subprocess.call('sudo service motion start', shell=True)
		beveiligcam_on=True;
	reset_sensors()
	time.sleep(1)
	reset_sensors()
	eerste=0
try:
     while alarm==0:
		if monitoring>0:
			nu=time.time()
			if nu-laatste_meting>mon_interval:
				laatste_meting=nu				
				haaldatatemp()
		if camper_domotica_on==True:
			toggle_backlight()	
		if GPIO.input(camptica_pin)==0:
			lcd.backlight(1)
			time.sleep(0.5)
			if GPIO.input(taalkeuze_pin)==0:
				init_webcam()
			else:
				laatste_camp=time.time()
				vatoud1=0	
				camper_domotica_on=True				
				toggle_backlight()
		if GPIO.input(slaapm_toggle)==0:
			lcd.backlight(1)
			time.sleep(0.5)
			if GPIO.input(taalkeuze_pin)==0:
				lcd.backlight(1)
				init_standaard()
			else:
				slaapmodus_toggle()
		if GPIO.input(taalkeuze_pin)==0:
			init_taal()
		#check of alarm aan wordt gezet
		controlnfc=checkcard()		
		if controlnfc>0:
			GPIO.output(voed_relais_pin,GPIO.HIGH) # zet hoofdvoeding aan	
			time.sleep(0.5)
			sound_waarschuwing("sound_only",0,13,0)
			time.sleep(uitschakeltijd)
			resultaat=testalarm(2)
			if resultaat==0:	
				int_lijst_b=orig_int_lijst_b #we pakken de originele interrupt-lijst van de sensors weer op 
				initMCP()
				voeding_on=True
				time.sleep(1)							
				sound_waarschuwing("sound_only",0,9,0)						
				alarmaan=1
				if controlnfc==1: # alarm gevoeligheid HOOG
					alarmtype=0;
				else:
					alarmtype=1; #alarm gevoeligheid LAAG
				controlnfc=0
				maakdatabase_leeg();
				int_lijst_b=orig_int_lijst_b
				time.sleep(30) #alarm op scherp na 30 sec
				if beveiligcam_on==False:
					subprocess.call('sudo motion -c /home/pi/alarmsys/motion.conf', shell=True)					
					time.sleep(1)
					subprocess.call('sudo service motion start', shell=True)
					beveiligcam_on=True;
				reset_sensors()
				reset_sensors()
				eerste=0
			else:
				sound_waarschuwing("sound_only",0,10,0)	
				GPIO.output(voed_relais_pin,GPIO.LOW) # zet hoofdvoeding uit
		#hier start de subloop als alarm aangezet is		
		while alarmaan==1:
			try:
				if monitoring==2:
					nu=time.time()
					if (nu-laatste_meting>mon_interval) and (alarmfase==1):
						laatste_meting=nu
						haaldatatemp()				
				check_state() # controleer sensors 
				check_pir()	# controleer infra-rood-sensoren							
				check_reed() # controleer reed-kontakten
				if GPIO.input(slaapm_toggle)==0: # als slaapmodus: check of slaapmodus wordt uitgezet
					slaapmodus_toggle()
				#nu NFC tag uitlezen voor het geval alarm uitgezet moet worden
				controlenfc=checkcard()
				if controlenfc>0:
					alarmaan=0
					alarmset = -1					
					voeding_on=False												
					if  bijzonderheden==0: # de lijst is leeg - behoudens de opening van de deur om alarm uit te zetten - en dus geen alarm afgegaan
						sound_waarschuwing("sound_only",0,11,0)
					else:
						sound_waarschuwing("sound_only",0,12,0)						
					myNegeermultilijst = [] #maak de negeerlijst leeg
					my_Triggerlist=[]						
					if beveiligcam_on:
						subprocess.call('sudo motion stop', shell=True)
						time.sleep(1)
						subprocess.call('sudo service motion stop', shell=True)
						beveiligcam_on=False;
					time.sleep(5) #wacht 5 seconden om "dubbel" lezen van de card tegen te gaan																
					GPIO.output(voed_relais_pin,GPIO.LOW) # geen voeding meer aan sensors						
			except KeyboardInterrupt:
				raise
			#hier eindigt de alarm-loop	
			
except KeyboardInterrupt:
	raise
#hier eindigt de hoofdroutine
db.close()
GPIO.cleanup()
