#!/usr/bin/python

import RPi.GPIO as GPIO
import time
import sys
import getopt
import string 
import datetime
import select
import sys
import os
import termios
import tty
import atexit
import threading
import serial
import subprocess
import pigpio
from evdev import InputDevice,ecodes

VT100_WHITE = "\x1B[37;40m"
VT100_RED = "\x1B[31;40m"
VT100_GREEN = "\x1B[32;40m"

RELAY_GPIO =34
DE_GPIO = 38
PWM_GPIO = 22

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(RELAY_GPIO,GPIO.OUT)
GPIO.output(RELAY_GPIO,GPIO.LOW)

GPIO.setup(DE_GPIO,GPIO.OUT)
GPIO.output(DE_GPIO,GPIO.LOW)

exit_event = threading.Event()

def VT100_ClearScreen():
    print('\033[2J\033[H', end='')

def VT100_MoveCursor(row,col):
	print(f'\033[{row+1};{col+1}H', end='')

def VT100_HideCursor():
    print('\033[?25l', end='')

def VT100_ShowCursor():
    print('\033[?25h', end='')

def VT100_Green():
    print('\033[32m',end='')

def VT100_Red():
    print('\033[31m',end='')

def VT100_White():
    print('\033[0m',end='')

def VT100_Error(message):
	VT100_MoveCursor(28,1)
	print(" " * 28,end='')
	VT100_Red()
	VT100_MoveCursor(28,1)
	print(message,end='')
	VT100_White()


def VT100_Message(message):
	VT100_MoveCursor(27,1)
	print(" " * 27,end='')
	VT100_Green()
	VT100_MoveCursor(27,1)
	print(message,end='')
	VT100_White()


def clickArea(row, col, length, height, x, y):
	char_width = 8
	char_height = 16

	# Calcola il bordo destro e il bordo inferiore dell'area
	right_edge = (col * char_width) + (length * char_width)
	bottom_edge = (row * char_height) + (height * char_height)

	#VT100_MoveCursor(25,1)
	#print("%3d < %3d < %3d" % (col * char_width,x,right_edge))
	#print("%3d < %3d < %3d" % (row * char_height,y,bottom_edge))
    
	# Verifica se x e y sono all'interno dell'area
	if (col * char_width)  < x < right_edge and  (row * char_height) < y < bottom_edge:
		return True
	else:
		return False


#		evkeycounter=evkeycounter+1
#		VT100_MoveCursor(28,1)
#		print("%3d" % (evkeycounter),end='')

def TouchXY():
	x=0
	y=0
	evkeycounter=0
	
	device = InputDevice('/dev/input/event1')

	for event in device.read_loop():
		if event.type == ecodes.EV_KEY and event.value == 1:

			# Rele
			if clickArea(5,0,19,3,x,y)==True:
				if GPIO.input(RELAY_GPIO)==0:
					GPIO.output(RELAY_GPIO,1)
				else:	
					GPIO.output(RELAY_GPIO,0)
			
			# Empty
			if clickArea(5,22,19,3,x,y)==True:
				pass;

			# RS232
			if clickArea(9,0,19,4,x,y)==True:
				if testSerial(False):
					VT100_Message("RS232 OK")
					VT100_Error("")
				else:	
					VT100_Message("")
					VT100_Error("RS232 KO")

			# RS422
			if clickArea(9,22,19,4,x,y)==True:
				if testSerial(False):
					VT100_Message("RS422 OK")
					VT100_Error("")
				else:	
					VT100_Message("")
					VT100_Error("RS422 KO")

			# RS485
			if clickArea(9,44,19,4,x,y)==True:
				if testSerial(True):
					VT100_Message("RS485 OK")
					VT100_Error("")
				else:	
					VT100_Message("")
					VT100_Error("RS485 KO")

			# PWM 50
			if clickArea(14,0,19,3,x,y)==True:
				pi.set_mode(PWM_GPIO, pigpio.OUTPUT)
				pi.set_PWM_frequency(PWM_GPIO, 800)
				pi.set_PWM_dutycycle(PWM_GPIO, 50)

			# PWM 100
			if clickArea(14,22,19,3,x,y)==True:
				pi.set_mode(PWM_GPIO, pigpio.OUTPUT)
				pi.set_PWM_frequency(PWM_GPIO, 800)
				pi.set_PWM_dutycycle(PWM_GPIO, 0)

			# SHUTDOWN
			if clickArea(14,44,19,3,x,y)==True:
				result = subprocess.run(['sudo', 'halt'], capture_output=True, text=True)

		if event.type==ecodes.EV_ABS:
			#print(event.code,event)
			if event.code==53:
				x=800-event.value
			if event.code==54:
				y=480-event.value           
			VT100_MoveCursor(3,1)
			VT100_White()
			print("Touch X,Y %s %3d %3d" % (VT100_GREEN,x,y))   

def testSerial(rs485):
	Failed=False
	
	data_to_send = bytearray(b'HelloWorld')

	try:
		serRS = serial.Serial('/dev/ttyAMA0', 115200,timeout=0.1)  
		serUSB = serial.Serial('/dev/ttyUSB0', 115200,timeout=0.1)  
	except:
		VT100_Error("Inserisci il cavo di test")
		return False

	serRS.flushOutput()
	serRS.flushInput()

	serUSB.flushOutput()
	serUSB.flushInput()


	if rs485:
		GPIO.output(DE_GPIO, GPIO.HIGH)  # Enable DE
	serRS.write(data_to_send)
	serRS.flush()  
	if rs485:
		GPIO.output(DE_GPIO, GPIO.LOW)  #Disable DE

	received_data = serUSB.read(len(data_to_send))

	if len(received_data)<len(data_to_send):
		VT100_Message("RS->ttyUSB0: trasmessi %d byte ricevuti %d byte" % (len(data_to_send),len(received_data)))
		return False

	if received_data!=data_to_send:
		VT100_Message("RS->ttyUSB0: caratteri ricevuti diversi da quelli trasmessi")
		return False

	# Test from ttyUSB0 to RS232

	serUSB.write(data_to_send)
	serUSB.flush()  

	received_data = serRS.read(len(data_to_send))

	if len(received_data)<len(data_to_send):
		VT100_Message("ttyUSB0->RS: trasmessi %d byte ricevuti %d byte" % (len(data_to_send),len(received_data)))
		return False

	if received_data!=data_to_send:
		VT100_Message("ttyUSB0->RS: caratteri ricevuti diversi da quelli trasmessi")
		return False

	serRS.close()
	serUSB.close()
		
	return True    

def checkDevices():
	VT100_White()
	VT100_MoveCursor(1,20)
	if os.path.exists("/dev/ttyUSB0"):
		print("/dev/ttyUSB0",end='') 
	else:	
		print("            ",end='') 

	VT100_White()
	VT100_MoveCursor(1,34)
	if os.path.exists("/dev/ttyUSB1"):
		print("/dev/ttyUSB1",end='') 
	else:	
		print("            ",end='') 

	VT100_White()
	VT100_MoveCursor(1,48)
	if os.path.exists("/dev/ttyUSB2"):
		print("/dev/ttyUSB2",end='') 
	else:	
		print("            ",end='') 
	

def main():
	global pi
		
	VT100_ClearScreen()
	VT100_HideCursor()
	VT100_MoveCursor(1,1)
	print("%sTEST CM-PANEL POE" % (VT100_GREEN))

	VT100_White()
	VT100_MoveCursor(5,0)
	print("+-----------------+  +-----------------+  +-----------------+")
	print("| RELE            |  |                 |  |                 |")
	print("+-----------------+  +-----------------+  +-----------------+")

	VT100_White()
	VT100_MoveCursor(9,0)
	print("+-----------------+  +-----------------+  +-----------------+")
	print("| RS232           |  | RS422           |  | RS485           |")
	print("| OFF OFF OFF OFF |  | ON  OFF OFF OFF |  | ON  ON  OFF OFF |")
	print("+-----------------+  +-----------------+  +-----------------+")

	VT100_White()
	VT100_MoveCursor(14,0)
	print("+-----------------+  +-----------------+  +-----------------+")
	print("| LOW             |  | HIGH            |  | SHUTDOWN        |")
	print("+-----------------+  +-----------------+  +-----------------+")


	result = subprocess.run(['sudo', 'pigpiod'], capture_output=True, text=True)

	pi = pigpio.pi()  # Si connette al Raspberry Pi locale
	if not pi.connected:
		print("Errore: Manca pigpiod")
		exit()

	thread1=threading.Thread(target=TouchXY)
	thread1.start()

	while True:
		checkDevices()	
		time.sleep(1)


#	try:
#		while True:
#			checkDevices()	
#			time.delay(1)
		
#	except KeyboardInterrupt:
#		print("\nCTRL-C ricevuto, fine...")
	
#	except Exception as e:
#		print(f"Errore generico: {e.__class__.__name__}")
    
#	finally:	
#		VT100_ShowCursor()
#		exit_event.set()
#		thread1.join()
#		thread2.join()


if __name__ == "__main__":
	main()

