#!/usr/bin/env python3
# cl_charging_stations_gui_v_03.py
# 20/03/187 by weigu

from tkinter import *
from tkinter import ttk
import paho.mqtt.client as mqtt
import json
from os import system as system_call
from platform import system as system_name # Returns the system/OS name
import threading
from time import gmtime, strftime, localtime, sleep
from datetime import datetime, timedelta, time

ftime = strftime("%d.%m.%y %H:%M:%S", localtime())
rtctime = strftime("%Y %m %d %H %M %S", localtime())
intyear = str(int(rtctime[0:4])-1892)
rtctimecorr = intyear[0:4]+rtctime[4:]


clientID = "cl_charging_stations_GUI"
brokerIP = "192.168.178.46"
brokerPort = 1883
topic1  = "clever_bus1"
topic2  = "clever_bus2"
topic  = topic1

standardFont = ["Helvetica", 12, "bold"]

class MySpinbox(ttk.Widget):
    def __init__(self, master, **kw):
        ttk.Widget.__init__(self, master, 'ttk::spinbox', kw)

#-----------------------------------------------------------------------------
class GUI(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self) # Tkinter canvas
        self.daemon = True # so it will be killed with the maim thread!
        self.start()
        self.flag_exit = 0
        self.flag_get = "0"
        self.flag_set = "0"
        self.flag_bus = "1"
        self.flag_function = "0"
        self.mbuttonwidth = 50 # width of 4 buttons (Asyn, Get, Set, Function)

    def callback(self):
        self.flag_exit = 1
    def asynReset(self):
        self.asyn_state1.set("no message til now")
        self.asyn_state2.set("")
        self.asyn_NUID1.set("no mycard til now")
        self.asyn_NUID2.set("")
    # Get commands
    def getAll(self):
        self.flag_get = "All"
    def getTimeLimit(self):
        self.flag_get = "G3"
    def getAmmeterSettings(self):
        self.flag_get = "GA"
    def getCurrentCapacityRange(self):
        self.flag_get = "GC"
    def getSettings(self):
        self.flag_get = "GE"
    def getFaultCounters(self):
        self.flag_get = "GF"
    def getChargingCurrentVoltage(self):
        self.flag_get = "GG"
    def getChargeLimit(self):
        self.flag_get = "GH"
    def getVoltmeterSettings(self):
        self.flag_get = "GM"
    def getOvertemperatureThreshold(self):
        self.flag_get = "GO"
    def getTemperature(self):
        self.flag_get = "GP"
    def getRFIDNUID(self):
        self.flag_get = "GR"
    def getState(self):
        self.flag_get = "GS"
    def getTimeRTC(self):
        self.flag_get = "GT"
    def getEnergyUsage(self):
        self.flag_get = "GU"
    def getVersion(self):
        self.flag_get = "GV"

    def setTime(self):
        self.flag_set = "S1"
    def setCapacity(self):
        self.flag_set = "SC"
    def setChargeLimit(self):
        self.flag_set = "SH"

    def funcEnableEVSE(self):
        self.flag_function = "FE"
    def funcDisableEVSE(self):
        self.flag_function = "FD"
    def funcResetEVSE(self):
        self.flag_function = "FR"
    def funcSleepEVSE(self):
        self.flag_function = "FS"
    def funcAllowCharging(self):
        self.flag_function = "FA"
    def funcCancelCharging(self):
        self.flag_function = "FC"
    def funcWriteDisplay(self):
        self.flag_function = "FP " + self.DispX.get() + ' ' + self.DispY.get() + ' ' + self.DispText.get()

    def BusIdUpdate(self):
        self.butt_eb1.state(["!disabled"])
        self.butt_eb2.state(["!disabled"])
        self.butt_eb3.state(["!disabled"])
        self.BusId.set(self.Bus.get()+self.Id.get())
        self.BusIdStr.set("BusId: " + self.Bus.get()+self.Id.get())
        self.flag_bus = self.Bus.get()
        if self.BusId.get()=="11":
            self.butt_eb1.state(["disabled"])
        if self.BusId.get()=="12":
            self.butt_eb2.state(["disabled"])
        if self.BusId.get()=="13":
            self.butt_eb3.state(["disabled"])

    def FontSizeUpdate(self):
        FSize = self.FSize.get()
        standardFont[1]=int(FSize)
        self.s.configure("default.TLabel", font=standardFont)
        self.s.configure("sy.TLabel", font=standardFont)
        self.s.configure("sr.TLabel", font=standardFont)
        self.s.configure("default.TEntry", font=standardFont)
        self.s.configure("default.TButton", font=standardFont)
        self.s.configure("header.TButton", font=standardFont)
        self.s.configure("ss.TButton", font=standardFont)
        self.s.configure("default.TSpinbox", background="lightgrey", fieldbackground="lightgrey", arrowsize=int(FSize)*2, font=standardFont )
        self.spinb_e1_v.config(font=standardFont)
        self.spinb_e2_v.config(font=standardFont)
        self.spinb_size_v.config(font=standardFont)
        self.spinb_func6_X.config(font=standardFont)
        self.spinb_func6_Y.config(font=standardFont)
        self.entry_func5.config(font=standardFont)

    def But11(self):
        self.Bus.set(1)
        self.Id.set(1)
        self.BusIdUpdate()

    def But12(self):
        self.Bus.set(1)
        self.Id.set(2)
        self.BusIdUpdate()

    def But13(self):
        self.Bus.set(1)
        self.Id.set(3)
        self.BusIdUpdate()

    def UpdateTime(self):
        global rtctimecorr
        ftime = strftime("%d.%m.%y %H:%M:%S", localtime())
        rtctime = strftime("%Y %m %d %H %M %S", localtime())
        intyear = str(int(rtctime[0:4])-1892)
        rtctimecorr = intyear[0:4]+rtctime[4:]
        self.label_time['text'] = ftime
        self.label_time.after(1000, self.UpdateTime)

    def run(self):

        self.mainWin = Tk()
        self.mainWin.protocol("WM_DELETE_WINDOW", self.callback)
        self.mainWin.title('Creative Lab Electric Vehicle Energy Reloader')
        self.mainWin.columnconfigure(0, weight=1)
        self.mainWin.rowconfigure(0, weight=1)

        self.mainFrame = ttk.Frame(self.mainWin, borderwidth=10, relief='ridge', padding="10 10 20 20", style = "all.TFrame")
        self.mainFrame.grid(column=0, row=0, sticky=(W, N, E, S))
        for column in range(1,10):
            self.mainFrame.columnconfigure(column, weight=5)
        for row in range(1,18):
            self.mainFrame.rowconfigure(row, weight=1)

        self.G3 = StringVar()
        self.G3.set("not yet acquired")
        self.GA = StringVar()
        self.GA.set("not yet acquired")
        self.GC = StringVar()
        self.GC.set("not yet acquired")
        self.GE = StringVar()
        self.GE.set("not yet acquired")
        self.GF = StringVar()
        self.GF.set("not yet acquired")
        self.GG = StringVar()
        self.GG.set("not yet acquired")
        self.GH = StringVar()
        self.GH.set("not yet acquired")
        self.GM = StringVar()
        self.GM.set("not yet acquired")
        self.GO = StringVar()
        self.GO.set("not yet acquired")
        self.GP = StringVar()
        self.GP.set("not yet acquired")
        self.GR = StringVar()
        self.GR.set("not yet acquired")
        self.GS = StringVar()
        self.GS.set("not yet acquired")
        self.GT = StringVar()
        self.GT.set("not yet acquired")
        self.GU = StringVar()
        self.GU.set("not yet acquired")
        self.GV = StringVar()
        self.GV.set("not yet acquired")

        self.asyn_state1 = StringVar()
        self.asyn_state1.set("no message til now")
        self.asyn_state2 = StringVar()
        self.asyn_state2.set("")
        self.asyn_NUID1 = StringVar()
        self.asyn_NUID1.set("no mycard til now")
        self.asyn_NUID2 = StringVar()
        self.asyn_NUID2.set("")

        self.numbers = [1,2,3,4,5,6,7,8,9]
        self.numbersX = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
        self.numbersY = [0,1,2,3,4,5,6,7]
        self.Bus = StringVar()
        self.Bus.set('1')
        self.Id = StringVar()
        self.Id.set('1')
        self.BusId = StringVar()
        self.BusId.set(self.Bus.get()+self.Id.get())
        self.BusIdStr = StringVar()
        self.BusIdStr.set("BusId: " + self.Bus.get()+self.Id.get())
        self.DispText = StringVar()
        self.DispText.set("Hallo:)")
        self.DispY = StringVar()
        self.DispY.set("0")
        self.DispX = StringVar()
        self.DispX.set("0")
        self.FSize = StringVar()
        self.FSize.set("12")

        # frameHeader ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        self.frameHeader = ttk.Frame(self.mainFrame, style = "all.TFrame")
        self.frameHeader.grid(column=1, row=1, columnspan = 20, sticky=(N))

        for column in range(1,3):
            self.frameHeader.columnconfigure(column, weight=1)
        self.frameHeader.rowconfigure(1, weight=1)

        self.imageL1 = PhotoImage(file='clever_600.png')

        self.label_png = ttk.Label(self.frameHeader, text="",image=self.imageL1, style="default.TLabel")
        self.label_png.grid(column=1, row=1, sticky=N)
        self.label_time = ttk.Label(self.frameHeader, text="", style="default.TLabel")
        self.label_time.grid(column=2, row=1, sticky=(N,E))

        # frameBusId ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        frameBusId = ttk.Frame(self.mainFrame, style = "all.TFrame")
        frameBusId.grid(column=1, row=2, columnspan = 10, sticky=(W, N))

        for column in range(1,20):
            frameBusId.columnconfigure(column, weight=10)
        for row in range(1,20):
            frameBusId.rowconfigure(row, weight=10)

        self.butt_eb1 = ttk.Button(frameBusId, text="11", command=self.But11, style="ss.TButton", state="disabled")
        self.butt_eb1.grid(column=1, row=1)
        self.butt_eb2 = ttk.Button(frameBusId, text="12", command=self.But12, style="ss.TButton")
        self.butt_eb2.grid(column=2, row=1)
        self.butt_eb3 = ttk.Button(frameBusId, text="13", command=self.But13, style="ss.TButton")
        self.butt_eb3.grid(column=3, row=1)

        label_e1_f = ttk.Label(frameBusId, text="Bus number: ", style="default.TLabel")
        label_e1_f.grid(column=4, row=1)
        self.spinb_e1_v = MySpinbox(frameBusId, values=self.numbers,
                          textvariable = self.Bus, command = self.BusIdUpdate, width=1, style="default.TSpinbox", font=standardFont)
        self.spinb_e1_v.grid(column=5, row=1)
        label_e2_f = ttk.Label(frameBusId, text="Station number on bus: ", style="default.TLabel")
        label_e2_f.grid(column=6, row=1)
        self.spinb_e2_v = MySpinbox(frameBusId, values=self.numbers,
                          textvariable = self.Id, command = self.BusIdUpdate, width=1, style="default.TSpinbox", font=standardFont)
        self.spinb_e2_v.grid(column=7, row=1)
        label_e3_v = ttk.Label(frameBusId, textvariable=self.BusIdStr, style="sr.TLabel")
        label_e3_v.grid(column=8, row=1)

        label_size_v = ttk.Label(frameBusId, text="Fontsize: ", style="default.TLabel")
        label_size_v.grid(column=15, row=1,sticky=(E))

        self.spinb_size_v = MySpinbox(frameBusId, values=self.numbersX,
                          textvariable = self.FSize, command = self.FontSizeUpdate, width=2, style="default.TSpinbox", font=standardFont)
        self.spinb_size_v.grid(column=16, row=1, sticky=(E))

        # frameAsyn +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        frameAsyn = ttk.Frame(self.mainFrame, style = "all.TFrame")
        frameAsyn.grid(column=1, row=4, sticky=(W, N))
        butt_asyn = ttk.Button(frameAsyn, text='Asynchronus messages (Reset)', command=self.asynReset, width = self.mbuttonwidth, style="header.TButton")
        butt_asyn.grid(column=1, row=1, columnspan=2, sticky=(W, E))
        label_asyn2_f = ttk.Label(frameAsyn, text="Last state: ", style="default.TLabel")
        label_asyn2_f.grid(column=1, row=2, sticky=(W,N))
        label_asyn3_f = ttk.Label(frameAsyn, text="Meaning: ", style="default.TLabel")
        label_asyn3_f.grid(column=1, row=3, sticky=(W,N))
        label_asyn4_f = ttk.Label(frameAsyn, text="Last NUID: ", style="default.TLabel")
        label_asyn4_f.grid(column=1, row=4, sticky=(W,N))
        label_asyn5_f = ttk.Label(frameAsyn, text="Name: ", style="default.TLabel")
        label_asyn5_f.grid(column=1, row=5, sticky=(W,N))
        label_asyn2_v = ttk.Label(frameAsyn, textvariable = self.asyn_state1, style="default.TLabel")
        label_asyn2_v.grid(column=2, row=2, sticky=(W,N))
        label_asyn3_v = ttk.Label(frameAsyn, textvariable = self.asyn_state2, style="default.TLabel")
        label_asyn3_v.grid(column=2, row=3, sticky=(W,N))
        label_asyn4_v = ttk.Label(frameAsyn, textvariable = self.asyn_NUID1, style="default.TLabel")
        label_asyn4_v.grid(column=2, row=4, sticky=(W,N))
        label_asyn5_v = ttk.Label(frameAsyn, textvariable = self.asyn_NUID2, style="default.TLabel")
        label_asyn5_v.grid(column=2, row=5, sticky=(W,N))
        # frameFunc +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        frameFunc = ttk.Frame(self.mainFrame, style = "all.TFrame")
        frameFunc.grid(column=1, row=5, sticky=(W, N))
        butt_func1 = ttk.Button(frameFunc, text='Function: Enable EVSE', command=self.funcEnableEVSE, width = self.mbuttonwidth, style="header.TButton")
        butt_func1.grid(column=1, row=1, columnspan=2, sticky=(W, E))
        butt_func2 = ttk.Button(frameFunc, text='Function: Disable EVSE', command=self.funcDisableEVSE, style="header.TButton")
        butt_func2.grid(column=1, row=2, columnspan=2, sticky=(W, E))
        butt_func3 = ttk.Button(frameFunc, text='Function: Reset EVSE', command=self.funcResetEVSE, style="header.TButton")
        butt_func3.grid(column=1, row=3, columnspan=2, sticky=(W, E))
        butt_func4 = ttk.Button(frameFunc, text='Function: Sleep EVSE', command=self.funcSleepEVSE, style="header.TButton")
        butt_func4.grid(column=1, row=4, columnspan=2, sticky=(W, E))
        butt_func5 = ttk.Button(frameFunc, text='Function: Write DISPLAY', command=self.funcWriteDisplay, style="default.TButton")
        butt_func5.grid(column=1, row=5, columnspan=1, sticky=(W, E))

        frameFPXY = ttk.Frame(frameFunc, style = "all.TFrame")
        frameFPXY.grid(column=2, row=5, sticky=(W, N))
        self.entry_func5 = ttk.Entry(frameFPXY, textvariable = self.DispText, width = 20, style = "default.TEntry", font=standardFont)
        self.entry_func5.grid(column=1, row=1, columnspan=4, sticky=(W,N))
        label_func5_f_X = ttk.Label(frameFPXY, text="X: ", style="default.TLabel")
        label_func5_f_X.grid(column=1, row=2, sticky=(W,N))
        self.spinb_func5_X = MySpinbox(frameFPXY, values=self.numbersX,
        textvariable = self.DispX, width=2, style="default.TSpinbox", font=standardFont)
        self.spinb_func5_X.grid(column=2, row=2, sticky=(W,N))
        label_func5_f_Y = ttk.Label(frameFPXY, text="Y: ", style="default.TLabel")
        label_func5_f_Y.grid(column=3, row=2, sticky=(W,N))
        self.spinb_func5_Y = MySpinbox(frameFPXY, values=self.numbersY,
        textvariable = self.DispY, width=1, style="default.TSpinbox", font=standardFont)
        self.spinb_func5_Y.grid(column=4, row=2, sticky=(W,N))
        butt_func6 = ttk.Button(frameFunc, text='Function: ALLOW CHARGING', command=self.funcAllowCharging, style="header.TButton")
        butt_func6.grid(column=1, row=6, columnspan=2, sticky=(W, E))
        butt_func7 = ttk.Button(frameFunc, text='Function: CANCEL CHARGING', command=self.funcCancelCharging, style="header.TButton")
        butt_func7.grid(column=1, row=7, columnspan=2, sticky=(W, E))
        # frameGet ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        frameGet = ttk.Frame(self.mainFrame, style = "all.TFrame")
        frameGet.grid(column=2, row=4, sticky=(W, N), rowspan = 2)
        butt_get = ttk.Button(frameGet, text='Get all data (wait a long time please)', command=self.getAll, width = self.mbuttonwidth, style="header.TButton")
        butt_get.grid(column=1, row=1, columnspan=2, sticky=(W, E))
        butt_g3_f = ttk.Button(frameGet, text="Get time limit", command=self.getTimeLimit, style="default.TButton")
        butt_g3_f.grid(column=1, row=3, sticky=(W,N))
        butt_ga_f = ttk.Button(frameGet, text="Get Ammeter settings", command=self.getAmmeterSettings, style="default.TButton")
        butt_ga_f.grid(column=1, row=4, sticky=(W,N))
        butt_gc_f = ttk.Button(frameGet, text="Get current capacity range", command=self.getCurrentCapacityRange, style="default.TButton")
        butt_gc_f.grid(column=1, row=5, sticky=(W,N))
        butt_ge_f = ttk.Button(frameGet, text="Get settings", command=self.getSettings, style="default.TButton")
        butt_ge_f.grid(column=1, row=6, sticky=(W,N))
        butt_gf_f = ttk.Button(frameGet, text="Get fault counters", command=self.getFaultCounters, style="default.TButton")
        butt_gf_f.grid(column=1, row=7, sticky=(W,N))
        butt_gg_f = ttk.Button(frameGet, text="Get charging current and voltage", command=self.getChargingCurrentVoltage, style="default.TButton")
        butt_gg_f.grid(column=1, row=8, sticky=(W,N))
        butt_gh_f = ttk.Button(frameGet, text="Get charge limit", command=self.getChargeLimit, style="default.TButton")
        butt_gh_f.grid(column=1, row=9, sticky=(W,N))
        butt_gm_f = ttk.Button(frameGet, text="Get voltmeter settings", command=self.getVoltmeterSettings, style="default.TButton")
        butt_gm_f.grid(column=1, row=10, sticky=(W,N))
        butt_go_f = ttk.Button(frameGet, text="Get overtemperature threshold", command=self.getOvertemperatureThreshold, style="default.TButton")
        butt_go_f.grid(column=1, row=11, sticky=(W,N))
        butt_gp_f = ttk.Button(frameGet, text="Get temperature", command=self.getTemperature, style="default.TButton")
        butt_gp_f.grid(column=1, row=12, sticky=(W,N))
        butt_gr_f = ttk.Button(frameGet, text="Get RFID NUID", command=self.getRFIDNUID, style="default.TButton")
        butt_gr_f.grid(column=1, row=13, sticky=(W,N))
        butt_gs_f = ttk.Button(frameGet, text="Get state", command=self.getState, style="default.TButton")
        butt_gs_f.grid(column=1, row=14, sticky=(W,N))
        butt_gt_f = ttk.Button(frameGet, text="Get time from RTC", command=self.getTimeRTC, style="default.TButton")
        butt_gt_f.grid(column=1, row=15, sticky=(W,N))
        butt_gu_f = ttk.Button(frameGet, text="Get energy usage", command=self.getEnergyUsage, style="default.TButton")
        butt_gu_f.grid(column=1, row=16, sticky=(W,N))
        butt_gv_f = ttk.Button(frameGet, text="Get version", command=self.getVersion, style="default.TButton")
        butt_gv_f.grid(column=1, row=17, sticky=(W,N))
        label_g3_v = ttk.Label(frameGet, textvariable = self.G3, style="default.TLabel")
        label_g3_v.grid(column=2, row=3, sticky=(W,N))
        label_ga_v = ttk.Label(frameGet, textvariable = self.GA, style="default.TLabel")
        label_ga_v.grid(column=2, row=4, sticky=(W,N))
        label_gc_v = ttk.Label(frameGet, textvariable = self.GC, style="default.TLabel")
        label_gc_v.grid(column=2, row=5, sticky=(W,N))
        label_ge_v = ttk.Label(frameGet, textvariable = self.GE, style="default.TLabel")
        label_ge_v.grid(column=2, row=6, sticky=(W,N))
        label_gf_v = ttk.Label(frameGet, textvariable = self.GF, style="default.TLabel")
        label_gf_v.grid(column=2, row=7, sticky=(W,N))
        label_gg_v = ttk.Label(frameGet, textvariable = self.GG, style="default.TLabel")
        label_gg_v.grid(column=2, row=8, sticky=(W,N))
        label_gh_v = ttk.Label(frameGet, textvariable = self.GH, style="default.TLabel")
        label_gh_v.grid(column=2, row=9, sticky=(W,N))
        label_gm_v = ttk.Label(frameGet, textvariable = self.GM, style="default.TLabel")
        label_gm_v.grid(column=2, row=10, sticky=(W,N))
        label_go_v = ttk.Label(frameGet, textvariable = self.GO, style="default.TLabel")
        label_go_v.grid(column=2, row=11, sticky=(W,N))
        label_gp_v = ttk.Label(frameGet, textvariable = self.GP, style="default.TLabel")
        label_gp_v.grid(column=2, row=12, sticky=(W,N))
        label_gr_v = ttk.Label(frameGet, textvariable = self.GR, style="default.TLabel")
        label_gr_v.grid(column=2, row=13, sticky=(W,N))
        label_gs_v = ttk.Label(frameGet, textvariable = self.GS, style="default.TLabel")
        label_gs_v.grid(column=2, row=14, sticky=(W,N))
        label_gt_v = ttk.Label(frameGet, textvariable = self.GT, style="default.TLabel")
        label_gt_v.grid(column=2, row=15, sticky=(W,N))
        label_gu_v = ttk.Label(frameGet, textvariable = self.GU, style="default.TLabel")
        label_gu_v.grid(column=2, row=16, sticky=(W,N))
        label_gv_v = ttk.Label(frameGet, textvariable = self.GV, style="default.TLabel")
        label_gv_v.grid(column=2, row=17, sticky=(W,N))
        # frameSet ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        frameSet = ttk.Frame(self.mainFrame, style = "all.TFrame")
        frameSet.grid(column=3, row=4, rowspan = 2, sticky=(W, N))
        butt_s1 = ttk.Button(frameSet, text='Set PC time', command=self.setTime, width = self.mbuttonwidth, style="default.TButton")
        butt_s1.grid(column=1, row=1, columnspan=2, sticky=(W, E))
        butt_sc = ttk.Button(frameSet, text='Set capacity', command=self.setCapacity, width = self.mbuttonwidth, style="default.TButton")
        butt_sc.grid(column=1, row=2, columnspan=2, sticky=(W, E))
        butt_sh = ttk.Button(frameSet, text='Set charge limit', command=self.setChargeLimit, width = self.mbuttonwidth, style="default.TButton")
        butt_sh.grid(column=1, row=3, columnspan=2, sticky=(W, E))



        # ttk styles +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        self.s = ttk.Style()

        self.s.configure("all.TFrame", background="lightgrey")
        self.s.configure("test.TFrame", background="grey")
        self.s.configure("default.TLabel", background="lightgrey", font=standardFont)
        self.s.configure("sy.TLabel", background="yellow", font=standardFont)
        self.s.configure("sr.TLabel", background="red", font=standardFont)
        self.s.configure("default.TEntry", background="lightgray", font=standardFont)
        self.s.configure("default.TSpinbox", background="lightgrey", fieldbackground="lightgrey", arrowsize=20 )

        self.s.configure("default.TButton", background="lawngreen", font=standardFont, borderwidth=5)
        self.s.configure("header.TButton", background="yellow", font=standardFont, borderwidth=5)
        self.s.configure("ss.TButton", background="yellow", font=standardFont, borderwidth=5)
        self.s.map("ss.TButton",foreground = [("disabled", 'black'), ("!disabled", 'black')], background =[("disabled", 'red'), ("!disabled", 'yellow')])

        self.s.map("header.TButton",background = [("active", 'gold')])
        self.s.map("default.TButton",background = [("active", 'limegreen')])

        self.UpdateTime()

        # Padding
        for child in self.mainFrame.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in self.frameHeader.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameBusId.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameGet.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameAsyn.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameSet.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameFunc.winfo_children():
            child.grid_configure(padx=10, pady=10)
        for child in frameFPXY.winfo_children():
            child.grid_configure(padx=10, pady=10)

        self.mainWin.mainloop()

#---End-GUI-class-------------------------------------------------------------

def ping(host):
    ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"
    return system_call("ping " + ping_param + " " + host) == 0

# Callback that is executed when the client receives a CONNACK from the server.
def onConnect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    mqttc.subscribe([(topic1, 0),(topic2,0)]) # Subscribe topics (tname, QoS)

# Callback that is executed when we disconnect from the broker.
def onDisconnect(client, userdata, message):
    print("Disconnected from the broker.")

# Callback that is executed when subscribing to a topic.
def onSubscribe(client, userdata, mid, granted_qos):
    print('Subscribed on topic.')

# Callback that is executed when unsubscribing to a topic
def onUnsubscribe(client, userdata, mid, granted_qos):
    print('Unsubscribed on topic.')

# Callback that is executed when a message is received.
def onMessage(client, userdata, message):
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    global flagNUID
    io=message.payload.decode("utf-8");
    print ("payload: ",end='')
    print(io)
    try:
        ioj=json.loads(io)
    except:
        ioj={"BusId":"error"}
    print ("json: ",end='')
    print(ioj)
    print("------------")
    temp = ioj["BusId"]
    if temp[0]!='e':
        try:
            BusId = ioj["BusId"]
            if "Command" in ioj:
                Info = ioj["Command"][0:3]
                print(Info)
            elif "Message" in ioj:
                Info = ioj["Message"]
                print(Info)
            Payload = ioj["Payload"]
            print(Payload)
            if Info=="RFID NUID":
                window.asyn_NUID1.set(Payload)
                flagNUID = temp + " " + Payload
            if Info=="State":
                window.asyn_state1.set("State: " + Payload + " on BusID " + temp)
                if Payload=="00":
                    window.asyn_state2.set("State: Unknown")
                elif Payload=="01":
                    window.asyn_state2.set("EV State A: not connected (12V)")
                elif Payload=="02":
                    window.asyn_state2.set("EV State B: connected, ready (9V)")
                elif Payload=="03":
                    window.asyn_state2.set("EV state C: charging (6V)")
                elif Payload=="04":
                    window.asyn_state2.set("EV state D: vent required (3V)")
                elif Payload=="05":
                    window.asyn_state2.set("Fault State: Diode check failed")
                elif Payload=="07":
                    window.asyn_state2.set("Fault State: Bad ground")
                elif Payload=="08":
                    window.asyn_state2.set("Fault State: Stuck relay")
                elif Payload=="0A":
                    window.asyn_state2.set("Fault State: Over temperature error shutdown")
                elif Payload=="ff":
                    window.asyn_state2.set("disabled")
            if BusId == window.BusId.get():
                print("Yes")
                if Info=="Get":
                    CGet = ioj["Command"][4]
                    print(CGet)
                    if CGet=='3':
                        window.G3.set(Payload)
                    elif CGet=='A':
                        window.GA.set(Payload)
                    elif CGet=='C':
                        window.GC.set(Payload)
                    elif CGet=='E':
                        window.GE.set(Payload)
                    elif CGet=='F':
                        window.GF.set(Payload)
                    elif CGet=='G':
                        window.GG.set(Payload)
                    elif CGet=='H':
                        window.GH.set(Payload)
                    elif CGet=='M':
                        window.GM.set(Payload)
                    elif CGet=='O':
                        window.GO.set(Payload)
                    elif CGet=='P':
                        RTCT = Payload + "°C"
                        window.GP.set(RTCT)
                    elif CGet=='R':
                        window.GR.set(Payload)
                    elif CGet=='S':
                        window.GS.set(Payload)
                    elif CGet=='T':
                        RTC = Payload
                        window.GT.set(RTC)
                    elif CGet=='U':
                        window.GU.set(Payload)
                    elif CGet=='V':
                        window.GV.set(Payload)

        except:
            exit
    else:
        print("an error occured")

def getMessages(flag):
    All = ["3 Time limit","A Ammeter settings","C Current capacity","E Settings","F Fault counter","G Current Voltage","H Charge limit","M Voltmeter settings","O Overtemperature thresholds","P Temperature","R RFID NUID","S State","T Time","U Energy usage","V Version"]
    m1 = "{\"BusId\":\"" + window.BusId.get() + "\",\"Command\":\"Get\",\"" \
         + "Parameter\":\""
    m2 = "\"}"
    if flag != "All":
        if flag == "G3":
            Text = All[0]
        elif flag == "GA":
            Text = All[1]
        elif flag == "GC":
            Text = All[2]
        elif flag == "GE":
            Text = All[3]
        elif flag == "GF":
            Text = All[4]
        elif flag == "GG":
            Text = All[5]
        elif flag == "GH":
            Text = All[6]
        elif flag == "GM":
            Text = All[7]
        elif flag == "GO":
            Text = All[8]
        elif flag == "GP":
            Text = All[9]
        elif flag == "GR":
            Text = All[10]
        elif flag == "GS":
            Text = All[11]
        elif flag == "GT":
            Text = All[12]
        elif flag == "GU":
            Text = All[13]
        elif flag == "GV":
            Text = All[14]
        message = m1 + Text + m2
        mqttc.publish(topic,message)
    else:
        for Txt in All:
            print(Txt)
            message = m1 + Txt + m2
            mqttc.publish(topic,message)
            sleep(2)

def setParameter(flag):
    All = ["1 126 03 26 12 30 00","C 10","H 16","Sleep EVSE","Print "]
    All[0] = "1 " + rtctimecorr
    m1 = "{\"BusId\":\"" + window.BusId.get() + "\",\"Command\":\"Set\",\"" \
         + "Parameter\":\""
    m2 = "\"}"
    if flag == "S1":
        Text = All[0]
    elif flag == "SC":
        Text = All[1]
    elif flag == "SH":
        Text = All[2]

    message = m1 + Text + m2
    mqttc.publish(topic,message)
    sleep(2)


def doFunction(flag):
    All = ["Enable EVSE","Disable EVSE","Reset EVSE","Sleep EVSE","Allow Charging","Cancel Charging","Print "]
    if flag == "FE":
        Text = All[0]
    elif flag == "FD":
        Text = All[1]
    elif flag == "FR":
        Text = All[2]
    elif flag == "FS":
        Text = All[3]
    elif flag == "FA":
        Text = All[4]
    elif flag == "FC":
        Text = All[5]
    elif flag[0:2] == "FP":
        Text = All[6] + flag[3:]
    else:
        exit
    fm1 = "{\"BusId\":\"" + window.BusId.get() + "\",\"Command\":\"Function" \
          + "\",\"Parameter\":\""
    fm2 = "\"}"
    funcMessage = fm1 + Text + fm2
    #print(funcMessage)
    mqttc.publish(topic,funcMessage)


