remove steps table wip, import ok

This commit is contained in:
neo 2024-09-18 14:18:07 +02:00
parent b5d4a07ab2
commit d65e2a03ea
9 changed files with 71 additions and 134 deletions

View File

@ -1,4 +1,4 @@
from lib.db import Recipes, Steps, db
from lib.db import Recipes, db
from PyQt5.QtCore import QSemaphore, pyqtSignal
from PyQt5.QtWidgets import QMessageBox
@ -333,7 +333,7 @@ class TecnaMarpossProvasetT3(ModbusComponent):
recipes = []
for recipe in list(Recipes.select().order_by(Recipes.name.asc())):
# if recipe.spec["leak_1"]:
recipes.append([recipe, Steps.get_by_id(recipe.spec["available_steps"]["leak_1"])])
recipes.append([recipe, recipe.spec["steps"]["leak_1"]])
# reverve last for our recipe control
if len(recipes) > max(self.max_program_number - 1, 0):
self.log.warning(f"too many recipes ({len(recipes)}), saving only first {max(self.max_program_number - 1, 0)}")

View File

@ -12,7 +12,6 @@ models_reference = {
"archive": Archive,
"log": Log,
"recipes": Recipes,
"steps": Steps,
"users": Users,
}
@ -49,57 +48,6 @@ def init_db():
except FileNotFoundError:
pass
# try:
# with open("src/lib/db/imports/connectors.csv", "r") as f:
# log.info("importing connectors")
# reader = csv.DictReader(f)
# count = 0
# for row in reader:
# steps = {}
# for step_type, step_spec in {
# "connector": {"connector": row["connector"]},
# "barcodes": {"serial": ""},
# "resistance": {"scale": 500, "expected": float(row["resistance_expected"]), "tolerance": float(row["resistance_tolerance"])},
# "leak_1": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
# "leak_2": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
# "vision": {"recipe": "termorestringente_923578.ini"},
# "print": {"template": "EtichettaR5.prn", },
# }.items():
# steps[step_type] = Steps(
# type=re.sub(r"^(.*)_[0-9]+$", r"\1", step_type),
# spec=step_spec,
# )
# steps[step_type].save(force_insert=True)
# recipe = Recipes(
# name=row["name"],
# client=row["client"],
# part_number=row["part_number"],
# spec={
# "connector": True,
# "barcodes": True,
# "resistance": True,
# "leak_1": False,
# "leak_2": False,
# "vision": False,
# "print": True,
# "steps": [steps["connector"].name, steps["resistance"].name, steps["print"].name, ], # pks of the enabled steps
# "available_steps": {
# "connector": steps["connector"].name,
# "barcodes": steps["barcodes"].name,
# "resistance": steps["resistance"].name,
# "leak_1": steps["leak_1"].name,
# "leak_2": steps["leak_2"].name,
# "vision": steps["vision"].name,
# "print": steps["print"].name,
# },
# },
# )
# recipe.save(force_insert=True)
# count += 1
# log.info(f"connectors: imported {count} rows.")
# except FileNotFoundError:
# pass
init_db()

View File

@ -2,5 +2,4 @@ from .archive import Archive
from .base_model import db
from .log import Log
from .recipes import Recipes
from .steps import Steps
from .users import Session, Users

8
src/lib/helpers/step.py Normal file
View File

@ -0,0 +1,8 @@
class Step(object):
step_type = None
spec = {}
def __init__(self,step_type=None,spec=dict):
self.step_type = step_type
self.spec = spec

View File

@ -277,7 +277,7 @@ try:
app = QApplication(sys.argv)
with SingleProcess() as single_process_lock:
if not single_process_lock:
if not single_process_lock and "--no-lock" not in sys.argv:
logging.error(f"Program already opened, exiting...")
QMessageBox.critical(None, "ERRORE", "IL PROGRAMMA E' GIA' IN ESECUZIONE")
exit(0)

View File

