meerk40t 0.9.7020__py2.py3-none-any.whl → 0.9.7040__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. meerk40t/balormk/clone_loader.py +3 -2
  2. meerk40t/balormk/controller.py +28 -11
  3. meerk40t/balormk/cylindermod.py +1 -0
  4. meerk40t/balormk/device.py +13 -9
  5. meerk40t/balormk/driver.py +9 -2
  6. meerk40t/balormk/galvo_commands.py +3 -1
  7. meerk40t/balormk/gui/gui.py +6 -0
  8. meerk40t/balormk/livelightjob.py +338 -321
  9. meerk40t/balormk/mock_connection.py +4 -3
  10. meerk40t/balormk/usb_connection.py +11 -2
  11. meerk40t/camera/camera.py +19 -14
  12. meerk40t/camera/gui/camerapanel.py +6 -0
  13. meerk40t/core/cutcode/cutcode.py +1 -1
  14. meerk40t/core/cutplan.py +169 -43
  15. meerk40t/core/elements/element_treeops.py +444 -147
  16. meerk40t/core/elements/elements.py +100 -9
  17. meerk40t/core/elements/grid.py +8 -1
  18. meerk40t/core/elements/offset_mk.py +2 -1
  19. meerk40t/core/elements/shapes.py +618 -279
  20. meerk40t/core/elements/tree_commands.py +10 -5
  21. meerk40t/core/node/elem_ellipse.py +18 -8
  22. meerk40t/core/node/elem_image.py +51 -19
  23. meerk40t/core/node/elem_line.py +18 -8
  24. meerk40t/core/node/elem_path.py +18 -8
  25. meerk40t/core/node/elem_point.py +10 -4
  26. meerk40t/core/node/elem_polyline.py +19 -11
  27. meerk40t/core/node/elem_rect.py +18 -8
  28. meerk40t/core/node/elem_text.py +11 -5
  29. meerk40t/core/node/filenode.py +2 -8
  30. meerk40t/core/node/groupnode.py +11 -11
  31. meerk40t/core/node/image_processed.py +11 -5
  32. meerk40t/core/node/image_raster.py +11 -5
  33. meerk40t/core/node/node.py +70 -19
  34. meerk40t/core/node/refnode.py +2 -1
  35. meerk40t/core/planner.py +23 -0
  36. meerk40t/core/svg_io.py +91 -34
  37. meerk40t/core/undos.py +1 -1
  38. meerk40t/core/wordlist.py +1 -0
  39. meerk40t/device/dummydevice.py +7 -1
  40. meerk40t/dxf/dxf_io.py +6 -0
  41. meerk40t/extra/mk_potrace.py +1959 -0
  42. meerk40t/extra/param_functions.py +1 -1
  43. meerk40t/extra/potrace.py +14 -10
  44. meerk40t/extra/vtracer.py +222 -0
  45. meerk40t/grbl/device.py +81 -8
  46. meerk40t/grbl/interpreter.py +1 -1
  47. meerk40t/gui/about.py +21 -3
  48. meerk40t/gui/basicops.py +3 -3
  49. meerk40t/gui/choicepropertypanel.py +1 -4
  50. meerk40t/gui/devicepanel.py +20 -16
  51. meerk40t/gui/gui_mixins.py +8 -1
  52. meerk40t/gui/icons.py +330 -253
  53. meerk40t/gui/laserpanel.py +8 -3
  54. meerk40t/gui/laserrender.py +41 -21
  55. meerk40t/gui/magnetoptions.py +158 -65
  56. meerk40t/gui/materialtest.py +229 -39
  57. meerk40t/gui/navigationpanels.py +229 -24
  58. meerk40t/gui/propertypanels/hatchproperty.py +2 -0
  59. meerk40t/gui/propertypanels/imageproperty.py +160 -106
  60. meerk40t/gui/ribbon.py +6 -1
  61. meerk40t/gui/scenewidgets/gridwidget.py +29 -32
  62. meerk40t/gui/scenewidgets/rectselectwidget.py +190 -192
  63. meerk40t/gui/simulation.py +75 -77
  64. meerk40t/gui/spoolerpanel.py +6 -9
  65. meerk40t/gui/statusbarwidgets/defaultoperations.py +84 -48
  66. meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
  67. meerk40t/gui/themes.py +7 -1
  68. meerk40t/gui/tips.py +15 -1
  69. meerk40t/gui/toolwidgets/toolpointmove.py +3 -1
  70. meerk40t/gui/wxmeerk40t.py +26 -0
  71. meerk40t/gui/wxmmain.py +242 -114
  72. meerk40t/gui/wxmscene.py +180 -4
  73. meerk40t/gui/wxmtree.py +4 -2
  74. meerk40t/gui/wxutils.py +60 -15
  75. meerk40t/image/imagetools.py +130 -66
  76. meerk40t/internal_plugins.py +4 -0
  77. meerk40t/kernel/kernel.py +49 -22
  78. meerk40t/kernel/settings.py +29 -8
  79. meerk40t/lihuiyu/device.py +30 -12
  80. meerk40t/main.py +22 -5
  81. meerk40t/moshi/device.py +20 -6
  82. meerk40t/network/console_server.py +22 -6
  83. meerk40t/newly/device.py +10 -3
  84. meerk40t/newly/gui/gui.py +10 -0
  85. meerk40t/ruida/device.py +22 -2
  86. meerk40t/ruida/gui/gui.py +6 -6
  87. meerk40t/ruida/gui/ruidaoperationproperties.py +1 -10
  88. meerk40t/ruida/loader.py +6 -3
  89. meerk40t/ruida/rdjob.py +3 -3
  90. meerk40t/tools/geomstr.py +195 -39
  91. meerk40t/tools/rasterplotter.py +179 -93
  92. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/METADATA +1 -1
  93. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/RECORD +98 -96
  94. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/WHEEL +1 -1
  95. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/LICENSE +0 -0
  96. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/entry_points.txt +0 -0
  97. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/top_level.txt +0 -0
  98. {meerk40t-0.9.7020.dist-info → meerk40t-0.9.7040.dist-info}/zip-safe +0 -0
@@ -1,6 +1,6 @@
1
1
  import ast
2
- import os
3
2
  import configparser
3
+ import os
4
4
  from pathlib import Path
5
5
  from typing import Any, Dict, Generator, Optional, Union
6
6
 
@@ -22,7 +22,9 @@ class Settings:
22
22
 
23
23
  def __init__(self, directory, filename, ignore_settings=False, create_backup=False):
24
24
  if directory:
25
- self._config_file = Path(get_safe_path(directory, create=True)).joinpath(filename)
25
+ self._config_file = Path(get_safe_path(directory, create=True)).joinpath(
26
+ filename
27
+ )
26
28
  else:
27
29
  self._config_file = filename
28
30
  self._config_dict = {}
@@ -51,11 +53,20 @@ class Settings:
51
53
  PermissionError,
52
54
  configparser.NoSectionError,
53
55
  configparser.MissingSectionHeaderError,
56
+ configparser.ParsingError,
57
+ configparser.NoOptionError,
54
58
  FileNotFoundError,
55
59
  ):
56
60
  return
57
- except (configparser.DuplicateOptionError, configparser.DuplicateSectionError) as e:
58
- print (f"We had a duplication error in the config, try to recover from {e}")
61
+ except UnicodeDecodeError as e:
62
+ print(
63
+ "The config file contained unsupported characters, please share the file with the dev team"
64
+ )
65
+ except (
66
+ configparser.DuplicateOptionError,
67
+ configparser.DuplicateSectionError,
68
+ ) as e:
69
+ print(f"We had a duplication error in the config, try to recover from {e}")
59
70
  for section in parser.sections():
60
71
  for option in parser.options(section):
61
72
  try:
@@ -63,7 +74,12 @@ class Settings:
63
74
  except KeyError:
64
75
  config_section = {}
65
76
  self._config_dict[section] = config_section
66
- config_section[option] = parser.get(section, option)
77
+ try:
78
+ config_section[option] = parser.get(section, option)
79
+ except Exception as e:
80
+ print(
81
+ f"We had an error in the config, section {section}.{option}, try to recover from {e}"
82
+ )
67
83
 
68
84
  def write_configuration(self, targetfile=None):
69
85
  """
@@ -89,8 +105,13 @@ class Settings:
89
105
  except configparser.NoSectionError:
90
106
  parser.add_section(section_key)
91
107
  parser.set(section_key, key, value)
92
- except (configparser.DuplicateOptionError, configparser.DuplicateSectionError) as e:
93
- print (f"We had a duplication error in the config, try to recover from {e}")
108
+ except (
109
+ configparser.DuplicateOptionError,
110
+ configparser.DuplicateSectionError,
111
+ ) as e:
112
+ print(
113
+ f"We had a duplication error in the config, try to recover from {e}"
114
+ )
94
115
 
95
116
  if self.create_backup:
96
117
  VERSIONS = 5
@@ -123,7 +144,7 @@ class Settings:
123
144
  pass
124
145
  with open(targetfile, "w", encoding="utf-8") as fp:
125
146
  parser.write(fp)
126
- except (PermissionError, FileNotFoundError):
147
+ except (PermissionError, FileNotFoundError, OSError, RuntimeError):
127
148
  return
128
149
 
129
150
  def literal_dict(self):
@@ -5,19 +5,21 @@ Registers the Device service for M2 Nano (and family), registering the relevant
5
5
  the given device type.
6
6
  """
7
7
 
8
+ import platform
8
9
  from hashlib import md5
10
+
9
11
  import meerk40t.constants as mkconst
10
12
  from meerk40t.core.laserjob import LaserJob
11
13
  from meerk40t.core.spoolers import Spooler
14
+ from meerk40t.core.units import UNITS_PER_MIL, Length
12
15
  from meerk40t.core.view import View
16
+ from meerk40t.device.devicechoices import get_effect_choices
17
+ from meerk40t.device.mixins import Status
13
18
  from meerk40t.kernel import CommandSyntaxError, Service, signal_listener
14
19
 
15
- from ..core.units import UNITS_PER_MIL, Length
16
- from ..device.mixins import Status
17
20
  from .controller import LihuiyuController
18
21
  from .driver import LihuiyuDriver
19
22
  from .tcp_connection import TCPOutput
20
- from meerk40t.device.devicechoices import get_effect_choices
21
23
 
22
24
 
23
25
  class LihuiyuDevice(Service, Status):
@@ -147,9 +149,7 @@ class LihuiyuDevice(Service, Status):
147
149
  "label": _("Board"),
148
150
  "style": "combosmall",
149
151
  "choices": ["M2", "M3", "B2", "M", "M1", "A", "B", "B1"],
150
- "tip": _(
151
- "Select the board to use. This affects the speedcodes used."
152
- ),
152
+ "tip": _("Select the board to use. This affects the speedcodes used."),
153
153
  "section": "_10_" + _("Configuration"),
154
154
  "subsection": _("Board Setup"),
155
155
  },
@@ -372,8 +372,13 @@ class LihuiyuDevice(Service, Status):
372
372
  "type": bool,
373
373
  "label": _("Use legacy raster method"),
374
374
  "tip": (
375
- _("Active: Use legacy method (seems to work better at higher speeds, but has some artifacts)") + "\n" +
376
- _("Inactive: Use regular method (no artifacts but apparently more prone to stuttering at high speeds)")
375
+ _(
376
+ "Active: Use legacy method (seems to work better at higher speeds, but has some artifacts)"
377
+ )
378
+ + "\n"
379
+ + _(
380
+ "Inactive: Use regular method (no artifacts but apparently more prone to stuttering at high speeds)"
381
+ )
377
382
  ),
378
383
  "section": "_00_" + _("General Options"),
379
384
  "subsection": "_20_",
@@ -514,7 +519,10 @@ class LihuiyuDevice(Service, Status):
514
519
  self.setting(str, "serial", None)
515
520
  self.setting(bool, "serial_enable", False)
516
521
 
517
- self.setting(int, "port", 1022)
522
+ # Linux prevents ports below 1024 to be used in an non-root context
523
+ def_port = 1022 if platform.system() == "Windows" else "1025"
524
+
525
+ self.setting(int, "port", def_port)
518
526
  self.setting(str, "address", "localhost")
519
527
 
520
528
  self.driver = LihuiyuDriver(self)
@@ -978,6 +986,7 @@ class LihuiyuDevice(Service, Status):
978
986
  server = self.open_as("module/TCPServer", server_name, port=port)
979
987
  if quit:
980
988
  self.close(server_name)
989
+ channel(_("TCP Server for lihuiyu has been closed"))
981
990
  return
