From df8ca1c547047120347ad4f3373aff0f921964bf Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Wed, 26 Mar 2025 10:35:14 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9C=BA=E5=9E=8B?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/model_menu.conf | 8 ++++---- ks_includes/ModelConfig.py | 10 +++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/config/model_menu.conf b/config/model_menu.conf index aca36403..126cc0aa 100644 --- a/config/model_menu.conf +++ b/config/model_menu.conf @@ -1,6 +1,6 @@ CreatBot_F430NX -CreatBot_D600Pro2 -CreatBot_D600Pro2_V0 -CreatBot_D1000 -CreatBot_D1000_V0 +CreatBot_D600Pro2HS +CreatBot_D600Pro2HS_KIT +CreatBot_D1000HS +CreatBot_D1000HS_KIT CreatBot_P800 diff --git a/ks_includes/ModelConfig.py b/ks_includes/ModelConfig.py index 0ef3bb5d..e7ca2daf 100644 --- a/ks_includes/ModelConfig.py +++ b/ks_includes/ModelConfig.py @@ -101,8 +101,16 @@ class ModelConfig: ) def wirte_printer_config(self, device_name): + config_dict = { + "CreatBot_F430NX": "CreatBot_F430NX", + "CreatBot_D600Pro2HS": "CreatBot_D600Pro2", + "CreatBot_D600Pro2HS_KIT": "CreatBot_D600Pro2_V0", + "CreatBot_D1000HS": "CreatBot_D1000", + "CreatBot_D1000HS_KIT": "CreatBot_D1000_V0", + "CreatBot_P800": "CreatBot_P800", + } if device_name: - source_path = f"{os.path.expanduser('~')}/klipper/config/{device_name}/" + source_path = f"{os.path.expanduser('~')}/klipper/config/{config_dict.get(device_name)}/" target_path = f"{os.path.expanduser('~')}/printer_data/config/" if not os.path.exists(target_path): os.makedirs(target_path) From 58d8df665291e71cf5c5802ea699d4923cd5ab67 Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Sat, 29 Mar 2025 15:31:20 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/model_menu.conf | 26 ++++++++++---- ks_includes/ModelConfig.py | 21 +++++++++-- panels/factory_settings.py | 72 ++++++++++++++++++++++++-------------- 3 files changed, 84 insertions(+), 35 deletions(-) diff --git a/config/model_menu.conf b/config/model_menu.conf index 126cc0aa..1de5b6dc 100644 --- a/config/model_menu.conf +++ b/config/model_menu.conf @@ -1,6 +1,20 @@ -CreatBot_F430NX -CreatBot_D600Pro2HS -CreatBot_D600Pro2HS_KIT -CreatBot_D1000HS -CreatBot_D1000HS_KIT -CreatBot_P800 + +[CreatBot_F430NX] +versions = 1.0 + +[CreatBot_D600Pro2HS] +versions = 1.0, 1.1 +#V1.1 Add door detection + +[CreatBot_D600Pro2HS_KIT] +versions = 1.0 + +[CreatBot_D1000HS] +versions = 1.0, 1.1 +#V1.1 Add door detection + +[CreatBot_D1000HS_KIT] +versions = 1.0 + +[CreatBot_P800] +versions = 1.0 diff --git a/ks_includes/ModelConfig.py b/ks_includes/ModelConfig.py index e7ca2daf..f027cae3 100644 --- a/ks_includes/ModelConfig.py +++ b/ks_includes/ModelConfig.py @@ -100,7 +100,7 @@ class ModelConfig: f"Configuration file {self.klipperscreen_config_path} not found." ) - def wirte_printer_config(self, device_name): + def wirte_printer_config(self, device_name, version): config_dict = { "CreatBot_F430NX": "CreatBot_F430NX", "CreatBot_D600Pro2HS": "CreatBot_D600Pro2", @@ -128,6 +128,21 @@ class ModelConfig: except Exception as e: logging.error(f"Error creating symlink for{device_name}:{e}") + source_module_path = os.path.join(source_path, os.path.basename(version)) + target_module_path = os.path.join(target_path, os.path.basename("module")) + try: + if os.path.islink(target_module_path) or os.path.exists(target_module_path): + os.remove(target_module_path) + if version != "1.0": + os.symlink(source_module_path, target_module_path) + logging.info(f"Created config version for {device_name}-{version}.") + except FileExistsError: + logging.error(f"Failed to create version symlink for {device_name}.") + except PermissionError: + logging.error(f"No permission to create version symlink for {device_name}.") + except Exception as e: + logging.error(f"Error creating version symlink for{device_name}:{e}") + source_printer_path = os.path.join(source_path, os.path.basename("printer.cfg")) target_printer_path = os.path.join(target_path, os.path.basename("printer.cfg")) command = ['cp','-f', source_printer_path, target_printer_path] @@ -151,13 +166,13 @@ class ModelConfig: except Exception as e: logging.error(f"An unexpected error occurred: {e}") - def generate_config(self, model): + def generate_config(self, model, version): model_name = model model_name = model_name.split("_")[1] device_name = self.generate_machine_name(model_name) self.write_mdns_config(device_name) self.write_device_name_config(device_name) - self.wirte_printer_config(model) + self.wirte_printer_config(model, version) self.wirte_hostname(device_name) os.system("systemctl restart klipper.service") os.system("systemctl restart moonraker.service") diff --git a/panels/factory_settings.py b/panels/factory_settings.py index 786ef4ef..97b4143a 100644 --- a/panels/factory_settings.py +++ b/panels/factory_settings.py @@ -19,6 +19,10 @@ class Panel(ScreenPanel): def __init__(self, screen, title): title = title or "factory settings" super().__init__(screen, title) + klipperscreendir = pathlib.Path(__file__).parent.resolve().parent + self.model_list_path = os.path.join(klipperscreendir, "config", "model_menu.conf") + self.model_list_config = configparser.ConfigParser() + self.model_list_config.read(self.model_list_path, encoding="utf-8") self.last_drop_time = datetime.now() self.factory_settings_list = [ { @@ -62,6 +66,7 @@ class Panel(ScreenPanel): ] self.settings = {} self.select_model = False + self.select_model_version = False self.labels["setting_menu"] = self._gtk.ScrolledWindow() self.labels["settings"] = Gtk.Grid() self.labels["setting_menu"].add(self.labels["settings"]) @@ -77,6 +82,9 @@ class Panel(ScreenPanel): self.content.show_all() def back(self): + if self.select_model_version: + self.hide_select_model_version() + return True if self.select_model: self.hide_select_model() return True @@ -99,38 +107,52 @@ class Panel(ScreenPanel): combo_box.popup() return False - def show_select_model(self, widget, option): - self.create_select_model() + def create_list_menu(self, menu_list, callback=None): + if "model_menu" in self.labels: + del self.labels["model_menu"] + self.labels["model_menu"] = self._gtk.ScrolledWindow() + self.labels["model"] = Gtk.Grid() + self.labels["model_menu"].add(self.labels["model"]) + self.models = {} + for value in menu_list: + self.models[value] = { + "name": value, + "type": "button", + "callback": callback, + } + self.add_option("model", self.models, value, self.models[value]) + + def show_select_model(self, widget=None, option=None): + self.create_list_menu(self.model_list_config.sections(), self._on_model_selected) for child in self.content.get_children(): self.content.remove(child) self.content.add(self.labels["model_menu"]) self.content.show_all() self.select_model = True - def create_select_model(self): - if "model_menu" in self.labels: - return + def show_select_model_version(self, model): + versions_str = self.model_list_config[model].get("versions", "") + versions = [v.strip() for v in versions_str.split(",") if v.strip()] + self.create_list_menu(versions, self._on_version_selected) + self.select_model_version = True + + def _on_model_selected(self, widget, event): + for child in self.content.get_children(): + self.content.remove(child) + self.show_select_model_version(event) + self.content.add(self.labels["model_menu"]) + self.content.show_all() + + def _on_version_selected(self, widget, version): if not hasattr(self, "model_config") or self.model_config is None: self.model_config = ModelConfig() - self.labels["model_menu"] = self._gtk.ScrolledWindow() - self.labels["model"] = Gtk.Grid() - self.labels["model_menu"].add(self.labels["model"]) - klipperscreendir = pathlib.Path(__file__).parent.resolve().parent - self.model_list_path = os.path.join(klipperscreendir, "config", "model_menu.conf") - self.model_list = pathlib.Path(self.model_list_path).read_text() - with open(self.model_list_path) as file: - self.models = {} - for line in file: - model_name = line.strip() - self.models[model_name] = { - "name": model_name, - "type": "button", - "callback": self.change_model, - } - self.add_option("model", self.models, model_name, self.models[model_name]) + self.model_config.generate_config(self.select_model, version) - def change_model(self, widget, event): - self.model_config.generate_config(event) + def hide_select_model_version(self): + for child in self.content.get_children(): + self.content.remove(child) + self.show_select_model() + self.select_model_version = False def hide_select_model(self): for child in self.content.get_children(): @@ -148,7 +170,7 @@ class Panel(ScreenPanel): {"name": _("Accept"), "response": Gtk.ResponseType.OK, "style": "dialog-error"}, {"name": _("Cancel"), "response": Gtk.ResponseType.CANCEL, "style": "dialog-info"}, ] - + text = _("Are you sure?\n") + "\n\n" + _("The system will reboot!") label = Gtk.Label(wrap=True, vexpand=True) label.set_markup(text) @@ -158,7 +180,6 @@ class Panel(ScreenPanel): checkbox.set_halign(Gtk.Align.CENTER) checkbox.set_valign(Gtk.Align.CENTER) - grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True) grid.set_row_spacing(20) grid.set_column_spacing(0) @@ -173,7 +194,6 @@ class Panel(ScreenPanel): self.confirm_factory_reset_production, checkbox, ) - def confirm_factory_reset_production(self, dialog, response_id, checkbox): self._gtk.remove_dialog(dialog) From 1b1322dffcef4dae7948a04702399493a8460d31 Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Sat, 29 Mar 2025 16:50:54 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=80=E9=97=A8?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panels/advanced.py | 60 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/panels/advanced.py b/panels/advanced.py index 974fbc37..6d06b9ad 100644 --- a/panels/advanced.py +++ b/panels/advanced.py @@ -3,17 +3,19 @@ import logging import gi gi.require_version("Gtk", "3.0") -from gi.repository import Gtk +from gi.repository import GLib, Gtk from ks_includes.KlippyFactory import KlippyFactory from ks_includes.KlippyGcodes import KlippyGcodes from ks_includes.screen_panel import ScreenPanel +from datetime import datetime class Panel(ScreenPanel): def __init__(self, screen, title): title = title or _("Advanced") super().__init__(screen, title) + self.last_drop_time = datetime.now() self.advanced = {} self.menu_list = {} self.advanced_options = [ @@ -59,6 +61,27 @@ class Panel(ScreenPanel): } }, ] + if self._printer.get_macro("_door_detection"): + self.advanced_options.append( + { + "door_open_detection": { + "section": "main", + "name": _("Door Open Protection Mode"), + "type": "dropdown", + "tooltip": _( + "This feature allows you to customize the printer's response when door opening is detected" + ), + "value": "Disabled", + "callback": self.door_open_detection, + "options": [ + {"name": _("Disabled") + " " + _("(default)"), "value": "Disabled"}, + {"name": _("Pause Print"), "value": "Pause Print"}, + {"name": _("Emergency Stop"), "value": "Emergency Stop"}, + ], + } + } + ) + options = self.advanced_options self.labels["advanced_menu"] = self._gtk.ScrolledWindow() self.labels["advanced"] = Gtk.Grid() @@ -69,6 +92,9 @@ class Panel(ScreenPanel): self.menu_list.update(res) self.content.add(self.labels["advanced_menu"]) + if "door_open_detection" in self.menu_list: + self.menu_list["door_open_detection"].connect("notify::popup-shown", self.on_popup_shown) + def reset_factory_settings(self, *args): text = _("Confirm factory reset?\n") + "\n\n" + _("The system will reboot!") label = Gtk.Label(wrap=True, vexpand=True) @@ -111,6 +137,26 @@ class Panel(ScreenPanel): if response_id == Gtk.ResponseType.OK: KlippyFactory.user_factory_reset(self._screen._ws.klippy, self._config, clear_files_checkbox.get_active()) + def on_popup_shown(self, combo_box, param): + if combo_box.get_property("popup-shown"): + logging.debug("Dropdown popup show") + self.last_drop_time = datetime.now() + else: + elapsed = (datetime.now() - self.last_drop_time).total_seconds() + if elapsed < 0.1: + logging.debug(f"Dropdown closed too fast ({elapsed}s)") + GLib.timeout_add(50, lambda: self.dropdown_keep_open(combo_box)) + return + logging.debug("Dropdown popup close") + + def dropdown_keep_open(self, combo_box): + if isinstance(combo_box, Gtk.ComboBox): + combo_box.popup() + return False + + def door_open_detection(self, str): + self.set_configuration_string("door_detect", str) + def set_adaptive_leveling(self, *args): self.set_configuration_feature("adaptive_meshing", *args) @@ -120,6 +166,11 @@ class Panel(ScreenPanel): def set_auto_change_nozzle(self, *args): self.set_configuration_feature("auto_change_nozzle", *args) + def set_configuration_string(self, feature_name, str): + script = KlippyGcodes.set_save_variables(feature_name, str) + self._screen._send_action(None, "printer.gcode.script", {"script": script}) + logging.info(f"Set {feature_name}: {str}") + def set_configuration_feature(self, feature_name, *args): enable_feature = any(args) script_value = True if enable_feature else False @@ -143,3 +194,10 @@ class Panel(ScreenPanel): self.menu_list["auto_change_nozzle"].set_active(variables["auto_change_nozzle"]) else: self.menu_list["auto_change_nozzle"].set_active(False) + + if self._printer.get_macro("_door_detection"): + if "door_detect" in variables: + model = self.menu_list["door_open_detection"].get_model() + for i, row in enumerate(model): + if row[0] == variables["door_detect"]: + self.menu_list["door_open_detection"].set_active(i) From facebc5c8e9f7330dd5fe01a359977261b812d69 Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Sat, 29 Mar 2025 17:29:22 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=BC=80=E9=97=A8?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ks_includes/locales/KlipperScreen.pot | 43 ++++++++++---- .../zh_CN/LC_MESSAGES/KlipperScreen.mo | Bin 23500 -> 24120 bytes .../zh_CN/LC_MESSAGES/KlipperScreen.po | 55 +++++++++++++----- .../zh_TW/LC_MESSAGES/KlipperScreen.mo | Bin 23219 -> 23839 bytes .../zh_TW/LC_MESSAGES/KlipperScreen.po | 55 +++++++++++++----- ks_includes/prompts_text.py | 6 ++ 6 files changed, 123 insertions(+), 36 deletions(-) diff --git a/ks_includes/locales/KlipperScreen.pot b/ks_includes/locales/KlipperScreen.pot index 4a1a2111..90649464 100644 --- a/ks_includes/locales/KlipperScreen.pot +++ b/ks_includes/locales/KlipperScreen.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-26 11:12+0800\n" +"POT-Creation-Date: 2025-03-29 17:34+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -76,6 +76,9 @@ msgstr "" msgid "Adaptive Bed Leveling" msgstr "" +msgid "Add" +msgstr "" + msgid "Add profile" msgstr "" @@ -292,6 +295,9 @@ msgstr "" msgid "Disable for 12hs with am / pm" msgstr "" +msgid "Disabled" +msgstr "" + msgid "Disconnect" msgstr "" @@ -306,6 +312,9 @@ msgstr "" msgid "Do you want to recover %s?" msgstr "" +msgid "Door Open Protection Mode" +msgstr "" + msgid "Elapsed trial time:" msgstr "" @@ -321,9 +330,6 @@ msgstr "" msgid "Enable screen power management" msgstr "" -msgid "Enabled successfully" -msgstr "" - msgid "Error" msgstr "" @@ -643,6 +649,9 @@ msgstr "" msgid "Minimum:" msgstr "" +msgid "Minus" +msgstr "" + msgid "Modified" msgstr "" @@ -763,6 +772,9 @@ msgstr "" msgid "Pause" msgstr "" +msgid "Pause Print" +msgstr "" + msgid "Paused" msgstr "" @@ -775,6 +787,9 @@ msgstr "" msgid "Pins" msgstr "" +msgid "Please close the door and click Resume to proceed." +msgstr "" + msgid "Please ensure that the Probe Calibrate has been performed" msgstr "" @@ -823,6 +838,12 @@ msgstr "" msgid "Printer Select" msgstr "" +msgid "Printer door is opened. Please close the door and then start printing." +msgstr "" + +msgid "Printer door is opening!" +msgstr "" + msgid "Printing" msgstr "" @@ -877,12 +898,6 @@ msgstr "" msgid "Reprint" msgstr "" -msgid "Reset" -msgstr "" - -msgid "Reset successfully" -msgstr "" - msgid "Restart" msgstr "" @@ -1052,6 +1067,9 @@ msgstr "" msgid "Temperature" msgstr "" +msgid "Test Mode" +msgstr "" + msgid "The last print job was not completed continue printing?" msgstr "" @@ -1067,6 +1085,11 @@ msgstr "" msgid "This device is not activated and is available for trial use only" msgstr "" +msgid "" +"This feature allows you to customize the printer's response when door " +"opening is detected" +msgstr "" + msgid "This operation is about to print the model" msgstr "" diff --git a/ks_includes/locales/zh_CN/LC_MESSAGES/KlipperScreen.mo b/ks_includes/locales/zh_CN/LC_MESSAGES/KlipperScreen.mo index b36aa86b3a48bc2e2839f6483c51f12e9372b957..6cc1981fdba6382731e67d0de9aa0d88d7b7a9af 100644 GIT binary patch delta 9304 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\n" "Language-Team: Chinese (Simplified) J)d5D@9VzrbFXtw0=3}7fX#;k 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 LJOz_Rj|ln~DA%wh delta 8689 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\n" "Language-Team: Chinese (Traditional) Date: Mon, 31 Mar 2025 10:49:05 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=B2=A1=E6=9C=89=E5=8F=8D=E5=BA=94=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panels/factory_settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/panels/factory_settings.py b/panels/factory_settings.py index 97b4143a..55f1a89a 100644 --- a/panels/factory_settings.py +++ b/panels/factory_settings.py @@ -135,6 +135,7 @@ class Panel(ScreenPanel): versions = [v.strip() for v in versions_str.split(",") if v.strip()] self.create_list_menu(versions, self._on_version_selected) self.select_model_version = True + self.model = model def _on_model_selected(self, widget, event): for child in self.content.get_children(): @@ -146,7 +147,7 @@ class Panel(ScreenPanel): def _on_version_selected(self, widget, version): if not hasattr(self, "model_config") or self.model_config is None: self.model_config = ModelConfig() - self.model_config.generate_config(self.select_model, version) + self.model_config.generate_config(self.model, version) def hide_select_model_version(self): for child in self.content.get_children(): From c8048c9732cca3a6e8ee0edd012c2f945733a4b7 Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Mon, 31 Mar 2025 10:51:44 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E5=87=BA=E5=8E=82=E8=AE=BE=E7=BD=AE=E6=97=B6=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=BC=80=E9=97=A8=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ks_includes/KlippyFactory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ks_includes/KlippyFactory.py b/ks_includes/KlippyFactory.py index 0995240b..3fe534c0 100644 --- a/ks_includes/KlippyFactory.py +++ b/ks_includes/KlippyFactory.py @@ -49,6 +49,7 @@ class KlippyFactory: "adaptive_meshing": False, "power_loss_recovery": True, "auto_change_nozzle": False, + "door_detect": "Disabled", } for key, val in option_list.items(): script = KlippyGcodes.set_save_variables(key, val) From 26452c9873d242518ae23f4db995367fbd21361d Mon Sep 17 00:00:00 2001 From: zkk <1007518571@qq.com> Date: Mon, 31 Mar 2025 11:11:56 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9D=9E=E8=8B=B1?= =?UTF-8?q?=E6=96=87=E6=83=85=E5=86=B5=E4=B8=8B=E5=BC=80=E9=97=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8D=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panels/advanced.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panels/advanced.py b/panels/advanced.py index 6d06b9ad..50ae4579 100644 --- a/panels/advanced.py +++ b/panels/advanced.py @@ -199,5 +199,5 @@ class Panel(ScreenPanel): if "door_detect" in variables: model = self.menu_list["door_open_detection"].get_model() for i, row in enumerate(model): - if row[0] == variables["door_detect"]: + if row[0] == _(variables["door_detect"]): self.menu_list["door_open_detection"].set_active(i)