@ -270,7 +270,7 @@ class Crud(Widget):
self.filter_delay = QTimer()
self.filter_delay.setSingleShot(True)
self.filter_delay.setInterval(500)
self.filter_delay.timeout.connect(lambda self=weakref.ref(self): self().do_filter(self().filter_cn))
self.filter_delay.timeout.connect(lambda selfi=weakref.ref(self): selfi().do_filter(selfi().filter_cn))
self.db_tw.crud = self
self.refresh("init")
self.db_tw.horizontalHeader().sectionClicked.connect(self.toggle_sort)
@ -283,13 +283,13 @@ class Crud(Widget):
else:
self.db_tw.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.db_tw.itemSelectionChanged.connect(self.show_selection)
self.revert_b.clicked.connect(lambda checked, self=weakref.ref(self): self().refresh("revert"))
self.revert_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().refresh("revert"))
if self.pagination is not False:
self.start_b.clicked.connect(lambda checked, self=weakref.ref(self): self().refresh("pagination", page=0))
self.previous_b.clicked.connect(lambda checked, self=weakref.ref(self): self().refresh("pagination", page=max(self().page - 1, 0)))
self.page_n_sb.valueChanged.connect(lambda page, self=weakref.ref(self): self().refresh("pagination", page=page - 1))
self.next_b.clicked.connect(lambda checked, self=weakref.ref(self): self().refresh("pagination", page=self().page + 1))
self.end_b.clicked.connect(lambda checked, self=weakref.ref(self): self().refresh("pagination", page=-1))
self.start_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().refresh("pagination", page=0))
self.previous_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().refresh("pagination", page=max(selfi().page - 1, 0)))
self.page_n_sb.valueChanged.connect(lambda page, selfi=weakref.ref(self): selfi().refresh("pagination", page=page - 1))
self.next_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().refresh("pagination", page=selfi().page + 1))
self.end_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().refresh("pagination", page=-1))
else:
self.next_b.setHidden(True)
self.previous_b.setHidden(True)
@ -468,8 +468,8 @@ class Crud(Widget):
if fn in self.db.table_fields:
w.setPlaceholderText("Filtro")
w.setText(self.filters.get(fn, None))
w.editingFinished.connect(lambda cn=cn, self=weakref.ref(self): self().do_filter(cn))
w.textChanged.connect(lambda text, cn=cn, self=weakref.ref(self): self().filter_edited(cn))
w.editingFinished.connect(lambda cni=cn, selfi=weakref.ref(self): selfi().do_filter(cni))
w.textChanged.connect(lambda text, cni=cn, selfi=weakref.ref(self): selfi().filter_edited(cni))
else:
w.setPlaceholderText("Non filtrabile")
w.setEnabled(False)

View File

@ -9,6 +9,8 @@ from lib.db import Recipes, Users, db
from PyQt5.QtCore import QTimer, pyqtSignal
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QShortcut
from lib.helpers.step import Step
from ui.crud import Crud, Json_External_Dialog_Editor_Cell_Widget
from ui.helpers import replace_widget
from ui.recipe_spec_and_step_editor import Recipe_Spec_And_Step_Editor
@ -298,6 +300,8 @@ class Recipe_Selection(Widget):
row = dict((k.lower(), v) for k, v in ucrow.items())
recipe_name = row.get(recipe_name_field, defaults["codice_ricetta"])
steps_specs = self.read_steps(row, defaults=defaults)
# create recipe or update existing one in DB
try:
recipe = Recipes.get_by_id(recipe_name)
steps = recipe.get_steps_map()
@ -305,14 +309,11 @@ class Recipe_Selection(Widget):
except Recipes.DoesNotExist:
recipe = Recipes(name=recipe_name, part_number="TEMPORARY")
steps = {}
for step_type, step_spec in steps_specs.items():
step = {}
steps[step_type] = step
recipe_is_new = True
for step_name, step_spec in steps_specs.items():
step = steps[step_name]
step.type = step_name
step.spec = step_spec
if step_name not in self.unsupported_steps:
steps[step_name] = step_spec
recipe_is_new = True
recipe.client = row.get("cliente", defaults["cliente"])
recipe.part_number = row.get(part_number_field, defaults["part_number"])
recipe.description = row.get(description_field, defaults["descrizione"])
@ -329,23 +330,8 @@ class Recipe_Selection(Widget):
"leak_2": len(row.get("prova_tenuta_abilitata_2", defaults["prova_tenuta_abilitata_2"])) and "leak_2" not in self.unsupported_steps,
"vision": len(row.get("test_visione_abilitato", defaults["test_visione_abilitato"])) and "vision" not in self.unsupported_steps,
"print": len(row.get("stampa_etichetta_abilitata", defaults["stampa_etichetta_abilitata"])) and "print" not in self.unsupported_steps,
"steps": [], # should be pks of the enabled steps
"available_steps": {
"count": steps["count"].get_id(),
"connector": steps["connector"].get_id(),
"barcodes": steps["barcodes"].get_id(),
"resistance": steps["resistance"].get_id(),
"screws": steps["screws"].get_id(),
"instruction": steps["instruction"].get_id(),
"leak_1": steps["leak_1"].get_id(),
"leak_2": steps["leak_2"].get_id(),
"vision": steps["vision"].get_id(),
"print": steps["print"].get_id(),
},
"steps": steps,
}
for step_name, step in recipe.spec["available_steps"].items():
if recipe.spec[step_name]:
recipe.spec["steps"].append(step)
if recipe_is_new:
recipe.save(force_insert=True)
else:

View File

@ -98,7 +98,6 @@ class Recipe_Spec_And_Step_Editor(Editor):
self.steps_tw.setTabVisible(self.steps_tw.indexOf(map["tab"]), not map.get("hidden", False))
self.save_steps_b.clicked.connect(self.save_steps)
self.reset_steps_b.clicked.connect(self.reset_steps)
self.available_steps = {}
self.recipe = None
def set_readonly(self, readonly=True):
@ -130,7 +129,6 @@ class Recipe_Spec_And_Step_Editor(Editor):
def render(self, data, field_name=None, row_number=None, crud=None):
super().render(data, field_name=field_name, row_number=row_number, crud=crud)
self.available_steps = data.get("available_steps", None)
steps = set(data.get("steps", set()))
for map in self.steps_map.values():
step = map.get("step", None)
@ -141,9 +139,7 @@ class Recipe_Spec_And_Step_Editor(Editor):
def parse(self, action=None, row_number=None, crud=None):
ret = super().parse(row_number=row_number, crud=crud)
ret["steps"] = []
ret["available_steps"] = {}
for step_name, map in self.steps_map.items():
ret["available_steps"][step_name] = map["step"].name
if map["enable"].isChecked() and not map.get("hidden", False):
ret["steps"].append(map["step"].name)
return ret

View File

