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

Value limits accepted by Slave on the Holding Register (HREGS) #69

Open
beyonlo opened this issue Mar 30, 2023 · 6 comments
Open

Value limits accepted by Slave on the Holding Register (HREGS) #69

beyonlo opened this issue Mar 30, 2023 · 6 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@beyonlo
Copy link

beyonlo commented Mar 30, 2023

Description

Is there a way to set what are the values allowed and/or min and max values allowed on the Slave?

"HREGS": {
    "EXAMPLE_HREG": {
        "register": 93,
        "len": 9,
        "val": [1, 38, 0, 1600, 2150, 5067, 2564, 8450, 3456]
    }

Example 1:
The address 93 is number 29. I would like that address accept just min value 1 and max value 8

Example 2:
The address 96 is number 1600. I would like that address accept just one of this list [1600, 2100, 2300, 5000, 132, 8003]

So, if ModBus Master try to set a different value than that allowed, will be not accepted by the Slave, and an error will be returned to the Master.

Is possible to do that or something similar?

Thank you!

Reproduction steps

...

MicroPython version

1.19.1

MicroPython board

ESP32

MicroPython Modbus version

2.4.0rc62.dev56

Relevant log output

No response

User code

No response

Additional informations

No response

@brainelectronics brainelectronics added enhancement New feature or request question Further information is requested labels Apr 4, 2023
@brainelectronics
Copy link
Owner

@beyonlo I see your need on this topic. As of now, according to the docs

Callbacks can be registered to be executed after setting a register with on_set_cb or to be executed before getting a register with on_get_cb.

request.send_response()
self._set_changed_register(reg_type=reg_type,
address=address,
value=val)
if self._register_dict[reg_type][address].get('on_set_cb', 0):
_cb = self._register_dict[reg_type][address]['on_set_cb']
_cb(reg_type=reg_type, address=address, val=val)

Maybe we could introduce a return value to the callbacks and stop executing further steps if the return value is e.g. False. This would of course only work for the on_get_cb as it is executed before the data is requested, but makes no sense to stop reading/returning data. A new callback would be necessary to be executed before setting the data. Like this e.g.

if self._register_dict[reg_type][address].get('pre_set_cb', 0):
    _cb = self._register_dict[reg_type][address]['on_set_cb']
    if _cb(reg_type=reg_type, address=address, val=val):
        return request.send_exception(Const.ILLEGAL_DATA_VALUE)

# the following code exists already
self._set_changed_register(reg_type=reg_type,
                           address=address,
                           value=val)
if self._register_dict[reg_type][address].get('on_set_cb', 0):
    _cb = self._register_dict[reg_type][address]['on_set_cb']
    _cb(reg_type=reg_type, address=address, val=val)

to be used as (not tested)

def my_holding_register_get_cb(reg_type, address, val):
    print('Custom callback, called on getting {} at {}, currently: {}'.
          format(reg_type, address, val))


def my_holding_register_set_cb(reg_type, address, val):
    print('Custom callback, called on setting {} at {} to: {}'.
          format(reg_type, address, val))


def my_holding_register_pre_set_cb(reg_type, address, val):
    print('Custom callback, called on setting {} at {} to: {}'.
          format(reg_type, address, val))

    if val not in range(0, 101):
        return False
    else:
        return True

client.add_hreg(
    address=93,
    value=19,
    on_pre_set_cb=my_holding_register_pre_set_cb,
    on_set_cb=my_holding_register_set_cb,
    on_get_cb=my_holding_register_get_cb
)

@beyonlo
Copy link
Author

beyonlo commented Apr 4, 2023

@brainelectronics Excellent! Thank you for the example :)

@beyonlo
Copy link
Author

beyonlo commented May 5, 2023

@GimmickNG could you please to port this example for the your async examples?

@GimmickNG
Copy link

@beyonlo Looking at this, I'm not sure it needs to specifically be ported for the async examples - the only changes required seem to be adding the pre_get_cb to modbus.py and then creating the example for that. That is, whatever works for the sync version will in theory work exactly the same for the async version with no changes required at all, since the async version is just an extension of the sync client/server.

@beyonlo
Copy link
Author

beyonlo commented Aug 31, 2023

@GimmickNG Could you please to create/add an example for that? Maybe just add an entry to the host_tests.py? So, I can test it for you :)

Thank you in advance!

GimmickNG added a commit to GimmickNG/pycopy-modbus that referenced this issue Oct 8, 2023
@Omid888
Copy link

Omid888 commented Nov 17, 2024

Are there any updates on this feature? the latest (2.3.7 version) does not include this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants