#!/usr/bin/env python3
# #! is a sha-bang. It tells that the Python interpreter should run this code

# /var/www/py/testpyserial.py *************************************************
# Created by: HARB rboek2@gmail.com november 2019 GPL copyrights                
# Target is to communicate with an Arduino through a serial USB connection.

# IMPORT LIBRARIES install like: pip install --upgrade psycopg2 --user ********
import platform                       # Needed to check if we are using Python3
import serial                          # Needed to communicate with the Arduino
import time    # Needed to give the Arduino a pause afte connecting serial port
import gi              # Graphical interface main library to create GTK windows
gi.require_version("Gtk", "3.0")                    # Minimum version requiered
from gi.repository import GLib, Gio, Gtk         # And finally the desired libs
import sys

# Show environment an requirements ********************************************
python_version=platform.python_version()        # Actual Python version request
print ("De gebruikte versie van Python is:", python_version)     # Show to user
print ("De gewenste versie van Python is: 3.6.9+")               # Show to user
print ("De gebruikte versie van Pyserial is:", serial.VERSION)   # Show to user
print ("De gewenste versie van Pyserial is: 3.4+")               # Show to user
print ("De gebruikte versie van GTK gi is:", gi.version_info)    # Show to user
print ("De gewenste versie van GTK gi is: 3+")                   # Show to user

try:
    ser = serial.Serial("/dev/ttyUSB0", 57600, timeout=3)  # Resets the Arduino
except:
    ser = serial.Serial("/dev/ttyUSB1", 57600, timeout=3)
    print ("Dit gaat fout: Geen poort gevonden")
print ("De gebruikte USB poort is:", ser.portstr) # Show the port is being used
print ()
time.sleep(2)                   # Arduino resets, so give it some time to reset


# This would typically be its own file
MENU_XML="""
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <menu id="app-menu">
    <section>
      <attribute name="label" translatable="yes">Change label</attribute>
      <item>
        <attribute name="action">win.change_label</attribute>
        <attribute name="target">String 1</attribute>
        <attribute name="label" translatable="yes">String 1</attribute>
      </item>
      <item>
        <attribute name="action">win.change_label</attribute>
        <attribute name="target">String 2</attribute>
        <attribute name="label" translatable="yes">String 2</attribute>
      </item>
      <item>
        <attribute name="action">win.change_label</attribute>
        <attribute name="target">String 3</attribute>
        <attribute name="label" translatable="yes">String 3</attribute>
      </item>
    </section>
    <section>
      <item>
        <attribute name="action">win.maximize</attribute>
        <attribute name="label" translatable="yes">Maximize</attribute>
      </item>
    </section>
    <section>
      <item>
        <attribute name="action">app.about</attribute>
        <attribute name="label" translatable="yes">_About</attribute>
      </item>
      <item>
        <attribute name="action">app.quit</attribute>
        <attribute name="label" translatable="yes">_Quit</attribute>
        <attribute name="accel">&lt;Primary&gt;q</attribute>
    </item>
    </section>
  </menu>
</interface>
"""


def read_values():
    global temperatuur, red_val, gre_val, blu_val, red_bri, gre_bri, blu_bri
    global datum, tijd, freqMeasSec
    ser.write(str.encode(chr(55)))
    temp = ser.readline()
    datum, tijd, temperatuur, red_val, gre_val, blu_val, red_bri, gre_bri, blu_bri, freqMeasSec = temp.split()
    datum = datum.decode('utf-8')
    tijd = tijd.decode('utf-8')
    temperatuur = temperatuur.decode('utf-8')
    red_val = red_val.decode('utf-8')
    gre_val = gre_val.decode('utf-8')
    blu_val = blu_val.decode('utf-8')
    red_bri = red_bri.decode('utf-8')
    gre_bri = gre_bri.decode('utf-8')
    blu_bri = blu_bri.decode('utf-8')
    freqMeasSec = freqMeasSec.decode('utf-8')
    print(temp, red_val)