982
991
  channel(_("TCP Server for lihuiyu on port: {port}").format(port=port))
983
992
  if verbose:
@@ -1016,10 +1025,12 @@ class LihuiyuDevice(Service, Status):
1016
1025
  return {
1017
1026
  "split_crossover": True,
1018
1027
  "unsupported_opt": (
1019
- mkconst.RASTER_GREEDY_H, mkconst.RASTER_GREEDY_V, mkconst.RASTER_SPIRAL,
1028
+ mkconst.RASTER_GREEDY_H,
1029
+ mkconst.RASTER_GREEDY_V,
1030
+ mkconst.RASTER_SPIRAL,
1020
1031
  ), # Greedy loses registration way too often to be reliable
1021
- "gantry" : True,
1022
- "legacy" : self.legacy_raster,
1032
+ "gantry": True,
1033
+ "legacy": self.legacy_raster,
1023
1034
  }
1024
1035
 
1025
1036
  @property
@@ -1179,3 +1190,10 @@ class LihuiyuDevice(Service, Status):
1179
1190
 
1180
1191
  def cool_helper(self, choice_dict):
1181
1192
  self.kernel.root.coolant.coolant_choice_helper(self)(choice_dict)
1193
+
1194
+ def location(self):
1195
+ if self.mock:
1196
+ return "mock"
1197
+ if self.networked:
1198
+ return f"tcp {self.address}:{self.port}"
1199
+ return f"usb {'auto' if self.usb_index < 0 else self.usb_index}"
meerk40t/main.py CHANGED
@@ -11,7 +11,7 @@ import os.path
11
11
  import sys
12
12
 
13
13
  APPLICATION_NAME = "MeerK40t"
14
- APPLICATION_VERSION = "0.9.7020"
14
+ APPLICATION_VERSION = "0.9.7040"
15
15
 
16
16
  if not getattr(sys, "frozen", False):
17
17
  # If .git directory does not exist we are running from a package like pypi
@@ -151,6 +151,9 @@ parser.add_argument(
151
151
  action="store_true",
152
152
  help="start window maximized",
153
153
  )
154
+ parser.add_argument(
155
+ "-d", "--daemon", action="store_true", help="keep MeerK40t in background"
156
+ )
154
157
 
155
158
 
156
159
  def run():
@@ -220,12 +223,26 @@ def _exe(restarted, args):
220
223
  kernel.add_plugin(internal_plugins)
221
224
  kernel.add_plugin(external_plugins)
222
225
  auto = hasattr(kernel.args, "auto") and kernel.args.auto
226
+ command = hasattr(kernel.args, "execute") and kernel.args.execute
223
227
  console = hasattr(kernel.args, "console") and kernel.args.console
228
+ daemon = hasattr(kernel.args, "daemon") and kernel.args.daemon
229
+ server_mode = False
230
+ if command:
231
+ for c in command:
232
+ server_mode = server_mode or any(substring in c for substring in ("lhyserver", "grblserver", "ruidacontrol", "grblcontrol", "webserver"))
233
+ nogui = (
234
+ (hasattr(kernel.args, "gui_suppress") and kernel.args.gui_suppress) or
235
+ (hasattr(kernel.args, "no_gui") and kernel.args.no_gui)
236
+ )
224
237
  for idx, attrib in enumerate(("mktablength", "mktabpositions")):
225
238
  kernel.register(f"registered_mk_svg_parameters/tabs{idx}", attrib)
226
239
 
227
- if auto and not console:
228
- kernel(partial=True)
229
- else:
230
- kernel()
240
+ require_partial_mode = False
241
+ if (
242
+ (not console or nogui) and
243
+ (auto or daemon or server_mode)
244
+ ):
245
+ require_partial_mode = True
246
+ # print (f"Auto: {auto}, Command: {command}, Console: {console}, daemon: {daemon}, nogui:{nogui}, Server: {server_mode} -> {require_partial_mode}")
247
+ kernel(partial=require_partial_mode)
231
248
  return hasattr(kernel, "restart") and kernel.restart
