#!/usr/bin/python
# -*- coding: utf-8 -*-

######################################################################################################
# SOFTWARE VERSIÓN 2.1.
#
#	Esta versión implementa una comunicación "constante" con el controlador bluetooth para ahorrar
#	tiempo en el proceso de respuesta al piloto. Además de esta mejora, se ahorra espacio de memoria
#	guardando en lecturas solo las últimas 5 lecturas y se genera el archivo EXCEL a medida que se
#	realiza el trabajo de pasillo.
#
# NOTAS:
#
#	En la versión 2.1. NO se puede realizar un borrado de última lectura. Para poder realizarlo hay
#	que parar el proceso de trabajo, abrir archivo_txt y borrar manualmente los registros. De tal modo
#	que estemos fuera de una multicapa y que la lectura anterior no sea tampoco una multicapa. Estos
#	problemas se resolverán en la versión 2.2.
#
# INFORMACIÓN:
#
#	Archivo:	 		interfaz_0201.py
#	Entorno de uso:		Python 2.7.13
#	Fecha:				2017/11/22
#	Autor:				Juan de Dios Yáñez Ávila	| CTO at Airvant
#	Contacto:			juandediosyanez@onw4rds.com	| juandediosyanez@airvant.es
#
# DERECHOS:
#
#	Los derechos de uso/explotación de este software son al 50% por Airvant sociedad, y el 
#	desarrollador del mismo. Software no destinado a venta. El código y archivos asociados están 
#	protegidos por las leyes de propiedad intelectual e industrial. El uso fraudulento y no permitido
#	de los mismos está penado por la ley.
#
######################################################################################################

#from Airvant_0201 import *
from bluetooth import *
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders
from openpyxl import Workbook
from Tkinter import *

import datetime
import io
import os
import RPi.GPIO as gpio
import serial
import smtplib
import time

######################################################################################################
######################################################################################################
# VARIABLES GLOBALES
######################################################################################################
## VARIABLES QUE OPERAN EN EL HARDWARE
######################################################################################################
LED1G = 4
LED1B = 17
LED2B = 27
LED34G = 18
LED3R = 23
LED4R = 24

gpio.setmode(gpio.BCM)
gpio.setwarnings(False)
gpio.setup(LED1G, gpio.OUT)
gpio.setup(LED1B, gpio.OUT)
gpio.setup(LED2B, gpio.OUT)
gpio.setup(LED34G, gpio.OUT)
gpio.setup(LED3R, gpio.OUT)
gpio.setup(LED4R, gpio.OUT)
######################################################################################################
## VARIABLES QUE OPERAN EN EL SOFTWARE
######################################################################################################
nombre_archivo_lecturas = str()
direccion_lecturas = str()
nombre_archivo_excel = str()
direccion_excel = str()
lecturas = list()
analisis_del_trabajo = list(range(2)) # [lecturas_realizadas, tiempo_duracion_trabajo]

alturamax = int()
alturamin = int()
anterior_multicapa = bool()
actual_multicapa = bool()
columna = int()
altura = int()
subiendo = bool()

ultima_lectura = str()
######################################################################################################
######################################################################################################

######################################################################################################
######################################################################################################
# FUNCIONES PARA LA FINALIZACIÓN DEL TRABAJO														 #
######################################################################################################
## FUNCIÓN PARA GENERAR ARCHIVO EXCEL PARA TRABAJO CODE-128																##
######################################################################################################
def crear_excel_code128():
	global direccion_lecturas
	global direccion_excel
	## Creamos una lista con las lecturas procesadas dentro del archivo_txt que hemos generado durante
	## el proceso de trabajo. El archivo tiene que existir.
	archivo_txt = open(direccion_lecturas, "r")
	lecturas = archivo_txt.readlines()
	archivo_txt.close()
	## Ahora procesaremos las lecturas para ubicarlas en el archivo excel
	lecturas_procesadas = list([])
	for lectura in lecturas:
		aux_lectura = lectura.split("|") #columna|altura|codigo|subiendo
		aux_lectura = list([aux_lectura[0], aux_lectura[1], aux_lectura[2]]) # columna, altura, codigo
		lecturas_procesadas.append(aux_lectura)
	## Tenemos en memoria el contenido de nuestro futuro archivo Excel, y ahora vamos a reorganizarla,
	## también en memoria, antes de guardarla toda como un archivo Excel.
	wb = Workbook()
	ws = wb.active
	ws.title = "Lecturas pasillo"
	ws.cell(row=1, column=1, value="Columna")
	ws.cell(row=1, column=2, value="Altura")
	ws.cell(row=1, column=3, value="Contenido")
	r = 2
	for dato in lecturas_procesadas:
		ws.cell(row=r, column=1, value=dato[0]) #columna
		ws.cell(row=r, column=2, value=dato[1]) #altura
		ws.cell(row=r, column=3, value=dato[2]) #lectura
		r = r + 1
	wb.save(direccion_excel)
