import socket 
from flask import Flask, render_template
from datetime import datetime
import codecs

app = Flask(__name__)
UDP_IP = "161.97.64.143" 
UDP_PORT = 5100
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))  #bind socket to UDP IP and port 

X = 0   #accelerometer Z axis
Y = 0   #accelerometer Z axis
Z = 0  #accelerometer Z axis
T = 0  #temperature 
RH = 0 #Humidity
CRCprint = "No data"  #CRC
now = datetime.now()  #timestamp

    
def twos_comp(val, bits):  #two's complement calculation
    if (val & (1 << (bits - 1))) != 0: 
        val = val - (1 << bits)        
    return val                         

def CalCRC16(data, length): #modbus CRC
    crc=0xFFFF
    if length == 0:
       length = 1
    j = 0
    while length != 0:
        crc ^= list.__getitem__(data, j)
        for i in range(0,8):
            if crc & 1:
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
        length -= 1
        j += 1
    return crc

def loop():
    global string, lock, X, Y, Z, T, RH, CRC, CRCprint, now
    while True:
        data, addr = sock.recvfrom(1024) #recieved data
        data = codecs.encode(data, "hex") #encoding data

        X, Y, Z, T, RH, CRC = [ data[i-4:i] for i in range(4,len(data)+4, 4) ]
        crccont = CalCRC16([(int(X,16)>>8) & 0xFF, int(X,16)& 0xFF, (int(Y,16)>>8) & 0xFF, int(Y,16)& 0xFF,(int(Z,16)>>8) & 0xFF, int(Z,16)& 0xFF, (int(T,16)>>8) & 0xFF, int(T,16)& 0xFF, (int(RH,16)>>8) & 0xFF, int(RH,16)& 0xFF],10)
        crccont = hex(crccont) #CRC check
        
        now = datetime.now()
        #data procesing:
        X= twos_comp(int(X,16), 16)
        Z= twos_comp(int(Z,16), 16)
        Y= twos_comp(int(Y,16), 16)
        T= int(T,16)
        RH= int(RH,16)
        CRC= int(CRC,16)
        CRC= hex(CRC)
        X= X*19.62/32767
        Y= Y*19.62/32767
        Z= Z*19.62/32767
        T=-45+175*T/65535
        RH=100*RH/65535
        X= round(X,1)
        Y= round(Y,1)
        Z= round(Z,1)
        T= round(T,1)
        RH=round(RH,0)
        RH= int(RH)
        if CRC==crccont:
            CRCprint="CRC OK"
        else:
            CRCprint="CRC ERROR"
        with app.app_context():
            with open('static/index.html','w') as f:
                html = render_template('index.html',timestamp=now, accX=X, accY=Y, accZ=Z, temp=T, humid=RH, CRCstate=CRCprint) #render template
                f.write(html) #write template to file which is hosted with apache

loop()



