mirror of
https://github.com/janishutz/BiogasControllerApp.git
synced 2025-11-25 13:54:24 +00:00
App launching, some porting work complete
This commit is contained in:
BIN
biogascontrollerapp/BiogasControllerAppLogo.png
Normal file
BIN
biogascontrollerapp/BiogasControllerAppLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,52 @@
|
||||
import os
|
||||
import configparser
|
||||
from typing import override
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read('./config.ini')
|
||||
|
||||
# Load config and disable kivy log if necessary
|
||||
if config['Dev Settings']['verbose'] == "True":
|
||||
pass
|
||||
else:
|
||||
os.environ["KIVY_NO_CONSOLELOG"] = "1"
|
||||
|
||||
|
||||
# Load kivy modules
|
||||
from kivy.core.window import Window, Config
|
||||
from kivy.uix.screenmanager import ScreenManager
|
||||
from kivy.app import App
|
||||
|
||||
# Load other libraries
|
||||
import threading
|
||||
|
||||
# Store the current app version
|
||||
app_version = f"{config['Info']['version']}{config['Info']['subVersion']}"
|
||||
|
||||
#---------#
|
||||
# Screens #
|
||||
#---------#
|
||||
|
||||
from gui.home.home import HomeScreen
|
||||
from gui.credits.credits import CreditsScreen
|
||||
from gui.settings.settings import SettingsScreen
|
||||
|
||||
#----------------#
|
||||
# Screen Manager #
|
||||
#----------------#
|
||||
class BiogasControllerApp(App):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.screen_manager = ScreenManager()
|
||||
|
||||
@override
|
||||
def build(self):
|
||||
self.icon = './BiogasControllerAppLogo.png'
|
||||
self.title = 'BiogasControllerApp-' + app_version
|
||||
self.screen_manager.add_widget(HomeScreen(name='home'))
|
||||
self.screen_manager.add_widget(CreditsScreen(name='credits'))
|
||||
self.screen_manager.add_widget(SettingsScreen(name='settings'))
|
||||
return self.screen_manager
|
||||
|
||||
if __name__ == "__main__":
|
||||
BiogasControllerApp().run()
|
||||
|
||||
19
biogascontrollerapp/config.ini
Normal file
19
biogascontrollerapp/config.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
[Port Settings]
|
||||
specificport = None
|
||||
|
||||
[UI Config]
|
||||
sizeh = 600
|
||||
sizew = 800
|
||||
|
||||
[Dev Settings]
|
||||
verbose = True
|
||||
log_level = DEBUG
|
||||
disableconnectioncheck = False
|
||||
|
||||
[License]
|
||||
show = 1
|
||||
|
||||
[Info]
|
||||
version = V2.3.0
|
||||
subversion =
|
||||
|
||||
3
biogascontrollerapp/gui/PopupManager.py
Normal file
3
biogascontrollerapp/gui/PopupManager.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from gui.popups import *
|
||||
|
||||
|
||||
27
biogascontrollerapp/gui/credits/credits.kv
Normal file
27
biogascontrollerapp/gui/credits/credits.kv
Normal file
@@ -0,0 +1,27 @@
|
||||
<CreditsScreen>:
|
||||
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 = "settings"
|
||||
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"
|
||||
Label:
|
||||
text: "This software is free Software licensed under the GPL V3 (GNU General Public License) and as such comes with absolutely no warranty. In return, you can use, modify, distribute or use any of the code of this software in your own project, if you reuse the same license. For more infos, you can find a copy of this license in the project folder."
|
||||
text_size: self.width, None
|
||||
8
biogascontrollerapp/gui/credits/credits.py
Normal file
8
biogascontrollerapp/gui/credits/credits.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
class CreditsScreen(Screen):
|
||||
pass
|
||||
|
||||
Builder.load_file('./gui/credits/credits.kv')
|
||||
46
biogascontrollerapp/gui/home/home.kv
Normal file
46
biogascontrollerapp/gui/home/home.kv
Normal file
@@ -0,0 +1,46 @@
|
||||
<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.start()
|
||||
Button:
|
||||
text: "Quit"
|
||||
background_color: (255, 0, 0, 0.6)
|
||||
font_size: 30
|
||||
on_release:
|
||||
root.quit()
|
||||
Label:
|
||||
text: "App version"
|
||||
id: app_version
|
||||
font_size: 13
|
||||
pos_hint: {"y": -0.45, "x":0.05}
|
||||
Button:
|
||||
text: "Settings"
|
||||
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:
|
||||
root.to_settings()
|
||||
17
biogascontrollerapp/gui/home/home.py
Normal file
17
biogascontrollerapp/gui/home/home.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
class HomeScreen(Screen):
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def quit(self):
|
||||
pass
|
||||
|
||||
def to_settings(self):
|
||||
self.manager.current = 'settings'
|
||||
self.manager.transition.direction = 'down'
|
||||
|
||||
|
||||
Builder.load_file('./gui/home/home.kv')
|
||||
105
biogascontrollerapp/gui/popups/popups.kv
Normal file
105
biogascontrollerapp/gui/popups/popups.kv
Normal file
@@ -0,0 +1,105 @@
|
||||
<SingleRowPopUp>:
|
||||
title: "INFORMATION"
|
||||
size_hint: 0.7, 0.5
|
||||
auto_dismiss: True
|
||||
GridLayout:
|
||||
cols: 1
|
||||
Label:
|
||||
id: msg
|
||||
text_size: self.width, None
|
||||
GridLayout:
|
||||
cols: 1
|
||||
Button:
|
||||
text: "Ok"
|
||||
on_release:
|
||||
root.dismiss()
|
||||
|
||||
<QuitPopUp>:
|
||||
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.quit()
|
||||
app.stop()
|
||||
Button:
|
||||
text: "No"
|
||||
font_size: 15
|
||||
on_press:
|
||||
root.dismiss()
|
||||
|
||||
<TwoActionPopup>:
|
||||
title: "WARNING!"
|
||||
font_size: 50
|
||||
size_hint: 0.5, 0.4
|
||||
auto_dismiss: False
|
||||
GridLayout:
|
||||
cols:1
|
||||
Label:
|
||||
id: msg
|
||||
text: "Message"
|
||||
font_size: 20
|
||||
GridLayout:
|
||||
cols:2
|
||||
Button:
|
||||
id: btn1
|
||||
text: "Details"
|
||||
on_release:
|
||||
root.action()
|
||||
Button:
|
||||
text:"Ok"
|
||||
on_release:
|
||||
root.dismiss()
|
||||
|
||||
<DualRowPopup>:
|
||||
title: "Details"
|
||||
font_size: 50
|
||||
size_hint: 0.7, 0.6
|
||||
auto_dismiss: False
|
||||
GridLayout:
|
||||
cols:1
|
||||
Label:
|
||||
id: msg_title
|
||||
text: "Message title"
|
||||
font_size: 20
|
||||
Label:
|
||||
id: msg_body
|
||||
text: "Message body"
|
||||
font_size: 14
|
||||
Button:
|
||||
text:"Ok"
|
||||
on_release:
|
||||
root.dismiss()
|
||||
|
||||
<LargeTrippleRowPopUp>:
|
||||
title: "DETAILS"
|
||||
font_size: 50
|
||||
size_hint: 1, 0.7
|
||||
auto_dismiss: False
|
||||
GridLayout:
|
||||
Label:
|
||||
cols:1
|
||||
id: msg_title
|
||||
text: "title"
|
||||
font_size: 20
|
||||
Label:
|
||||
id: msg_body
|
||||
text: "Message"
|
||||
font_size: 13
|
||||
Label:
|
||||
text: msg_extra
|
||||
font_size: 13
|
||||
Button:
|
||||
text:"Ok"
|
||||
on_release:
|
||||
root.dismiss()
|
||||
16
biogascontrollerapp/gui/popups/popups.py
Normal file
16
biogascontrollerapp/gui/popups/popups.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
class HomeScreen(Screen):
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def quit(self):
|
||||
pass
|
||||
|
||||
def to_settings(self):
|
||||
pass
|
||||
|
||||
|
||||
Builder.load_file('./gui/home/home.kv')
|
||||
16
biogascontrollerapp/gui/program/program.py
Normal file
16
biogascontrollerapp/gui/program/program.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
class HomeScreen(Screen):
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def quit(self):
|
||||
pass
|
||||
|
||||
def to_settings(self):
|
||||
pass
|
||||
|
||||
|
||||
Builder.load_file('./gui/home/home.kv')
|
||||
37
biogascontrollerapp/gui/settings/settings.kv
Normal file
37
biogascontrollerapp/gui/settings/settings.kv
Normal file
@@ -0,0 +1,37 @@
|
||||
<SettingsScreen>:
|
||||
name: "settings"
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: (50,50,50,0.2)
|
||||
Rectangle:
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
GridLayout:
|
||||
cols: 1
|
||||
Label:
|
||||
text: "Settings"
|
||||
font_size: 40
|
||||
color: (0, 113, 0, 1)
|
||||
bold: True
|
||||
FloatLayout:
|
||||
GridLayout:
|
||||
pos_hint: {"x":0.05, "y":0.05}
|
||||
size_hint: 0.9, 0.9
|
||||
cols: 3
|
||||
Button:
|
||||
text: "Back"
|
||||
background_color: (255,0,0,0.6)
|
||||
on_release:
|
||||
app.root.current = "home"
|
||||
root.manager.transition.direction = "up"
|
||||
Button:
|
||||
text: "Report a\nBug"
|
||||
background_color: (255,0,0,0.6)
|
||||
on_release:
|
||||
root.report_issue()
|
||||
Button:
|
||||
text: "Credits"
|
||||
background_color: (255,0,0,0.6)
|
||||
on_release:
|
||||
app.root.current = "credits"
|
||||
root.manager.transition.direction = "left"
|
||||
10
biogascontrollerapp/gui/settings/settings.py
Normal file
10
biogascontrollerapp/gui/settings/settings.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.lang import Builder
|
||||
import webbrowser
|
||||
|
||||
|
||||
class SettingsScreen(Screen):
|
||||
def report_issue(self):
|
||||
webbrowser.open('https://github.com/janishutz/BiogasControllerApp/issues', new=2)
|
||||
|
||||
Builder.load_file('./gui/settings/settings.kv')
|
||||
@@ -9,11 +9,22 @@ class Com:
|
||||
self._serial: Optional[serial.Serial] = None
|
||||
self._filters = filters if filters != None else [ 'USB-Serial Controller', 'Prolific USB-Serial Controller' ]
|
||||
self._port_override = ''
|
||||
self._baudrate = 19200
|
||||
|
||||
def set_port_override(self, override: str) -> None:
|
||||
"""Set the port override, to disable port search"""
|
||||
self._port_override = override
|
||||
|
||||
def _connection_check(self) -> bool:
|
||||
if self._serial == None:
|
||||
return self._open()
|
||||
if self._serial != None:
|
||||
if not self._serial.is_open:
|
||||
self._serial.open()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_comport(self) -> str:
|
||||
"""Find the comport the microcontroller has attached to"""
|
||||
if self._port_override != '':
|
||||
@@ -34,20 +45,24 @@ class Com:
|
||||
|
||||
return ''
|
||||
|
||||
def connect(self, baud_rate: int, port_override: Optional[str] = None) -> bool:
|
||||
"""Try to find a comport and connect to the microcontroller. Returns the success as a boolean"""
|
||||
def _open(self) -> bool:
|
||||
comport = self.get_comport()
|
||||
|
||||
# Comport search returns empty string if search unsuccessful
|
||||
if comport == '':
|
||||
try:
|
||||
self._serial = serial.Serial(comport, baud_rate, timeout=5)
|
||||
self._serial = serial.Serial(comport, self._baudrate, timeout=5)
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def connect(self, baud_rate: int) -> bool:
|
||||
"""Try to find a comport and connect to the microcontroller. Returns the success as a boolean"""
|
||||
self._baudrate = baud_rate
|
||||
return self._connection_check()
|
||||
|
||||
def close(self) -> None:
|
||||
"""Close the serial connection, if possible"""
|
||||
if self._serial != None:
|
||||
@@ -58,23 +73,24 @@ class Com:
|
||||
|
||||
def receive(self, byte_count: int) -> bytes:
|
||||
"""Recieve bytes from microcontroller over serial. Returns bytes. Might want to decode using functions from lib.tools"""
|
||||
if self._serial == None:
|
||||
self.connect(19200)
|
||||
self._connection_check()
|
||||
if self._serial != None:
|
||||
return self._serial.read(byte_count)
|
||||
else:
|
||||
raise Exception('ERR_CONNECTION')
|
||||
raise Exception('ERR_CONNECTING')
|
||||
|
||||
def send(self, msg: str) -> None:
|
||||
"""Send a string over serial connection."""
|
||||
if self._serial == None:
|
||||
self.connect(19200)
|
||||
"""Send a string over serial connection. Will open a connection if none is available"""
|
||||
self._connection_check()
|
||||
if self._serial != None:
|
||||
self._serial.write(msg.encode())
|
||||
else:
|
||||
raise Exception('ERR_CONNECTING')
|
||||
|
||||
def send_float(self, msg: float) -> None:
|
||||
"""Send a float number over serial connection"""
|
||||
if self._serial == None:
|
||||
self.connect(19200)
|
||||
self._connection_check()
|
||||
if self._serial != None:
|
||||
self._serial.write(bytearray(struct.pack('>f', msg))[0:3])
|
||||
else:
|
||||
raise Exception('ERR_CONNECTING')
|
||||
|
||||
@@ -1,22 +1,61 @@
|
||||
from typing import Optional
|
||||
import lib.com
|
||||
import lib.decoder
|
||||
import time
|
||||
|
||||
# TODO: Load filters (for comport search)
|
||||
com = lib.com.Com()
|
||||
decoder = lib.decoder.Decoder()
|
||||
|
||||
class Instructions:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
def set_port_override(self, override: str) -> None:
|
||||
com.set_port_override(override)
|
||||
|
||||
def _hook(self, instruction: str, sequence: list[str]) -> bool:
|
||||
# Send instruction to microcontroller to start hooking process
|
||||
com.send(instruction)
|
||||
|
||||
# Record start time to respond to timeout
|
||||
start = time.time()
|
||||
|
||||
# Check for timeout
|
||||
pointer = 0
|
||||
sequence_max = len(sequence) - 1
|
||||
while time.time() - start < 5:
|
||||
if ( decoder.decode_ascii( com.receive(1) ) ) == sequence[pointer]:
|
||||
pointer += 1
|
||||
else:
|
||||
pointer = 0
|
||||
|
||||
if pointer == sequence_max:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def change_temperature(self, new_temps: list[float]) -> None:
|
||||
pass
|
||||
def _change_data(self, instruction: str, readback: list[str], data: list[float], readback_length: int) -> None:
|
||||
# Hook to stream
|
||||
if self._hook(instruction, readback):
|
||||
while len(data) > 0:
|
||||
if com.receive(readback_length) != '':
|
||||
com.send_float(data.pop(0))
|
||||
else:
|
||||
com.close()
|
||||
raise Exception('Failed to transmit data. No response from controller')
|
||||
com.close()
|
||||
else:
|
||||
com.close()
|
||||
raise ConnectionError('Failed to hook to controller data stream. No fitting response received')
|
||||
|
||||
def change_config(self, new_config: list[float]) -> None:
|
||||
pass
|
||||
self._change_data('PR', ['\n', 'P', 'R', '\n'], new_config, 3)
|
||||
|
||||
def change_temperature(self, temperatures: list[float]) -> None:
|
||||
self._change_data('PT', ['\n', 'P', 'T', '\n'], temperatures, 3)
|
||||
|
||||
def enable_fastmode(self) -> None:
|
||||
com.send('FM')
|
||||
com.close()
|
||||
|
||||
def disable_fastmode(self) -> None:
|
||||
com.send('NM')
|
||||
com.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user