class MyWindow(Gtk.ApplicationWindow):                # A Gtk ApplicationWindow
    # constructor: the title is "Welcome to GNOME" and the window belongs
    # to the application app

    def __init__(self, app):
        Gtk.Window.__init__(self, title="Couveuse sturing", application=app)
        self.set_icon_from_file("py/flower-icon.png")
        self.set_default_size(400, 600)
        self.set_border_width(15)
        self.set_position(Gtk.WindowPosition.CENTER)

        read_values()

        grid = Gtk.Grid()
        self.add(grid)

        label1 = Gtk.Label("LED rood ", margin=7)
        label2 = Gtk.Label("LED groen ", margin=7)
        label3 = Gtk.Label("LED blauw ", margin=7)
        label4 = Gtk.Label(" Temperatuur ")
        self.label5 = Gtk.Label(temperatuur)
        label6 = Gtk.Label("Verwarming programma")
        label7 = Gtk.Label("Aanschakelen onder")
        label8 = Gtk.Label("Uitschakelen boven")
        label9 = Gtk.Label("Verlichting programma")
        label10 = Gtk.Label("°C")
        label11 = Gtk.Label("°C")
        label12 = Gtk.Label("Klok")
        self.label13 = Gtk.Label(datum)
        self.label14 = Gtk.Label(tijd)
        label15 = Gtk.Label("Branduren per dag")
        label16 = Gtk.Label("Verwarmingsrelais")
        label17 = Gtk.Label("Verlichtingsrelais")
        label18 = Gtk.Label("Automatisch")
        label19 = Gtk.Label("Handmatig")
        label20 = Gtk.Label("Aan")
        label21 = Gtk.Label("Uit")
        label22 = Gtk.Label(" ")
        label23 = Gtk.Label(" ")
        label24 = Gtk.Label(" ")
        label25 = Gtk.Label("Meting iedere")
        label26 = Gtk.Label("seconden")
        label27 = Gtk.Label("°C")
        label28 = Gtk.Label("Zet klok gelijk")

        red_sw = Gtk.Switch()
        red_sw.connect("notify::active", self.on_red_sw_activated)
        if red_val == '0':
            red_sw.set_active(False)
        else:
            red_sw.set_active(True)

        red_adjust = Gtk.Adjustment(0, 0, 255, 1, 0, 0)
        self.spin_red = Gtk.SpinButton()
        self.spin_red.set_adjustment(red_adjust)
        self.spin_red.set_value(int(red_bri))

        gre_sw = Gtk.Switch()
        gre_sw.connect("notify::active", self.on_gre_sw_activated)
        if gre_val == '0':
            gre_sw.set_active(False)
        else:
            gre_sw.set_active(True)

        gre_adjust = Gtk.Adjustment(0, 0, 255, 1, 0, 0)
        self.spin_gre = Gtk.SpinButton()
        self.spin_gre.set_adjustment(gre_adjust)
        self.spin_gre.set_value(int(gre_bri))

        blu_sw = Gtk.Switch()
        blu_sw.connect("notify::active", self.on_blu_sw_activated)
        if blu_val == '0':
            blu_sw.set_active(False)
        else:
            blu_sw.set_active(True)

        blu_adjust = Gtk.Adjustment(0, 0, 255, 1, 0, 0)
        self.spin_blu = Gtk.SpinButton()
        self.spin_blu.set_adjustment(blu_adjust)
        self.spin_blu.set_value(int(blu_bri))


        uurpd_adjust = Gtk.Adjustment(0, 0, 24, 2, 0, 0)
        self.spin_uurpd = Gtk.SpinButton()
        self.spin_uurpd.set_adjustment(uurpd_adjust)
        #self.spin_uurpd.set_value(int(blu_bri))
        self.spin_uurpd.set_value(16)

        tmpaan_adjust = Gtk.Adjustment(0, 0, 25, 1, 0, 0)
        self.spin_tmpaan = Gtk.SpinButton()
        self.spin_tmpaan.set_adjustment(tmpaan_adjust)
        #self.spin_tmpaan.set_value(int(blu_bri))
        self.spin_tmpaan.set_value(20)

        tmpuit_adjust = Gtk.Adjustment(0, 0, 25, 1, 0, 0)
        self.spin_tmpuit = Gtk.SpinButton()
        self.spin_tmpuit.set_adjustment(tmpuit_adjust)
        #self.spin_tmpuit.set_value(int(blu_bri))
        self.spin_tmpuit.set_value(22)

        measec_adjust = Gtk.Adjustment(0, 0, 25, 1, 0, 0)
        self.spin_measec = Gtk.SpinButton()
        self.spin_measec.set_adjustment(measec_adjust)
        self.spin_measec.set_value(int(freqMeasSec))


        button1 = Gtk.Button(label=" Update data+ ")
        button1.connect("clicked", self.on_button1_clicked)

        button5 = Gtk.Button(label="LED sturing")
        button5.connect("clicked", self.on_button5_clicked)

        button6 = Gtk.Button(label="Verwarming sturing")
        button6.connect("clicked", self.on_button6_clicked)

        button7 = Gtk.Button(label="Verlichting sturing")
        button7.connect("clicked", self.on_button6_clicked)

        button2 = Gtk.RadioButton.new_with_label_from_widget(None, "Uit")
        button2.connect("toggled", self.on_button_2_toggled)
        button2.set_active(False)

        button3 = Gtk.RadioButton.new_from_widget(button2)
        button3.set_label("Auto")
        button3.connect("toggled", self.on_button_toggled, "2")
        button3.set_active(True)

        button4 = Gtk.RadioButton.new_with_mnemonic_from_widget(button2,"Aan")
        button4.connect("toggled", self.on_button_4_toggled, "3")
        button4.set_active(False)

        button8 = Gtk.RadioButton.new_with_label_from_widget(None, "Uit")
        button8.connect("toggled", self.on_button_8_toggled)

        button9 = Gtk.RadioButton.new_from_widget(button8)
        button9.set_label("Auto")
        button9.connect("toggled", self.on_button_toggled, "2")
        button9.set_active(True)

        button10 = Gtk.RadioButton.new_with_mnemonic_from_widget(button8,"Aan")
        button10.connect("toggled", self.on_button_10_toggled)

        button11 = Gtk.Button(label="Algemene instellingen")
        button11.connect("clicked", self.on_button5_clicked)

        self.separator1 = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
        self.separator2 = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
        self.separator3 = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)

        grid.attach(button5, 0, 0, 4, 1)      # Child, left, top, width, height

        grid.attach(label1, 0, 1, 1, 1)       # Child, left, top, width, height
        grid.attach(red_sw, 1, 1, 1, 1)       # Child, left, top, width, height
        grid.attach(self.spin_red, 2, 1, 1, 1)# Child, left, top, width, height

        grid.attach(label2, 0, 2, 1, 1)       # Child, left, top, width, height
        grid.attach(gre_sw, 1, 2, 1, 1)       # Child, left, top, width, height
        grid.attach(self.spin_gre, 2, 2, 1, 1)# Child, left, top, width, height

        grid.attach(label3, 0, 3, 1, 1)       # Child, left, top, width, height
        grid.attach(blu_sw, 1, 3, 1, 1)       # Child, left, top, width, height
        grid.attach(self.spin_blu, 2, 3, 1, 1)# Child, left, top, width, height

        grid.attach(label22, 0, 4, 1, 1)      # Child, left, top, width, height

        #STURING VERWARMING ***************************************************
        grid.attach(self.separator1, 0, 5, 4, 1) # Child,left,top,width, height
        grid.attach(button6, 0, 6, 4, 1)      # Child, left, top, width, height

        grid.attach(label6, 0, 7, 1, 1)       # Child, left, top, width, height
        grid.attach(button2, 1, 7, 1, 1)
        grid.attach(button3, 2, 7, 1, 1)
        grid.attach(button4, 3, 7, 1, 1)

        grid.attach(label4, 0, 8, 1, 1)       # Child, left, top, width, height
        grid.attach(self.label5, 1, 8, 1, 1)  # Child, left, top, width, height
        grid.attach(label10, 2, 8, 1, 1)      # Child, left, top, width, height

        grid.attach(label7, 0, 9, 1, 1)       # Child, left, top, width, height
        grid.attach(self.spin_tmpaan, 1, 9, 1, 1) # Child,left,top,width,height
        grid.attach(label11, 2, 9, 1, 1)      # Child, left, top, width, height

        grid.attach(label8, 0, 10, 1, 1)      # Child, left, top, width, height
        grid.attach(self.spin_tmpuit, 1, 10, 1, 1) #Child,left,top,width,height
        grid.attach(label27, 2, 10, 1, 1)     # Child, left, top, width, height

        grid.attach(label16, 0, 11, 1, 1)     # Child, left, top, width, height
        grid.attach(label18, 1, 11, 1, 1)     # Child, left, top, width, height

        grid.attach(label23, 0, 12, 1, 1)     # Child, left, top, width, height


        #STURING VERLICHTING **************************************************
        grid.attach(self.separator2, 0, 13, 4, 1) # Child,left,top,width,height
        grid.attach(button7, 0, 14, 4, 1)     # Child, left, top, width, height

        grid.attach(label9, 0, 15, 1, 1)      # Child, left, top, width, height
        grid.attach(button8, 1, 15, 1, 1)
        grid.attach(button9, 2, 15, 1, 1)
        grid.attach(button10, 3, 15, 1, 1)

        grid.attach(label12, 0, 16, 1, 1)     # Child, left, top, width, height
        grid.attach(self.label14, 1, 16, 1, 1) # Child,left, top, width, height
        grid.attach(self.label13, 2, 16, 1, 1) # Child,left, top, width, height

        grid.attach(label15, 0, 17, 1, 1)     # Child, left, top, width, height
        grid.attach(self.spin_uurpd, 1, 17, 1, 1) # Child,left,top,width,height

        grid.attach(label17, 0, 18, 1, 1)     # Child, left, top, width, height
        grid.attach(label19, 1, 18, 1, 1)     # Child, left, top, width, height
        grid.attach(label21, 2, 18, 1, 1)     # Child, left, top, width, height

        grid.attach(label24, 0, 19, 1, 1)     # Child, left, top, width, height
        grid.attach(self.separator3, 0, 20, 4, 1) #Child,left,top,width, height
        grid.attach(button11, 0, 21, 4, 1)    # Child, left, top, width, height

        grid.attach(label25, 0, 22, 1, 1)     # Child, left, top, width, height
        grid.attach(self.spin_measec, 1, 22, 1, 1) #Child,left,top,width,height
        grid.attach(label26, 2, 22, 1, 1)     # Child, left, top, width, height

        grid.attach(label28, 1, 23, 2, 1)     # Child, left, top, width, height


    def on_button_toggled(self, button, name):
        if button.get_active():
            state = "on"
        else:
            state = "off"
        print("Button", name, "was turned", state)


    def on_button_2_toggled(self, button):
        if button.get_active():
            ser.write(str.encode('8'))
        print("Button 2 uitschakelen verwarming")


    def on_button_4_toggled(self, button, name):
        if button.get_active():
            state = "on"
            ser.write(str.encode('9'))
        else:
            state = "off"
        print("Button 4 eigen routine", name, "was turned", state)

    def on_button_8_toggled(self, button):
        if button.get_active():
            ser.write(str.encode(':'))
        print("Button 2 Uitschakelen verlichting")

    def on_button_10_toggled(self, button):
        if button.get_active():
            ser.write(str.encode(';'))
        print("Button 2 Aanschakelen verlichting")


    def on_red_sw_activated(self, switch, gparam):
        if switch.get_active():
            ser.write(str.encode('1'))
            self.spin_red.set_visible(True)
            print(ser.readline(8))
        else:
            ser.write(str.encode('2'))
            self.spin_red.set_visible(False)
            print(ser.readline(9))


    def on_gre_sw_activated(self, switch, gparam):
        if switch.get_active():
            ser.write(str.encode('3'))
            self.spin_gre.set_visible(True)
            print(ser.readline(8)) 
        else:
            ser.write(str.encode('4'))
            self.spin_gre.set_visible(False)
            print(ser.readline(9))


    def on_blu_sw_activated(self, switch, gparam):
        if switch.get_active():
            ser.write(str.encode('5'))
            self.spin_blu.set_visible(True)
            print(ser.readline(8)) 
        else:
            ser.write(str.encode('6'))
            self.spin_blu.set_visible(False)
            print(ser.readline(9))


    def on_button1_clicked(self, widget):
        read_values()
        self.label5.set_text(temperatuur)
        self.label13.set_text(datum)
        self.label14.set_text(tijd)

    def on_button5_clicked(self, widget):
        read_values()
        self.label5.set_text(temperatuur)
        self.label13.set_text(datum)
        self.label14.set_text(tijd)

    def on_button6_clicked(self, widget):
        read_values()
        self.label5.set_text(temperatuur)
        self.label13.set_text(datum)
        self.label14.set_text(tijd)

    def on_button7_clicked(self, widget):
        read_values()
        self.label5.set_text(temperatuur)
        self.label13.set_text(datum)
        self.label14.set_text(tijd)

    def on_button11_clicked(self, widget):
        read_values()
        self.label5.set_text(temperatuur)
        self.label13.set_text(datum)
        self.label14.set_text(tijd)