@ -7,8 +7,9 @@ from datetime import datetime, timedelta
from components import ArchiveSynchronizer
from PyQt5.QtCore import QTimer, pyqtSlot
from PyQt5.QtWidgets import QMessageBox
from lib.db import Archive, Steps, Users
from lib.db import Archive, Recipes, Users
from lib.helpers import get_shift
from lib.helpers.step import Step
from playhouse.shortcuts import model_to_dict
from ui.barcode_recipe_selection import Barcode_Recipe_Selection
from ui.helpers import replace_widget
@ -259,7 +260,7 @@ class Test(Widget):
if self.config["hardware_config"]["tecna_t3"] == "present" or self.config["hardware_config"]["furness_controls"] == "present":
self.cycle_available_steps["leak_1"].widget.recipe_written = False
self.cycle_available_steps["leak_2"].widget.recipe_written = False
self.step = Steps(type="select_recipe")
self.step = Step(step_type="select_recipe")
self.cycle_index = -1
self.recipe = None
self.cycle_steps = None
@ -269,7 +270,7 @@ class Test(Widget):
elif action in ("fail", "abort"):
self.log.info(f"cycle next: action: {action!r}")
# FAIL AND RESTART TEST
self.step = Steps(type="fail")
self.step = Step(step_type="fail")
self.cycle_index = -1
# COUNT FAIL
if action == "fail":
@ -282,10 +283,10 @@ class Test(Widget):
# if recipe not set: select_recipe
if self.recipe_selection_mode == "barcode":
self.log.info(f"returning to barcode recipe selection")
self.step = Steps(type="barcode_recipe_selection")
self.step = {"type":"barcode_recipe_selection","spec":{}}
else:
self.log.info(f"returning to recipe selection table")
self.step = Steps(type="select_recipe")
self.step = Step(step_type="select_recipe")
elif action is None:
if self.autotest_request is not False and self.autotest_cycle_steps is not None and not self.autotesting and (self.cycle_index == -1 or self.cycle_index + 1 >= len(self.cycle_steps)):
# if autotest was requested
@ -324,25 +325,25 @@ class Test(Widget):
else:
self.cycle_index = -1
self.step = Steps(type=None)
self.step = Step(step_type=None)
# enable/disable cycle controls
self.change_recipe_b.setEnabled(self.recipe is not None)
self.cancel_b.setEnabled(self.step.type is not None and self.step.type not in {
self.cancel_b.setEnabled(self.step.step_type is not None and self.step.step_type not in {
"emergency",
"fail",
"select_recipe",
"wait",
})
self.log.info(f"next cycle step: {model_to_dict(self.step)!r}")
self.log.info(f"next cycle step: {self.step.step_type!r}")
# INIT TEST DATA IF STARTING CYCLE LOOP OR IF RESET IS NEEDED
if self.cycle_index == 0:
self.data = {"ok": True, "overridden": False}
self.archived = None
if self.recipe is not None and "recipe" not in self.data:
self.data["recipe"] = model_to_dict(self.recipe)
w = self.cycle_available_steps[self.step.type]
w = self.cycle_available_steps[self.step.step_type]
show = None
if self.step.type == "leak_2":
if self.step.step_type == "leak_2":
self.setCentralWidget(w) # NEED TO PRESHOW UI
if hasattr(w, "start"):
show = w.start(recipe=self.recipe, step=self.step, pieces=self.pieces)
@ -350,16 +351,16 @@ class Test(Widget):
self.setCentralWidget(w)
elif show is False:
self.next_timer.start(0)
if self.step.type == "done":
if self.step.step_type == "done":
self.archived = self.done()
self.last_label = copy.deepcopy(self.archived)
self.next_timer.start(500)
elif self.step.type == "print":
elif self.step.step_type == "print":
compiled_label = self.print(self.archived, self.step.spec.get("template", "EtichettaR5"))
self.archived.label = compiled_label
self.archived.save()
self.next_timer.start(500)
elif self.step.type == "wait":
elif self.step.step_type == "wait":
self.next_timer.start(500)
# UPDATE COUNT DISPLAY
self.update_count_display()
@ -387,7 +388,7 @@ class Test(Widget):
# create step sequence list
barcode_names = ['serial', 'barcode_input_2', 'barcode_input_3', 'barcode_input_4', 'barcode_input_5']
for i, step in enumerate(steps):
if step.type == "barcodes":
if step.step_type == "barcodes":
n_pieces = int(step.spec.get("n_pieces", 1))
n_pieces_adapted = n_pieces
if n_pieces_adapted == 1:
@ -401,47 +402,47 @@ class Test(Widget):
steps.insert(i + 1, new_barcode_step)
if i in skip:
continue
if step.type == "vision":
if step.step_type == "vision":
self.components["vision"].config_changed(vision_recipe=self.recipe.name)
if step.type == "count":
if step.step_type == "count":
count_found = True
if "warning_img" in step.spec:
if step.spec["warning_img"]:
steps.insert(i, Steps(type="warning_img", spec={"warning_img": step.spec["warning_img"]}))
steps.insert(i, Step(step_type="warning_img", spec={"warning_img": step.spec["warning_img"]}))
skip.add(i + 1)
if "assembly" in step.spec:
if step.spec["assembly"]:
steps.insert(i, Steps(type="instructions", spec={}))
steps.insert(i, Step(step_type="instructions", spec={}))
skip.add(i + 1)
if "require_discard_piece" in step.spec:
if step.spec["require_discard_piece"]:
self.require_discard_piece = True
if step.type == "resistance": # ADD STEP TO ENSURE REMOVAL OF CONNECTOR
steps.insert(i + 1, Steps(type="resistance", spec={
if step.step_type == "resistance": # ADD STEP TO ENSURE REMOVAL OF CONNECTOR
steps.insert(i + 1, Step(step_type="resistance", spec={
"scale": 500,
"expected": float("+inf"),
"tolerance_pos": 0,
"tolerance_neg": 0,
}))
skip.add(i + 1)
if step.type == "print":
if step.step_type == "print":
if print_found:
continue
steps.insert(i, Steps(type="done"))
steps.insert(i, Step(step_type="done"))
print_found = True
self.print_step = step
if self.config["hardware_config"].get("enforce_piece_removal", "no") == "yes":
steps.append(Steps(type="piece_removal"))
steps.append(Step(step_type="piece_removal"))
if count_found:
steps.append(Steps(type="count_end"))
if step.type in ("leak_1", "leak_2"):
steps.append(Step(step_type="count_end"))
if step.step_type in ("leak_1", "leak_2"):
self.leak_step = step
if not print_found:
steps.append(Steps(type="done"))
steps.append(Step(step_type="done"))
if count_found:
steps.append(Steps(type="count_end"))
steps.append(Steps(type="wait"))
steps.append(Step(step_type="count_end"))
steps.append(Step(step_type="wait"))
self.cycle_steps = steps
self.check_steps_dependencies(self.cycle_steps)
leak_autotest_steps = []
@ -457,32 +458,32 @@ class Test(Widget):
l_at_2["test_pressure_qneg"] = l_at_2["test_pressure_tt_qneg"]
l_at_2["test_pressure_qpos"] = l_at_2["test_pressure_tt_qpos"]
l_at_2["autotest"] = "ok_check"
leak_autotest_steps = [Steps(type="leak_1", spec=l_at_1), Steps(type="leak_1", spec=l_at_2)]
leak_autotest_steps = [Step(step_type="leak_1", spec=l_at_1), Step(step_type="leak_1", spec=l_at_2)]
self.autotest_cycle_steps = [
*([
Steps(type="resistance", spec={
Step(step_type="resistance", spec={
"scale": 500,
"expected": 1,
"tolerance_pos": 5,
"tolerance_neg": 5,
"autotest": True,
}),
Steps(type="resistance", spec={
Step(step_type="resistance", spec={
"scale": 500,
"expected": float("+inf"),
"tolerance_pos": 0,
"tolerance_neg": 0,
"autotest": True,
}),
Steps(type="resistance", spec={
Step(step_type="resistance", spec={
"scale": 500,
"expected": 10,
"tolerance_pos": 1,
"tolerance_neg": 1,
"autotest": True,
}),
Steps(type="resistance", spec={
Step(step_type="resistance", spec={
"scale": 500,
"expected": float("+inf"),
"tolerance_pos": 0,
@ -491,8 +492,8 @@ class Test(Widget):
}),
] if "resistance" not in self.unsupported_steps else []),
*(leak_autotest_steps),
Steps(type="done"),
Steps(type="wait"),
Step(step_type="done"),
Step(step_type="wait"),
]
for w in self.cycle_available_steps.values():
if hasattr(w, "reset"):
@ -513,13 +514,13 @@ class Test(Widget):
unsupported_steps = set()
missing_components = set()
for step in steps:
if step.type in self.unsupported_steps or step.type not in self.cycle_available_steps:
unsupported_steps.add(step.type)
if step.step_type in self.unsupported_steps or step.step_type not in self.cycle_available_steps:
unsupported_steps.add(step.step_type)
else:
for dependency in self.steps_dependencies.get(step.type, []):
for dependency in self.steps_dependencies.get(step.step_type, []):
if isinstance(dependency, tuple):
if all([d not in self.components for d in dependency]):
unsupported_steps.add(step.type)
unsupported_steps.add(step.step_type)
else:
unready = set()
for d in dependency:
@ -534,7 +535,7 @@ class Test(Widget):
missing_components.add(" or ".join(dependency))
else:
if dependency not in self.components:
unsupported_steps.add(step.type)
unsupported_steps.add(step.step_type)
else:
if not self.components[dependency].ready:
self.components[dependency].reconfigure()
@ -571,7 +572,6 @@ class Test(Widget):
# remove useless info
self.data.get("recipe", {}).get("spec", {}).pop("steps", None)
self.data.get("recipe", {}).get("spec", {}).pop("available_steps", None)
for leak in ["leak_1", "leak_2"]:
if leak in self.data.keys():
results = {k: self.data[leak]["results"][self.tester_component][k] for k in ["Running test: result"]}
@ -757,7 +757,7 @@ class Test(Widget):
def load_recipe_from_rfid(self, data):
if data not in(None,''):
self.tag_loaded_recipe = data
if self.step.type == "barcode_recipe_selection":
if self.step.step_type == "barcode_recipe_selection":
if data is not None:
self.cycle_available_steps["barcode_recipe_selection"].widget.get(data)
else: