import ugfx, wifi, badge, urandom
from umqtt.simple import MQTTClient
from time import sleep

def go_home(pushed):
    if(pushed):
        import machine
        machine.deepsleep(1)

def drawGraph(xpos,ypos,xsize,ysize,data,unit = ''):
    maxdata = xsize/4
    #Draw Frame
    ugfx.line(xpos      ,ypos      ,xpos+xsize,ypos      ,ugfx.BLACK)
    ugfx.line(xpos      ,ypos      ,xpos      ,ypos+ysize,ugfx.BLACK)
    ugfx.line(xpos      ,ypos+ysize,xpos+xsize,ypos+ysize,ugfx.BLACK)
    ugfx.line(xpos+xsize,ypos      ,xpos+xsize,ypos+ysize,ugfx.BLACK)
    #Find Max and min values
    minyval =data[0]
    maxyval =data[0]
    for d in data:
        if d>maxyval:
            maxyval=d
        if d<minyval:
            minyval=d
    #print("[GRAPH] Min X:" + str(minyval) +  " MaxX:" + str(maxyval))
    dataCount = 0
    xstart = xpos+xsize
    ystart = ypos+ysize
    maxy = int(ysize*0.9)
    lastx= xstart
    lasty= ystart
    count = 0
    #Draw
    ugfx.string(xpos+1,ypos+ysize-14,str(data[-1])+unit, "Roboto_Regular12", ugfx.BLACK)
    
    for d in reversed(data):
        dataCount = dataCount+1
        if dataCount>maxdata:
            break
        x = xstart-count
        if maxyval == 0 :
          maxyval=1
        y = ystart-int((float(d)/float(maxyval))*float(maxy))
        ugfx.line(lastx,lasty,x,y,ugfx.BLACK)
        lastx = x
        lasty = y
        count = count+4

psuvoltage=0
psucurrent=0
psutemperature=0
current=['0.0','0.0', '0.0','0.0', '0.0','0.0']
notification=['','','','','','']
error=['','','','','','']
ledjes=[0,0,0,0,0,0]

laptopChargerVolt  ='0.0'
laptopChargerCurrent ='0.0'
laptopChargerWatts ='0.0'
laptopChargerTemp  ='0.0'
laptopChargerHumid ='0.0'

laptopChargerCurrenta =[0]
laptopChargerWattsa   =[0]
laptopChargerTempa    =[0]
laptopChargerHumida   =[0]

psuvoltagea     =[0]
psucurrenta     =[0]
psutemperaturea =[0]
psuwattsa       =[0]
    
  

# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
    global psuvoltage
    global psucurrent
    global psutemperature
    global error
    global notification
    global ledjes
    
    global laptopChargerVolt
    global laptopChargerCurrent
    global laptopChargerWatts
    global laptopChargerTemp
    global laptopChargerHumid
    
    print((topic, msg))
    
    #lets strip all the extra characters
    message = (msg.decode('utf-8'))
    message = message.replace('\x08', '')
    message = message.replace('\x05', '')
    message = message.replace(',', '.')
    message = message.strip()
    try:
      message = float(message)
    except:
      message = 0
    updated = 0
    if(topic.decode('utf-8')=='altpwr/psu/voltage'):
    	psuvoltage  = message
        psuvoltagea.append(float(message))
        psuwattsa.append(psucurrent*psuvoltage)
        updated = 1
    if(topic.decode('utf-8')=='altpwr/psu/current'):
        psucurrent = message
        psucurrenta.append(float(message))
        psuwattsa.append(psucurrent*psuvoltage)
        updated = 1
    if(topic.decode('utf-8')=='altpwr/psu/temperature'):
        psutemperature = message
        psutemperaturea.append(float(message))
        updated = 1

    if(topic.decode('utf-8')=='altpwr/node/laptopChargeStation/temperature'):
    	laptopChargerTemp = message
        laptopChargerTempa.append(message)
        updated = 1
    if(topic.decode('utf-8')=='altpwr/node/laptopChargeStation/humidity'):
        laptopChargerHumid = message
        laptopChargerHumida.append(message)
        updated = 1
    if(topic.decode('utf-8')=='altpwr/node/laptopChargeStation/watts'):
        laptopChargerWatts = message
        laptopChargerWattsa.append(message)
        updated = 1
    if(topic.decode('utf-8')=='altpwr/node/laptopChargeStation/voltage'):
    	laptopChargerVolt = message
        updated = 1
    if(topic.decode('utf-8')=='altpwr/node/laptopChargeStation/current'):
        laptopChargerCurrent = message
        laptopChargerCurrenta.append(message)
        updated = 1
    if not updated:
      return 0
    
    ugfx.clear(ugfx.WHITE) 
    ugfx.string(112,1,"ALTPWR.NET PSU","Roboto_Black22", 0)
    badge.eink_png(0,0,'/lib/altpwrnetmonitor/altpwr.png')
    ugfx.line(65,23,291,23,ugfx.BLACK)
    
    if len(psuvoltagea)>25:
      psuvoltagea.pop(0)
    if len(psucurrenta)>25:
      psucurrent.pop(0)
    if len(psuwattsa)>25:
      psuwattsa.pop(0)
    if len(psuvoltagea)>25:
      psuvoltagea.pop(0)
    if len(psutemperaturea)>25:
      psutemperaturea.pop(0)
    if len(laptopChargerTempa)>25:
      laptopChargerTempa.pop(0)
    if len(laptopChargerHumida)>25:
      laptopChargerHumida.pop(0)
    if len(laptopChargerWattsa)>25:
      laptopChargerWattsa.pop(0)      
    if len(laptopChargerCurrenta)>25:
      laptopChargerCurrenta.pop(0)
      
    ugfx.string(60, 24, "psuvoltage","Roboto_Black12", 0) 
    drawGraph  (60,36,50,35,psuvoltagea,"V")
    ugfx.string(115, 24, "psucurrent","Roboto_Black12", 0)
    drawGraph  (115,36,50,35,psucurrenta,"A")
    ugfx.string(175, 24, "P = V * I","Roboto_Black12", 0)
    drawGraph  (175,36,50,35,psuwattsa,"W")
    ugfx.string(230, 24, "psutemp","Roboto_Black12", 0)
    drawGraph  (230,36,50,35,psutemperaturea,"C")
    
    ugfx.string(10,75,"LaptopChargerStation:","Roboto_Black12", 0)    
    #ugfx.string(40, 85, "Watts","Roboto_Black12", 0)
    drawGraph  (60,90,50,35,laptopChargerCurrenta,"A")    
    drawGraph  (115,90,50,35,laptopChargerWattsa,"W")
    #ugfx.string(110,85 , "Amb temp","Roboto_Black12", 0)
    drawGraph  (175,90,50,35,laptopChargerTempa,"*C")
    #ugfx.string(155, 85, "Amb Humid","Roboto_Black12", 0)
    drawGraph  (230,90,50,35,laptopChargerHumida,"H%")
    
    ugfx.flush()

ugfx.init()
ugfx.LUT_FULL
ugfx.input_init()
ugfx.input_attach(ugfx.BTN_B, go_home)
ugfx.clear(ugfx.BLACK)
ugfx.flush()
ugfx.clear(ugfx.WHITE)
ugfx.flush()
ugfx.clear(ugfx.BLACK)
ugfx.flush()
# Make sure WiFi is connected
wifi.init()  
ugfx.clear(ugfx.WHITE);
ugfx.string(10,10,"Waiting for wifi...","Roboto_Regular12", 0)
ugfx.flush()

# Wait for WiFi connection
while not wifi.sta_if.isconnected():
  sleep(0.1)
  pass
server="mqtt.sha2017.org"
clientname = 'SHA2017Badge ' + str(urandom.getrandbits(30))
c = MQTTClient(clientname, server)    
ugfx.clear(ugfx.WHITE);
ugfx.string(10,10,"Connecting to MQTT...","Roboto_Regular12", 0)
ugfx.flush()
c.set_callback(sub_cb)
c.connect()
c.subscribe(b"altpwr/#")
print('mqtt set')

def init():
  # Make sure WiFi is connected
  ugfx.string(0,1,"W","Roboto_Black22", 0)
  ugfx.flush()
  wifi.init()  
  # Wait for WiFi connection
  while not wifi.sta_if.isconnected():
      sleep(0.1)
      pass  
  c.set_callback(sub_cb)
  ugfx.string(0,1,"M","Roboto_Black22", 0)
  ugfx.flush()
  c.connect()
  c.subscribe(b"altpwr/#")
  print('mqtt set')
    
def main():
    while True:
        if wifi.sta_if.isconnected():
          try:
            c.check_msg()
          except:
            ugfx.string(0,1,"E","Roboto_Black22", 0)
            ugfx.flush()
            c.disconnect()
            sleep(2)
            init()
        else:          
          ugfx.string(0,1,"E","Roboto_Black22", 0)
          ugfx.flush()
          c.disconnect()
          sleep(2)
          init()
        sleep(0.25)
    c.disconnect()

main()