######################################################################################################
## FUNCIÓN PARA GENERAR ARCHIVO EXCEL PARA TRABAJO GS1-128																##
######################################################################################################

######################################################################################################
## FUNCIÓN PARA ENVIAR ARCHIVO EXCEL																##
######################################################################################################
def enviar_trabajo():
	global direccion_excel

	empresa = interfaz_empresa.get()
	pasillo = int(interfaz_pasillo.get())
	pasillo = str("{:03d}".format(pasillo))		
	
	## Para construir el mensaje tenemos que definir remitente y receptor del mismo.
	## Si no hemos establecido uno, se enviará por defecto al email de operativa.airvant@gmail.com
	email = str(interfaz_email.get())
	if(email == ""):
		email = "operativa.airvant@gmail.com"
	#else:
	#	continue
	addr_to = str(email)
	addr_from = "operativa.airvant@gmail.com"
	## Definimos SMTP del email
	smtp_server = "stmp.gmail.com"
	smtp_user = "operativa.airvant@gmail.com"
	smtp_pass = "#airvant.onw"
	## Construimos el email
	mensaje = MIMEMultipart()
	mensaje['From'] = addr_from
	mensaje['To'] = str(email)
	mensaje['Subject'] = "Airvant | Empresa: {0} Pasillo: {1}" .format(empresa, pasillo)
	# El cuerpo del mensaje se estructura en HTML
	mensaje.attach(MIMEText('<h1>Trabajo de pasillo finalizado</h1><p>Descargue el archivo EXCEL adjunto.<p>Gracias por confiar en <b>Airvant</b>.', 'HTML'))
	# Adjuntamos el archivo de direccion_excel
	fp = open(direccion_excel, 'rb')
	adjunto = MIMEBase('multipart', 'encrypted')
	adjunto.set_payload(fp.read())
	fp.close()
	# Encriptamos archivo.
	encoders.encode_base64(adjunto)
	nombre_archivo = empresa + " " + pasillo + ".xlsx"
	adjunto.add_header('Content-Disposition', 'attachment', filename = nombre_archivo)
	mensaje.attach(adjunto)
	
	## Script para el envío del correo electrónico a la dirección indicada
	mailServer = smtplib.SMTP('smtp.gmail.com', 587)
	mailServer.ehlo()
	mailServer.starttls()
	mailServer.ehlo()
	mailServer.login(smtp_user, smtp_pass)
	mailServer.sendmail(addr_from, addr_to, mensaje.as_string())
	mailServer.quit()
######################################################################################################
######################################################################################################

