Skip to content

Commit

Permalink
Merge pull request #1860 from OpenC3/py_expression
Browse files Browse the repository at this point in the history
Document using globals() in python expressions
  • Loading branch information
jmthomas authored Jan 28, 2025
2 parents b2797b6 + c251df4 commit 6de3c5c
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 67 deletions.
176 changes: 127 additions & 49 deletions docs.openc3.com/docs/guides/scripting-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ Prompts the user for input with a question. User input is automatically converte
Ruby / Python Syntax:

```ruby
ask("<question>", <blank_or_default>, <password>)
ask("<question>", <Blank or Default>, <Password>)
```

| Parameter | Description |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| question | Question to prompt the user with. |
| blank_or_default | Whether or not to allow empty responses (optional - defaults to false). If a non-boolean value is passed it is used as a default value. |
| password | Whether to treat the entry as a password which is displayed with dots and not logged. Default is false. |
| Blank or Default | Whether or not to allow empty responses (optional - defaults to false). If a non-boolean value is passed it is used as a default value. |
| Password | Whether to treat the entry as a password which is displayed with dots and not logged. Default is false. |

Ruby Example:

Expand All @@ -186,14 +186,14 @@ Prompts the user for input with a question. User input is always returned as a s
Ruby / Python Syntax:

```ruby
ask_string("<question>", <blank_or_default>, <password>)
ask_string("<question>", <Blank or Default>, <Password>)
```

| Parameter | Description |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| question | Question to prompt the user with. |
| blank_or_default | Whether or not to allow empty responses (optional - defaults to false). If a non-boolean value is passed it is used as a default value. |
| password | Whether to treat the entry as a password which is displayed with dots and not logged. Default is false. |
| Blank or Default | Whether or not to allow empty responses (optional - defaults to false). If a non-boolean value is passed it is used as a default value. |
| Password | Whether to treat the entry as a password which is displayed with dots and not logged. Default is false. |

Ruby Example:

Expand Down Expand Up @@ -224,15 +224,15 @@ The message_box, vertical_message_box, and combo_box methods create a message bo
Ruby / Python Syntax:

```ruby
message_box("<message>", "<button text 1>", ...)
vertical_message_box("<message>", "<button text 1>", ...)
combo_box("<message>", "<selection text 1>", ...)
message_box("<Message>", "<button text 1>", ...)
vertical_message_box("<Message>", "<button text 1>", ...)
combo_box("<Message>", "<selection text 1>", ...)
```

| Parameter | Description |
| --------------------- | -------------------------------- |
| message | Message to prompt the user with. |
| button/selection text | Text for a button or selection |
| Message | Message to prompt the user with. |
| Button/Selection Text | Text for a button or selection |

Ruby Example:

Expand Down Expand Up @@ -279,7 +279,7 @@ get_target_file("<File Path>", original=False)

| Parameter | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb |
| File Path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb |
| original | Whether to get the original file from the plug-in, or any modifications to the file. Default is false which means to grab the modified file. If the modified file does not exist the API will automatically try to pull the original. |

