mirror of
https://github.com/janishutz/BiogasControllerApp.git
synced 2025-11-25 05:44:23 +00:00
Redesign app, prepare for 3.1.0 release
This commit is contained in:
@@ -1,126 +1,123 @@
|
||||
<ProgramScreen>:
|
||||
name: "program"
|
||||
on_enter: self.config_loader = root.load_config()
|
||||
md_bg_color: app.theme_cls.primary_color
|
||||
FloatLayout:
|
||||
Label:
|
||||
text: "Configuration"
|
||||
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}
|
||||
MDGridLayout:
|
||||
cols: 1
|
||||
pos_hint: {'x': 0, 'y': 0.4}
|
||||
MDLabel:
|
||||
text: "Configuration"
|
||||
font_size: 40
|
||||
halign: 'center'
|
||||
valign: 'center'
|
||||
pos_hint: {'center_x': 0, 'center_y': 0}
|
||||
bold: True
|
||||
|
||||
MDGridLayout:
|
||||
cols: 1
|
||||
pos_hint: {'x': 0, 'y': 0.33}
|
||||
MDLabel:
|
||||
text: "Change the configuration of the microcontroller"
|
||||
font_size: 18
|
||||
halign: 'center'
|
||||
valign: 'center'
|
||||
pos_hint: {'center_x': 0, 'center_y': 0}
|
||||
italic: True
|
||||
|
||||
MDGridLayout:
|
||||
cols: 1
|
||||
pos_hint: {'x': 0, 'y': 0.25}
|
||||
MDLabel:
|
||||
id: status
|
||||
text: "Loading..."
|
||||
font_size: 17
|
||||
halign: 'center'
|
||||
bold: True
|
||||
|
||||
MDGridLayout:
|
||||
size_hint: 0.9, 0.5
|
||||
spacing: 10
|
||||
pos_hint: {"x":0.05, "y":0.2}
|
||||
cols: 4
|
||||
Label:
|
||||
text: "Sensor 1, a:"
|
||||
TextInput:
|
||||
MDTextField:
|
||||
id: s1_a
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 1, b:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 1 a'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s1_b
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 1, c:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 1 b'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s1_c
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 1, Temp:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 1 c'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s1_t
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 2, a:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 1 Temperature'
|
||||
on_text: root.validate_float(self)
|
||||
|
||||
MDTextField:
|
||||
id: s2_a
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 2, b:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 2 a'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s2_b
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 2, c:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 2 b'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s2_c
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 2, Temp:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 2 c'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s2_t
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 3, a:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 2 Temperature'
|
||||
on_text: root.validate_float(self)
|
||||
|
||||
MDTextField:
|
||||
id: s3_a
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 3, b:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 3 a'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s3_b
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 3, c:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 3 b'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s3_c
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 3, Temp:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 3 c'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s3_t
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 4, a:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 3 Temperature'
|
||||
on_text: root.validate_float(self)
|
||||
|
||||
MDTextField:
|
||||
id: s4_a
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 4, b:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 4 a'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s4_b
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 4, c:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 4 b'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s4_c
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Label:
|
||||
text: "Sensor 4, Temp:"
|
||||
TextInput:
|
||||
hint_text: 'Sensor 4 c'
|
||||
on_text: root.validate_float(self)
|
||||
MDTextField:
|
||||
id: s4_t
|
||||
multiline: False
|
||||
input_filter: "float"
|
||||
Button:
|
||||
hint_text: 'Sensor 4 Temperature'
|
||||
on_text: root.validate_float(self)
|
||||
|
||||
MDFillRoundFlatButton:
|
||||
size_hint: 0.1, 0.07
|
||||
text: "Back"
|
||||
size_hint: 0.1, 0.1
|
||||
pos_hint: {"x":0.1, "y":0.1}
|
||||
background_color: (255, 0, 0, 0.6)
|
||||
on_release:
|
||||
app.root.current = "main"
|
||||
root.manager.transition.direction = "up"
|
||||
Button:
|
||||
MDFillRoundFlatButton:
|
||||
size_hint: 0.15, 0.09
|
||||
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.save()
|
||||
|
||||
@@ -3,7 +3,8 @@ from kivymd.uix.screen import MDScreen
|
||||
from kivy.lang import Builder
|
||||
from lib.decoder import Decoder
|
||||
from lib.instructions import Instructions
|
||||
from gui.popups.popups import SingleRowPopup, TwoActionPopup, empty_func
|
||||
from kivymd.uix.button import MDFlatButton
|
||||
from kivymd.uix.dialog import MDDialog
|
||||
from lib.com import ComSuperClass
|
||||
from kivy.clock import Clock
|
||||
|
||||
@@ -18,13 +19,60 @@ class ProgramScreen(MDScreen):
|
||||
self._com = com
|
||||
self._instructions = Instructions(com)
|
||||
self._decoder = Decoder()
|
||||
|
||||
self.connection_error_dialog = MDDialog(
|
||||
title="Connection",
|
||||
text="Failed to connect. Do you wish to retry?",
|
||||
buttons=[
|
||||
MDFlatButton(
|
||||
text="Cancel",
|
||||
on_release=lambda dt: self.connection_error_dialog.dismiss(),
|
||||
),
|
||||
MDFlatButton(text="Retry", on_release=lambda dt: self._load()),
|
||||
],
|
||||
)
|
||||
|
||||
self.missing_fields_error_dialog = MDDialog(
|
||||
title="Save",
|
||||
text="Some fields are missing entries. Please fill them out and try again",
|
||||
buttons=[
|
||||
MDFlatButton(
|
||||
text="Ok",
|
||||
on_release=lambda dt: self.missing_fields_error_dialog.dismiss(),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
self.save_error_dialog = MDDialog(
|
||||
title="Save",
|
||||
text="Failed to save data. Please try again",
|
||||
buttons=[
|
||||
MDFlatButton(
|
||||
text="Ok",
|
||||
on_release=lambda dt: self.save_error_dialog.dismiss(),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
self.save_success_dialog = MDDialog(
|
||||
title="Save",
|
||||
text="Data saved successfully!",
|
||||
buttons=[
|
||||
MDFlatButton(
|
||||
text="Ok",
|
||||
on_release=lambda dt: self.save_success_dialog.dismiss(),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
super().__init__(**kw)
|
||||
|
||||
def load_config(self):
|
||||
Clock.schedule_once(self._load)
|
||||
Clock.schedule_once(lambda dt: self._load())
|
||||
|
||||
# Load the current configuration from the micro-controller
|
||||
def _load(self, dt: float):
|
||||
def _load(self):
|
||||
self.ids.status.text = "Loading..."
|
||||
# Hook to the microcontroller's data stream (i.e. sync up with it)
|
||||
if self._instructions.hook("RD", ["\n", "R", "D", "\n"]):
|
||||
config: List[List[str]] = []
|
||||
@@ -37,13 +85,7 @@ class ProgramScreen(MDScreen):
|
||||
received = self._com.receive(28)
|
||||
except:
|
||||
# Open error popup
|
||||
TwoActionPopup().open(
|
||||
"Failed to connect to micro-controller, retry?",
|
||||
"Cancel",
|
||||
empty_func,
|
||||
"Retry",
|
||||
lambda: self._load(0),
|
||||
)
|
||||
self.connection_error_dialog.open()
|
||||
return
|
||||
|
||||
# Create a list of strings to store the config for the sensor
|
||||
@@ -58,16 +100,11 @@ class ProgramScreen(MDScreen):
|
||||
|
||||
# Add it to the config
|
||||
config.append(config_sensor_i)
|
||||
self.ids.status.text = ""
|
||||
|
||||
self._set_ui(config)
|
||||
else:
|
||||
TwoActionPopup().open(
|
||||
"Failed to connect to micro-controller, retry?",
|
||||
"Cancel",
|
||||
empty_func,
|
||||
"Retry",
|
||||
lambda: self._load(0),
|
||||
)
|
||||
self.connection_error_dialog.open()
|
||||
|
||||
# Set the elements of the UI to the values of the config
|
||||
def _set_ui(self, config: List[List[str]]):
|
||||
@@ -96,16 +133,37 @@ class ProgramScreen(MDScreen):
|
||||
|
||||
# Transmit the changed data to the micro-controller to reconfigure it
|
||||
def save(self):
|
||||
self.ids.status.text = "Saving..."
|
||||
data = self._read_ui()
|
||||
if data == None:
|
||||
SingleRowPopup().open("Some fields are missing values!")
|
||||
self.missing_fields_error_dialog()
|
||||
else:
|
||||
try:
|
||||
self._instructions.change_config(data)
|
||||
except Exception as e:
|
||||
SingleRowPopup().open("Could not save data!")
|
||||
self.save_error_dialog.open()
|
||||
return
|
||||
SingleRowPopup().open("Data saved successfully")
|
||||
self.save_success_dialog.open()
|
||||
self.ids.status.text = "Saved!"
|
||||
Clock.schedule_once(self.reset_update, 5)
|
||||
|
||||
def reset_update(self, dt):
|
||||
self.ids.status.text = ""
|
||||
|
||||
def validate_float(self, instance):
|
||||
text = instance.text
|
||||
|
||||
# Allow only digits and one dot
|
||||
if text.count(".") > 1 or any(c not in "0123456789." for c in text):
|
||||
# Remove invalid characters
|
||||
clean_text = "".join(c for c in text if c in "0123456789.")
|
||||
# Remove extra dots
|
||||
if clean_text.count(".") > 1:
|
||||
first_dot = clean_text.find(".")
|
||||
clean_text = clean_text[: first_dot + 1] + clean_text[
|
||||
first_dot + 1 :
|
||||
].replace(".", "")
|
||||
instance.text = clean_text
|
||||
|
||||
|
||||
# Load the design file for this screen (.kv files)
|
||||
|
||||
Reference in New Issue
Block a user