######################################################################################################
######################################################################################################
# FUNCIONES DE LECTURA																				 #
######################################################################################################
## LECTURA DEL SENSOR DE UN CODE-128																##
######################################################################################################
def lectura_code128(longitud_de_codigo, tiempo_para_lectura):
	global ultima_lectura
    ##################################################################################################
    # 1) Se borra cualquier operación anterior activa en el sensor.
	##################################################################################################
	if 'sensor' in locals():
		sensor.close()
	if 'sensor' in globals():
		sensor.close()
	###################################################################################################
	# 2) Se establecen la configuración para la lectura. Longitud del código buscado, tiempo
	#    establecido para encontrar dicha lectura y el puerto desde donde opera el sensor.
	###################################################################################################
	TIEMPO_INICIO_LECTURA = datetime.datetime.now()
	TIEMPO_TRANSCURRIDO_LECTURA = 0
	TIEMPO_DIFERENCIA_LECTURA = 0
	## Ponemos el puerto en escucha estableciendo ciertos términos ligados con read():
	## timeout = none -> espera por siempre hasta completar L (nº de bytes)
	## timeout = 0 -> modo de no bloqueo, va enviando todo lo que coge.
	## timeout = x -> envia lo que coge hasta que el tiempo x ha transcurrido.
	sensor = serial.Serial('/dev/ttyACM0', baudrate = 115200, timeout = 0)
	##################################################################################################
	# 3) Comenzamos el proceso de búsqueda del código.
	#    - Si se encuentra la lectura se envía la cadena de bytes interpretada por el sensor.
	#    - Si no se encuentra la lectura se envía una cadena vacía.
	##################################################################################################
	while(True):
    	## Borramos instrucción de lectura anterior localizada en buffer de entrada.
		## Si no existe instrucción no borra nada.
		sensor.flushInput()
		## Enviamos instrucción de lectura al sensor por buffer de entrada.
		sensor.write("\x16T\r")
		## Tomamos x longitud de bytes de la lectura hecha por el sensor.
		lectura = sensor.read(longitud_de_codigo)
		## Si el sensor ha realizado una lectura de una longitud de bytes mayor estos se quedan enespera.
		enespera = sensor.inWaiting()
		## Procesamos la validez de la lectura.
		if((len(lectura) == longitud_de_codigo) and (enespera == 0) and (lectura != ultima_lectura)):
			sensor.close()
			## La lectura es una cadena de bytes SIN terminación en \n
			ultima_lectura = lectura
			return lectura
		TIEMPO_TRANSCURRIDO_LECTURA = datetime.datetime.now()
		TIEMPO_DIFERENCIA_LECTURA = TIEMPO_TRANSCURRIDO_LECTURA - TIEMPO_INICIO_LECTURA
		## Si se supera el tiempo_para_lectura y no hemos obtenido ninguna lectura, limpiamos los buffer
		## del sensor y enviamos una cadena vacía.
		if(TIEMPO_DIFERENCIA_LECTURA.seconds >= tiempo_para_lectura):
			### Tenemos que cerrar el proceso de lectura que estaba activo
			#sensor.flushInput()
			###
			sensor.flushOutput()
			sensor.close()
			return ""
######################################################################################################
######################################################################################################

######################################################################################################
######################################################################################################
# FUNCIONES DE AVANCE																				 #
######################################################################################################
## AVANCE CONTINUO																					##
######################################################################################################
def avance_continuo():
	global alturamax
	global alturamin
	global columna
	global altura
	global subiendo
	if(subiendo == True):
		altura = altura + 1
		if(altura > alturamax):
			altura = altura - 1
			columna = columna + 1
			Subiendo = False
	else:
		altura = altura - 1
		if(altura < alturamin):
			altura = altura + 1
			columna = columna + 1
			subiendo = True 

	posicion = [columna, altura, subiendo]
	return posicion
######################################################################################################
######################################################################################################



	







######################################################################################################
######################################################################################################
# FUNCIONES DE TRABAJO																		 		 #
######################################################################################################
## GUARDADO DE LECTURA																				##
######################################################################################################
def guardar_lectura(lectura_procesada):
	global direccion_lecturas
	global lecturas
	global actual_multicapa
	global anterior_multicapa
	global columna
	global altura
	global subiendo
	global ultima_lectura

	if((anterior_multicapa == False) and (actual_multicapa == False)):
		## Guardamos en memoria para casos de borrado.
		lecturas.append(lectura_procesada)
		## Guardamos en archivo
		archivo_txt = open(direccion_lecturas, "a")
		archivo_txt.write(lectura_procesada)
		archivo_txt.close()
		posicion = avance_continuo()
							
	elif((anterior_multicapa == False) and (actual_multicapa == True)):
		lecturas.append(lectura_procesada)
		archivo_txt = open(direccion_lecturas, "a")
		archivo_txt.write(lectura_procesada)
		archivo_txt.close()
		anterior_multicapa = True

	elif((anterior_multicapa == True) and (actual_multicapa == False)):
		posicion = avance_continuo()
		lecturas.append(lectura_procesada)
		archivo_txt = open(direccion_lecturas, "a")
		archivo_txt.write(lectura_procesada)
		archivo_txt.close()
		anterior_multicapa = False
		posicion = avance_continuo()

	elif((anterior_multicapa == True) and (actual_multicapa == True)):
		lecturas.append(lectura_procesada)
		archivo_txt = open(direccion_lecturas, "a")
		archivo_txt.write(lectura_procesada)
		archivo_txt.close()
