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

Implement RDM_PID_SUPPORTED_PARAMETERS #90

Merged

Conversation

arneboe
Copy link
Contributor

@arneboe arneboe commented Aug 19, 2023

I want to support more parameters, to be able to do that the PID_SUPPORTED_PARAMETERS must be supported.
This is implemented by this PR.
I am not sure that this is the best way to do it. Please feel free to point out any mistakes or strange things. I am not very familiar with your code base and might have overlooked a more obvious solution.

This requires #89 to be merged first

On top of this, I am currently implementing support for PID_DMX_PERSONALITY and will provide a PR within the next 1-2 days :)

@someweisguy
Copy link
Owner

Thanks for submitting this! Adding support for RDM_PID_SUPPORTED_PARAMETERS is on my to-do list. It is a feature that, in my estimation, is a bit of an edge case so I am thrilled to get some more input from others on how it should be implemented.

As I'm sure you're aware, RDM_PID_SUPPORTED_PARAMETERS interacts with the RDM sub-devices of an RDM responder. RDM responders should send a different response to an RDM_PID_SUPPORTED_PARAMETERS request depending on which sub-device is queried. After considerable thought about the design of this library, I decided that the functions in rdm/responder.h such as rdm_register_device_info() should only support registering the RDM_PID_DEVICE_INFO parameter for the RDM root device. In other words, it is not possible to create an RDM responder which supports the use of sub-devices using functions in rdm/responder.h. The reason for this choice was to make it easier for users to create their own RDM responder; sub-devices would be completely abstracted away from the user. The function rdm_register_parameter() in rdm_utils.h does take a sub_device argument. If an advanced user (such as yourself 😄) wanted to create an RDM responder which supported multiple sub-devices, they would be able to do so by calling this function directly.

The design I had in mind for RDM_PID_SUPPORTED_PARAMETERS was to add two arrays to the dmx_driver_t struct found in dmx/struct.h. One array would contain all the PIDs supported by the root device, and the other array would contain all the PIDs supported by sub-devices. The callback function for RDM_PID_SUPPORTED_PARAMETERS would iterate one of these arrays and emplace the PIDs into the RDM response. PIDs would be added to the appropriate array when rdm_register_parameter() was called.

I haven't looked closely at this PR yet, so if any of this is repetitive, I apologize! I'll review your code and mark it up with notes which hopefully explain the above a bit more clearly.

Copy link
Owner

@someweisguy someweisguy left a comment

Choose a reason for hiding this comment

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

Excellent work! Please let me know your thoughts! :)

src/dmx/config.h Outdated
Comment on lines 68 to 74
#define RDM_RESPONDER_PIDS_MAX (8 + 16)
#endif

/** @brief The maximum number of additional parameters that is supported.
*
* According to ANSI-E1-20-2010 we can support up to 115 additional parameters.
* In practice we will never need that many, thus we limit it to save memory.
*/
#define RDM_MAX_NUM_ADDITIONAL_PARAMETERS 25

Copy link
Owner

Choose a reason for hiding this comment

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

The way I had designed this library, I had intended RDM_RESPONDER_PIDS_MAX to be the only macro needed to describe the number of supported RDM parameters. Upon reviewing this PR, it now seems like it makes more sense to do it the way you've written it and have two separate macros: RDM_RESPONDER_NUM_PIDS_REQUIRED (which would evaluate to 9 instead of 8) and RDM_RESPONDER_NUM_PIDS_OPTIONAL. The maximum supported number of PIDs would then be RDM_RESPONDER_NUM_PIDS_REQUIRED + RDM_RESPONDER_NUM_PIDS_OPTIONAL. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds fine.

src/rdm/responder.c Outdated Show resolved Hide resolved
src/rdm/responder.c Outdated Show resolved Hide resolved
src/rdm/responder.c Outdated Show resolved Hide resolved
src/rdm_utils.c Outdated Show resolved Hide resolved
src/dmx/config.h Outdated Show resolved Hide resolved
@arneboe
Copy link
Contributor Author

arneboe commented Aug 19, 2023

As I'm sure you're aware, RDM_PID_SUPPORTED_PARAMETERS interacts with the RDM sub-devices of an RDM responder. RDM responders should send a different response to an RDM_PID_SUPPORTED_PARAMETERS request depending on which sub-device is queried. After considerable thought about the design of this library, I decided that the functions in rdm/responder.h such as rdm_register_device_info() should only support registering the RDM_PID_DEVICE_INFO parameter for the RDM root device. In other words, it is not possible to create an RDM responder which supports the use of sub-devices using functions in rdm/responder.h. The reason for this choice was to make it easier for users to create their own RDM responder; sub-devices would be completely abstracted away from the user. The function rdm_register_parameter() in rdm_utils.h does take a sub_device argument. If an advanced user (such as yourself 😄) wanted to create an RDM responder which supported multiple sub-devices, they would be able to do so by calling this function directly.

I have not put much thought into sub-devices. I just skimmed the part of the specification that deals with sub-devices and am not really sure what to make of it. I have never seen a dmx fixture in the real world that supports this (to be fair I have seen very little fixtures that do support rdm at all).

For my use case the root device hast to support RDM_PID_SUPPORTED_PARAMETERS because of the personalities.
Personalities are a property of the root device. But the getters/setters for personality and personality_description are optional. For optional parameters the rdm master queries RDM_PID_SUPPORTED_PARAMETERS to figure out which parameters are supported. Thus without RDM_PID_SUPPORTED_PARAMETERS on the root level the rdm master will not offer the ability to change the personality to the user (at least my dmx tester behaves that way).

The design I had in mind for RDM_PID_SUPPORTED_PARAMETERS was to add two arrays to the dmx_driver_t struct found in dmx/struct.h. One array would contain all the PIDs supported by the root device, and the other array would contain all the PIDs supported by sub-devices. The callback function for RDM_PID_SUPPORTED_PARAMETERS would iterate one of these arrays and emplace the PIDs into the RDM response. PIDs would be added to the appropriate array when rdm_register_parameter() was called.

That makes perfect sense if rdm_register_parameter() is exposed to the user.

@arneboe
Copy link
Contributor Author

arneboe commented Aug 19, 2023

Thanks for the very detailed answers :) I really appreciate it :)
I will update the PR tomorrow. Too late now :D

@arneboe arneboe force-pushed the rdm_supported_parameters branch 2 times, most recently from dad2fa0 to 2ffcaff Compare August 20, 2023 10:43
@arneboe
Copy link
Contributor Author

arneboe commented Aug 20, 2023

The design I had in mind for RDM_PID_SUPPORTED_PARAMETERS was to add two arrays to the dmx_driver_t struct found in dmx/struct.h. One array would contain all the PIDs supported by the root device, and the other array would contain all the PIDs supported by sub-devices. The callback function for RDM_PID_SUPPORTED_PARAMETERS would iterate one of these arrays and emplace the PIDs into the RDM response. PIDs would be added to the appropriate array when rdm_register_parameter() was called.

In that case we need to store the sub-device id in rdm_cb_table_t as well. Otherwise sub-devices can never register a parameter that is already registered by the root device (e.g. dmx addr).

Edit: This will also clash with how the nvs storage is implemented at the moment.
If a sub-device registeres the same parameter as the root device, the pid will no longer be unique and thus cannot be used as key in dmx_nvs_set

@someweisguy
Copy link
Owner

Again, great work! I'll go ahead and merge.

@someweisguy someweisguy merged commit 0662963 into someweisguy:release/v3.1 Aug 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants