Publish the files

This commit is contained in:
simplePCBuilding
2022-01-27 17:06:30 +00:00
parent 8a1b59a988
commit bf990dd4cf
20 changed files with 1458 additions and 164 deletions

Binary file not shown.

3
BiogasControllerApp-V2.1/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
BiogasControllerApp-V2.1/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
biogascontrollerapp.py

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.8" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
BiogasControllerApp-V2.1/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ENATECH.iml" filepath="$PROJECT_DIR$/.idea/ENATECH.iml" />
</modules>
</component>
</project>

Binary file not shown.

View File

@@ -1,164 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="43897116-ac04-4f5b-8eff-fc5cb04568e4" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="22KGuuzRDpdzoqI4wOq43fWt1iz" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="preferences.keymap" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/bin/lib" />
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="RunManager" selected="Python.biogascontrollerapp">
<configuration name="app3" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="ENATECH" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app3.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="biogascontrollerapp" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="ENATECH" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/biogascontrollerapp.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="comname" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="ENATECH" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/comname.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="comport_search" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="ENATECH" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/bin/lib/comport_search.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="ENATECH" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.biogascontrollerapp" />
<item itemvalue="Python.comname" />
<item itemvalue="Python.test" />
<item itemvalue="Python.comport_search" />
<item itemvalue="Python.app3" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="43897116-ac04-4f5b-8eff-fc5cb04568e4" name="Changes" comment="" />
<created>1639579090743</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1639579090743</updated>
</task>
<servers />
</component>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -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 ======
==================================

View File

@@ -0,0 +1,611 @@
RootScreen:
HomeScreen:
ReadoutScreen:
ReadData:
ProgramTemp:
Program:
Credits:
<QuitPU>:
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()
<NoConnection>:
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()
<ConnectionFail>:
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()
<DetailInfo>:
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()
<Modeswitch>:
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()
<SaveConf>:
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()
<Connecting_PU>:
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()
<MissingFieldsError>:
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()
<Disconnecting_PU>:
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
######################################
<HomeScreen>:
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"
<ReadoutScreen>:
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}
<ReadData>:
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: ""
<ProgramTemp>:
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()
<Program>:
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()
<Credits>:
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"

View File

@@ -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()

View File

@@ -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

View File

@@ -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])

View File

@@ -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()