######################################################################################################
## BORRADO DE LECTURA																				##
######################################################################################################

######################################################################################################
## TRABAJO AVANCE CONTINUO CON CODE-128																##
######################################################################################################
def trabajo_avance_continuo_code128(longitud_de_codigo, tiempo_para_lectura):
	global direccion_lecturas
	global lecturas

	global anterior_multicapa
	global actual_multicapa
	global columna
	global altura
	global subiendo

	global ultima_lectura

	### SE COMIENZA A CONTAR EL TIEMPO DE TRABAJO DEL PILOTO ¿GLOBAL O LOCAL?
	tiempo_inicio_trabajo = datetime.datetime.now()
	tiempo_fin_trabajo = 0
	timepo_duracion_trabajo = 0
	lecturas_realizadas = 0
	## Activamos una conexión continua por bluetooth, que espere 2 segundos una instrucción.
	print("""
		Estableciendo conexión:
			s) SIMPLE.
			m) MULTICAPA-SIMPLE
			h) HUECO
			b) BULTO
			i) INCIDENCIA
			y) MULTICAPA-INCIDENCIA
			d) BORRAR ÚLTIMA
			t) TERMINAR
	""")
	server_socket = BluetoothSocket( RFCOMM )
	port = 1
	## Suponemos que solo hay un dispositivo bluetooth conectado por drone
	server_socket.bind(("",port))
	## Intentamos la conexión 5 veces
	server_socket.listen(5)
	client_socket,address = server_socket.accept()
	## Vamos añadir un tiempo de espera para la respuesta, si no la hay, salta un error
	client_socket.settimeout(0.1)
	## INDICAR QUE LA CONEXIÓN SE HA REALIZADO
	mensaje = "Conexión activa. Inicie trabajo...\n"
	print(mensaje)
	client_socket.send(mensaje)
	data = str()
	while True:
		## Si no hay respuesta lo que queremos es que continue ejecutándose el programa
		try:
			## Intenta por el tiempo especificado tomar un mensaje.
			## DEBERIAMOS INDICAR CON UNA LUZ UN TIEMPO PARA ENVIAR EL MENSAJE, QUE SE APAGUE AL FINAL
			## DEL INTENTO
			data = client_socket.recv(1024)
		except:
			## Ante cualquier error, como que no se ha recibido un mensaje, que no cierre en error.
			## TENEMOS QUE ESPECIFICAR UN except EN CASO DE QUE SE PIERDA LA CONEXIÓN, PARA VOLVER
			## A CONECTARNOS
			continue
		finally:

			if(data == "s"):
				actual_multicapa = False
				mensaje = "MODO SIMPLE: "
				client_socket.send(mensaje)
				## Realizamos lectura en modo simple: "00001" ó "" después de un tiempo.
				## Al ser una lectura code128 no necesitamos procesarla, como en el caso de los GS1.
				lectura = lectura_code128(longitud_de_codigo, tiempo_para_lectura)
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = False

			if(data=="m"):
				actual_multicapa = True
				mensaje = "MODO MULTICAPA-SIMPLE: "
				client_socket.send(mensaje)
				## Realizamos lectura en modo simple: "00001" ó "" después de un tiempo.
				## Al ser una lectura code128 no necesitamos procesarla, como en el caso de los GS1.
				lectura = lectura_code128(longitud_de_codigo, tiempo_para_lectura)
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = True

			if(data=="h"):
				actual_multicapa = False
    			## Los huecos no son válidos en multicapas.
				mensaje = "HUECO: "
				client_socket.send(mensaje)
				## Realizamos lectura hueco: "HUECO"
				## Al ser una lectura code128 no necesitamos procesarla, como en el caso de los GS1.
				lectura = "HUECO"
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = False
				## Volvemos al modo simple
				data = "s"

			if(data=="b"):
				actual_multicapa = False
				mensaje = "BULTO: "
				client_socket.send(mensaje)
				lectura = "BULTO"
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = False
				## Volvemos al modo simple
				data = "s"

			if(data=="i"):
				actual_multicapa = False
				mensaje = "INCIDENCIA: "
				client_socket.send(mensaje)
				lectura = "INCIDENCIA"
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = False
				## Volvemos al modo simple
				data = "s"

			if(data=="y"):
				actual_multicapa = True
				mensaje = "MULTICAPA-INCIDENCIA: "
				client_socket.send(mensaje)
				lectura = "MULTICAPA-INCIDENCIA"
				if(lectura != ""):
					lectura_procesada = str(columna)+"|"+str(altura)+"|"+str(lectura)+"|"+str(subiendo)+"\n"
					guardar_lectura(lectura_procesada)
					mensaje = str(lectura_procesada)
					print(mensaje)
					client_socket.send(mensaje)
					anterior_multicapa = True
				## Volvemos al modo simple
				data = "s"

			if(data=="d"):
				mensaje = "BORRANDO ULTIMA: "
				client_socket.send(mensaje)
				mensaje = str(lecturas[-1])
				client_socket.send(mensaje)
				## Las lecturas incorporan ya \n
				lecturas.pop()
				archivo_txt = open(direccion_lecturas, 'w')
				archivo_txt.close()
				###
				for dato in lecturas:
					archivo_txt = open(direccion_lecturas, 'a')
					aux = str(dato)
					archivo_txt.write(aux)  # el método write NO añade \n automáticamente
					archivo_txt.close()
				###
				penultima_lectura = lecturas[-2].split("|")
				ultima_lectura = lecturas[-1].split("|")
				## ¿Estamos en una multicapa o no?
				if((penultima_lectura[0] == ultima_lectura[0]) and (penultima_lectura[1] == ultima_lectura[1])):
					anterior_multicapa = True
					actual_multicapa = True
					data = "m"
				else:
					anterior_multicapa = False
					actual_multicapa = False
					data = "s"
				columna = int(ultima_lectura[0])
				altura = int(ultima_lectura[1])
				## ¿Estamos subiendo o bajando?
				if(ultima_lectura[3] == "True"):
					subiendo = True
				if(ultima_lectura[3] == "False"):
					subiendo = False
				ultima_lectura = str(ultima_lectura[2])
				# Avanzamos un puesto
				posicion = avance_continuo()

			if(data=="t"):
				mensaje = "TRABAJO TERMINADO\n"
				print(mensaje)
				client_socket.send(mensaje)
				## Procesamos los parámetros del análisis del trabajo.
				tiempo_fin_trabajo = datetime.datetime.now()
				tiempo_duracion_trabajo = tiempo_fin_trabajo - tiempo_inicio_trabajo
				tiempo_duracion_trabajo = int(tiempo_duracion_trabajo.seconds)
				lecturas_realizadas = int(len(lecturas))
				## También tenemos que crear el archivo_excel y enviarlo.
				crear_excel_code128()
				mensaje = "EXCEL DE TRABAJO CREADO\n"
				print(mensaje)
				client_socket.send(mensaje)
				enviar_trabajo()
				mensaje = "TRABAJO ENVIADO POR EMAIL\n"
				print(mensaje)
				client_socket.send(mensaje)
				break
	return [lecturas_realizadas, tiempo_duracion_trabajo]
