-
Notifications
You must be signed in to change notification settings - Fork 51
New methods for Handler and SharedPV #172
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
Draft
Monarda
wants to merge
15
commits into
epics-base:master
Choose a base branch
from
Monarda:new_handler_methods
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
58e5c65
New Handler and SharedPV methods with example
Monarda cfe99a1
Small improvements to structure and commenting of example code
Monarda e6c0df0
Implemented changes suggested in #172
Monarda 6cb32f4
Added new example for #172
Monarda c57723d
Remove unnecessary kwargs
Monarda 2e9e6bc
Fix examples based on previous commits, fix persist.put
Monarda 09b11ba
Improve formating and status messages
Monarda 0601bcf
Fix put so that account and peer info is recorded
Monarda 7c602e9
Merge branch 'epics-base:master' into new_handler_methods
Monarda 45b3df5
Add basic unit tests for new Handler and SharedPV open, close, and post
Monarda 9e1347c
Merge branch 'epics-base:master' into new_handler_methods
Monarda c38b8be
Simplify examples
Monarda 8ffedfa
Handle put and post changing control limits
Monarda feb7a5c
Forgot to remove some diagnostic prints
Monarda 8ab03fe
Merge branch 'epics-base:master' into new_handler_methods
Monarda File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| """ | ||
| Demonstrate a Handler which uses open() and post() to apply control.limits | ||
| to a pair of PVs. | ||
| Run the program and use | ||
| - `pvget demo:limit_open` to verify that although the initial value was set | ||
| to 14 the control.limitHigh means that it is set to 10. | ||
| - `pvmonitor demo:limit_post` to see the behaviour of a PV with control limits | ||
| set to restrict values to >=3 and <=7 as a post() sweeps it between 0 and 10. | ||
| - `pvput demo:limit_open control.limitHigh=5` to see that changing the control | ||
| limits is correctly supported. | ||
| """ | ||
|
|
||
| import time | ||
|
|
||
| from p4p import Value | ||
| from p4p.nt.scalar import NTScalar | ||
| from p4p.server import Server, ServerOperation | ||
| from p4p.server.raw import Handler | ||
| from p4p.server.thread import SharedPV | ||
|
|
||
|
|
||
| class LimitsHandler(Handler): | ||
| """ | ||
| A handler which applies the control.limits to a PV. | ||
| """ | ||
|
|
||
| def _eval_limits(self, value: Value): | ||
| """Check the value against the control.limits and adjust if necessary.""" | ||
|
|
||
| # Have "control.limitHigh" and "control.limitLow" been set? If they have | ||
| # then the changed flag will be set and we can use the value. If they | ||
| # haven't then the changed flag will not be set, they will have a default | ||
| # value of 0, and we shouldn't use them to test the value. | ||
|
|
||
| limit_high = value.get("control.limitHigh") | ||
| if ( | ||
| limit_high is not None | ||
| and value.changed("control.limitHigh") | ||
| and value["value"] > limit_high | ||
| ): | ||
| # print(f"Value {value['value']} is above the high limit of {limit_high}, setting to {limit_high}") | ||
| value["value"] = limit_high | ||
|
|
||
| limit_low = value.get("control.limitLow") | ||
| if ( | ||
| limit_low is not None | ||
| and value.changed("control.limitLow") | ||
| and value["value"] < limit_low | ||
| ): | ||
| # print(f"Value {value['value']} is below the low limit of {limit_low}, setting to {limit_low}") | ||
| value["value"] = limit_low | ||
|
|
||
| def open(self, value: Value): | ||
| """Check any initial value against the limits.""" | ||
| self._eval_limits(value) | ||
|
|
||
| def post(self, pv: SharedPV, value: Value): | ||
| """Check changes to the value against the limits.""" | ||
|
|
||
| # The value and control limits we need to evaluate are shared between | ||
| # the pv and the value. We need to check which fields are most current | ||
| # (value takes precedence) and set them in the value variable | ||
| # approppriately. | ||
| pv_value: Value = pv.current().raw | ||
| self._merge_field(value, pv_value, "value") | ||
| self._merge_field(value, pv_value, "control.limitHigh") | ||
| self._merge_field(value, pv_value, "control.limitLow") | ||
|
|
||
| self._eval_limits(value) | ||
|
|
||
| def _merge_field(self, value: Value, pv_value: Value, field: str): | ||
| if not value.changed(field) and pv_value.changed(field): | ||
| value[field] = pv_value[field] | ||
|
|
||
| def put(self, pv: SharedPV, op: ServerOperation): | ||
| """Allow puts by simply forwarding to the post and invoking the associated handler.""" | ||
|
|
||
| pv.post(op.value()) | ||
| op.done() | ||
|
|
||
|
|
||
| def main(): | ||
| """ | ||
| Create a pvaServer with two PVs with limits. | ||
| """ | ||
|
|
||
| # Construct a PV with a high limit of 10, but an initial value of 14. | ||
| # The handler will be responsible for enforcing the limit and ensuring | ||
| # that the value is set to 10 instead of 14. | ||
| open_pv = SharedPV( | ||
| nt=NTScalar("i", control=True), | ||
| handler=LimitsHandler(), | ||
| initial={ | ||
| "value": 14, | ||
| "control.limitHigh": 10, | ||
| }, | ||
| ) | ||
|
|
||
| # Construct a PV starting within its limit but which we will use posts | ||
| # to step within a range of 0 to 10 every second. Observe the behaviour | ||
| # with a pvmonitor. | ||
| value = 5 | ||
| post_pv = SharedPV( | ||
| nt=NTScalar("i", control=True), | ||
| handler=LimitsHandler(), | ||
| initial={ | ||
| "value": value, | ||
| "control.limitLow": 3, | ||
| "control.limitHigh": 7, | ||
| }, | ||
| ) | ||
|
|
||
| pvs = {"demo:limit_open": open_pv, "demo:limit_post": post_pv} | ||
|
|
||
| server = None | ||
| try: | ||
| server = Server(providers=[pvs]) | ||
| while True: | ||
| time.sleep(1) | ||
| value = value + 1 | ||
| if value > 10: | ||
| value = 0 | ||
| # post_pv.post(value) | ||
| except KeyboardInterrupt: | ||
| pass | ||
| finally: | ||
| for pv in pvs.values(): | ||
| pv.close() | ||
| if server: | ||
| server.stop() | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.