diff --git a/BiogasControllerApp-V2.1-Installer-V2.exe b/BiogasControllerApp-V2.1-Installer-V2.exe new file mode 100644 index 0000000..11c87b4 Binary files /dev/null and b/BiogasControllerApp-V2.1-Installer-V2.exe differ diff --git a/BiogasControllerApp-V2.1/.idea/.gitignore b/BiogasControllerApp-V2.1/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/BiogasControllerApp-V2.1/.idea/.name b/BiogasControllerApp-V2.1/.idea/.name new file mode 100644 index 0000000..06ffd37 --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/.name @@ -0,0 +1 @@ +biogascontrollerapp.py \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/.idea/ENATECH.iml b/BiogasControllerApp-V2.1/.idea/ENATECH.iml new file mode 100644 index 0000000..0e4e9fa --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/ENATECH.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/.idea/inspectionProfiles/profiles_settings.xml b/BiogasControllerApp-V2.1/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/.idea/misc.xml b/BiogasControllerApp-V2.1/.idea/misc.xml new file mode 100644 index 0000000..d1e22ec --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/.idea/modules.xml b/BiogasControllerApp-V2.1/.idea/modules.xml new file mode 100644 index 0000000..6610bd3 --- /dev/null +++ b/BiogasControllerApp-V2.1/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1.exe b/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1.exe new file mode 100644 index 0000000..02ebde7 Binary files /dev/null and b/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1.exe differ diff --git a/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1/.idea/workspace.xml b/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1/.idea/workspace.xml deleted file mode 100644 index c692da6..0000000 --- a/BiogasControllerApp-V2.1/BiogasControllerApp-V2.1/.idea/workspace.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1639579090743 - - - - \ No newline at end of file diff --git a/BiogasControllerApp-V2.1/BiogasControllerAppLogo.png b/BiogasControllerApp-V2.1/BiogasControllerAppLogo.png new file mode 100644 index 0000000..b8e71ad Binary files /dev/null and b/BiogasControllerApp-V2.1/BiogasControllerAppLogo.png differ diff --git a/BiogasControllerApp-V2.1/Readme.txt b/BiogasControllerApp-V2.1/Readme.txt new file mode 100644 index 0000000..ebb7e2a --- /dev/null +++ b/BiogasControllerApp-V2.1/Readme.txt @@ -0,0 +1,117 @@ + + + ---------------------------------------------------------- + + BiogasControllerApp V2.1 + + ---------------------------------------------------------- + + + Thank you for downloading the new Version of the BiogsaControllerApp! You are greeted with + lots of new features, including a new and redesigned Graphical User Interface (later "GUI") + and an automatic assignment of the comport on Windows. + + ---------------------------------------------------------------------------- + +*FEATURE LIST* + - Easily read out the data the Microcontroller used in ENATECH sends + - Easily change the coefficients for the temperature sonds + - Easily change the temperature that is set for the controller to heat to + - Easy to navigate menus and submenus for better organisation + - (Almost) Bugfree + - Highly detailed error resolving instructions directly inside of the app + - Easy to run: No extra Software required (e.g. Python or similar) + - Easy to install and uninstall as it has an installer and uninstaller + + +####################################################################################################### + + _________ + + CHANGELOG + _________ + + DEVELOPMENT VERSIONS + ....................... + + dev-V2rev1: + - new GUI + - complete rework of the backend + - functioning value reading module + + dev-V2rev2: + - functioning Read-Data Screen + - automatic assignment of the serial port + + dev-V2rev3: + - functioning Change-Temperature screen + - functioning Change-All-Data screen + + dev-V2rev4: + - some Error-Infos were added + + V2-Rc1: + - Bugfixes + + V2-Rc2: + - Bugfixes + + + dev-V2.1rev1: + - fixed a bug, where it was possible that the app crashed if an error in + the communication module occured + + dev-V2.1rev2: + - Optimised port assignment so that it now can handle multiple comports + + dev-V2.1rev3: + - added way more detailed Error information and Error-resolving hints + + dev-v2.1rev4: + - fixed a bug, where it was possible that the app crashed if one unplugged + the cable whilst in any other screen than the homescreen or credits screen + + V2.1-Rc1: + - small Bugfixes + + + + FULL RELEASES + ...................... + + V2: + - NEW GUI + - NEW Backend + - AUTOMATIC assignment of COMPORTS + + V2.1 + - DETAILED Error-Info + - DETAILED Error-Resolving-Tips + - MORE RELIABLE Comport handling + - BUGFIXES + + + +****************************************************************************************************** + + THIS APP IS FREE TO USE FOR ALL STUDENTS AT THE + KANTONSSCHULE WOHLEN + +****************************************************************************************************** + + + DEVELOPMENT: + + - Microcontroller Software: Dr. A. Cornaz + - BiogasControllerApp V1.0.0: S. Reichmuth + - BiogasControllerApp V2.x: J. Hutz + + + +================================== +=== COPYRIGHT 2022 J. Hutz ====== +================================== + + + + diff --git a/BiogasControllerApp-V2.1/__pycache__/biogascontrollerapp.cpython-38.pyc b/BiogasControllerApp-V2.1/__pycache__/biogascontrollerapp.cpython-38.pyc new file mode 100644 index 0000000..ddccd89 Binary files /dev/null and b/BiogasControllerApp-V2.1/__pycache__/biogascontrollerapp.cpython-38.pyc differ diff --git a/BiogasControllerApp-V2.1/bin/gui/gui.kv b/BiogasControllerApp-V2.1/bin/gui/gui.kv new file mode 100644 index 0000000..babb5f3 --- /dev/null +++ b/BiogasControllerApp-V2.1/bin/gui/gui.kv @@ -0,0 +1,611 @@ +RootScreen: + HomeScreen: + ReadoutScreen: + ReadData: + ProgramTemp: + Program: + Credits: + +: + title: "BiogasControllerApp" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Are you sure you want to leave?" + font_size: 20 + GridLayout: + cols:2 + Button: + text: "Yes" + font_size: 15 + on_release: + root.quitapp() + app.stop() + Button: + text: "No" + font_size: 15 + on_press: + root.dismiss() + +: + title: "WARNING!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Unable to open Serial Port" + font_size: 20 + GridLayout: + cols:2 + Button: + text: "Details" + on_release: + root.details() + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "WARNING!" + font_size: 50 + size_hint: 0.7, 0.6 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Unable to communicate" + font_size: 20 + Label: + text: "Possible ways to resolve this problem:\n- Try again\n- Restart the PIC16F877 or reset the program\n- Check the cable / connect one" + font_size: 14 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + on_open: self.update_details = root.infos() + title: "DETAILS" + font_size: 50 + size_hint: 1, 0.7 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Unable to open Serial Port" + font_size: 20 + Label: + id: errormessage + text: root.infos() + font_size: 13 + Label: + text: root.error_tips() + font_size: 13 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "NOTICE!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Mode Switched!" + font_size: 30 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "NOTICE!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "SAVED!" + font_size: 30 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "NOTICE!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Establishing connection with PIC16F877" + font_size: 18 + Label: + text: "This Process may take a while..." + font_size: 15 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "WARNING!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Missing Information!" + font_size: 18 + Label: + text: "Check your entry" + font_size: 15 + Button: + text:"Ok" + on_release: + root.dismiss() + +: + title: "NOTICE!" + font_size: 50 + size_hint: 0.5, 0.4 + auto_dismiss: False + GridLayout: + cols:1 + Label: + text: "Connection with PIC16F877 terminated" + font_size: 18 + Label: + text: "The connection to the Microcontroller\nhas been terminated successfully" + font_size: 15 + Button: + text:"Ok" + on_release: + root.dismiss() + +###################################### +# SCREENS +###################################### + +: + name: "Home" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + GridLayout: + cols:1 + Label: + text: "BiogasanlageControllerApp" + font_size: 50 + color: (0, 113, 0, 1) + bold:True + italic:True + FloatLayout: + GridLayout: + cols: 2 + size_hint: 0.8, 0.8 + pos_hint: {"x": 0.1, "y": 0.1} + Button: + text: "Start" + background_color: (255, 0, 0, 0.6) + font_size: 30 + on_release: + root.tryconnection() + Button: + text: "Quit" + background_color: (255, 0, 0, 0.6) + font_size: 30 + on_release: + root.exitapp() + Label: + text: "You are currently running Version 2.1.0 - If you encounter a bug, please report it!" + font_size: 13 + pos_hint: {"y": -0.45, "x":0.05} + Button: + text: "credits" + font_size: 13 + size_hint: 0.07, 0.06 + pos_hint: {"x":0.01, "y":0.01} + background_color: (50, 0, 0, 0.2) + on_release: + app.root.current = "Credits" + root.manager.transition.direction = "left" + +: + on_pre_enter: self.reset_screen = root.resscreen() + name: "Readout" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + GridLayout: + FloatLayout: + Label: + pos_hint: {"y":0.4} + text: "READOUT" + font_size: 40 + color: (0, 113, 0, 1) + bold: True + GridLayout: + cols:4 + size_hint: 0.8, 0.3 + pos_hint: {"x":0.1, "y":0.4} + Label: + text: "SONDE 1: " + font_size: 20 + Label: + id: sonde1 + text: "" + Label: + text: "SONDE 2: " + font_size: 20 + Label: + id: sonde2 + text: "" + Label: + text: "SONDE 3: " + font_size: 20 + Label: + id: sonde3 + text: "" + Label: + text: "SONDE 4: " + font_size: 20 + Label: + id: sonde4 + text: "" + Button: + text: "Start communication" + size_hint: 0.2, 0.1 + pos_hint: {"x": 0.5, "y": 0.05} + background_color: (255, 0, 0, 0.6) + on_release: + root.start_com() + Button: + text: "End communication" + size_hint: 0.2, 0.1 + pos_hint: {"x": 0.7, "y": 0.05} + background_color: (255, 0, 0, 0.6) + on_release: + root.end_com() + Button: + text: "Back" + size_hint: 0.3, 0.1 + pos_hint: {"x":0.05, "y":0.05} + background_color: (255, 0, 0, 0.6) + on_release: + root.leave_screen() + app.root.current = "Home" + root.manager.transition.direction = "left" + ToggleButton: + id: mode_sel + size_hint: 0.15, 0.1 + pos_hint: {"x":0.1, "y":0.2} + text: "Normal Mode" if self.state == "normal" else "Fast Mode" + on_text: root.switch_mode(mode_sel.text) + background_color: (255,0,0,0.6) if self.state == "normal" else (0,0,255,0.6) + Button: + text: "Read Data" + size_hint: 0.15, 0.1 + pos_hint: {"x":0.3, "y":0.2} + background_color: (255, 0, 0, 0.6) + on_release: + root.leave_screen() + app.root.current = "RD" + root.manager.transition.direction = "down" + Button: + text: "Temperature" + size_hint: 0.15, 0.1 + pos_hint: {"x":0.5, "y":0.2} + background_color: (255, 0, 0, 0.6) + on_release: + root.leave_screen() + app.root.current = "PT" + root.manager.transition.direction = "down" + Button: + text: "Change all Data" + size_hint: 0.15, 0.1 + pos_hint: {"x":0.7, "y":0.2} + background_color: (255, 0, 0, 0.6) + on_release: + root.leave_screen() + app.root.current = "PR" + root.manager.transition.direction = "down" + Label: + id: frequency + text: "Frequency will appear here" + font_size: 10 + pos_hint: {"x":0.4, "y": 0.3} + +: + name: "RD" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + GridLayout: + FloatLayout: + Label: + text: "Read Data" + font_size: 40 + color: (0, 113, 0, 1) + bold: True + pos_hint: {"y":0.4} + Button: + text: "Start Readout" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.4, "y":0.1} + on_release: + root.read_data() + Button: + text: "Back" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.1, "y":0.1} + background_color: (255, 0, 0, 0.6) + on_release: + app.root.current = "Readout" + root.manager.transition.direction = "up" + GridLayout: + cols:4 + size_hint: 0.8, 0.4 + pos_hint: {"x":0.1, "y":0.3} + Label: + text: "Sonde 1" + font_size: 20 + Label: + id: inf_sonde1 + text: "" + Label: + text: "Sonde 2" + font_size: 20 + Label: + id: inf_sonde2 + text: "" + Label: + text: "Sonde 3" + font_size: 20 + Label: + id: inf_sonde3 + text: "" + Label: + text: "Sonde 4" + font_size: 20 + Label: + id: inf_sonde4 + text: "" + +: + name: "PT" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + GridLayout: + FloatLayout: + Label: + text: "Change Temperature" + pos_hint: {"y":0.4} + font_size: 40 + color: (0, 113, 0, 1) + bold: True + GridLayout: + size_hint: 0.8, 0.4 + pos_hint: {"x": 0.1, "y":0.3} + cols:2 + Label: + text: "Temperatur Sonde 1: " + TextInput: + id: temp_s1 + multiline: False + input_filter: "float" + Label: + text: "Temperatur Sonde 2: " + TextInput: + id: temp_s2 + multiline: False + input_filter: "float" + Label: + text: "Temperatur Sonde 3: " + TextInput: + id: temp_s3 + multiline: False + input_filter: "float" + Label: + text: "Temperatur Sonde 4: " + TextInput: + id: temp_s4 + multiline: False + input_filter: "float" + Button: + text: "Back" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.1, "y":0.1} + background_color: (255, 0, 0, 0.6) + on_release: + app.root.current = "Readout" + root.manager.transition.direction = "up" + Button: + text: "Save" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.6, "y":0.1} + background_color: (255, 0, 0, 0.6) + on_release: + root.send_data() + +: + name: "PR" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + FloatLayout: + Label: + text: "Change all Data" + font_size: 40 + color: (0, 113, 0, 1) + bold: True + pos_hint: {"y":0.4} + GridLayout: + size_hint: 0.8, 0.5 + pos_hint: {"x":0.1, "y":0.2} + cols: 4 + Label: + text: "Sonde 1, a:" + TextInput: + id: s1_a + multiline: False + input_filter: "float" + Label: + text: "Sonde 1, b:" + TextInput: + id: s1_b + multiline: False + input_filter: "float" + Label: + text: "Sonde 1, c:" + TextInput: + id: s1_c + multiline: False + input_filter: "float" + Label: + text: "Sonde 1, Temp:" + TextInput: + id: s1_t + multiline: False + input_filter: "float" + Label: + text: "Sonde 2, a:" + TextInput: + id: s2_a + multiline: False + input_filter: "float" + Label: + text: "Sonde 2, b:" + TextInput: + id: s2_b + multiline: False + input_filter: "float" + Label: + text: "Sonde 2, c:" + TextInput: + id: s2_c + multiline: False + input_filter: "float" + Label: + text: "Sonde 2, Temp:" + TextInput: + id: s2_t + multiline: False + input_filter: "float" + Label: + text: "Sonde 3, a:" + TextInput: + id: s3_a + multiline: False + input_filter: "float" + Label: + text: "Sonde 3, b:" + TextInput: + id: s3_b + multiline: False + input_filter: "float" + Label: + text: "Sonde 3, c:" + TextInput: + id: s3_c + multiline: False + input_filter: "float" + Label: + text: "Sonde 3, Temp:" + TextInput: + id: s3_t + multiline: False + input_filter: "float" + Label: + text: "Sonde 4, a:" + TextInput: + id: s4_a + multiline: False + input_filter: "float" + Label: + text: "Sonde 4, b:" + TextInput: + id: s4_b + multiline: False + input_filter: "float" + Label: + text: "Sonde 4, c:" + TextInput: + id: s4_c + multiline: False + input_filter: "float" + Label: + text: "Sonde 4, Temp:" + TextInput: + id: s4_t + multiline: False + input_filter: "float" + Button: + text: "Back" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.1, "y":0.1} + background_color: (255, 0, 0, 0.6) + on_release: + app.root.current = "Readout" + root.manager.transition.direction = "up" + Button: + text: "Save" + size_hint: 0.2, 0.1 + pos_hint: {"x":0.6, "y":0.1} + background_color: (255, 0, 0, 0.6) + on_release: + root.send_data() + +: + name: "Credits" + canvas.before: + Color: + rgba: (50,50,50,0.2) + Rectangle: + size: self.size + pos: self.pos + FloatLayout: + Button: + text: "back" + size_hint: 0.4, 0.2 + pos_hint: {"x":0.3, "y":0.1} + on_release: + app.root.current = "Home" + root.manager.transition.direction = "right" + GridLayout: + cols:1 + pos_hint:{"x":0.05, "y":0.35} + size_hint: 0.9, 0.5 + Label: + text: "This is a rework of the BiogasControllerApp V1, that was originally programmed by S. Reichmuth." + Label: + text: "Written by: Janis Hutz\nDesigned by: Janis Hutz\nDesign language: Kivy" diff --git a/BiogasControllerApp-V2.1/bin/lib/__pycache__/communication.cpython-38.pyc b/BiogasControllerApp-V2.1/bin/lib/__pycache__/communication.cpython-38.pyc new file mode 100644 index 0000000..a508582 Binary files /dev/null and b/BiogasControllerApp-V2.1/bin/lib/__pycache__/communication.cpython-38.pyc differ diff --git a/BiogasControllerApp-V2.1/bin/lib/__pycache__/comport_search.cpython-38.pyc b/BiogasControllerApp-V2.1/bin/lib/__pycache__/comport_search.cpython-38.pyc new file mode 100644 index 0000000..5b24120 Binary files /dev/null and b/BiogasControllerApp-V2.1/bin/lib/__pycache__/comport_search.cpython-38.pyc differ diff --git a/BiogasControllerApp-V2.1/bin/lib/__pycache__/lib.cpython-38.pyc b/BiogasControllerApp-V2.1/bin/lib/__pycache__/lib.cpython-38.pyc new file mode 100644 index 0000000..cac2669 Binary files /dev/null and b/BiogasControllerApp-V2.1/bin/lib/__pycache__/lib.cpython-38.pyc differ diff --git a/BiogasControllerApp-V2.1/bin/lib/communication.py b/BiogasControllerApp-V2.1/bin/lib/communication.py new file mode 100644 index 0000000..768f6d6 --- /dev/null +++ b/BiogasControllerApp-V2.1/bin/lib/communication.py @@ -0,0 +1,96 @@ +import bin.lib.lib +com = bin.lib.lib.Com() + + +class Communication: + def __init__(self): + self.__x = 0 + self.__data_recieve = 0 + self.__output = "" + + def change_temp(self, data, special_port): + com.connect(19200, special_port) + com.send("PT") + self.go = 0 + while True: + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "P": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "T": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.go = 1 + break + else: + pass + else: + pass + else: + pass + else: + pass + if self.go == 1: + self.data = data + while len(self.data) > 0: + self.__data_recieve = com.receive(3) + if self.__data_recieve != "": + com.send_float(float(self.data.pop(0))) + else: + print("error") + break + else: + print("Error") + com.quitcom() + + def change_all(self, data, special_port): + com.connect(19200, special_port) + com.send("PR") + self.go = 0 + while True: + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "P": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "R": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.go = 1 + break + else: + pass + else: + pass + else: + pass + else: + pass + if self.go == 1: + self.data = data + while len(self.data) > 0: + self.__data_recieve = com.receive(3) + if self.__data_recieve != "": + com.send_float(float(self.data.pop(0))) + else: + print("error") + break + else: + print("Error") + com.quitcom() + + +class SwitchMode: + def __init__(self): + pass + + def enable_fastmode(self): + com.connect(19200,"") + com.send("FM") + com.quitcom() + + def disable_fastmode(self): + com.connect(19200, "") + com.send("NM") + com.quitcom() diff --git a/BiogasControllerApp-V2.1/bin/lib/comport_search.py b/BiogasControllerApp-V2.1/bin/lib/comport_search.py new file mode 100644 index 0000000..020e75a --- /dev/null +++ b/BiogasControllerApp-V2.1/bin/lib/comport_search.py @@ -0,0 +1,22 @@ +import serial.tools.list_ports + + +class ComportService: + def __init__(self): + self.__comport = [] + self.__import = [] + self.__working = [] + + def get_comport(self, special_port=""): + self.__comport = [comport.device for comport in serial.tools.list_ports.comports()] + self.__pos = 0 + if special_port != "": + self.__working = special_port + else: + while self.__working == []: + self.__com_name = serial.tools.list_ports.comports()[self.__pos] + if "USB-Serial Controller" or "Prolific USB-Serial Controller" in self.__com_name: + self.__working = self.__comport.pop(self.__pos) + else: + self.__pos += 1 + return self.__working diff --git a/BiogasControllerApp-V2.1/bin/lib/lib.py b/BiogasControllerApp-V2.1/bin/lib/lib.py new file mode 100644 index 0000000..7c5f507 --- /dev/null +++ b/BiogasControllerApp-V2.1/bin/lib/lib.py @@ -0,0 +1,73 @@ +import serial +import struct +import bin.lib.comport_search +"""@package docstring +This package can communicate with a microcontroller""" + +coms = bin.lib.comport_search.ComportService() + + +class Com: + def __init__(self): + self.xr = "" + self.output = "" + self.str_input = "" + self.str_get_input = "" + self.xs = "" + self.__comport = '/dev/ttyUSB0' + + def connect(self, baudrate, special_port): + try: + self.__comport = coms.get_comport(special_port) + except: + pass + self.ser = serial.Serial(self.__comport, baudrate=baudrate, timeout=5) + + def quitcom(self): + try: + self.ser.close() + except: + pass + + def receive(self, amount_bytes): + self.xr = self.ser.read(amount_bytes) + return self.xr + + def decode_ascii(self, value): + try: + self.output = value.decode() + except: + self.output = "Error" + return self.output + + def check_value(self, value_check, checked_value): + if value_check == checked_value: + return 1 + else: + return 0 + + def decode_int(self, value): + self.i = int(value, base = 16) + return self.i + + def decode_float(self, value): + self.fs = str(value, 'ascii') + '00' + self.f = struct.unpack('>f', bytes.fromhex(self.fs)) + return str(self.f[0]) + + def decode_float_2(self, value): + self.fs = str(value, 'ascii') + '0000' + self.f = struct.unpack('>f', bytes.fromhex(self.fs)) + return str(self.f[0]) + + def get_input(self): + self.str_get_input = input("please enter a character to send: ") + return self.str_get_input + + def send(self, str_input): + self.xs = str_input.encode() + self.ser.write(self.xs) + + def send_float(self, float_input): + ba = bytearray(struct.pack('>f', float_input)) + self.ser.write(ba[0:3]) diff --git a/BiogasControllerApp-V2.1/biogascontrollerapp.py b/BiogasControllerApp-V2.1/biogascontrollerapp.py new file mode 100644 index 0000000..a14538a --- /dev/null +++ b/BiogasControllerApp-V2.1/biogascontrollerapp.py @@ -0,0 +1,507 @@ +print(""" + +===================== + +BIOGASCONTROLLERAPP + +---------- +Version 2.1 +Copyright 2022 J.Hutz""") +import time +import threading +import platform +import os +os.environ["KIVY_NO_CONSOLELOG"] = "1" +from kivy.uix.screenmanager import Screen, ScreenManager +from kivy.uix.popup import Popup +from kivy.app import App +from kivy.lang import Builder +from kivy.clock import mainthread +import bin.lib.lib +import bin.lib.communication +import bin.lib.comport_search + + + + +com = bin.lib.lib.Com() + +################################################################## +# Popups +################################################################## + + +class QuitPU(Popup): + def quitapp(self): + com.quitcom() + + +class NoConnection(Popup): + def details(self): + self.detailsinfo = DetailInfo() + self.detailsinfo.open() + + +class DetailInfo(Popup): + update_details = "" + def infos(self): + self.err = "" + try: + com.connect(19200, "") + com.quitcom() + except Exception as err: + self.err += "Errormessage:\n" + self.err += str(err) + self.err += "\n-------------------------------------------------------------------------------------------------------------------------------------------------------------\n" + return str(self.err) + + def error_tips(self): + self.err_tip = "" + try: + com.connect(19200, "") + com.quitcom() + except Exception as err: + self.err_tip += "Possible way to resolve the issue: \n\n" + if str(err)[0:10] == "[Errno 13]": + if platform.system() == "Linux": + self.err_tip += f"Open a terminal and type in: sudo chmod 777 {bin.lib.comport_search.ComportService().get_comport()}" + elif platform.system() == "Macintosh": + self.err_tip += "Give permission to access the cable" + elif platform.system() == "Windows": + self.err_tip += "Try a different cable or install another driver" + else: + self.err_tip += "Unknown OS" + elif str(err)[0:10] == "[Errno 2] ": + if platform.system() == "Linux": + self.err_tip += "Connect a cable, open a terminal and type in: sudo chmod 777 /dev/ttyUSB0" + elif platform.system() == "Macintosh": + self.err_tip += "Give permission to access the cable" + elif platform.system() == "Windows": + self.err_tip += "Try a different cable or install another driver" + else: + self.err_tip += "Unknown OS" + elif str(err)[0:34] == "could not open port '/dev/ttyUSB0'": + self.err_tip += "Please connect the PC with the microcontroller!" + elif str(err)[0:26] == f"could not open port '{bin.lib.comport_search.ComportService().get_comport()}'": + self.err_tip += "Try using a different cable or close all monitoring software (like MSI Afterburner)" + else: + self.err_tip += "Special Error, consult the manual of Serial" + return str(self.err_tip) + + +class Modeswitch(Popup): + pass + + +class Connecting_PU(Popup): + pass + + +class Disconnecting_PU(Popup): + pass + + +class MissingFieldsError(Popup): + pass + + +class ConnectionFail(Popup): + pass + + +class SaveConf(Popup): + pass + + +#################################################################### +# SCREENS +#################################################################### + +class HomeScreen(Screen): + connected = 1 + try: + com.connect(19200, "") + com.quitcom() + except: + connected = 0 + + def tryconnection(self): + try: + com.connect(19200, "") + com.quitcom() + self.connected = 1 + self.manager.current = "Readout" + self.manager.transition.direction = "right" + except: + self.connected = 0 + self.open_popup() + + def open_popup(self): + self.popups = NoConnection() + self.popups.open() + + def exitapp(self): + self.pup = QuitPU() + self.pup.open() + + +class ReadoutScreen(Screen): + go = 1 + def start_com(self): + self.comstart(1) + + def comstart(self, pu_on): + try: + com.connect(19200, "") + self.go = 1 + except: + self.go = 0 + + if self.go == 1: + self.parent.current = "Readout" + if pu_on == 1: + self.openstartpu() + else: + pass + self.communication = threading.Thread(name="communication", target=self.start_coms) + self.communication.start() + else: + self.openconnectionfailpu() + + def end_com(self): + self.stopcom(1) + + def stopcom(self, pu_on): + self.go = 0 + try: + self.communication.join() + except: + pass + if pu_on == 1: + self.openendpu() + else: + pass + + def start_coms(self): + self.check = 1 + self.__level = 0 + self.__distance = 0 + self.__x = "" + self.__begin = time.time() + self.go = 1 + while self.__x != "\n": + if time.time() - self.__begin > 5: + self.go = 0 + break + else: + self.__x = com.decode_ascii(com.receive(1)) + + if self.go == 1: + while self.__level < 3: + self.__x = com.decode_ascii(com.receive(1)) + if self.__x == " ": + if self.__distance == 4: + self.__level += 1 + else: + pass + self.__distance = 0 + else: + if self.__distance > 4: + self.__level = 0 + self.__distance = 0 + else: + self.__distance += 1 + self.check = 1 + com.receive(5) + else: + self.go = 0 + self.check = 0 + + while self.go == 1: + self.__starttime = time.time() + self.__output = "" + self.__data_recieve = com.receive(68) + self.__output += "Tadc: " + self.__output += str(com.decode_int(self.__data_recieve[0:4])) + self.__output += "\nTemperatur: " + self.__output += com.decode_float(self.__data_recieve[5:11]) + self.__output += f"\nDuty-Cycle: {(float(com.decode_float_2(self.__data_recieve[48:52])) / 65535) * 100}%" + self.change_screen(1, self.__output) + self.__output = "Tadc: " + self.__output += str(com.decode_int(self.__data_recieve[12:16])) + self.__output += "\nTemperatur: " + self.__output += com.decode_float(self.__data_recieve[17:23]) + self.__output += f"\nDuty-Cycle: {(float(com.decode_float_2(self.__data_recieve[53:57])) / 65535) * 100}%" + self.change_screen(2, self.__output) + self.__output = "Tadc: " + self.__output += str(com.decode_int(self.__data_recieve[24:28])) + self.__output += "\nTemperatur: " + self.__output += com.decode_float(self.__data_recieve[29:35]) + self.__output += f"\nDuty-Cycle: {(float(com.decode_float_2(self.__data_recieve[58:62])) / 65535) * 100}%" + self.change_screen(3, self.__output) + self.__output = "Tadc: " + self.__output += str(com.decode_int(self.__data_recieve[36:40])) + self.__output += "\nTemperatur: " + self.__output += com.decode_float(self.__data_recieve[41:47]) + self.__output += "\nDuty-Cycle: " + self.__output += f"\nDuty-Cycle: {(float(com.decode_float_2(self.__data_recieve[63:67])) / 65535) * 100}%" + self.change_screen(4, self.__output) + self.change_screen(5, f"F={1 / (time.time() - self.__starttime)}") + self.change_screen(6, "") + com.quitcom() + + def switch_mode(self, text): + self.go = 0 + try: + self.communication.join() + com.quitcom() + except: + pass + if text == "Normal Mode": + bin.lib.communication.SwitchMode().disable_fastmode() + else: + bin.lib.communication.SwitchMode().enable_fastmode() + self.openpupups() + self.comstart(0) + + @mainthread + def change_screen(self, pos, value): + if pos == 1: + self.ids.sonde1.text = value + elif pos == 2: + self.ids.sonde2.text = value + elif pos == 3: + self.ids.sonde3.text = value + elif pos == 4: + self.ids.sonde4.text = value + elif pos == 6: + self.openconnectionfailpu() + else: + self.ids.frequency.text = value + + def openpupups(self): + self.popup = Modeswitch() + self.popup.open() + + def openendpu(self): + self.pu = Disconnecting_PU() + self.pu.open() + + def openstartpu(self): + self.pup = Connecting_PU() + self.pup.open() + + def openconnectionfailpu(self): + if self.check == 0: + self.cfpu = ConnectionFail() + self.cfpu.open() + else: + pass + + def leave_screen(self): + self.stopcom(0) + + def resscreen(self): + self.ids.sonde1.text = "" + self.ids.sonde2.text = "" + self.ids.sonde3.text = "" + self.ids.sonde4.text = "" + self.ids.frequency.text = "" + + +class Program(Screen): + def create_com(self): + self.coms = bin.lib.communication.Communication() + + def send_data(self): + try: + self.create_com() + self.go = 1 + except: + self.go = 0 + + if self.go == 1: + self.__transmit = [] + if self.ids.s1_a.text != "" and self.ids.s1_b.text != "" and self.ids.s1_c.text != "" and self.ids.s1_t.text != "" and self.ids.s2_a.text != "" and self.ids.s2_b.text != "" and self.ids.s2_c.text != "" and self.ids.s2_t.text != "" and self.ids.s3_a.text != "" and self.ids.s3_b.text != "" and self.ids.s3_c.text != "" and self.ids.s3_t.text != "" and self.ids.s4_a.text != "" and self.ids.s4_b.text != "" and self.ids.s4_c.text != "" and self.ids.s4_t.text != "": + self.__transmit.append(self.ids.s1_a.text) + self.__transmit.append(self.ids.s1_b.text) + self.__transmit.append(self.ids.s1_c.text) + self.__transmit.append(self.ids.s1_t.text) + self.__transmit.append(self.ids.s2_a.text) + self.__transmit.append(self.ids.s2_b.text) + self.__transmit.append(self.ids.s2_c.text) + self.__transmit.append(self.ids.s2_t.text) + self.__transmit.append(self.ids.s3_a.text) + self.__transmit.append(self.ids.s3_b.text) + self.__transmit.append(self.ids.s3_c.text) + self.__transmit.append(self.ids.s3_t.text) + self.__transmit.append(self.ids.s4_a.text) + self.__transmit.append(self.ids.s4_b.text) + self.__transmit.append(self.ids.s4_c.text) + self.__transmit.append(self.ids.s4_t.text) + self.coms.change_all(self.__transmit,"") + self.ids.s1_a.text = "" + self.ids.s1_b.text = "" + self.ids.s1_c.text = "" + self.ids.s1_t.text = "" + self.ids.s2_a.text = "" + self.ids.s2_b.text = "" + self.ids.s2_c.text = "" + self.ids.s2_t.text = "" + self.ids.s3_a.text = "" + self.ids.s3_b.text = "" + self.ids.s3_c.text = "" + self.ids.s3_t.text = "" + self.ids.s4_a.text = "" + self.ids.s4_b.text = "" + self.ids.s4_c.text = "" + self.ids.s4_t.text = "" + self.openconfpu() + else: + self.openerrorpu() + else: + self.open_confail_pu() + + def openerrorpu(self): + self.pu = MissingFieldsError() + self.pu.open() + + def open_confail_pu(self): + self.cfpu = ConnectionFail() + self.cfpu.open() + + def openconfpu(self): + self.confpus = SaveConf() + self.confpus.open() + + +class ProgramTemp(Screen): + def create_com(self): + self.coms = bin.lib.communication.Communication() + + def send_data(self): + try: + self.create_com() + self.go = 1 + except: + self.go = 0 + + if self.go == 1: + self.__transmit = [] + if self.ids.temp_s1.text != "" and self.ids.temp_s2.text != "" and self.ids.temp_s3.text != "" and self.ids.temp_s4.text != "": + self.__transmit.append(self.ids.temp_s1.text) + self.__transmit.append(self.ids.temp_s2.text) + self.__transmit.append(self.ids.temp_s3.text) + self.__transmit.append(self.ids.temp_s4.text) + self.coms.change_temp(self.__transmit, "") + self.ids.temp_s1.text = "" + self.ids.temp_s2.text = "" + self.ids.temp_s3.text = "" + self.ids.temp_s4.text = "" + self.openconfpu() + else: + self.openerrorpu() + else: + self.open_confail_pu() + + def openerrorpu(self): + self.pu = MissingFieldsError() + self.pu.open() + + def openconfpu(self): + self.confpu = SaveConf() + self.confpu.open() + + def open_confail_pu(self): + self.cfpu = ConnectionFail() + self.cfpu.open() + + +class ReadData(Screen): + def read_data(self): + try: + com.connect(19200, "") + self.go = 1 + except: + self.go = 0 + + if self.go == 1: + com.send("RD") + self.__pos = 1 + self.__beginning = time.time() + self.go = 1 + while True: + if time.time() - self.__beginning < 5: + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "R": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "D": + self.__data_recieve = com.decode_ascii(com.receive(1)) + if self.__data_recieve == "\n": + self.go = 1 + break + else: + pass + else: + pass + else: + pass + else: + pass + else: + self.go = 0 + break + if self.go == 1: + for i in range(4): + self.__x = com.receive(28) + self.__output = "a: " + self.__output += str(com.decode_float(self.__x[0:6])) + self.__output += f"\nb: {str(com.decode_float(self.__x[7:13]))}" + self.__output += f"\nc: {str(com.decode_float(self.__x[14:20]))}" + self.__output += f"\nTemp: {str(com.decode_float(self.__x[21:27]))}" + if self.__pos == 1: + self.ids.inf_sonde1.text = self.__output + elif self.__pos == 2: + self.ids.inf_sonde2.text = self.__output + elif self.__pos == 3: + self.ids.inf_sonde3.text = self.__output + elif self.__pos == 4: + self.ids.inf_sonde4.text = self.__output + self.__pos += 1 + else: + self.open_confail_pu() + com.quitcom() + else: + self.open_confail_pu() + + def open_confail_pu(self): + self.cfpu = ConnectionFail() + self.cfpu.open() + + +class Credits(Screen): + pass + + +######################################################## +# Screenmanager +######################################################## + + +class RootScreen(ScreenManager): + pass + + +kv = Builder.load_file("./bin/gui/gui.kv") + + +class BiogasControllerApp(App): + def build(self): + self.icon = "./BiogasControllerAppLogo.png" + return kv + + +if __name__ == "__main__": + BiogasControllerApp().run()