######################################################################################################
######################################################################################################

######################################################################################################
######################################################################################################
# INTERFAZ DEL PROGRAMA																				 #
######################################################################################################
## FUNCIONES ESPECÍFICAS DE LOS BOTONES DE LA INTERFAZ DE USUARIO                                   ##
######################################################################################################
### FUNCIÓN PARA INICIAR EL TRABAJO	EN AVANCE CONTINUO			                                   ###
######################################################################################################
def iniciar_trabajo_continuo():
	global nombre_archivo_lecturas
	global direccion_lecturas
	global nombre_archivo_excel
	global direccion_excel
	global lecturas
	global analisis_del_trabajo

	global alturamax
	global alturamin
	global anterior_multicapa
	global actual_multicapa
	global columna
	global altura
	global subiendo

	## 1) Lo primero es definir las direcciones donde se irán guardando las lecturas y creando el excel.
	empresa = interfaz_empresa.get()
	## El número de pasillo se define en una cadena de 3 bytes (nunca tendremos un pasillo 1000).
	pasillo = int(interfaz_pasillo.get())
	pasillo = str("{:03d}".format(pasillo))
	nombre_archivo_lecturas = empresa + " " + pasillo + ".txt"
	direccion_lecturas = "lecturas/" + str(nombre_archivo_lecturas)
	nombre_archivo_excel = empresa + " " + pasillo + ".xlsx"
	direccion_excel = "excel/" + str(nombre_archivo_excel)
	
	## 2) Definimos la configuración del trabajo, tomando del usuario los datos.
	nombre_del_piloto = str(interfaz_nombre_del_piloto.get())
	tipo_de_codigo = str(interfaz_tipo_de_codigo.get())	
	longitud_de_codigo = int(interfaz_longitud_de_codigo.get())
	tiempo_para_lectura = int(interfaz_tiempo_para_lectura.get())
	alturamax = int(interfaz_alturamax.get())
	piking = str(interfaz_piking.get())
	if(piking == "True"):
		alturamin = 2
	else:
		alturamin = 1
	anterior_multicapa = False
	actual_multicapa = False
	columna = 1
	altura = alturamin
	subiendo = True

	## 3) Analizamos si existe o no el trabajo, y actualizamos la configuración si es necesario.
	existe = False
	if(os.path.exists(direccion_lecturas) == False):
    	## Si el trabajo no existe, se crean los archivos vacíos.
		archivo_txt = open(direccion_lecturas, "w")
		archivo_txt.close()
		archivo_excel = open(direccion_excel, "w")
		archivo_excel.close()
	else:
    	## Si el trabajo existe, tenemos que ver que tiene en su interior.
		existe = True
		## MOSTRAMOS UNA SEÑAL DE QUE EXISTE EL TRABAJO
		"""
			for aviso in range(10):
				gpio.output(LED1G, gpio.HIGH)
				time.sleep(0.3)
				gpio.output(LED1G, gpio.LOW)
				gpio.output(LED1B, gpio.HIGH)
				gpio.output(LED2B, gpio.HIGH)
				time.sleep(0.3)
				gpio.output(LED1B, gpio.LOW)
				gpio.output(LED2B, gpio.LOW)
		"""
		archivo_txt = open(direccion_lecturas, "r")
		lecturas = archivo_txt.readlines()
		archivo_txt.close()
		if(len(lecturas) == 0):
    		## Si el trabajo existe pero no tenía lecturas, realmente no se había comenzado
			archivo_txt = open(direccion_lecturas, "w")
			archivo_txt.close()
			archivo_excel = open(direccion_excel, "w")
			archivo_excel.close()
		else:
    		## Si el trabajo existe y tiene lecturas, tenemos que actualizar la posición y las
			## lecturas.
			## VAMOS A SUPONER QUE ESTO NO VA A OCURRIR DE MOMENTO
			"""
				ultima_lectura = items[-1].split("|")
				###
				print(ultima_lectura)
				# columna | altura | lectura item
				columna = int(ultima_lectura[0]) #3
				altura = int(ultima_lectura[1])  #3
				aux = str(ultima_lectura[3])
				ultima_lectura = str(ultima_lectura[2]) #0000000000010
				if(aux[0] == 'T'):
					SUBIENDO = True
				if(aux[0] == 'F'):
					SUBIENDO = False
				else:
					print("Trabajo terminado en MULTICAPA, requerir técnico para borrado de multicapa")
				print(SUBIENDO)

					if(SUBIENDO == True):
						altura = altura + 1 #4
						if(altura > alturamax):
							altura = altura - 1
							columna = columna + 1
							SUBIENDO = False
						if(altura == alturamax):
							columna = columna + 1 #4
							SUBIENDO = False      # false	
					else:
						altura = altura - 1 		#2
						if(altura < alturamin):
							altura = altura + 1	#3
							columna = columna +1
							SUBIENDO = True
						if(altura == alturamin):
							columna = columna +1	#7
							SUBIENDO = True

				archivo_trabajo.close()
			"""

	## 4) Iniciamos el trabajo según el tipo de código, del cual obtendremos además un análisis
	if(tipo_de_codigo == ""):
		print("Seleccione un tipo de código correcto")
		return
	if(tipo_de_codigo == "Code128"):
		analisis_del_trabajo = trabajo_avance_continuo_code128(longitud_de_codigo, tiempo_para_lectura)
		print(" Análisis del trabajo realizado por el piloto {0}:\n Nº de lecturas realizadas: {1}\n Tiempo requerido: {2}"
			.format(str(nombre_del_piloto), str(analisis_del_trabajo[0]), str(analisis_del_trabajo[1])))
	
	#if(tipo_de_codigo == "GS1128"):
	#	analisis_del_trabajo = iniciarTrabajo_GS1128(empresa, pasillo, alturamax, tiempolectura, PIKING)
	#	print(" Análisis del trabajo realizado por el piloto {0}:\n Nº de lecturas realizadas: {1}\n Tiempo requerido: {2}"
	#		.format(str(nombre_del_piloto), str(analisis_del_trabajo[0]), str(analisis_del_trabajo[1])))
	#if(tipo_de_codigo == "GS1128noSSCC"):
	#	analisis_del_trabajo = iniciarTrabajo_GS1128_noSSCC(empresa, pasillo, alturamax, tiempolectura, PIKING)
	#	print(" Análisis del trabajo realizado por el piloto {0}:\n Nº de lecturas realizadas: {1}\n Tiempo requerido: {2}"
	#		.format(str(nombre_del_piloto), str(analisis_del_trabajo[0]), str(analisis_del_trabajo[1])))
######################################################################################################
### FUNCIÓN PARA INICIAR EL TRABAJO	EN AVANCE APILAMIENTO		                                   ###
######################################################################################################
"""
def iniciarTrabajo_apilamiento():
	global ANALISIS_OPERATIVA
	ANALISIS_OPERATIVA = ()
	empresa = dato_empresa.get()
	# Reajustamos el número de pasillo para que siempre sea lo que queremos.
	# No tendremos 1000 pasillos en un mismo almacén, por tanto con una designación 001 es suficiente.
	pasillo = int(dato_pasillo.get())
	pasillo = str("{:03d}".format(pasillo))
	alturamax = int(dato_alturamax.get())
	CODE = str(dato_CODE.get())
	longitud = int(dato_longitudcodigo.get())
	tiempolectura = int(dato_tiempolectura.get())
	if(CODE==""):
		print("Seleccione un tipo de código correcto")
		return
	if(CODE == "Code128"):
		ANALISIS_OPERATIVA = iniciarTrabajo_Code128_apilamiento(empresa, pasillo, alturamax, longitud, tiempolectura)
	if(CODE == "GS1128"):
		ANALISIS_OPERATIVA = iniciarTrabajo_GS1128_apilamiento(empresa, pasillo, alturamax, tiempolectura)
	if(CODE == "GS1128noSSCC"):
		ANALISIS_OPERATIVA = iniciarTrabajo_GS1128_noSSCC_apilamiento(empresa, pasillo, alturamax, tiempolectura)
	return
"""
######################################################################################################
## OPERACIONES DE ARRANQUE DEL PROGRAMA                                                             ##
######################################################################################################
## Encendemos todas las luces para indicar que el técnico esta configurando el trabajo y borramos   ##
## de la pantalla cualquier alerta o trabajo anterior.                                              ##
######################################################################################################
gpio.output(LED1G, gpio.HIGH)
gpio.output(LED1B, gpio.HIGH)
gpio.output(LED2B, gpio.HIGH)
gpio.output(LED34G, gpio.HIGH)
gpio.output(LED3R, gpio.HIGH)
gpio.output(LED4R, gpio.HIGH)
print("\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n")
######################################################################################################
## DISEÑO DE LA INTERFAZ												                            ##
######################################################################################################
# - El técnico tiene que introducir los datos del trabajo a realizar por el piloto.                  #
# - El técnico autoriza al piloto para comenzar su trabajo.                                          #
# - El técnico se encarga del envío y procesado del trabajo. Además de verificar que el trabajo.     #
######################################################################################################	
root = Tk()
root.title("Airvant Inventario")
root.resizable(0,0)
# root.iconbitmap('onwards.ico') # DA ERROR PONER EL ICONO

menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Salir", command=root.quit) #root.quit
menubar.add_cascade(label="Archivo", menu=filemenu)
root.config(menu=menubar)
img_airvant = PhotoImage(file="airvant_logo.png")

## Variables implicadas en la interfaz del usuario.
interfaz_nombre_del_piloto = StringVar()
interfaz_tipo_de_codigo = StringVar()
interfaz_longitud_de_codigo = IntVar()
interfaz_tiempo_para_lectura = IntVar()
interfaz_empresa = StringVar()
interfaz_pasillo = StringVar()
interfaz_alturamax = IntVar()
interfaz_piking = StringVar()
interfaz_email = StringVar()

## Diseño de la interfaz del usuario
Label(root, text = "ID PILOTO").grid(row=0, column=0)
Label(root, text = "TIEMPO PILOTO").grid(row=0, column=1)
Entry(root, textvariable = interfaz_nombre_del_piloto).grid(row=1, column=0)
Entry(root, textvariable = interfaz_tiempo_para_lectura, width = 2).grid(row=1, column=1)

Label(root, text = "EMPRESA").grid(row=2, column=0)
Label(root, text = "PASILLO").grid(row=2, column=1)
Label(root, text = "ALTURA").grid(row=2, column=2)
Entry(root, textvariable = interfaz_empresa).grid(row=3, column=0)
Entry(root, textvariable = interfaz_pasillo, width = 3).grid(row=3, column=1)
Entry(root, textvariable = interfaz_alturamax, width = 2).grid(row=3, column=2)

Label(root, text = "ZONA DE PIKING").grid(row=4, column=0)
Radiobutton(root, text="en altura 1", variable=interfaz_piking, value="True").grid(row=5, column=1)
Radiobutton(root, text="sin piking", variable=interfaz_piking, value="False").grid(row=5, column=2)

Label(root, text = "CÓDIGO A LEER").grid(row=6, column=0)
Radiobutton(root, text="Code-128 de longitud", variable=interfaz_tipo_de_codigo, value="Code128").grid(row=7, column=1)
Entry(root, textvariable = interfaz_longitud_de_codigo, width = 3).grid(row=7, column=2)
Radiobutton(root, text="GS1-128", variable=interfaz_tipo_de_codigo, value="GS1128").grid(row=8, column=1)
Radiobutton(root, text="GS1-128 no SSCC", variable=interfaz_tipo_de_codigo, value="GS1128noSSCC").grid(row=8, column=2)

Label(root , text = "EMAIL DE ENVÍO").grid(row=10, column=0)
Entry(root, textvariable = interfaz_email).grid(row=10, column=1, columnspan=2)

## BOTONES
Button(root, text = "GO NORMAL", command = iniciar_trabajo_continuo).grid(row=11, column=0)
#Button(root, text = "GO APILAMIENTO", command = iniciarTrabajo_apilamiento).grid(row=11, column=1)
#Button(root, text = "ENVIAR TRABAJO", command = envio_trabajo).grid(row=11, column=2)

Label(root, image=img_airvant).grid(row=0, rowspan=11, column=3)

root.mainloop()




## Puede que queramos borrar un pasillo entero por el motivo que sea, en ese caso llamaremos al técnico
## y será el encargado de acceder via VNC o Putty al archivo del pasillo que queremos borrar.
## El piloto solo puede borrar una última lectura, en el tiempo indicado por los led amarillos.
	##	def borrar(pasillo):
	##		import os
	##		pasillo = str(pasillo)
	##		name_doc = 'lecturas/'+pasillo+'.txt'
	##		fichero = open(name_doc, 'r')
	##		a = []
	##		for linea in fichero.readlines():
	##			a.append(linea)
	##		fichero.close()
	##		a.pop(len(a)-1)
	##		os.remove(name_doc)
	##		fichero2 = open(name_doc, 'w')
	##		for i in range(len(a)):
	##			for j in range(len(a[i])):
	##				fichero2.write(a[i][j])
	##		fichero2.close()
	##		print("Borrado")
##
	##	def borrar_():
	##			empresa_b = empresa.get()
	##			pasillo_b = entrada_pasillo.get()
	##			pasar = empresa_b+pasillo_b
	##			pasar = str(pasar)
	##			borrar(pasar)
##
"""
    				#####
    				actual_multicapa == False
    				if(anterior_multicapa == True):
						if(subiendo == True):
							altura = altura + 1
							if(altura > alturamax):
								altura = altura - 1
								columna = columna + 1
								subiendo = False
						else:
							altura = altura - 1
							if(altura < alturamin):
								altura = altura + 1
								columna = columna + 1
								subiendo = True            
						posicion = [columna, altura, subiendo]
					#####
"""