import serial
import time

#Can be Downloaded from this Link
#https://pypi.python.org/pypi/pyserial

#Global Variables
ser = 0

special_key = 3        # Special key for different Comm modes.
COMM_MODE = 5          # Not for PC Comm Mode for internal use
COMM_status = 6        # Not for PC. Comm Status
COMM_RAWiBATT = 7      # Not for PC. to be able to get the offset of the slave unit
COMM_iBATT = 8         # Not for PC
COMM_vPV = 9           # PV Voltage displayed on the kid
COMM_vBATT = 10        # Battery voltage displayed on the kid
COMM_fetTEMP = 11      # Internal FET temperature
COMM_loadSTATE = 12    # Load state On, off, iddle, overcurrent
COMM_KWH =13           # displayed KWH daily
COMM_PWMERROR = 14     # Not for PC Twin mode Only
COMM_wimpf = 15        # Not for PC Twin mode Only
COMM_batteryStage = 16 # Battery charge stage Absorb, Bulk, Float, EQ
COMM_batt_setpoint =17 # for test Do not use, invalid parameter
COMM_absorbV = 18      # Absorb battery voltage setpoint value
COMM_floatV =19        # Float  battery voltage setpoint value
COMM_eqV = 20          # Eq  battery voltage setpoint value
COMM_absorbT =21       # Absorb battery time setpoint in minutes
COMM_batteryTemp = 22  # Battery Temperature as read from the BTS
COMM_TempCompV = 23    # Battery temperature compensation setpoint in mV
COMM_SystemSet = 24    # For Twin mode. set the other unit system
COMM_BattNominal = 25  # battery nominal 12, 24, 36,48 v
COMM_EqT =26           # Eq battery time setpoint in minutes



class Kid:
  '''This class represent a kid charger controller object'''

  def __init__(self,no):
    self.no = no
    self.comm_battery_temp=0.0
    self.comm_battery_stage=0
    self.comm_absorb_v=0.0
    self.comm_float_v=0.0
    self.comm_eq_v=0.0
    self.comm_temp_comp_v=0.0
    self.comm_batt_nominal=0.0
    self.comm_v_batt=0.0
    self.comm_absorb_t=0.0
    self.comm_eq_t=0.0

#Function to Initialize the Serial Port
def init_serial():
    global ser          #Must be declared in Each Function
    ser = serial.Serial()
    ser.baudrate = 57200
    ser.parity=serial.PARITY_NONE
    ser.bytesize=serial.EIGHTBITS
    ser.stopbits=serial.STOPBITS_ONE
    ser.port = '/dev/ttyUSB0' #If Using Linux
    ser.open()          #Opens SerialPort

    # print port open or closed
    if ser.isOpen():
        print 'Open: ' + ser.portstr
#Function Ends Here
        

#Call the Serial Initilization Function, Main Program Starts from here
init_serial()

#temp = raw_input('Type what you want to send, hit enter:\r\n')
#ser.write(temp)         #Writes to the SerialPort

kid = Kid(1)

to_add=0

line = time.strftime('%X')
PK_TYPE_SET_mask=0b10000000
PK_TYPE_GET_mask=0b11000000
register_mask = 0b00111111 

while 1:    
    tt = int(time.time()) # tt - time in seconds
    bytes = ser.read(4)   # Read 4 bytes from Serial Port
    b_array = bytearray(bytes)

    if b_array[0] & PK_TYPE_SET_mask:  # if PK_TYPE_SET 
        register_name = b_array[0] & register_mask
        register_data = b_array[1] << 8
        register_data = register_data | b_array[2]

        if register_name == COMM_batteryTemp:
          print "COMM_batteryTemp (deg. C)"
          print register_data
        elif register_name == COMM_batteryStage:
          print "COMM_batteryStage"
          if register_data == 0:
            print "Resting"
          elif register_data == 3:
            print "Absorb"
          elif register_data == 4:
            print "BulkMPPT"
          elif register_data == 5:
            print "Float"
          elif register_data == 6:
            print "FloatMPPT"
        elif register_name == COMM_absorbV:
          print "COMM_absorbV (V)"
          print float(register_data)/10
        elif register_name == COMM_floatV:
          print "COMM_floatV (V)"
          print float(register_data) /10
        elif register_name == COMM_eqV:
          print "COMM_eqV (V)"
          print float(register_data) / 10
        elif register_name == COMM_TempCompV:
          print "COMM_TempCompV (mV)"
          print register_data
        elif register_name == COMM_BattNominal:
          print "COMM_BattNominal (V)"
          print register_data
        elif register_name == COMM_vBATT:
          print "COMM_vBATT (V)"
          print float(register_data) / 10
        elif register_name == COMM_absorbT:
          print "COMM_absorbT (minutes)"
          print register_data
        elif register_name == COMM_EqT:
          print "COMM_EqT (minutes)"
          print register_data
        elif register_name == COMM_vPV:
          print "COMM_vPV"
          print float(register_data)/10
          
    d_tt=int(time.time()) - tt 

    if d_tt > 5:
      line = time.strftime('%X')
      line = line + "  " + ':'.join('{:02x}'.format(ord(c)) for c in bytes)
      to_add= to_add + 1

    elif to_add > 0:      
      line = line + "  " + ':'.join('{:02x}'.format(ord(c)) for c in bytes)
      to_add= to_add + 1      

    if to_add == 10:
      print line

      register_data = PK_TYPE_GET_mask
      b_array[0] = register_data = register_data | COMM_vPV
      b_array[1] = 0
      b_array[2] = 0
      b_array[3] = 2 # XOR??  Don't know what to do...

      print b_array[0], b_array[1], b_array[2], b_array[3]
      print len(b_array)
      ser.write(b_array)         #Writes to the SerialPort
      to_add=0
    
#Ctrl+C to Close Python Window
