#region import libraries

import socket
import time
from datetime import datetime
import pandas as pd
import os
import logging
import influxdb_client
from influxdb_client.client.influxdb_client import InfluxDBClient
from influxdb_client.client.write_api import SYNCHRONOUS, WriteApi
from pyModbusTCP.client import ModbusClient

#endregion

# Update interval in seconds
update_interval = 30

# Tell the computer from where to read data
ip = "0.0.0.0"
port = 5005

# InfluxDB settings
BUCKET = "data"
ORG    = "QF"
TOKEN  = "dd_SteCtXS0sSuEA43GpkUOns0mImV76oyT1vz-M11_aiSvMIR1u05kocjIQR8MaZfiqURm-1RockNGkAjLfvA=="
URL    = "http://smartlab.physi.uni-heidelberg.de:8086/"


#region define functions 
def init_influxdb(url: str, token: str, org: str):
    """initiate influxDB client"""
    client = influxdb_client.InfluxDBClient(
        url=url,
        token=token,
        org=org)
    write_api = client.write_api(write_options=SYNCHRONOUS)
    print('InfluxDB client and influx write_API started.')
    return client, write_api

def write_data_to_influxDB(influx_client: InfluxDBClient, write_api: WriteApi, record):
    """check if influxDB is alive and write data to influxDB, else start influxDB client"""
    try:
        # check if influxDB is ready
        influx_client.ping()
        # write data points
        write_api.write(bucket=BUCKET, org=ORG, record=record)
        print('Data written to influxDB.')
    except:
        print('InfluxDB ping not successful. InfluxDB cannot be reached.')
        try:
            # try to open the influx DB client and write API
            influx_client, write_api = init_influxdb(URL, TOKEN, ORG)
        except Exception as e:
            print('Error with InfluxDB: {}'.format(e))
            print('Data not written.')
            time.sleep(10)
    return influx_client, write_api

def setup_logger(logName):

    # creat logger
    log_dir = "../../Data/logs"
    os.makedirs(log_dir, exist_ok=True)

    # setup logging
    log_file = os.path.join(log_dir, f"%s - {datetime.now():%Y-%m-%d}.log" %logName)
    logging.basicConfig(
        filename=log_file,
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(message)s",
        encoding="utf-8"
    )

    # sync output to termianl
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    logging.getLogger().addHandler(console)

    # example
    logging.info("Logger set up complete")
#endregion 

def read_temp (ip, port, influx_client, write_api):
    with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind ((ip, port))
        s.listen()
       # print ("Listening")
        conn, addr = s.accept()
        with conn:
            data = conn.recv (1024)
            return data.decode().strip()
            


            


if __name__ == "__main__":
    influx_client, write_api = init_influxdb(URL, TOKEN, ORG)
    setup_logger ("FerDy_exp_table_Temp.")
    logging.info ("Reading the temperature on exp. table in FerDy")
    with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind ((ip, port))
        s.listen()
       # print ("Listening")
        
        temp_or_hum = "a"
        while 1:
            
            conn, addr = s.accept()
            with conn:
                data = conn.recv (1024)
                message = data.decode().strip()
            #T = read_temp (ip, port, influx_client, write_api)
            
            

            if (message is not None and temp_or_hum == "T" and message <= "9" and message >= "0"):
                #if type (message) != int:
                   # continue
                print (str (datetime.now () )[:19] + ": Temp is " + message)
                T = float (message)
                p1 = influxdb_client.Point ("FerDy").tag("Climate_control", "temperature").field ("temp_exp_table", T)
                temp_or_hum = "a"
                influx_client, write_api = write_data_to_influxDB (influx_client, write_api, p1)
                time.sleep (update_interval/2)

            elif (message is not None and temp_or_hum == "H" and message <= "9" and message >= "0"):
               # if type (message) != int:
                  #  continue
                print (str (datetime.now () )[:19] + ": humidity is " + message)
                H = float (message)
                p1 = influxdb_client.Point ("FerDy").tag("Climate_control", "humidity").field ("hum_exp_table", H)
                temp_or_hum = "a"
                influx_client, write_api = write_data_to_influxDB (influx_client, write_api, p1)
                time.sleep (update_interval/2)

            elif (message is not None):
                temp_or_hum = message[0]
                
                        
            