#!/usr/bin/python  
########################################################################
#                         RPi_logger5.py                               #
########################################################################
#
########################################################################  
# Raspberry Pi Sensor Data Collector                                   #  
# Collect Temperature/Humidity/Analog data readings from               #  
# a remote microcontroller and post the data to a Google form          #  
# Using Adafruit Example Routines and RF24 Example Routines            #  
# March 7, 2016                                                        #  
# ST                                                                   #
# There are limited error check routines in this script.               #
# This script expects to find 28 bytes of data sent by the nRF24L01+   #
# This script will fail should there not be 28 bytes of data, even     #
# though dynamic payloads has been enabled.                            #
########################################################################
  
# Using Optimized nRF24L01 Libraries  
  
########################################################################  
# Data format                                                          #  
#                                                                      #  
# Integers, 2 bytes long Low byte, High byte                           #  
# result given by 256*High byte + Low byte                             #  
#                                                                      #  
# payload length = 26 bytes                                            #  
# note as written the program will fail should the data payload length #  
# change ... we need to put a dynamic allowance in place               #  
# [Sensor],[startTime],[thisTime],[Apin0(Light)],[Apin1],Apin2], ...   #  
# [Apin3],[Apin4],[Apin5],[Apin6],[Apin7],[temperatureC],[humidity], ..#
# [ds18b20C] 
########################################################################
#                                                                      #
# Require urllib3                                                      #
# get it by:                                                           #
# pip install urllib3                                                  #
# or download from github                                              #
########################################################################
# nCurses Screen Layout 75 x 25 characters:
# nCurses coordinates y,x 
#
# A_BLINK       Blinking text
# A_BOLD 	    Extra bright or bold text
# A_DIM 	    Half bright text
# A_REVERSE 	Reverse-video text
# A_STANDOUT 	The best highlighting mode available
# A_UNDERLINE 	Underlined text

########################################################################
#            1         2         3         4         5         6         7
#  0123456789012345678901234567890123456789012345678901234567890123456789012345
# 0                 Raspberry Pi Base Station Unit #1
# 1
# 2 Data Collected:
# 3
# 4Sensor ID:            
# 5
# 6DHT11 Temperature(C):               Analog Pin 0:
# 7DHT11 Humidity(%):                  Analog Pin 1:
# 8DS18B20 Temperature(C):             Analog Pin 2:
# 9Photo Resistor:                     Analog Pin 3:
#10thisTime(millis):                   Analog Pin 4:                                    Analog Pin 4:
#11                                    Analog Pin 5:
#12                                    Analog Pin 6:
#13                                    Analog Pin 7:
#14=====================================================================
#15Base Station Data Readings:                               
#16DHT11 Temperature:    C                               
#17DHT11 Humidity:        %
#18Raspberry Pi Internal Temperature:     C
#19
#20=====================================================================
#21                            Message Area
#22                               
#23
#24
########################################################################

from __future__ import print_function  
  
import RPi.GPIO as GPIO  
import time  
import os  
import Adafruit_DHT  

import curses
  
import requests  
  
import time  
from RF24 import *  
  
########################################################################  
  
pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2]  # only using two pipes at the moment
length = 0  

Sid = 0
temperatureC = 0
humidity = 0
startTime = 0
thisTime = 0
ds18b20C = 0

Apin0 = 0
Apin1 = 0
Apin2 = 0
Apin3 = 0
Apin4 = 0
Apin5 = 0
Apin6 = 0
Apin7 = 0

GPIO4 = 7    # GPIO  4 Pin  7 DHT11 Temperature/Humidity sensor  
pDHT11 = 4   # GPIO 4 ==> DHT11  
  
LED1 = 29  
LED2 = 33  
noLEDS = 2  
  
LOOP = 1  
LOOP_No = 3

HUM = 0.0  
TempC = 0.0  
TempF = 0.0  
RPiC = 0.0  
RPiF = 0.0  
  
# cleanup and begin  
  
pins = [LED1, LED2]  # all LED pins  
                                                                 
sensor = Adafruit_DHT.DHT11 
  
########################################################################  
# Google Forms URL Data                                                #  
########################################################################  
  
# Copy the form autofill address from Google.  
#  
# https://docs.google.com/forms/d/1onnROUjj1Orjoge0STvMRA7PDDR-YKw5eoo2mruLSCQ/viewform?entry.1183120755=ID&entry.408289807=DT&entry.2133582784=DH&entry.181535051=18B&entry.1756888165=Ph&entry.1187558071=sT&entry.498543388=nT&entry.1127599175=RDT&entry.751073501=RDH&entry.1895537677=RI&entry.773327888=SSub  
# 
# break the url down and create the submission entries
# Submissions:  
# entry.1183120755=ID& : Sid  
# entry.408289807=DT&  : temperatureC   
# entry.2133582784=DH& : humidity  
# entry.181535051=18B& : ds18b20C  
# entry.1756888165=Ph& : Apin0  
# entry.1187558071=sT& : startTime  
# entry.498543388=nT&  : thisTime  
# entry.1127599175=RDT&: TempC  
# entry.751073501=RDH& : HUM  
# entry.1895537677=RI& : RPiC  
# entry.773327888=SSub : Submitter  
#
########################################################################  
  
Submitter = 'Raspberry Pi B+ (nRF24L01+ Radio Sensor Board Base #1)'  
  
submissions =   {'entry.1183120755': Sid , 'entry.408289807': temperatureC , 'entry.2133582784': humidity , 'entry.181535051': ds18b20C , 'entry.1756888165': Apin0 , 'entry.1187558071': startTime , 'entry.498543388': thisTime , 'entry.1127599175': TempC , 'entry.751073501': HUM , 'entry.1895537677': RPiC , 'entry.773327888': Submitter  }  
 
url = 'https://docs.google.com/forms/d/1onnROUjj1Orjoge0STvMRA7PDDR-YKw5eoo2mruLSCQ/viewform?entry.1183120755=ID&entry.408289807=DT&entry.2133582784=DH&entry.181535051=18B&entry.1756888165=Ph&entry.1187558071=sT&entry.498543388=nT&entry.1127599175=RDT&entry.751073501=RDH&entry.1895537677=RI&entry.773327888=SSub'  
formID = '1onnROUjj1Orjoge0STvMRA7PDDR-YKw5eoo2mruLSCQ'  
formviewurl = 'https://docs.google.com/forms/d/' + formID + '/viewform'  
formResponseurl = 'https://docs.google.com/forms/d/' + formID + '/formResponse'  
   
########################################################################  
  
GPIO.setmode(GPIO.BOARD)  # use the pin numbers to identify GPIO  
   
########################################################################  
  
# Based on Adafruit Example   
def readDHT11(p):  
        GPIO.output(LED1, False)  
        # Adafruit library requires GPIO pin numbers  
        # Try to grab a sensor reading.  Use the read_retry method which will retry up  
        # to 15 times to get a sensor reading (waiting 2 seconds between each retry).  
        humidity, temperature = Adafruit_DHT.read_retry(sensor, p)  
        # Note that sometimes you won't get a reading and  
        # the results will be null (because Linux can't  
        # guarantee the timing of calls to read the sensor).    
        # If this happens try again!  
        if humidity is not None and temperature is not None:  
                    #print ('Temperature =   {0:0.1f}C  Humidity=  {1:0.1f}%'.format(temperature, humidity))  
                    global HUM ; HUM = humidity  
                    global TempC ; TempC = temperature  
                    global TempF ; TempF = (TempC * 1.8) + 32.0  
                    GPIO.output(LED1, True)
        else:  
                   mscreen.addstr(21,0, "...Failed to read the DHT11. Trying again!!!...            ")  
                   mscreen.refresh()
        GPIO.output(LED1,False)  
   
########################################################################  
  