meerk40t/moshi/device.py CHANGED
@@ -7,6 +7,7 @@ Registers relevant commands and options.
7
7
  """
8
8
  import meerk40t.constants as mkconst
9
9
  from meerk40t.core.view import View
10
+ from meerk40t.device.devicechoices import get_effect_choices
10
11
  from meerk40t.kernel import CommandSyntaxError, Service, signal_listener
11
12
 
12
13
  from ..core.laserjob import LaserJob
@@ -15,7 +16,6 @@ from ..core.units import Length
15
16
  from ..device.mixins import Status
16
17
  from .controller import MoshiController
17
18
  from .driver import MoshiDriver
18
- from meerk40t.device.devicechoices import get_effect_choices
19
19
 
20
20
 
21
21
  class MoshiDevice(Service, Status):
@@ -210,8 +210,13 @@ class MoshiDevice(Service, Status):
210
210
  "type": bool,
211
211
  "label": _("Use legacy raster method"),
212
212
  "tip": (
213
- _("Active: Use legacy method (seems to work better at higher speeds, but has some artifacts)") + "\n" +
214
- _("Inactive: Use regular method (no artifacts but apparently more prone to stuttering at high speeds)")
213
+ _(
214
+ "Active: Use legacy method (seems to work better at higher speeds, but has some artifacts)"
215
+ )
216
+ + "\n"
217
+ + _(
218
+ "Inactive: Use regular method (no artifacts but apparently more prone to stuttering at high speeds)"
219
+ )
215
220
  ),
216
221
  "section": "_20_Behaviour",
217
222
  },
@@ -485,11 +490,20 @@ class MoshiDevice(Service, Status):
485
490
  return {
486
491
  "split_crossover": True,
487
492
  "unsupported_opt": (
488
- mkconst.RASTER_GREEDY_H, mkconst.RASTER_GREEDY_V, mkconst.RASTER_SPIRAL,
493
+ mkconst.RASTER_GREEDY_H,
494
+ mkconst.RASTER_GREEDY_V,
495
+ mkconst.RASTER_SPIRAL,
489
496
  ), # Greedy loses registration way too often to be reliable
490
- "gantry" : True,
491
- "legacy" : self.legacy_raster,
497
+ "gantry": True,
498
+ "legacy": self.legacy_raster,
492
499
  }
493
500
 
494
501
  def cool_helper(self, choice_dict):
495
502
  self.kernel.root.coolant.coolant_choice_helper(self)(choice_dict)
503
+
504
+ def location(self):
505
+ return (
506
+ "mock"
507
+ if self.mock
508
+ else f"usb {'auto' if self.usb_index < 0 else self.usb_index}"
509
+ )
@@ -12,6 +12,13 @@ def plugin(kernel, lifecycle=None):
12
12
  action="store_true",
13
13
  help=_("do not watch server channels"),
14
14
  )
15
+ @kernel.console_option(
16
+ "suppress",
17
+ "u",
18
+ type=bool,
19
+ action="store_true",
20
+ help=_("suppress input prompt '>>'"),
21
+ )
15
22
  @kernel.console_option(
16
23
  "quit",
17
24
  "q",
@@ -23,8 +30,18 @@ def plugin(kernel, lifecycle=None):
23
30
  "consoleserver", help=_("starts a console_server on port 23 (telnet)")
24
31
  )
25
32
  def server_console(
26
- command, channel, _, port=23, silent=False, quit=False, **kwargs
33
+ command,
34
+ channel,
35
+ _,
36
+ port=23,
37
+ silent=False,
38
+ quit=False,
39
+ suppress=False,
40
+ **kwargs,
27
41
  ):
42
+ if suppress is None:
43
+ suppress = False
44
+ kernel.show_aio_prompt = not suppress
28
45
  root = kernel.root
29
46
  # Variable to store input
30
47
  root.__console_buffer = ""
@@ -42,9 +59,9 @@ def plugin(kernel, lifecycle=None):
42
59
  except (OSError, ValueError):
43
60
  channel(_("Server failed on port: {port}").format(port=port))
44
61
  return
45
-
62
+
46
63
  def exec_command(data: str) -> None:
47
- # We are in a different thread, so let's hand over stuff to the gui
64
+ # We are in a different thread, so let's hand over stuff to the gui
48
65
  if isinstance(data, bytes):
49
66
  try:
50
67
  data = data.decode()
@@ -60,7 +77,7 @@ def plugin(kernel, lifecycle=None):
60
77
  # No: we can split the command
61
78
  quotations = data.count('"', 0, idx)
62
79
  if quotations % 2 == 0:
63
- data = data[:idx].rstrip() + "\n" + data[idx+1:].lstrip()
80
+ data = data[:idx].rstrip() + "\n" + data[idx + 1 :].lstrip()
64
81
  start = idx + 1
65
82
  root.__console_buffer += data
66
83
  while "\n" in root.__console_buffer:
@@ -76,7 +93,7 @@ def plugin(kernel, lifecycle=None):
76
93
  for result in root.find("gui/handover"):
77
94
  # Do we have a thread handover routine?
78
95
  if result is not None:
79
- handover, _path, suffix_path = result
96
+ handover, _path, suffix_path = result
80
97
  break
81
98
  recv.watch(exec_command)
82
99
 
@@ -93,7 +110,6 @@ def plugin(kernel, lifecycle=None):
93
110
  console.watch(send)
94
111
  server.events_channel.watch(console)
95
112
 
96
-
97
113
  @kernel.console_option(
98
114
  "port", "p", type=int, default=2080, help=_("port to listen on.")
99
115
  )
meerk40t/newly/device.py CHANGED
@@ -5,10 +5,10 @@ from meerk40t.core.laserjob import LaserJob
5
5
  from meerk40t.core.spoolers import Spooler
6
6
  from meerk40t.core.units import Length
7
7
  from meerk40t.core.view import View
8
+ from meerk40t.device.devicechoices import get_effect_choices
8
9
  from meerk40t.device.mixins import Status
9
10
  from meerk40t.kernel import CommandSyntaxError, Service, signal_listener
10
11
  from meerk40t.newly.driver import NewlyDriver
11
- from meerk40t.device.devicechoices import get_effect_choices
12
12
 
13
13
 
14
14
  class NewlyDevice(Service, Status):
@@ -757,12 +757,16 @@ class NewlyDevice(Service, Status):
757
757
  help=_("Sets the default file index to use"),
758
758
  all_arguments_required=True,
759
759
  )
760
- def set_file_index(command, channel, _, file_index=None, data=None, remainder=None, **kwgs):
760
+ def set_file_index(
761
+ command, channel, _, file_index=None, data=None, remainder=None, **kwgs
762
+ ):
761
763
  old_value = self.file_index
762
764
  if file_index is None or file_index < 0 or file_index >= 10:
763
765
  file_index = 0
764
766
  self.file_index = file_index
765
- channel(f"File index was set to #{file_index} (previous value: {old_value})")
767
+ channel(
768
+ f"File index was set to #{file_index} (previous value: {old_value})"
769
+ )
766
770
  # Let propertypanels know that this value was updated
767
771
  self.signal("file_index", file_index, self)
768
772
 
@@ -856,6 +860,9 @@ class NewlyDevice(Service, Status):
856
860
  )
857
861
  self.signal("view;realized")
858
862
 
863
+ def location(self):
864
+ return "mock" if self.mock else "usb"
865
+
859
866
  @property
860
867
  def current(self):
861
868
  """
