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

Improved Example #19

Open
wants to merge 5 commits into
base: v3.6-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 38 additions & 2 deletions examples/custom_m_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@
from dsf.commands.code import CodeType
from dsf.object_model import MessageType

# needed to resolve meta variables
from dsf.connections import CommandConnection
from dsf.commands.generic import evaluate_expression


# function to ask RRF to resolve a meta variable
def eval_expr( meta_var, channel):
command_connection = CommandConnection(debug=True)
command_connection.connect()

try:
res = command_connection.perform_command(evaluate_expression( channel, meta_var ))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have to use perform_command. You should rather use command_connection.evaluate_expression directly as evaluate_expression is a method of BaseCommandConnection. See https://github.com/vicimikec/dsf-python/blob/main/src/dsf/connections/base_command_connection.py#L56

It may also be possible to pass the intercept connection as parameter of eval_expr function so you won't have to open another connection to send that command.

result = res.result
print(f"Evaluated expression: {result}")
finally:
command_connection.close()

return result
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result will be undefined if there is an exception triggered above. You have to define result = 1 before the try...finallyclause.

Copy link
Author

@vicimikec vicimikec Apr 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Problem there is that 1 is a valid return value even though the function failed. Would it be better to set this to False or None? I will be honest Python is not my strongest programming language so I am not sure what the convention of indicating a failure in these instances is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set it to None. If something fails, an exception will be thrown anyway



def start_intercept():
filters = ["M1234", "M5678", "M7722"]
Expand Down Expand Up @@ -50,10 +69,27 @@ def start_intercept():
# Exit this example
return
elif cde.type == CodeType.MCode and cde.majorNumber == 7722:
if cde.parameter("S") is None :
# if there isnt an S parameter set minutes to 1
minutes = "1"
elif cde.parameter("S").is_expression :
# if there is an S parameter and it is an expression
# resolve the expression and set minutes equal to it
minutes = eval_expr( cde.parameter("S").string_value, cde.channel )
else :
# if there is an S parameter and it isnt an expression
# set minutes to it
minutes = cde.parameter("S").string_value

# add a + to the beginning of minutes
min_plus = "+" + str(minutes)

# We are going to shut down the SBC in one minute
subprocess.run(["sudo", "shutdown", "+1"])
subprocess.run(["sudo", "shutdown", min_plus])

# Resolve it with a custom response message text
intercept_connection.resolve_code(MessageType.Warn, "Shutting down SBC in 1min...")
warn_msg = "Shutting down SBC in " + str(minutes) + "min..."
intercept_connection.resolve_code(MessageType.Warning, warn_msg)
else:
# We did not handle it so we ignore it and it will be continued to be processed
intercept_connection.ignore_code()
Expand Down
4 changes: 2 additions & 2 deletions src/dsf/commands/code_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, letter: str, value, isString: bool = None, isDriverId: bool =
self.letter = letter
self.string_value = str(value)
self.__parsed_value = value
self.is_expression = self.string_value.startswith("{}") and self.string_value.endswith("}")
self.is_expression = self.string_value.startswith("{") and self.string_value.endswith("}")
return

self.letter = letter
Expand All @@ -60,7 +60,7 @@ def __init__(self, letter: str, value, isString: bool = None, isDriverId: bool =
# Empty parameters are represented as integers with the value 0 (e.g. G92 XY => G92 X0 Y0)
if not value:
self.__parsed_value = 0
elif value.startswith("{}") and value.endswith("}"): # It is an expression
elif value.startswith("{") and value.endswith("}"): # It is an expression
self.is_expression = True
self.__parsed_value = value
elif ":" in value: # It is an array (or a string)
Expand Down