def readPiTemp():  
            GPIO.output(LED2, False)  
            res = os.popen('vcgencmd measure_temp').readline()  
            GPIO.output(LED2, True)  
            time.sleep(1)  
            GPIO.output(LED2, False)  
            return(res.replace("temp=","").replace("'C\n",""))  
   
########################################################################  
          
def flashLEDs(n):  
    for n in range(0, n):  
        for i in range(0,(noLEDS-1)):  
            gpin=pins[i]  
            GPIO.output(gpin,True)  
            time.sleep(0.1)  
            GPIO.output(gpin,False)  
            time.sleep(0.1)  
              
    for n in range(0, LOOP_No):  
       for i in range((noLEDS-1), -1, -1):  
            gpin=pins[i]  
            GPIO.output(gpin,True)  
            time.sleep(0.1)  
            GPIO.output(gpin,False)  
            time.sleep(0.1)  
  
########################################################################  
  
def postData():  
	submissions = {'entry.1183120755': Sid , 'entry.408289807': temperatureC , 'entry.2133582784': humidity , 'entry.181535051': ds18b20C , 'entry.1756888165': Apin0 , 'entry.1187558071': startTime , 'entry.498543388': thisTime , 'entry.1127599175': TempC , 'entry.751073501': HUM , 'entry.1895537677': RPiC , 'entry.773327888': Submitter}
	response = requests.post(formResponseurl, submissions)
	return 1
  
########################################################################  

def nCursesPrint():
    mscreen.addstr(2,1, "Data Collected:", curses.A_BOLD)
    mscreen.addstr(4,1, "Sensor ID:", curses.A_UNDERLINE)
    mscreen.addstr(6,1, "DHT11 Temperature(C):")
    mscreen.addstr(7,1, "DHT11 Humidity(%):")
    mscreen.addstr(8,1, "DS18B20 Temperature(C):")
    mscreen.addstr(9,1, "Photo Resistor:")
    mscreen.addstr(10,1, "thisTime(millis):")
    mscreen.addstr(6,35, "Analog Pin 0:")
    mscreen.addstr(7,35, "Analog Pin 1:")
    mscreen.addstr(8,35, "Analog Pin 2:")
    mscreen.addstr(9,35, "Analog Pin 3:")
    mscreen.addstr(10,35, "Analog Pin 4:")
    mscreen.addstr(11,35, "Analog Pin 5:")
    mscreen.addstr(12,35, "Analog Pin 6:")
    mscreen.addstr(13,35, "Analog Pin 7:")
    mscreen.addstr(14,0, "===========================================================================")
    mscreen.refresh()
    
########################################################################

def nCursesData():
    string = str(Sid) + "    "
    mscreen.addstr(4,11, string)
    string = str(temperatureC) + "    "
    mscreen.addstr(6,22, string)
    string = str(humidity) + "    "
    mscreen.addstr(7,19, string)
    string = str(ds18b20C)
    mscreen.addstr(8,24, string)
    string = str(Apin0) + "    "
    mscreen.addstr(9,16, string)
    string = str(thisTime) + "    "
    mscreen.addstr(10,18, string)
    string = str(Apin0) + "    "
    mscreen.addstr(6,48, string)
    string = str(Apin1) + "    "
    mscreen.addstr(7,48, string)
    string = str(Apin2) + "    "
    mscreen.addstr(8,48, string)
    string = str(Apin3) + "    "
    mscreen.addstr(9,48, string)
    string = str(Apin4) + "    "
    mscreen.addstr(10,48, string)
    string = str(Apin5) + "    "
    mscreen.addstr(11,48, string)
    string = str(Apin6) + "    "
    mscreen.addstr(12,48, string)
    string = str(Apin7) + "    "
    mscreen.addstr(13,48, string)
    mscreen.refresh()

########################################################################

def nCursesPiH():
    mscreen.clear()
    mscreen.addstr(0,17, "Raspberry Pi Base Station Unit #1", curses.A_REVERSE)
    string = "==========================================================================="
    mscreen.addstr(20,0, string)
    mscreen.refresh()
    
