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

import datetime, serial, time
import RPi.GPIO as gpio

## Designamos las variables relacionadas con 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)


def n568xug(L):
    # import serial
	###
	## ¿? NO SE ENCIENDE EL LED DE TODOS MODOS
	#global LED1G
	#gpio.output(LED1G, gpio.HIGH)
	###
	if 'sensor' in locals():
		sensor.close()
	if 'sensor' in globals():
		sensor.close()

	
	###
	## ACTIVAMOS EL SENSOR Y ESTABLECEMOS UN TIEMPO DE LECTURA (  ligado con read() :
	## timeout = none -> espera por siempre hasta completar L
	## timeout = 0 -> modo de no bloqueo, va enviando todo lo que coge.
	## timeout = x -> envia lo que coge hasta el tiempo x transcurrido.
	sensor = serial.Serial('/dev/ttyACM0', timeout = 20) # esperará 30 segundos para realizar la lectura
	sensor.flushInput()
	sensor.write("\x16T\r") # enviamos una señal al sensor diciendole que le vamos a pedir una lectura
	# a = sensor.read(N)
	# Si el codigo es mas largo, inWaiting() se carga de información y se envia, por eso hay
	# que borrar la última lectura.
	# En cambio si el código es más corto, el sensor envía lo que tenga pero el operario no ve
	# la lectura como finalizada. Se envía lo que haya leído.
	# enespera = sensor.inWaiting()
	lectura = sensor.read(L) # pedimos la lectura de una longitud dada
	enespera = sensor.inWaiting()
	if(len(lectura) < L and lectura != ""):
		#print("INCIDENCIA-01")
		sensor.close()
		return "INCIDENCIA-01"
	if(enespera != 0):
		#print("INCIDENCIA-02")
		sensor.close()
		return "INCIDENCIA-02"
	sensor.close()
	return lectura


def n568xug_new(L):
    	## AL ENTRAR EN LA FUNCIÓN SE APAGA EL LED1G VERDE, POR LO QUE VOLVEMOS A ENCENDERLO
	global LED1G
	gpio.output(LED1G, gpio.HIGH)
	## ENTRAMOS EN EL CÓDIGO PARA EL SENSOR
	if 'sensor' in locals():
		sensor.close()
	if 'sensor' in globals():
		sensor.close()
	## ESTA VARIABLE VA A MARCAR EL TIEMPO MÁXIMO PARA REALIZAR UNA LECTURA CORRECTA, Y PEDIR ALGUNA
	## ACCIÓN AL PILOTO.
	TIEMPO_INICIO_LECTURA = datetime.datetime.now()
	TIEMPO_TRANSCURRIDO_LECTURA = 0
	TIEMPO_DIFERENCIA_LECTURA = 0
	###
	## ACTIVAMOS EL SENSOR Y ESTABLECEMOS UN TIEMPO DE LECTURA (  ligado 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)
	while(True):
    	## BORRAMOS CUALQUIER INFORMACIÓN ACUMULADA EN EL BUFFER DE ENTRADA.
		sensor.flushInput()
		## CODIGO DE ACCIÓN EN EL BUFFER DE SALIDA (esto lo lee el sensor para realizar la lectura)
		sensor.write("\x16T\r")
		## REALIZAMOS LA LECTURA DE UN NÚMERO L DE BYTES
		lectura = sensor.read(L)
		#print(lectura)
		## SI LA LECTURA ES MÁS LARGA DE L, SE QUEDAN UNOS BYTES EN ESPERA DE ENTRADA.
		enespera = sensor.inWaiting()
		## CUANDO LA LONGITUD LEÍDA SEA DEL TAMAÑO QUE BUSCAMOS, DEJAREMOS DE BUSCAR.
		if(len(lectura) == L and enespera == 0):
    		sensor.close()
			return lectura
		TIEMPO_TRANSCURRIDO_LECTURA = datetime.datetime.now()
		TIEMPO_DIFERENCIA_LECTURA = TIEMPO_TRANSCURRIDO_LECTURA - TIEMPO_INICIO_LECTURA
		## SI HAN PASADO EN EL PROCESO DE BÚSQUEDA X SEGUNDOS, EL OPERARIO DEBE REALIZAR ALGUNA OPCIÓN.
		if(TIEMPO_DIFERENCIA_LECTURA.seconds >= 10):
			## BORRAMOS LA INSTRUCCIÓN DE LECTURA, PERO EL SENSOR NO SE APAGA HASTA QUE NO RECIBE ALGO
    		sensor.flushOutput()
			sensor.close()
			return ""



def n568xug_gs1():
    ## GS1
	## IA PALET COMPLETO: (01)123456789abcde(--)...
	## IA PALET EMPEZADO: (02)123456789abcde(37)... HASTA 8 BYTES
	## IA MATRÍCULA ÚNICA SSCC (00)123456789abcdefghi(--)... SSCC = (00) + 18 bytes A VECES NO APARECE
	## LOS () NO APARECEN EN EL CODIGO DE BARRAS, PERO TIENEN QUE APARECER COMO HUMANAMENTE LEGIBLE
	## EL NÚMERO MÁXIMO DE BYTES POR CÓDIGO GS1-128 ES DE 48 BYTES (NÚMEROS O LETRAS)
	IA01 = False
	IA02 = False
	IA00 = False
	L = 48
	## AL ENTRAR EN LA FUNCIÓN SE APAGA EL LED1G VERDE, POR LO QUE VOLVEMOS A ENCENDERLO
	global LED1G
	gpio.output(LED1G, gpio.HIGH)
	## ENTRAMOS EN EL CÓDIGO PARA EL SENSOR
	if 'sensor' in locals():
		sensor.close()
	if 'sensor' in globals():
		sensor.close()
	## ESTA VARIABLE VA A MARCAR EL TIEMPO MÁXIMO PARA REALIZAR UNA LECTURA CORRECTA, Y PEDIR ALGUNA
	## ACCIÓN AL PILOTO.
	TIEMPO_INICIO_LECTURA = datetime.datetime.now()
	TIEMPO_TRANSCURRIDO_LECTURA = 0
	TIEMPO_DIFERENCIA_LECTURA = 0
	###
	## ACTIVAMOS EL SENSOR Y ESTABLECEMOS UN TIEMPO DE LECTURA (  ligado 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', timeout = 0)
	## LEÉMOS CÓDIGOS HASTA DAR CON EL DESEADO
	while(True):
    	## BORRAMOS CUALQUIER INFORMACIÓN ACUMULADA EN EL BUFFER DE ENTRADA.
		sensor.flushInput()
		## CODIGO DE ACCIÓN EN EL BUFFER DE SALIDA (esto lo lee el sensor para realizar la lectura)
		sensor.write("\x16T\r")
		## REALIZAMOS LA LECTURA DE UN NÚMERO L DE BYTES
		lectura = sensor.read(L)
		## TENEMOS QUE CONFIRMAR QUE EL CÓDIGO LEÍDO COMIENZA POR (00) PARA QUE SEA EL SSCC
		if(lectura[0:3] == "(00)"):
    		
			## SI LA LECTURA ES MÁS LARGA DE L, SE QUEDAN UNOS BYTES EN ESPERA DE ENTRADA.
			enespera = sensor.inWaiting()
			## CUANDO LA LONGITUD LEÍDA SEA DEL TAMAÑO QUE BUSCAMOS, DEJAREMOS DE BUSCAR.
			if(len(lectura) == L and enespera == 0):
    			sensor.close()
			return lectura
		TIEMPO_TRANSCURRIDO_LECTURA = datetime.datetime.now()
		TIEMPO_DIFERENCIA_LECTURA = TIEMPO_TRANSCURRIDO_LECTURA - TIEMPO_INICIO_LECTURA
		## SI HAN PASADO EN EL PROCESO DE BÚSQUEDA X SEGUNDOS, EL OPERARIO DEBE REALIZAR ALGUNA OPCIÓN.
		if(TIEMPO_DIFERENCIA_LECTURA.seconds >= 4):
    		sensor.close()
			return ""






def n568xug_something(L):
	## AL ENTRAR EN LA FUNCIÓN SE APAGA EL LED1G VERDE, POR LO QUE VOLVEMOS A ENCENDERLO
	global LED1G
	gpio.output(LED1G, gpio.HIGH)
	## ENTRAMOS EN EL CÓDIGO PARA EL SENSOR
	if 'sensor' in locals():
		sensor.close()
	if 'sensor' in globals():
		sensor.close()
	## ESTA VARIABLE VA A MARCAR EL TIEMPO MÁXIMO PARA REALIZAR UNA LECTURA CORRECTA, Y PEDIR ALGUNA
	## ACCIÓN AL PILOTO.
	TIEMPO_INICIO_LECTURA = datetime.datetime.now()
	TIEMPO_TRANSCURRIDO_LECTURA = 0
	TIEMPO_DIFERENCIA_LECTURA = 0
	###
	## ACTIVAMOS EL SENSOR Y ESTABLECEMOS UN TIEMPO DE LECTURA (  ligado 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)
	while(True):
    	sensor.flushInput()
		sensor.write("\x16T\r")
		## VAMOS A ELEGIR UNA L LO SUFICIENTEMENTE GRANDE COMO PARA QUE LEA CUALQUIER COSA
		lectura = sensor.read(L)
		enespera = sensor.inWaiting()
		if(len(lectura) != 0 and enespera == 0):
    		## SI EXISTE LECTURA LA ENVIAMOS
    		sensor.close()
			return lectura
		TIEMPO_TRANSCURRIDO_LECTURA = datetime.datetime.now()
		TIEMPO_DIFERENCIA_LECTURA = TIEMPO_TRANSCURRIDO_LECTURA - TIEMPO_INICIO_LECTURA
		## SI HAN PASADO EN EL PROCESO DE BÚSQUEDA X SEGUNDOS, EL OPERARIO DEBE REALIZAR ALGUNA OPCIÓN.
		if(TIEMPO_DIFERENCIA_LECTURA.seconds >= 10):
			## BORRAMOS LA INSTRUCCIÓN DE LECTURA, PERO EL SENSOR NO SE APAGA HASTA QUE NO RECIBE ALGO
    			sensor.flushOutput()
			sensor.close()
			return ""



L = input("Indique longitud de código: ")
#lec = n568xug_new(L)
lec = n568xug_something(L)
print("Hemos leído:\n {0}".format(lec))
