import serial
import sys
import os
import array as arr
import binascii

#DEBUG = True
DEBUG = False

def hextranslate(s):
        res = ""
        for i in range(len(s)/2):
                realIdx = i*2
                t = lambda x: int(x, 16) - ((int(x, 16) >> 7) * 256)
                res = res + str(t(s[realIdx:realIdx+2]))
        return res

def ReadAtagSer(ser):
   """
   ReadAtagSer
   In:
     ser
   Return:
     dict list with data
   """

   data = []
   r = ser.read(size=600)        #600 bytes is voldoende voor het gehele bericht  
   r = binascii.b2a_hex(r)
#   r = r.encode("hex") #Thisis the old way only supported in Python2.x.x
   if DEBUG:
     print("Debug ","All the serial data coming from the line....")   
#     print (r)
   a = r.split(b'064182')
   if DEBUG:
     print("Debug ","We split the string to a known Start of the sequence, in my case this is 064182...ymmv......")   
     print("Debug ","Please also see a thread on this topic for more explanation https://www.circuitsonline.net/forum/view/77974/1 ")   
     print (a)
# Make the list of received string uniq and preserve sequence
   seen = {}
   new_list = [seen.setdefault(x, x) for x in a if x not in seen]
   for uniq_list in new_list:
#    print(uniq_list) #This prints the list of data splitted into segments
    if uniq_list.startswith(b'1020102101'):        #This is line number 1
        if len(uniq_list) == 50:
           d = dict(name="",string_value="", int_value=0)
           #print(uniq_list[9:10], uniq_list)                
           datapart_1 = uniq_list[21:40]
           if DEBUG:
             print("Debug ","Data for this line is not relevenant......")   
             print("hex data voor regel1:", datapart_1)
             print ()

    if uniq_list.startswith(b'1020102102'):        #This is line number 2
        if len(uniq_list) == 50:
           d = dict(name="",string_value="", int_value=0)
           #print(uniq_list[9:10], uniq_list)                
           datapart_2 = uniq_list[21:40]
           if DEBUG:
             print("Debug ","Data for this line is not relevenant......")   
             print("hex data voor regel1:", datapart_2)
             print

    if uniq_list.startswith(b'1010012109'):
        if len(uniq_list) == 54:
           d = dict(name="",table_name="", int_value=0)
           if uniq_list[29:30] == "3":                #This is line number 3
              datapart_3 = uniq_list[30:46]
              atag_03 = arr.array('i')
              for datapart in [datapart_3[i:i+2] for i in range(0,len(datapart_3), 2)]:
                atag_03.append(int(datapart, 16))
              if DEBUG:
                print("Debug ","Data for this line is less relevenant......")   
                print("hex data voor regel3:", datapart_3)
                print("decimal array atag_03", atag_03)
                print

           if uniq_list[29:30] == "4":                #This is line number 4
              datapart_4 = uniq_list[30:46]
              atag_04 = arr.array('i')
              for datapart in [datapart_4[i:i+2] for i in range(0,len(datapart_4), 2)]:
                atag_04.append(int(datapart, 16))
              if DEBUG:
                print("Debug ","Data for this line is less relevenant......")   
                print("hex data voor regel3:", datapart_3)
                print("decimal array atag_04", atag_04)
                print

           if uniq_list[29:30] == "5":                #This is line number 5
              datapart_5 = uniq_list[30:46]
              atag_05 = arr.array('i')
              for datapart in [datapart_5[i:i+2] for i in range(0,len(datapart_5), 2)]:
                atag_05.append(int(datapart, 16))
              if DEBUG:
                print("Debug ","Data for this line is less relevenant......")   
                print("hex data voor regel5:", datapart_5)
                print("decimal array atag_05", atag_05)
                print

           if uniq_list[29:30] == "6":                #This is line number 6
              datapart_6 = uniq_list[30:46]
              atag_06 = arr.array('i')
              for datapart in [datapart_6[i:i+2] for i in range(0,len(datapart_6), 2)]:
                atag_05.append(int(datapart, 16))
              if DEBUG:
                print("Debug ","Data for this line is less relevenant......")   
                print("hex data voor regel6:", datapart_6)
                print("decimal array atag_06", atag_06)
                print

           if uniq_list[29:30] == "7":                #This is line number 7
              datapart_7 = uniq_list[30:46]
              atag_07 = arr.array('i')
              for datapart in [datapart_7[i:i+2] for i in range(0,len(datapart_7), 2)]:
                atag_07.append(int(datapart, 16))
              if DEBUG:
                print("Debug ","Data for this line is less relevenant......")   
                print("hex data voor regel7:", datapart_7)
                print("decimal array atag_07", atag_07)
                print

        if len(uniq_list) == 234:                #This is line number 8 based on lenght
           #print(uniq_list[29:30], uniq_list)                
           dlist = uniq_list.split(b'8260200e')
           #print(dlist)
           for d_element in dlist:
             if d_element.startswith(b'd0'):        #This is line number d0
               #print(d_element[0:2], d_element)                
               datapart_d0 = d_element[2:30]
               atag_d0 = arr.array('i')
               for datapart in [datapart_d0[i:i+2] for i in range(0,len(datapart_d0), 2)]:
                atag_d0.append(int(datapart, 16))
               if DEBUG:
                 print("Debug ","Data for this line is relevenant......")   
                 print("hex data voor regeld0:", datapart_d0)
                 print("decimal array atag_d0", atag_d0)
                 print

             if d_element.startswith(b'd1'):        #This is line number d1
               #print(d_element[0:2], d_element)                
               datapart_d1 = d_element[2:30]
               atag_d1 = arr.array('i')
               for datapart in [datapart_d1[i:i+2] for i in range(0,len(datapart_d1), 2)]:
                atag_d1.append(int(datapart, 16))
               if DEBUG:
                 print("Debug ","Data for this line is relevenant......")   
                 print("hex data voor regeld1:", datapart_d1)
                 print("decimal array atag_d1", atag_d1)
                 print

             if d_element.startswith(b'd2'):        #This is line number d2
               #print(d_element[0:2], d_element)                
               datapart_d2 = d_element[2:30]
               atag_d2 = arr.array('i')
               for datapart in [datapart_d2[i:i+2] for i in range(0,len(datapart_d2), 2)]:
                atag_d2.append(int(datapart, 16))
               if DEBUG:
                 print("Debug ","Data for this line is relevenant......")   
                 print("hex data voor regeld2:", datapart_d2)
                 print("decimal array atag_d2", atag_d2)
                 print

