Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SW-3951 backend refactor the printer profile class and use it to implement rotary profile #1831

Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
63103aa
SW-3951 Add profile class
Oct 22, 2023
d050c80
SW-3951 Add laser cutter profile model
Oct 22, 2023
231e671
SW-3951 Add laser cutter profile service
Oct 22, 2023
8cf0dcf
SW-3951 Add laser cutter profiles to constants
Oct 22, 2023
b287fc4
SW-3951 Refactor services
Oct 22, 2023
eb5ea9c
SW-3951 Remove duplicated class
Oct 22, 2023
0141b67
SW-3951 Refactor laser cutter profiles viewmodel
Oct 22, 2023
1dcbf5c
SW-3951 Implement the new laser cutter profile service
Oct 22, 2023
c2a181f
SW-3951 Set default profile as a constant
Oct 23, 2023
655fc6b
SW-3951 Update the profile initialization
Oct 23, 2023
80f3451
SW-3951 Refactor profile initialization
Oct 24, 2023
addec00
SW-3951 Refactor laser cutter profiles
Oct 24, 2023
e05c480
SW-3951 Remove unnecessary parameter
Oct 24, 2023
4b8aa4d
SW-3951 Fix bug
Oct 24, 2023
00d21f8
SW-3951 Add line breaks to hard refresh window
Oct 24, 2023
50e3119
SW-3807 Modify GRBL rate and acceleration
Oct 24, 2023
99ef962
SW-3727 Implement Rotary homing mechanism
Oct 24, 2023
abf4ea5
SW-3951 Refactor updating the laser cutter profile
Oct 24, 2023
35a511c
SW-3951 Fix bug
Oct 24, 2023
115d4f9
SW-3951 Fix order
Oct 24, 2023
104e16e
SW-3815 Add soft limits to the rotary profile
Oct 24, 2023
566638c
SW-3951 Clean up old profile files
Oct 24, 2023
d9cff72
SW-3951 Fix default profile
Oct 24, 2023
e946bd4
SW-3951 Handle 2C series
Oct 24, 2023
670a970
SW-3951 Clean up and fix code smells and PR review notes
Oct 26, 2023
0c26502
SW-3951 Fix bug
Oct 26, 2023
4988525
SW-3951 Add PR review feedback
Oct 29, 2023
917963a
SW-3857 Add unit tests for __init__.py changes
khaledsherkawi Nov 15, 2023
9fb9302
SW-3857 Add unit tests for __init__.py changes
khaledsherkawi Nov 15, 2023
379834b
SW-3857 Rearrange unit tests structure
khaledsherkawi Nov 15, 2023
f98c594
SW-3857 Add unit tests for some profile.py methods
khaledsherkawi Nov 21, 2023
f43138b
SW-3857 Update unit tests for some profile.py methods
khaledsherkawi Nov 23, 2023
cda2471
SW-3857 Add unit tests for some profile.py methods
khaledsherkawi Nov 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 60 additions & 50 deletions octoprint_mrbeam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,13 @@
from octoprint_mrbeam.os_health_care import os_health_care
from octoprint_mrbeam.rest_handler.docs_handler import DocsRestHandlerMixin
from octoprint_mrbeam.model.laser_cutter_mode import LaserCutterModeModel
from octoprint_mrbeam.services import settings_service
from octoprint_mrbeam.services.settings_service import SettingsService
from octoprint_mrbeam.services.burger_menu_service import BurgerMenuService
from octoprint_mrbeam.services.document_service import DocumentService
from octoprint_mrbeam.services.laser_cutter_mode import laser_cutter_mode_service
from octoprint_mrbeam.service import settings_service
from octoprint_mrbeam.service.settings_service import SettingsService
from octoprint_mrbeam.service.burger_menu_service import BurgerMenuService
from octoprint_mrbeam.service.document_service import DocumentService
from octoprint_mrbeam.service.laser_cutter_mode import laser_cutter_mode_service
from octoprint_mrbeam.service.profile.laser_cutter_profile import laser_cutter_profile_service
from octoprint_mrbeam.wizard_config import WizardConfig
from octoprint_mrbeam.printing.profile import (
laserCutterProfileManager,
InvalidProfileError,
CouldNotOverwriteError,
Profile,
)
from octoprint_mrbeam.software_update_information import (
get_update_information,
switch_software_channel,
Expand Down Expand Up @@ -111,6 +106,8 @@
from octoprint_mrbeam.util import get_thread
from octoprint_mrbeam import camera
from octoprint_mrbeam.util.version_comparator import compare_pep440_versions
from octoprint_mrbeam.constant.profile import laser_cutter as laser_cutter_profiles
from octoprint_mrbeam.enums.laser_cutter_mode import LaserCutterModeEnum

# this is a easy&simple way to access the plugin and all injections everywhere within the plugin
__builtin__._mrbeam_plugin_implementation = None
Expand Down Expand Up @@ -169,6 +166,8 @@ class MrBeamPlugin(
RESTART_OCTOPRINT_CMD = "sudo systemctl restart octoprint.service"

def __init__(self):
self._laser_cutter_mode_service = None
self.laser_cutter_profile_service = None
self.mrbeam_plugin_initialized = False
self._shutting_down = False
self._slicing_commands = dict()
Expand All @@ -195,12 +194,7 @@ def __init__(self):

self._iobeam_connected = False
self._laserhead_ready = False

# Create the ``laserCutterProfileManager`` early to inject into the ``Laser``
# See ``laser_factory``
self.laserCutterProfileManager = laserCutterProfileManager(
profile_id=self._device_info.get_type()
)
self._laser_cutter_profile_initialized = False

self._boot_grace_period_counter = 0

Expand All @@ -217,9 +211,6 @@ def __init__(self):
# Jinja custom filters need to be loaded already on instance creation
FilterLoader.load_custom_jinja_filters()

# Initialize the laser cutter mode service attribute
self._laser_cutter_mode_service = None

# inside initialize() OctoPrint is already loaded, not assured during __init__()!
def initialize(self):
self._plugin_version = __version__
Expand All @@ -240,6 +231,7 @@ def initialize(self):
self._event_bus.subscribe(
MrBeamEvents.LASER_HEAD_READ, self._on_laserhead_ready
)
self._event_bus.subscribe(MrBeamEvents.LASER_CUTTER_PROFILE_INITIALIZED, self._on_laser_cutter_profile_initialized)

self.start_time_ntp_timer()

Expand Down Expand Up @@ -268,6 +260,9 @@ def initialize(self):
)

self.analytics_handler = analyticsHandler(self)
self._laser_cutter_mode_service = laser_cutter_mode_service(self)
self.laser_cutter_profile_service = laser_cutter_profile_service(self)
self.update_laser_cutter_profile(self.get_laser_cutter_profile_for_current_configuration())
self.user_notification_system = user_notification_system(self)
self.onebutton_handler = oneButtonHandler(self)
self.interlock_handler = interLockHandler(self)
Expand Down Expand Up @@ -301,8 +296,23 @@ def initialize(self):
self._do_initial_log()
self._printer.register_user_notification_system(self.user_notification_system)

# Initialize the laser cutter mode service
self._laser_cutter_mode_service = laser_cutter_mode_service(self)
def update_laser_cutter_profile(self, profile):
self.laser_cutter_profile_service.save(profile, allow_overwrite=True, make_default=True)
self.laser_cutter_profile_service.select(profile['id'])

def get_laser_cutter_profile_for_current_configuration(self):
laser_cutter_mode = self.get_laser_cutter_mode()
device_series = self._device_info.get_series()
profile = laser_cutter_profiles.default_profile
if laser_cutter_mode == LaserCutterModeEnum.DEFAULT.value:
if device_series == "2C":
irlaec marked this conversation as resolved.
Show resolved Hide resolved
profile = laser_cutter_profiles.series_2c
elif laser_cutter_mode == LaserCutterModeEnum.ROTARY.value:
profile = laser_cutter_profiles.rotary_profile
if device_series == "2C":
profile = laser_cutter_profiles.series_2c_rotary_profile
return profile


def get_settings(self):
return self._settings
Expand Down Expand Up @@ -335,14 +345,29 @@ def _on_laserhead_ready(self, *args, **kwargs):
self._laserhead_ready = True
self._try_to_connect_laser()

def _on_laser_cutter_profile_initialized(self, *args, **kwargs):
irlaec marked this conversation as resolved.
Show resolved Hide resolved
"""Called when the laser cutter profile is initialized is initialized.
irlaec marked this conversation as resolved.
Show resolved Hide resolved

Args:
*args:
**kwargs:

Returns:

"""
self._logger.info("MrBeamPlugin on_laser_cutter_profile_initialized")
self._laser_cutter_profile_initialized = True
self._try_to_connect_laser()

def _try_to_connect_laser(self):
"""Tries to connect the laser if both iobeam and laserhead are ready and the laser is not connected yet."""
if (
self._iobeam_connected
and self._laserhead_ready
and self._laser_cutter_profile_initialized
and self._printer.is_closed_or_error()
):
self._printer.connect()
self._printer.connect(profile=self.laser_cutter_profile_service.get_current_or_default())

def _init_frontend_logger(self):
handler = logging.handlers.RotatingFileHandler(
Expand Down Expand Up @@ -382,7 +407,7 @@ def _do_initial_log(self):

msg = (
"MrBeam Lasercutter Profile: %s"
% self.laserCutterProfileManager.get_current_or_default()
% self.laser_cutter_profile_service.get_current_or_default()
)
self._logger.info(msg, terminal=True)
self._frontend_logger.info(msg)
Expand Down Expand Up @@ -596,7 +621,7 @@ def on_settings_load(self):
fps=self._settings.get(["leds", "fps"]),
),
isFirstRun=self.isFirstRun(),
laser_cutter_mode=self._settings.get(["laser_cutter_mode"]),
laser_cutter_mode=self.get_laser_cutter_mode(),
)

def on_settings_save(self, data):
Expand Down Expand Up @@ -862,7 +887,7 @@ def on_ui_render(self, now, request, render_kwargs):
enable_accesscontrol and self._user_manager.hasBeenCustomized()
)

selectedProfile = self.laserCutterProfileManager.get_current_or_default()
selectedProfile = self.laser_cutter_profile_service.get_current_or_default()
enable_focus = selectedProfile["focus"]
safety_glasses = selectedProfile["glasses"]
# render_kwargs["templates"]["settings"]["entries"]["serial"][1]["template"] = "settings/serialconnection.jinja2"
Expand Down Expand Up @@ -1620,7 +1645,7 @@ def printLabel(self):
)
@restricted_access_or_calibration_tool_mode
def engraveCalibrationMarkers(self, intensity, feedrate):
profile = self.laserCutterProfileManager.get_current_or_default()
profile = self.laser_cutter_profile_service.get_current_or_default()
try:
i = int(int(intensity) / 100.0 * JobParams.Max.INTENSITY)
f = int(feedrate)
Expand All @@ -1646,7 +1671,7 @@ def engraveCalibrationMarkers(self, intensity, feedrate):
return make_response("Laser: Serial not connected", 400)

if self._printer.get_state_id() == "LOCKED":
self._printer.home("xy")
self._printer.home()

seconds = 0
while (
Expand Down Expand Up @@ -1700,31 +1725,16 @@ def engraveCalibrationMarkers(self, intensity, feedrate):
# return NO_CONTENT

# Laser cutter profiles
@octoprint.plugin.BlueprintPlugin.route("/profiles", methods=["GET"])
@octoprint.plugin.BlueprintPlugin.route("/currentProfile", methods=["GET"])
def laserCutterProfilesList(self):
irlaec marked this conversation as resolved.
Show resolved Hide resolved
all_profiles = self.laserCutterProfileManager.converted_profiles()
for profile_id, profile in all_profiles.items():
all_profiles[profile_id]["resource"] = url_for(
".laserCutterProfilesGet", identifier=profile["id"], _external=True
)
return jsonify(dict(profiles=all_profiles))

@octoprint.plugin.BlueprintPlugin.route(
"/profiles/<string:identifier>", methods=["GET"]
)
def laserCutterProfilesGet(self, identifier):
profile = self.laserCutterProfileManager.get(identifier)
if profile is None:
return make_response("Unknown profile: %s" % identifier, 404)
else:
return jsonify(self._convert_profile(profile))
return jsonify(self.laser_cutter_profile_service.get_current_or_default())

# ~ Calibration
def generateCalibrationMarkersSvg(self):
"""Used from the calibration screen to engrave the calibration
markers."""
# TODO mv this func to other file
profile = self.laserCutterProfileManager.get_current_or_default()
profile = self.laser_cutter_profile_service.get_current_or_default()
cm = CalibrationMarker(
str(profile["volume"]["width"]), str(profile["volume"]["depth"])
)
Expand Down Expand Up @@ -2117,7 +2127,7 @@ def on_api_command(self, command, data):
parse_csv(
device_model=self.get_model_id(),
laserhead_model=self.get_current_laser_head_model(),
laser_cutter_mode=self.get_laser_cutter_mode(),
laser_cutter_mode = self.get_laser_cutter_mode() if self.get_laser_cutter_mode() is not None else LaserCutterModeEnum.DEFAULT.value,
irlaec marked this conversation as resolved.
Show resolved Hide resolved
)
),
200,
Expand Down Expand Up @@ -2604,7 +2614,7 @@ def is_job_cancelled():

is_job_cancelled() # check before conversion started

profile = self.laserCutterProfileManager.get_current_or_default()
profile = self.laser_cutter_profile_service.get_current_or_default()
maxWidth = profile["volume"]["width"]
maxHeight = profile["volume"]["depth"]

Expand Down Expand Up @@ -2693,7 +2703,7 @@ def on_event(self, event, payload):

if event == MrBeamEvents.BOOT_GRACE_PERIOD_END:
if self.calibration_tool_mode:
self._printer.home("Homing before starting calibration tool")
self._printer.home()
self.lid_handler.onLensCalibrationStart()

if event == OctoPrintEvents.ERROR:
Expand Down Expand Up @@ -2833,7 +2843,7 @@ def laser_factory(self, components, *args, **kwargs):
return Laser(
components["file_manager"],
components["analysis_queue"],
self.laserCutterProfileManager,
self.laser_cutter_profile_service,
)

def laser_filemanager(self, *args, **kwargs):
Expand Down
Empty file.
16 changes: 16 additions & 0 deletions octoprint_mrbeam/constant/profile/laser_cutter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import absolute_import

from octoprint.util import dict_merge
from . import default, series_2c, rotary, series_2c_rotary
irlaec marked this conversation as resolved.
Show resolved Hide resolved

# Default profile for the Mr beam laser cutter in default mode and a non-2C series
default_profile = default.profile

# Default profile for the Mr beam laser cutter in default mode and a 2C series
series_2c_profile = dict_merge(default_profile, series_2c.profile)

# Default profile for the Mr beam laser cutter in rotary mode and a non-2C series
rotary_profile = dict_merge(default_profile, rotary.profile)

# Default profile for the Mr beam laser cutter in rotary mode and a 2C series
series_2c_rotary_profile = dict_merge(default_profile, series_2c_rotary.profile)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Default config for the Mr beam laser cutter
# Default profile for the Mr beam laser cutter in default mode and a non-2C series

__all__ = ["profile"]

profile = dict(
id="_default",
id="default",
name="MrBeam2",
model="X",
axes=dict(
Expand Down Expand Up @@ -47,6 +47,9 @@
width=500.0,
working_area_shift_x=7.0,
working_area_shift_y=0.0,
after_homing_shift_x=0.0,
after_homing_shift_y=0.0,
after_homing_shift_rate=5000,
),
grbl=dict(
resetOnConnect=True,
Expand Down
23 changes: 23 additions & 0 deletions octoprint_mrbeam/constant/profile/laser_cutter/rotary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Default profile for the Mr beam laser cutter in default mode and a non-2C series

__all__ = ["profile"]

profile = dict(
id="rotary",
volume=dict(
depth=390.0,
width=500.0,
after_homing_shift_y=-80.0, # After homing shift in Y direction
after_homing_shift_rate=500, # After homing feed rate mm / min
),
grbl=dict(
settings={
110: 500, # X Max rate, mm / min
111: 500, # Y Max rate, mm / min
120: 30, # X Acceleration, mm / sec ^ 2
121: 30, # Y Acceleration, mm / sec ^ 2
130: 360, # X max travel, mm # !! C-Series: 501.1
131: 200, # Y max travel, mm
},
),
)
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#!/usr/bin/env python3

profile = dict(
id="MrBeam2C",
id="series_2c",
irlaec marked this conversation as resolved.
Show resolved Hide resolved
model="C",
legacy=dict(
job_done_home_position_x=250,
),
volume=dict(
working_area_shift_x=0.0,
),
grbl=dict(
settings={
130: 501.1, # X max travel, mm
},
),
)
23 changes: 23 additions & 0 deletions octoprint_mrbeam/constant/profile/laser_cutter/series_2c_rotary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Default profile for the Mr beam laser cutter in default mode and a non-2C series

__all__ = ["profile"]

profile = dict(
id="series_2c_rotary",
volume=dict(
depth=390.0,
width=500.0,
after_homing_shift_y=-80.0, # After homing shift in Y direction
after_homing_shift_rate=500, # After homing feed rate mm / min
),
grbl=dict(
settings={
110: 500, # X Max rate, mm / min
111: 500, # Y Max rate, mm / min
120: 30, # X Acceleration, mm / sec ^ 2
121: 30, # Y Acceleration, mm / sec ^ 2
130: 346, # X max travel, mm # !! C-Series: 501.1
131: 200, # Y max travel, mm
},
),
)
2 changes: 1 addition & 1 deletion octoprint_mrbeam/filemanager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, plugin):
self,
self._plugin._analysis_queue,
self._plugin._slicing_manager,
self._plugin.laserCutterProfileManager,
self._plugin.laser_cutter_profile_service,
initial_storage_managers=storage_managers,
)

Expand Down
2 changes: 1 addition & 1 deletion octoprint_mrbeam/iobeam/lid_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def __init__(self, plugin):
self._printer = plugin._printer
self._plugin_manager = plugin._plugin_manager
self._laserCutterProfile = (
plugin.laserCutterProfileManager.get_current_or_default()
plugin.laser_cutter_profile_service.get_current_or_default()
)
self._logger = mrb_logger(
"octoprint.plugins.mrbeam.iobeam.lidhandler", logging.INFO
Expand Down
4 changes: 2 additions & 2 deletions octoprint_mrbeam/iobeam/temperature_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, plugin, laser):
self._plugin.laserhead_handler.current_laserhead_high_temperature_warn_offset
)
self.cooling_duration = (
plugin.laserCutterProfileManager.get_current_or_default()["laser"][
plugin.laser_cutter_profile_service.get_current_or_default()["laser"][
"cooling_duration"
]
)
Expand Down Expand Up @@ -147,7 +147,7 @@ def reset(self, kwargs):
self._plugin.laserhead_handler.current_laserhead_high_temperature_warn_offset
)
self.cooling_duration = (
self._plugin.laserCutterProfileManager.get_current_or_default()["laser"][
self._plugin.laser_cutter_profile_service.get_current_or_default()["laser"][
"cooling_duration"
]
)
Expand Down
Loading