def sendName():
    if flagNUID[3:]=="b53b0788":
        ProfName = "Josy NAZLO"
    elif flagNUID[3:]=="3d1976af":
        ProfName = "Guy WEILER"
    else:
        ProfName = "missing in database"
    window.asyn_NUID2.set(ProfName + " on BusId " + flagNUID[0:2])
    fm1 = "{\"BusId\":\"" + flagNUID[0:2] + "\",\"Command\":\"Function" \
          + "\",\"Parameter\":\""
    fm2 = "\"}"
    PrintNameMessage = fm1 + "Print 0 6 Hello " + ProfName + fm2
    mqttc.publish(topic,PrintNameMessage)
    if ProfName != "missing in database":
        funcMessage = "{\"BusId\":\"" + flagNUID[0:2] + "\",\"Command\":\"Function" + "\",\"Parameter\":\"Allow Charging\"}"
        mqttc.publish(topic,funcMessage)



#-----------------------------------------------------------------------------
# MAIN SETUP
#-----------------------------------------------------------------------------
mqttc = mqtt.Client(client_id=clientID, clean_session=True) # create client
mqttc.on_connect      = onConnect   # define the callback functions
mqttc.on_disconnect   = onDisconnect
mqttc.on_subscribe    = onSubscribe
mqttc.on_unsubscribe  = onUnsubscribe
mqttc.on_message      = onMessage
#mqttc.username_pw_set(config['MQTT']['userMQTT'], password=config['MQTT']['passwdMQTT'])

if ping(brokerIP) != False:
    mqttc.connect(brokerIP, brokerPort, keepalive=60, bind_address="") # connect to the broker
    mqttc.loop_start() # start loop to process callbacks! (new thread!)
else:
    print("broker not found!!")

flagNUID = "0"
window = GUI()

#-----------------------------------------------------------------------------
# MAIN LOOP
#-----------------------------------------------------------------------------
try:
    while (window.flag_exit != 1):

        #window.UpdateTime()


        #print("Main  ",end='')
        if window.flag_bus=="1":
            topic = topic1
        if window.flag_bus=="2":
            topic = topic2

        if window.flag_get != "0":
            getMessages(window.flag_get)
            window.flag_get = "0"
        if window.flag_set != "0":
            setParameter(window.flag_set)
            window.flag_set = "0"
        if window.flag_function != "0":
            doFunction(window.flag_function)
            window.flag_function = "0"

        if flagNUID != "0":
            sendName()
            flagNUID = "0"

        #sleep(1)

except KeyboardInterrupt:
    mqttc.disconnect()
    mqttc.loop_stop() # clean up
    print("Keyboard interrupt by user")

mqttc.disconnect()
mqttc.loop_stop() # clean up
print("closed by window")