#   return(atag_03,atag_04,atag_d0,atag_d1,atag_d2)
   return(atag_d0,atag_d1,atag_d2)

# Printing the usable data for logging purposes to a flat file
def PrintLog(atag_all):
   Atag_log=open('/home/sirtm/nas/atag/rrd/data/Atag_logging', 'a+')
   Atag_log.write(','.join(map(str, atag_all)))
   Atag_log.write('\n')
   return

# Printing the usable data for logging purposes to a flat file
def PrintCacti():
   Cacti_Atag_interface=open('/tmp/Cacti_Atag_interface', 'w+')
   Cacti_Atag_interface.writelines('Boilerwatertemp:{} ' .format(atag_d0[0]))
   Cacti_Atag_interface.writelines('Buitentemp:{} ' .format(atag_d0[4]))
   Cacti_Atag_interface.writelines('Kamertemp_gem:{} ' .format(atag_d2[2]))
   Cacti_Atag_interface.writelines('Kamertemp_gew:{} ' .format(atag_d2[0]))
   Cacti_Atag_interface.writelines('Modulatie:{} ' .format(atag_d0[5]))
   Cacti_Atag_interface.writelines('Waterdruk:{} ' .format(atag_d0[7]))
   Cacti_Atag_interface.writelines('Aanvoerwatertemp:{} ' .format(atag_d0[1]))
   Cacti_Atag_interface.writelines('Retourwatertemp:{} ' .format(atag_d0[2]))
   Cacti_Atag_interface.write('\n')
   Cacti_Atag_interface.close
   return

# This is the start of the program, it works with Brainq thermostats connected to Qsolar or Blauwe Engel 2
#print ("Read some ATAG Qsolar or Blauwe Engel 2 Data")
if DEBUG: 
   print("Debug ","Read Data and give some more diagnostic output on the content of the data, helpful if your thermostat uses different codes")
   print("Open Port")
# Setup COM port, use dmesg |grep tty to see what is there
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600
ser.stopbits = 1
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.interCharTimeout = 0
ser.timeout = 6000

if ser.isOpen() == True:
   print("ERROR "," already open")

ser.open()
ser.setRTS(False)
ser.setDTR(True)
#ser.setXON(False)
ser.setBreak(False)
ser.flushOutput()
ser.flushInput()
   
   # Read ATAG data
if DEBUG:
   print("Debug ","reading data....")   
ser.flushInput()
ser.flushOutput()
r = ReadAtagSer(ser)
if DEBUG:
   print("Debug ","output data from the function....")   
   print (r)
   print ('\n'.join(['%i: %s' % (n, r[n]) for n in range(len(r))]))
#print ('\n'.join(['%i: %s' % (n, r[n]) for n in range(len(r))]))
#print (r)
#re-gatering the correct data from the list of lists
atag_d0 = (r[0])
atag_d1 = (r[1])
atag_d2 = (r[2])
atag_all = atag_d0 + atag_d1 + atag_d2

# The data is in atag_d0, atag_d1 and atag_d2, a concat of the data for logging purposes is in atag_all
# now lets do somethin with that data, first print the log file
PrintLog(atag_all)

# Pass the information over to Cacti
PrintCacti()


#print(' '.join(map(str, atag_all)))		# Print a csv string of all data
print(','.join(map(str, atag_all)))		# Print a csv string of all data
print(atag_d0,atag_d1,atag_d2)
print()
print("Data voor d0", atag_d0)
print("Data voor d1", atag_d1)
print("Data voor d2", atag_d2)
print()
print("Verwarmingsdeel:")
print('Boilerwatertemp_d0[0]:{}' .format(atag_d0[0]))
print("Boilerrtemperatuur_d1[4+5]$:", ((atag_d1[5]*256 + atag_d1[4]))/10)
print()
print("Buitentemp d0:", (atag_d0[4]))
print("Buitentemp d1[8]:", (atag_d1[8])/10)
print()
print("Kamertemperatuur gemeten:", (((atag_d2[3]*256) + atag_d2[2]))/10)
print("Kamertemperatuur gewenst:", ((atag_d2[1]*256 + atag_d2[0]))/10)
print("Brander Modulatie %:", (atag_d0[5]))
print("Waterdruk:", (atag_d0[7])/10)
print()
print("Aanvoerwater temp_d0[1]$", (atag_d0[1]))
print("Retourwater temp_d0[2]$", (atag_d0[2]))
print()
print("Onduidelijke parameters:")
print("Boilerwater?? temp_d1[0+1]?:", ((atag_d1[1]*256 + atag_d1[0]))/10)
print("Boilerwater?? temp_d1[2+3]?:", ((atag_d1[3]*256 + atag_d1[2]))/10)
print()
print("apparaat temp_d0[8]?", (atag_d0[8]))
print("apparaat temp_d0[11]?", (atag_d0[11]))
print()
print("Toestel/Brander?? temperatuur_d2[6+7]:", ((atag_d2[7]*256 + atag_d2[6]))/10)
print("Toestel/Brander?? temperatuur_d2[4+5]:", ((atag_d2[5]*256 + atag_d2[4]))/10)

ser.close()
if DEBUG:
   print("Debug: We are done...........")