meerk40t/newly/gui/gui.py CHANGED
@@ -78,6 +78,7 @@ def plugin(service, lifecycle):
78
78
  "tip": _("File {index}").format(index=0),
79
79
  "help": "devicenewly",
80
80
  "action": lambda v: service("select_file 0\n"),
81
+ "multi_autoexec": True,
81
82
  },
82
83
  {
83
84
  "identifier": 1,
@@ -85,6 +86,7 @@ def plugin(service, lifecycle):
85
86
  "tip": _("File {index}").format(index=1),
86
87
  "help": "devicenewly",
87
88
  "action": lambda v: service("select_file 1\n"),
89
+ "multi_autoexec": True,
88
90
  },
89
91
  {
90
92
  "identifier": 2,
@@ -92,6 +94,7 @@ def plugin(service, lifecycle):
92
94
  "tip": _("File {index}").format(index=2),
93
95
  "help": "devicenewly",
94
96
  "action": lambda v: service("select_file 2\n"),
97
+ "multi_autoexec": True,
95
98
  },
96
99
  {
97
100
  "identifier": 3,
@@ -99,6 +102,7 @@ def plugin(service, lifecycle):
99
102
  "tip": _("File {index}").format(index=3),
100
103
  "help": "devicenewly",
101
104
  "action": lambda v: service("select_file 3\n"),
105
+ "multi_autoexec": True,
102
106
  },
