#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Program name : serveur_tcp24.py
# Source : eme1.f4klo.ampr.org - ~/home/f4klo/Pyindi/f4klo-utils/
#
# 26/sept/2020 - Version 1.0 lecture port rotator control Gpredict
# 27/sept/2020 - Version 1.1 boucle infinie et lecture fictive des AzEl
# 01/mars/2021 - Version 1.2 sortie en fin de connexion
# 03/mars/2021 - Version 1.3 predict -n <port> -t <fichier.tle> s
# 09/avril/2021- Version 1.4 temporisation dans attente de data
# 11/avril/2021- Version 1.6 condition réponse selon message serveur
# 14/avril/2021- Version 1.7 envoi conditionnel si écarte supérieur au minimum
# 15/avril/2021- Version 2.1 conversion RA/dec d'après pycoord.py de N5FXH 
# 16/avril/2021- Version 2.2 seuil 0,3 et ajout affichage heure et vitesses 
# 22/novembre/2021- Version 2.4 Debug avec SEUIL 0.0 (REM : la librairie pytz n'est pas disponible sous Windows ?)   
# 24/novembre/2021- Version 2.5 Script de lancement  
#
# Le script de lancement :
#	!#bin-bash
#	LC_NUMERIC=en_US.UTF-8
#	printenv | grep LC_NUMERIC
#	./serveur_tcp24.py &
#	gpredict
#
# ToDo : 
#		Vérifier que la variable d'environnement est bien LC_NUMERIC=en_US.UTF-8 sinon sortir avec message
#		Il faudrait mieux faire le calcul des différences sur les coordonnées RA /DEC que sur Az /El
#		Calculer les vitesses par minute : le moteur de déclinaison effectue 6 degrés par minute
#		mettre condition de différence en RA ou Dec pour envoi des valeurs au driver INDI 

# Réservation / déclaration des ports utilisés par l'application
# 'localhost' Standard loopback interface address (localhost)
## Gpredict Port 4533 to listen on (non-privileged ports are > 1023)
# Edit /etc/services
# Local services
# gpredict        4533/tcp                        # Gpredict / KD2BD
# gpredict        4533/udp                        # Gpredict / KD2BD
#

import socket
import sys
import time
import struct
import locale
import os
import subprocess
import math
import datetime
import pytz

#from math import pi, sin, cos, tan, atan2, asin

from skyfield.api import Star, Topos, load
# Urilitaires par François-Xavier N5FXH
import coords

longitude = coords.deg2rad(2.387856)
latitude = coords.deg2rad(48.893995)

# specific locale MUST be en US for dots floating point delimiter
#os.environ["LANG"] = "en_US.UTF-8"
#os.environ["LC_NUMERIC"] = "en_US.UTF-8"
#os.environ["LC_MEASUREMENT"] = "en_US.UTF-8"
locale.setlocale(locale.LC_NUMERIC, "en_US.UTF-8")
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
print()
print('Specific locale MUST be en US for dots floating point delimiter : LC_NUMERIC=en_US.UTF-8')
#print('LANG : ' + os.getenv('LANG'))
print('LC_NUMERIC : ' + os.getenv('LC_NUMERIC'))
#print('MEASUREMENT : ' + os.getenv('LC_MEASUREMENT'))

# localhost  = "127.0.0.1"
server_address = ('localhost', 4533)

Old_Az = 359.0
Old_El = 89.0
Az = Old_Az
El = Old_El
# Le seuil règle l'envoi ou non des valeurs calculées au radiotélescope
#SEUIL = 0.3
SEUIL = 0.0

# Fonction d'attente et de lecture des données quand disponibles
# avec renvoie d'un acquitement
def RxData():
	while True:
		data = conn.recv(128)
		if not data:
			time.sleep(0.1)
			break
		else :
			dataR = str(data)
			if (dataR[3] == '\\'):
				conn.sendall(b'P \n')
			else :
				return data



### mode fichier
ts = load.timescale()

print()
print('Demande de connexion avec Gpredict adresse, port : ', server_address)
#result = subprocess.run(["gpredict"],capture_output=False)
#result = subprocess.run(["gpredict"])

print("Seuil d'envoi : " + str(SEUIL))

while 1:
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.bind((server_address))
		s.listen(1)
		print("Lancer gpredict et la commande d'antenne")
		conn, addr = s.accept()
		data = RxData()
		Old_Az = float(data[2:8])
		Old_El = float(data[8:16])
		conn.sendall(b'p \n')
		print(Old_Az, Old_El)
		with conn:
			print('Connected by', addr)
			tt_now = ts.now()
			while True:
				data = RxData()
# Acquitement renvoyé en echo de valeurs Az / El fictives
# devraient s'afficher sur les lignes "lecture" de Gprecict 
				dataS = b'p 23.45 67.89\n'
				conn.sendall(dataS)
				Az = float(data[2:8])
				diff = abs(Az - Old_Az)
				if (diff >= SEUIL) :
					tt = ts.now()
					utc_now = pytz.utc.localize(datetime.datetime.utcnow())
					print(str(utc_now.isoformat('T',"seconds")))
					print(Az, El)
					vitesse = diff / float(tt - tt_now) / 1000
					print('%.1f' % (vitesse), 'deg/sec Az')
					ra, dec = coords.convertir_azelev2radec(longitude, latitude, tt, Az, El)
					print ('%.4f %.4f' % (ra, dec))
					Old_Az = Az
				El = float(data[8:16])
				diff = abs(El - Old_El)
				if (diff >= SEUIL) :
					tt = ts.now()
					utc_now = pytz.utc.localize(datetime.datetime.utcnow())
					print(str(utc_now.isoformat('T',"seconds")))
					print(Az, El)
					vitesse = diff / float(tt - tt_now) / 1000
					print('%.1f' % (vitesse), 'deg/sec Déc')
					ra, dec = coords.convertir_azelev2radec(longitude, latitude, tt, Az, El)
					print ('%.4f %.4f' % (ra, dec))
					tt_now = tt
					Old_El = El
			time.sleep(0.1)
	print('Fermeture de la connexion avec le client.')
	conn.close()
	print('Arret du serveur.')
	s.close()
 
