import serial
from flask import Flask, jsonify
from flask_socketio import SocketIO
from flask_cors import CORS
import datetime
import threading
from Display import Display
from subprocess import check_output
import logging
from database.DP1Database import Database

logging.basicConfig(filename='logging.txt',level=logging.INFO, format="%(asctime)s\t%(levelname)s -- %(processName)s %(filename)s:%(lineno)s -- %(message)s")
logging.info("test")
app = Flask(__name__)
CORS(app)
socketio = SocketIO(app)

data = {"BMPTemp":"","BMPPress":"","DHTTemperature":"","DHTHumidity":"","CO2":"","CO":""}
arduino = serial.Serial("/dev/rfcomm0", baudrate=9600)
conn = Database(app=app, user='mct', password='mct', db='project1')
sensor = conn.get_data("select idSensor, type_sensor from sensors")
s = {}
for sensor in sensor:
    s[sensor['idSensor']] = sensor['type_sensor']


@app.route('/')
def hallo():
    return "Server is running"

@socketio.on("connect")
def connecting():
    socketio.emit("connected")
    logging.info("Connection with client established")

@socketio.on("dashboard")
def get_data_dashboard():
    send_live_data();
    send_gmm_data();

@socketio.on('geschiedenis')
def stuur_data(datum):
    try:
        sensors = "','".join(datum['sensor'])
        te_versturen_data = {'labels':[], 'data':[]}
        data = conn.get_data("select sensor_id, waarde, tijdstip from sensor_data where sensor_id in(%s) and tijdstip between %s and %s", [sensors,datum['van'], datum['tot']])
        for waarde in data:
            te_versturen_data['labels'].append(waarde['tijdstip'].strftime("%Y-%m-%d %H:%M:%S"))
            te_versturen_data['data'].append(waarde['waarde'])
        socketio.emit('geschiedenisChartData', te_versturen_data)
    except Exception as e:
        logging.error(e)


@socketio.on("rgb")
def change_rgb(rgb):
    try:
        red = round(int(rgb[0])*(int(rgb[3])/100))
        green = round(int(rgb[1])*(int(rgb[3])/100))
        blue = round(int(rgb[2])*(int(rgb[3])/100))
        message = ('pwm' + str('%03d'%red) + str('%03d'%green) + str('%03d'%blue))
        logging.info("licht: " + message)
        arduino.write(message.encode())
        arduino.write("\n".encode())
    except Exception as e:
        logging.error(e)

@socketio.on("manual")
def manual_message(message):
    try:
        logging.info("manual: " + message)
        arduino.write(message.encode())
        arduino.write("\n".encode())
    except Exception as e:
        logging.error(e)

def send_live_data():
    try:
        live = {}
        livedata = conn.get_data("select sd.sensor_id, sd.waarde from sensor_data sd inner join (select sensor_id, max(tijdstip) as max_date from sensor_data where sensor_id in (1,2,3,5,7) group by sensor_id) l on sd.sensor_id = l.sensor_id and sd.tijdstip = l.max_date;")
        for data in livedata:
           live[s[data['sensor_id']]] = data['waarde']
        socketio.emit('data-dashboard', live )
    except Exception as e:
        logging.error(e)

def send_gmm_data():
    try:
        values24 = {}
        data24 = conn.get_data("select sensor_id,round(avg(waarde),2) as 'avg', round(max(waarde),2) as 'max', round(min(waarde),2) as 'min' from sensor_data where tijdstip between %s and %s  and sensor_id in (1,2,3,5,7) group by sensor_id;", [datetime.datetime.now()-datetime.timedelta(1), datetime.datetime.now()])
        if data24:
            for waarde in data24:
                values24[s[waarde['sensor_id']]] = {"avg": waarde['avg'], "min": waarde['min'], "max":waarde['max']}
        else:
            for waarde in data24:
                values24[s[waarde['sensor_id']]] = {"avg": "0", "min": "0", "max": "0"}
        socketio.emit('data-24', values24)
    except Exception as e:
        logging.error(e)

def get_data_arduino():
    try:
        for sensor in data.keys():
            arduino.write(str(sensor).encode())
            arduino.write( "\n".encode())
            data[sensor] = float(arduino.readline().strip().decode())
        conn.set_data("insert into sensor_data (sensor_id, waarde) values(1,%s),(2, %s),(3, %s),(4, %s),(5, %s),(7, %s)",[data["CO"], data["CO2"],data["DHTHumidity"],data["DHTTemperature"],data["BMPPress"],data["BMPTemp"]])
        live = {}
        livedata = conn.get_data("select sd.sensor_id, sd.waarde from sensor_data sd inner join (select sensor_id, max(tijdstip) as max_date from sensor_data where sensor_id in (1,2,3,5,7) group by sensor_id) l on sd.sensor_id = l.sensor_id and sd.tijdstip = l.max_date;")
        for data_item in livedata:
            live[s[data_item['sensor_id']]] = data_item['waarde']
        socketio.emit('data-dashboard', live )
    except Exception as e:
        logging.error(e)
    finally:
        threading.Timer(10, get_data_arduino).start()


def display_ip():
    try:
        datapins = [17, 27, 22, 12, 21, 26, 16, 20][::-1]
        rs = 25
        e = 23
        lcdvar = Display(datapins, rs, e)
        ips = check_output(['hostname', '--all-ip-addresses']).decode().strip()
        logging.info(ips)
        try:
            ips = ips.split()[1]
        except IndexError:
            ips = ips
        tekst = "IP-address:"
        lcdvar.write_message(tekst)
        lcdvar.second_row()
        lcdvar.write_difference_second_row(str(ips))
    except Exception as e:
        logging.error(e)
    finally:
        threading.Timer(100, display_ip).start()



display_ip()
get_data_arduino()

if __name__ == '__main__':
    socketio.run(app, host="0.0.0.0", port=5000)