103
107
  {
104
108
  "identifier": 4,
@@ -106,6 +110,7 @@ def plugin(service, lifecycle):
106
110
  "tip": _("File {index}").format(index=4),
107
111
  "help": "devicenewly",
108
112
  "action": lambda v: service("select_file 4\n"),
113
+ "multi_autoexec": True,
109
114
  },
110
115
  {
111
116
  "identifier": 5,
@@ -113,6 +118,7 @@ def plugin(service, lifecycle):
113
118
  "tip": _("File {index}").format(index=5),
114
119
  "help": "devicenewly",
115
120
  "action": lambda v: service("select_file 5\n"),
121
+ "multi_autoexec": True,
116
122
  },
117
123
  {
118
124
  "identifier": 6,
@@ -120,6 +126,7 @@ def plugin(service, lifecycle):
120
126
  "tip": _("File {index}").format(index=6),
121
127
  "help": "devicenewly",
122
128
  "action": lambda v: service("select_file 6\n"),
129
+ "multi_autoexec": True,
123
130
  },
124
131
  {
125
132
  "identifier": 7,
@@ -127,6 +134,7 @@ def plugin(service, lifecycle):
127
134
  "tip": _("File {index}").format(index=7),
128
135
  "help": "devicenewly",
129
136
  "action": lambda v: service("select_file 7\n"),
137
+ "multi_autoexec": True,
130
138
  },
131
139
  {
132
140
  "identifier": 8,
@@ -134,6 +142,7 @@ def plugin(service, lifecycle):
134
142
  "tip": _("File {index}").format(index=8),
135
143
  "help": "devicenewly",
136
144
  "action": lambda v: service("select_file 8\n"),
145
+ "multi_autoexec": True,
137
146
  },
138
147
  {
139
148
  "identifier": 9,
@@ -141,6 +150,7 @@ def plugin(service, lifecycle):
141
150
  "tip": _("File {index}").format(index=9),
142
151
  "help": "devicenewly",
143
152
  "action": lambda v: service("select_file 9\n"),
153
+ "multi_autoexec": True,
144
154
  },
145
155
  ],
146
156
  },
meerk40t/ruida/device.py CHANGED
@@ -5,6 +5,7 @@ Ruida device interfacing. We do not send or interpret ruida code, but we can emu
5
5
  ruida files (*.rd) and turn them likewise into cutcode.
6
6
  """
7
7
  from meerk40t.core.view import View
8
+ from meerk40t.device.devicechoices import get_effect_choices
8
9
  from meerk40t.kernel import CommandSyntaxError, Service, signal_listener
9
10
 
10
11
  from ..core.laserjob import LaserJob
@@ -16,7 +17,6 @@ from .mock_connection import MockConnection
16
17
  from .serial_connection import SerialConnection
17
18
  from .tcp_connection import TCPConnection
18
19
  from .udp_connection import UDPConnection
19
- from meerk40t.device.devicechoices import get_effect_choices
20
20
 
21
21
 
22
22
  class RuidaDevice(Service):
@@ -264,6 +264,7 @@ class RuidaDevice(Service):
264
264
  choice_dict["display"] = ["pyserial-not-installed"]
265
265
 
266
266
  from platform import system
267
+
267
268
  is_linux = system() == "Linux"
268
269
 
269
270
  choices = [
@@ -278,7 +279,7 @@ class RuidaDevice(Service):
278
279
  "section": "_10_Serial Interface",
279
280
  "subsection": "_00_",
280
281
  "dynamic": update,
281
- "exclusive": not is_linux,
282
+ "exclusive": not is_linux,
282
283
  },
283
284
  {
284
285
  "attr": "baud_rate",
@@ -581,6 +582,25 @@ class RuidaDevice(Service):
581
582
  name = self.label.replace(" ", "-")
582
583
  return name.replace("/", "-")
583
584
 
585
+ @property
586
+ def tcp_address(self):
587
+ return self.address
588
+
589
+ @property
590
+ def tcp_port(self):
591
+ return 5005
592
+
593
+ def location(self):
594
+ if self.interface == "mock":
595
+ return "mock"
596
+ elif self.interface == "udp":
597
+ return "udp, port 40200"
598
+ elif self.interface == "tcp":
599
+ return f"tcp {self.tcp_address}:{self.tcp_port}"
600
+ elif self.interface == "usb":
601
+ return f"usb: {self.serial_port}"
602
+ return f"undefined {self.interface}"
603
+
584
604
  @property
585
605
  def has_endstops(self):
586
606
  return True
meerk40t/ruida/gui/gui.py CHANGED
@@ -48,7 +48,7 @@ def plugin(service, lifecycle):
48
48
 
49
49
  from meerk40t.ruida.gui.ruidaconfig import RuidaConfiguration
50
50
  from meerk40t.ruida.gui.ruidacontroller import RuidaController
51
- from meerk40t.ruida.gui.ruidaoperationproperties import RuidaOperationPanel
51
+ # from meerk40t.ruida.gui.ruidaoperationproperties import RuidaOperationPanel
52
52
 
53
53
  service.register("window/Controller", RuidaController)
54
54
  service.register("window/Configuration", RuidaConfiguration)
@@ -56,11 +56,11 @@ def plugin(service, lifecycle):
56
56
  service.register("winpath/Controller", service)
57
57
  service.register("winpath/Configuration", service)
58
58
 
59
- service.register("property/RasterOpNode/Ruida", RuidaOperationPanel)
60
- service.register("property/CutOpNode/Ruida", RuidaOperationPanel)
61
- service.register("property/EngraveOpNode/Ruida", RuidaOperationPanel)
62
- service.register("property/ImageOpNode/Ruida", RuidaOperationPanel)
63
- service.register("property/DotsOpNode/Ruida", RuidaOperationPanel)
59
+ # service.register("property/RasterOpNode/Ruida", RuidaOperationPanel)
60
+ # service.register("property/CutOpNode/Ruida", RuidaOperationPanel)
61
+ # service.register("property/EngraveOpNode/Ruida", RuidaOperationPanel)
62
+ # service.register("property/ImageOpNode/Ruida", RuidaOperationPanel)
63
+ # service.register("property/DotsOpNode/Ruida", RuidaOperationPanel)
64
64
 
65
65
  service.add_service_delegate(RuidaGui(service))
66
66
 
@@ -17,16 +17,7 @@ class RuidaOperationPanel(ScrolledPanel):
17
17
  self.parent = args[0]
18
18
  self.operation = node
19
19
 
20
- choices = [
21
- {
22
- "attr": "air_assist",
23
- "object": node,
24
- "default": True,
25
- "type": bool,
26
- "label": _("Air Assist"),
27
- "tip": _("Trigger the per element air assist"),
28
- },
29
- ]
20
+ choices = []
30
21
 
31
22
  self.panel = ChoicePropertyPanel(
32
23
  self, wx.ID_ANY, context=self.context, choices=choices, scrolling=False
meerk40t/ruida/loader.py CHANGED
@@ -26,10 +26,13 @@ def command_viewer(data, data_type):
26
26
 
27
27
  job = RDJob()
28
28
  job.write_blob(data)
29
- commands = list()
29
+ commands = []
30
30
  job.channel = commands.append
31
- while not job.execute(None):
32
- pass
31
+ try:
32
+ while not job.execute(None):
33
+ pass
34
+ except Exception as e:
35
+ commands.append(f"!! Error !!: {e}")
33
36
  return "\n".join(commands)
34
37
 
35
38
 
meerk40t/ruida/rdjob.py CHANGED
@@ -1376,13 +1376,13 @@ class RDJob:
1376
1376
  part = current_settings.get("part", 0)
1377
1377
  speed = current_settings.get("speed", 0)
1378
1378
  power = current_settings.get("power", 0) / 10.0
1379
- air = current_settings.get("air_assist", True)
1379
+ air = current_settings.get("coolant", 0)
1380
1380
  self.layer_end()
1381
1381
  self.layer_number_part(part)
1382
1382
  self.laser_device_0()
1383
- if air:
1383
+ if air == 1:
1384
1384
  self.air_assist_on()
1385
- else:
1385
+ elif air==2:
1386
1386
  self.air_assist_off()
1387
1387
  self.speed_laser_1(speed)
1388
1388
  self.laser_on_delay(0)