Ruby Example:
Expand Down Expand Up @@ -316,10 +316,10 @@ Ruby or Python Syntax:
put_target_file("<File Path>", "IO or String")
```

| Parameter | Description |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb. The file can previously exist or not. Note: The original file from the plug-in will not be modified, however existing modified files will be overwritten. |
| data | The data can be an IO object or String |
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| File Path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb. The file can previously exist or not. Note: The original file from the plug-in will not be modified, however existing modified files will be overwritten. |
| IO or String | The data can be an IO object or String |

Ruby Example:

Expand Down Expand Up @@ -355,7 +355,7 @@ delete_target_file("<File Path>")

| Parameter | Description |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb. Note: Only files created with put_target_file can be deleted. Original files from the plugin installation will remain. |
| File Path | The path to the file in the target directory. Should assume to start with a TARGET name, e.g. INST/procedures/proc.rb. Note: Only files created with put_target_file can be deleted. Original files from the plugin installation will remain. |

Ruby / Python Example:

Expand All @@ -375,15 +375,15 @@ Note: COSMOS 5 has deprecated the save_file_dialog and open_directory_dialog met
Ruby Syntax:

```ruby
open_file_dialog("<title>", "<message>", filter: "<filter>")
open_files_dialog("<title>", "<message>", filter: "<filter>")
open_file_dialog("<Title>", "<Message>", filter: "<filter>")
open_files_dialog("<Title>", "<Message>", filter: "<filter>")
```

Python Syntax:

```python
open_file_dialog("<title>", "<message>", filter="<filter>")
open_files_dialog("<title>", "<message>", filter="<filter>")
open_file_dialog("<Title>", "<Message>", filter="<filter>")
open_files_dialog("<Title>", "<Message>", filter="<filter>")
```

| Parameter | Description |
Expand Down Expand Up @@ -436,12 +436,12 @@ Displays a message to the user and waits for them to press an ok button.
Ruby / Python Syntax:

```ruby
prompt("<message>")
prompt("<Message>")
```

| Parameter | Description |
| --------- | -------------------------------- |
| message | Message to prompt the user with. |
| Message | Message to prompt the user with. |

Ruby / Python Example:

Expand Down Expand Up @@ -1213,22 +1213,40 @@ This evaluates to `yes == 'yes'` which is not valid syntax because the variable

Now this evaluates to `'yes' == 'yes'` which is true so the check passes.

Ruby / Python Syntax:
Ruby Syntax:

```ruby
check_expression("<Expression>")
check_expression(exp_to_eval, context = nil)
```

| Parameter | Description |
| ---------- | -------------------------- |
| Expression | An expression to evaluate. |
Python Syntax:

Ruby / Python Example:
```python
check_expression(exp_to_eval, globals=None, locals=None)
```

| Parameter | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| exp_to_eval | An expression to evaluate. |
| context (ruby only) | The context to call eval with. Defaults to nil. Context in Ruby is typically binding() and is usually not needed. |
| globals (python only) | The globals to call eval with. Defaults to None. Note that to use COSMOS APIs like tlm() you must pass globals(). |
| locals (python only) | The locals to call eval with. Defaults to None. Note that if you're using local variables in a method you must pass locals(). |

Ruby Example:

```ruby
check_expression("tlm('INST HEALTH_STATUS COLLECTS') > 5 and tlm('INST HEALTH_STATUS TEMP1') > 25.0")
```

Python Example:

```python
def check(value):
# Here we using both tlm() and a local 'value' so we need to pass globals() and locals()
check_expression("tlm('INST HEALTH_STATUS COLLECTS') > value", 5, 0.25, globals(), locals())
check(5)
```

### check_exception

Executes a method and expects an exception to be raised. If the method does not raise an exception, a CheckError is raised.
Expand Down Expand Up @@ -1914,24 +1932,56 @@ success = wait_tolerance("INST HEALTH_STATUS COLLECTS", 10.0, 5.0, 10, type='RAW

Pauses the script until an expression is evaluated to be true or a timeout occurs. If a timeout occurs the script will continue. This method can be used to perform more complicated comparisons than using wait as shown in the example. Note that on a timeout, wait_expression does not stop the script, usually [wait_check_expression](#wait_check_expression) is a better choice.

Syntax:
Ruby Syntax:

```ruby
# Returns true or false based on the whether the expression is true or false
success = wait_expression("<Expression>", <Timeout>, <Polling Rate (optional)>, quiet)
# Return true or false based the expression evaluation
wait_expression(
exp_to_eval,
timeout,
polling_rate = DEFAULT_TLM_POLLING_RATE,
context = nil,
quiet: false
) -> boolean
```

| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| Expression | A ruby expression to evaluate. |
| Timeout | Timeout in seconds. Script will proceed if the wait statement times out waiting for the comparison to be true. |
| Polling Rate | How often the comparison is evaluated in seconds. Defaults to 0.25 if not specified. |
| quiet | Named parameter indicating whether to log the result. Defaults to true. |
Python Syntax:

Ruby / Python Example:
```python
# Return True or False based on the expression evaluation
wait_expression(
exp_to_eval,
timeout,
polling_rate=DEFAULT_TLM_POLLING_RATE,
globals=None,
locals=None,
quiet=False,
) -> bool
```

| Parameter | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| expression | An expression to evaluate. |
| timeout | Timeout in seconds. Script will proceed if the wait statement times out waiting for the comparison to be true. |
| polling_rate | How often the comparison is evaluated in seconds. Defaults to 0.25 if not specified. |
| context (ruby only) | The context to call eval with. Defaults to nil. Context in Ruby is typically binding() and is usually not needed. |
| globals (python only) | The globals to call eval with. Defaults to None. Note that to use COSMOS APIs like tlm() you must pass globals(). |
| locals (python only) | The locals to call eval with. Defaults to None. Note that if you're using local variables in a method you must pass locals(). |
| quiet | Whether to log the result. Defaults to false which means to log. |

Ruby Example:

```ruby
success = wait_expression("tlm('INST HEALTH_STATUS COLLECTS') > 5 and tlm('INST HEALTH_STATUS TEMP1') > 25.0", 10)
success = wait_expression("tlm('INST HEALTH_STATUS COLLECTS') > 5 and tlm('INST HEALTH_STATUS TEMP1') > 25.0", 10, 0.25, nil, quiet: true)
```

Python Example:

```python
def check(value):
# Here we using both tlm() and a local 'value' so we need to pass globals() and locals()
return wait_expression("tlm('INST HEALTH_STATUS COLLECTS') > value", 5, 0.25, globals(), locals(), quiet=True)
success = check(5)
```

### wait_packet
Expand Down Expand Up @@ -2035,25 +2085,53 @@ elapsed = wait_check_tolerance("INST HEALTH_STATUS COLLECTS", 10.0, 5.0, 10, typ

Pauses the script until an expression is evaluated to be true or a timeout occurs. If a timeout occurs the script will stop. This method can be used to perform more complicated comparisons than using wait as shown in the example. Also see the syntax notes for [check_expression](#check_expression).

Ruby / Python Syntax:
Ruby Syntax:

```ruby
# Returns the amount of time elapsed waiting for the expression
elapsed = wait_check_expression("<Expression>", <Timeout>, <Polling Rate (optional)>)
# Return time spent waiting for the expression to evaluate to true
wait_check_expression(
exp_to_eval,
timeout,
polling_rate = DEFAULT_TLM_POLLING_RATE,
context = nil
) -> int
```

Python Syntax:

```python
# Return time spent waiting for the expression to evaluate to True
wait_check_expression(
exp_to_eval,
timeout,
polling_rate=DEFAULT_TLM_POLLING_RATE,
globals=None,
locals=None
) -> int
```

| Parameter | Description |
| ------------ | ----------------------------------------------------------------------------------------------------------- |
| Expression | A ruby expression to evaluate. |
| Timeout | Timeout in seconds. Script will stop if the wait statement times out waiting for the comparison to be true. |
| Polling Rate | How often the comparison is evaluated in seconds. Defaults to 0.25 if not specified. |
| Parameter | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| expression | An expression to evaluate. |
| timeout | Timeout in seconds. Script will proceed if the wait statement times out waiting for the comparison to be true. |
| polling_rate | How often the comparison is evaluated in seconds. Defaults to 0.25 if not specified. |
| context (ruby only) | The context to call eval with. Defaults to nil. Context in Ruby is typically binding() and is usually not needed. |
| globals (python only) | The globals to call eval with. Defaults to None. Note that to use COSMOS APIs like tlm() you must pass globals(). |
| locals (python only) | The locals to call eval with. Defaults to None. Note that if you're using local variables in a method you must pass locals(). |

Ruby / Python Example:
Ruby Example:

```ruby
elapsed = wait_check_expression("tlm('INST HEALTH_STATUS COLLECTS') > 5 and tlm('INST HEALTH_STATUS TEMP1') > 25.0", 10)
```

Python Example:

```python
# Note that for Python we need to pass globals() to be able to use COSMOS API methods like tlm()
elapsed = wait_check_expression("tlm('INST HEALTH_STATUS COLLECTS') > 5 and tlm('INST HEALTH_STATUS TEMP1') > 25.0", 10, 0.25, globals())
```

### wait_check_packet

Pauses the script until a certain number of packets have been received. If a timeout occurs the script will stop.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
wait_packet("<%= target_name %>","ADCS", 2, 5)
wait_check("<%= target_name %> ADCS BIASX == 100", 5)
wait_check_tolerance("<%= target_name %> ADCS BIASX", 5, 0.5, 5)
wait_check_expression("true == false", 5)
wait_check_expression("tlm('<%= target_name %> HEALTH_STATUS TEMP1') < 101", 5, 0.25)
wait_check_packet("<%= target_name %>","ADCS", 2, 5)
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
wait_packet("<%= target_name %>", "ADCS", 2, 5)
wait_check("<%= target_name %> ADCS BIASX == 100", 5)
wait_check_tolerance("<%= target_name %> ADCS BIASX", 5, 0.5, 5)
wait_check_expression("True == False", 5)
wait_check_expression(f"tlm('<%= target_name %> HEALTH_STATUS TEMP1') < 101", 5, 0.25, globals())
wait_check_packet("<%= target_name %>", "ADCS", 2, 5)
Loading

0 comments on commit 6de3c5c

Please sign in to comment.