class MyApplication(Gtk.Application):
    # constructor of the Gtk Application

    def __init__(self):
        Gtk.Application.__init__(self)

    # create and activate a MyWindow, with self (the MyApplication) as
    # application the window belongs to.
    # Note that the function in C activate() becomes do_activate() in Python
    def do_activate(self):
        self.win = MyWindow(self)
        builder = Gtk.Builder.new_from_string(MENU_XML, -1)
        self.set_app_menu(builder.get_object("app-menu"))
        # show the window and all its content
        # this line could go in the constructor of MyWindow as well
        self.win.show_all()
        self.win.spin_red.set_visible(False)
        self.win.spin_gre.set_visible(False)
        self.win.spin_blu.set_visible(False)

    # start up the application
    # Note that the function in C startup() becomes do_startup() in Python
    def do_startup(self):
        Gtk.Application.do_startup(self)

        action = Gio.SimpleAction.new("quit", None)
        action.connect("activate", self.on_quit)
        self.add_action(action)

        action = Gio.SimpleAction.new("about", None)
        action.connect("activate", self.on_about)
        self.add_action(action)

    def on_about(self, action, param):
        about_dialog = Gtk.AboutDialog(transient_for=self.win, modal=True)
        about_dialog.set_comments("Dit is het comments veld")
        about_dialog.set_version("0.97")
        about_dialog.set_authors("Richard Boekamp")
        about_dialog.set_copyright("November 2019 GPL copyrights")
        about_dialog.present()

    def on_quit(self, action, param):
        self.quit()


# create and run the application, exit with the value returned by
# running the program
app = MyApplication()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
ser.close()                                                        # Close port
