#!/usr/bin/env python

###############################################################################
#
# Copyright 2017 - 2019 NXP
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
###############################################################################

# DESCRIPTION:		  Read the accelerometer and store the data into database
# INPUT/S:			  NA  
# OUTPUT/S:			  Data_Collection_<time stamp>.xls

import serial
from xlwt import Workbook
import time
from serial.serialutil import portNotOpenError
from datetime import datetime
import os
import glob
import sys

###################################################################
# Serial configurations
###################################################################
COMPORT = "COM16"					# Serial Port number of EVKB i.MXRT1050 development board
BAUDRATE = "115200"

###################################################################
# Data Base
###################################################################
DATABASE = "Data_Collection_"

###################################################################
# Data Base Configurations
###################################################################
saveflag = 0

SheetLimit = 50
Sheet_No = 0

raw = 0
RawLimit = 65500

GeneratedExcel = None
WriteSheet = None

temp = 0
temp_report = 0

###################################################################
# Timming Configurations
###################################################################
Hours_ = 0.25								# No. of hours for which we want to read the accelerometer data 
time_period =  (60*60)*Hours_               
timeout = time.time() + time_period
CurrentTime = time.time()
tmptimeout = time.time() + 60*1


###################################################################
# Class for the serial operation
###################################################################
class SerLine(object):
	
	def __init__(self,device,baudrate):
		self._device = device
		self._baudrate = "115200"
		self._serial = None
		
	def open(self):
		"""
		Open serial line with predefined settings.
		"""
		try:
			self._serial = serial.Serial(
				port=self._device,
				baudrate=self._baudrate)
			
			return self._serial
		
		except serial.SerialException:
			print("Serial Failure")
			sys.exit()
			self._serial = None
			
			
	def close(self):
		"""
		Close serial line.
		"""
		if self._serial is not None:
			self._serial.close()
			self._serial = None
			
	def writeBytes(self, message):
		"""
		Write message, given as bytes or byte array, to serial line.
		
		message - data to be written.
		
		Returns the number of bytes written.
		
		Remarks: wait until all data is written.
		"""
		self._serial.flushInput()
		self._serial.flushOutput()
		
		if self._serial is None:
			print ("Port is not opened")
			raise portNotOpenError
		
		message = message.encode()
		self._serial.write(message)
		time.sleep(0.2)		
		return message
	
	def readBytes(self):
		"""
		Read data from the serial line until there is no more data to be read.
		
		Returns the bytes read from the serial line when line is open.
		"""
		if self._serial is None:
			raise portNotOpenError
		
		temp = self._serial.readline()
		try:
			data = str(temp.decode('utf-8'))
			return data
		except:
			return None
				
###################################################################
# Class for the Excel operation
###################################################################	
class WriteExcel(object):
	def __init__(self,ExcelName):
		self.Excel = ExcelName
		self.wb = None
		self.sheet = None
		self.wb = Workbook()

	def Create_Excel(self,SheetName):
		self.sheet = self.wb.add_sheet(SheetName)
		
	def Write_Excel(self,raw,clm,value):
		self.sheet.write(raw,clm,value)
		
	def Close_Excel(self):
		self.wb.save(self.Excel)
		

###################################################################
# Main function
###################################################################	
if __name__ == "__main__":
	
	try:
		os.chdir("../DataBase")
		for file_ in glob.glob("*.xls"):
			os.remove(file_)
	except:
		os.mkdir("../DataBase")
		os.chdir("../DataBase")
	
	SerialComm = SerLine(COMPORT,BAUDRATE)
	SerialPort = SerialComm.open()

	print ("="*73)
	print ("\nReading the accelerometer and storing the data into datbase...")
	print ("\nStart Time = ",datetime.now())
	print ("="*73)
	
	while (time.time() < timeout):
		ReceivedData = SerialComm.readBytes()
		
		if((int(tmptimeout - time.time())) == 0):
			print ("Saving Data at ",datetime.now())
			GeneratedExcel.Close_Excel()
			tmptimeout = time.time() + 60*1
			
		if (ReceivedData != None):
			if (("X=" in ReceivedData) and ("Y=" in ReceivedData) and ("Z=" in ReceivedData)):
				ReceivedData = ReceivedData[:-1]
				xindex = ReceivedData.index("X")
				yindex = ReceivedData.index("Y")
				zindex = ReceivedData.index("Z")
				xyz_val = [ReceivedData[(xindex+2):(yindex-1)],ReceivedData[(yindex+2):(zindex-1)],ReceivedData[(zindex+2):]]

				if ((temp_report % SheetLimit) == 0):
					if saveflag == 1:
						GeneratedExcel.Close_Excel()
						saveflag = 0
	
					timestr = time.strftime("%Y%m%d-%H%M%S")   
					DATABASE_NAME = DATABASE+timestr+".xls"
					print ("Generating.....",DATABASE_NAME,"database")
					GeneratedExcel = WriteExcel (DATABASE_NAME)
					saveflag = 1
					temp = 0
	
				if ((temp % RawLimit) != 0):
					try:
						xyz_val = list(map(int,xyz_val))
						for index,val in enumerate(xyz_val):
							GeneratedExcel.Write_Excel(raw,index,val)
						temp = temp + 1
						raw = raw+1
						
					except:
						continue
	
				elif ((temp % RawLimit) == 0):
					raw = 1
					Sheet_No = Sheet_No + 1
					print ("Generating sheet...",Sheet_No)
					sheet = "sheet_"+str(Sheet_No)
					WriteSheet = GeneratedExcel.Create_Excel(sheet)
					ttl1 = ['X','Y','Z']
					for idx,value in enumerate(ttl1):
						GeneratedExcel.Write_Excel(0,idx,value)
					temp = temp + 1
					temp_report = temp_report + 1

		
	GeneratedExcel.Close_Excel()
	print ("="*73)
	print ("End Time = ",datetime.now())
	print ("="*73)
