#!/usr/bin/python
# Code to control the BMP180 I2C sensor. Write observations to disk
# and to web in intervals determined by input.txt
# Paul A. Kucera, Ph.D. and Joseph E. Rener
# UCAR
# Boulder, CO USA
# Email: pkucera@ucar.edu and jrener@ucar.edu
# Copyright (c) 2018 UCAR
# Developed at COMET at University Corporation for Atmospheric Research and the Research Applications Laboratory at the National Center for Atmospheric Research (NCAR)
# Updated: 28 September 2018

import spidev, time, os, glob, csv, datetime, sys, RPi.GPIO as GPIO, helper_functions # pylint: disable=import-error
from helper_functions import root

# Code for MCP3002
# Channel 0 is for wind direction
def analog_read(channel, spi):
	if ((channel > 1) or (channel < 0)):
		return -1
	r = spi.xfer2([1, (2 + channel) << 6, 0])
	adc_out = ((r[1]&31) << 6) + (r[2]>>2)
	return adc_out


# Get script arguments
arguments = helper_functions.getArguments()
interval = arguments[0]
chords_toggle = arguments[1]
chords_id = arguments[2]

# Set up sensors
spi = spidev.SpiDev()
spi.open(0,0)

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13, GPIO.OUT)

# Get current time
now_file = datetime.datetime.now()

# Initial Wind Count
wnd_cnt = 1
time_cnt = 1

print "Wind Direction Sensor"

# Read wind sensor data
while True:
	then = float(time.time())
	try:
		# Wind sensor is on channel 0
		ch = 0

		# Read the channel
		reading = analog_read(ch, spi)
		
		# Input of min/max from ADC taken from Calibration
		ADC_min = 103
		ADC_max = 920
		ADC_range = ADC_max - ADC_min

		# Convert to deg from north
		if (reading < ADC_min):
			wnddir = 0
		elif (reading > ADC_max):
			wnddir = 360
		else:
			# Get ADC to relative zero
			ADC_rel = reading - ADC_min
			wnddir = ADC_rel*360.0/ADC_range

		# Record the first angle
		if(time_cnt == 1):
			wnddir_sum = wnddir
			wnddir_prev = wnddir
			time_cnt = 2
		elif (time_cnt < 61):
			delta_wnd = wnddir - wnddir_prev
			# Assign the next value
			if( delta_wnd < -180.0):
				wnddir_sum = wnddir_sum + (wnddir_prev + delta_wnd + 360.0)
				wnddir_prev = wnddir_prev + delta_wnd + 360.0
				wnd_cnt = wnd_cnt + 1
			elif (abs(delta_wnd) < 180.0):
				wnddir_sum = wnddir_sum + (wnddir_prev + delta_wnd)
				wnddir_prev = wnddir_prev + delta_wnd
				wnd_cnt = wnd_cnt + 1
			elif (delta_wnd > 180):
				wnddir_sum = wnddir_sum + (wnddir_prev + delta_wnd - 360.0)
				wnddir_prev = wnddir_prev + delta_wnd - 360.0
				wnd_cnt = wnd_cnt + 1
			else:
				print("delta wind is 180 deg, undefined and not used")
			# Increase the time cnt by 1
			time_cnt = time_cnt + 1
		else:
			if( wnd_cnt > 1):
				wnddir_avg = wnddir_sum/wnd_cnt
				if(wnddir_avg > 360.0):
					wnddir_avg = 360.0
				if(wnddir_avg < 0.0):
					wnddir_avg = 0.0
			else:
				wnddir_avg = -999.0
					
			# Get current time for writing to file
			now = datetime.datetime.now()

			# Handle script output
			line = "%02d %02d %4d %02d %02d %5d %5.1f %5.1f" % (now.month, now.day, now.year, now.hour, now.minute, reading, wnddir, wnddir_avg)			
			filename = root + 'data/wind_direction/wind_direction_%4d%02d%02d.dat' % (now.year, now.month, now.day)
			helper_functions.output(True, line, filename)

			# Function to send data to CHORDS (if applicable)
			if wnddir_avg > 0.0:
				url = "http://3d.chordsrt.com/measurements/url_create?instrument_id=%d&wd=%05.1f&key=21DE6A8A" % (chords_id, wnddir_avg)
			else:
				url = "http://3d.chordsrt.com/measurements/url_create?instrument_id=%d&wd=%05.1f&key=21DE6A8A" % (chords_id, wnddir)
			helper_functions.reportCHORDS(chords_toggle, now.minute, interval, url)

			# Reset variables
			wnd_cnt = 1
			time_cnt = 1
				
		# Wait until a second has passed since current run began, and run again
		now = float(time.time())
		diff = now-then
		sleep_time = 1-diff
		if sleep_time > 0:
			time.sleep(sleep_time)
	
	except Exception, e:
		helper_functions.handleError(e)

GPIO.cleanup()