########################################################################

def nCursesPiData():
	mscreen.addstr(14,0, "===========================================================================")
	mscreen.addstr(15,1, "Base Station Data Readings:", curses.A_BOLD)
	string = "DHT11 Temperature: " + str(TempC) + " C      "
	mscreen.addstr(17,1, string)
	string = "DHT11 Humidity:" + str(HUM) + " %      "
	mscreen.addstr(18,1, string)
	string = "Raspberry Pi Internal Temperature: " + str(RPiC) + " C      "
	mscreen.addstr(19,1, string)
	mscreen.refresh()

########################################################################

def nCursesExit():
	cuses.nocbreak()
	mscreen.keypad(False)
	curses.echo()
	curses.endwin()
	
########################################################################
def nCursesSleeping():
	string = "==========================================================================="
	mscreen.addstr(20,0, string)
	string = "            zzz...sleeping...radio not available...zzz                    "	
	mscreen.addstr(21,0, string, curses.A_REVERSE)
	mscreen.refresh()
########################################################################

def nCursesRadio():
	string = "==========================================================================="
	mscreen.addstr(20,0, string)
	string = "   ...now we have a radio...reading the buffer...buffer length = " + str(length) + "    "
	mscreen.addstr(21,0, string, curses.A_REVERSE)
	mscreen.refresh()
    
def nCursesWindow():
	nCursesPiH()
	nCursesPrint()
	nCursesData()
	nCursesPiData()
	    
######################################################################## 
 
radio = RF24(RPI_BPLUS_GPIO_J8_22, RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ)  
  
########################################################################  
  
radio.begin()  
  
radio.enableDynamicPayloads()  
radio.setRetries(15,15)  
  
radio.setChannel(0x4C)  
radio.setPALevel(RF24_PA_MAX)  
radio.setDataRate(RF24_250KBPS)  
  
radio.openWritingPipe(pipes[1])  
radio.openReadingPipe(1,pipes[0])  
  
radio.stopListening()  
  
#radio.printDetails()  
  
radio.startListening()  
  
for i in range(0,noLEDS):  
    gpin=pins[i]  
    GPIO.setup(gpin,GPIO.OUT)   # set the pin to OUTPUT  
    GPIO.output(gpin,False)     # and make sure it is OFF  
    
# Set up the nCurses window

mscreen = curses.initscr()
mscreen = curses.newwin(25, 75, 0, 0)
mscreen.border(0)
nCursesWindow()

while True:  
    pipe = [0]  
    while not radio.available():  
        time.sleep(2)  
        nCursesSleeping()
        length = radio.getDynamicPayloadSize()  
    buffer = radio.read(length)
    
    nCursesRadio()
      
    flashLEDs(3)  
      
    Sid = buffer[0] + 256*buffer[1]  
    startTime = buffer[2] + 256*buffer[3]  
    thisTime = buffer[4] + 256*buffer[5]  
    Apin0 = buffer[6] + 256*buffer[7]  
    Apin1 = buffer[8] + 256*buffer[9]  
    Apin2 = buffer[10] + 256*buffer[11]  
    Apin3 = buffer[12] + 256*buffer[13]  
    Apin4 = buffer[14] + 256*buffer[15]  
    Apin5 = buffer[16] + 256*buffer[17]  
    Apin6 = buffer[18] + 256*buffer[19]  
    Apin7 = buffer[20] + 256*buffer[21]  
    temperatureC = buffer[22] + 256*buffer[23]  
    humidity = buffer[24] + 256*buffer[25]
    ds18b20C = buffer[26] + 256*buffer[27]  
      
    # now read the DHT11 sensor on the Raspberry Pi  
    readDHT11(pDHT11)  
    readPi = readPiTemp()  
    RPiC = float(readPi)  
    RPiF = (RPiC * 1.8) + 32.0  
    
    nCursesWindow
    
    mscreen.refresh()
    mscreen.clear()
    
    postIt = postData()
    
    nCursesWindow()
    
