You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I would like to simulate a PLC.
In my case when I read an address, let's say 10 words starting from 0x200, I get some values back (I.E. a string containing the Producer), instead when I read 10 words from 0x201 I will get completely different values.
Which is the proper way to realize this? For what I have understood with app.route I can only define one value at a time. Is there a way to get the lenght of the request at application level?
The workaround that came to my mind was to trigger the modification of regs_word when the first register is requested, like:
Thanks for your question. From what I understand you want the value of a register to be depending on the start address of the request. Am I correct?
For what I have understood with app.route I can only define one value at a time.
It is correct that the the handlers should return only 1 value. If a client requests multiple registers than the handler is executed multiple times using a different value for each address.
But wouldn't something like this work for your?
@app.route(slave_ids=[1],function_codes=[3], addresses=list(range(0x200,0x215))):
defproducer(slave_id, function_code, address):
ifaddress==0x200:
# prepare all your other registersregs_word[0x200] =0xaabb# first registersregs_word[0x201] =0x2231# prepares other registersregs_word[0x202] =0x231a# prepares other registersreturnregs_word[0x200]
Thanks for your question. From what I understand you want the value of a register to be depending on the start address of the request. Am I correct?
Exactly, in fact I am replicating the PLC behavior and if I read 16 regs starting from 0x200 I get one string I.E. Producer name, If I read 16 regs starting from 0x201 I get another string I.E. production date. Is not really a standard modbus behavior from my point of view... but is like this 😄
For what I have understood with app.route I can only define one value at a time.
It is correct that the the handlers should return only 1 value. If a client requests multiple registers than the handler is executed multiple times using a different value for each address.
But wouldn't something like this work for your?
@app.route(slave_ids=[1],function_codes=[3], addresses=list(range(0x200,0x215))):
defproducer(slave_id, function_code, address):
ifaddress==0x200:
# prepare all your other registersregs_word[0x200] =0xaabb# first registersregs_word[0x201] =0x2231# prepares other registersregs_word[0x202] =0x231a# prepares other registersreturnregs_word[0x200]
Yes, this will work better than my code! Thanks!
It's a hack anyway but for a simulator I think is fine.
Really thanks!
mmm thinking better I don't know if this (in general) will work because should be something like this:
@app.route(slave_ids=[1],function_codes=[3], addresses=list(range(0x200,0x215))):
defproducer(slave_id, function_code, address):
ifaddress==0x200:
# prepare all your other registersregs_word[0x200] =0xaabb# first registersregs_word[0x201] =0x2231# prepares other registersregs_word[0x202] =0x231a# prepares other registersreturnregs_word[address]
@app.route(slave_ids=[1],function_codes=[3], addresses=list(range(0x201,0x216))):
defproduction_date(slave_id, function_code, address):
ifaddress==0x201:
# prepare all your other registersregs_word[0x200] =0x1111# first registersregs_word[0x201] =0x0000# prepares other registersregs_word[0x202] =0x123b# prepares other registersreturnregs_word[address]
In fact the region are overlapping... I don't think will work, what do you think?
It's a hack anyway but for a simulator I think is fine.
I am not sure if there is a non-hacky option. To be fair, your requirement of having registers values depend on the start address seem a little bit odd for me.
In fact the region are overlapping... I don't think will work, what do you think?
I am not exactly how this will work out, but I don't think it will work as you want it to work. At least uModbus is not intended to work that way when I created this package.
I am not sure if there is a non-hacky option. To be fair, your requirement of having registers values depend on the start address seem a little bit odd for me.
Yeah, I agree, that seems odd to me too... but ask Wago producers... 😄
In fact the region are overlapping... I don't think will work, what do you think?
I am not exactly how this will work out, but I don't think it will work as you want it to work. At least uModbus is not intended to work that way when I created this package.
If you think that it is possible to retrieve the length of the request just tell me where to start and eventually I can write the code.
If not I will close the issue, thank you for uModbus, is cool! 😄
If you think that it is possible to retrieve the length of the request just tell me where to start and eventually I can write the code.
Assuming you run a Modbus TCP server than you could create your own request handler that extends from the umodbus.server.tcp.RequestHandler. If you than override than the umodbus.server.AbstractRequestHandler.execute_route() you have access to the info you want.
Activity
OrangeTux commentedon Aug 27, 2019
Hello @piertoni,
Thanks for your question. From what I understand you want the value of a register to be depending on the start address of the request. Am I correct?
It is correct that the the handlers should return only 1 value. If a client requests multiple registers than the handler is executed multiple times using a different value for each
address.But wouldn't something like this work for your?
piertoni commentedon Aug 27, 2019
Exactly, in fact I am replicating the PLC behavior and if I read 16 regs starting from 0x200 I get one string I.E. Producer name, If I read 16 regs starting from 0x201 I get another string I.E. production date. Is not really a
standard modbusbehavior from my point of view... but is like this 😄Yes, this will work better than my code! Thanks!
It's a hack anyway but for a simulator I think is fine.
Really thanks!
piertoni commentedon Aug 27, 2019
mmm thinking better I don't know if this (in general) will work because should be something like this:
In fact the region are overlapping... I don't think will work, what do you think?
OrangeTux commentedon Aug 27, 2019
I am not sure if there is a non-hacky option. To be fair, your requirement of having registers values depend on the start address seem a little bit odd for me.
I am not exactly how this will work out, but I don't think it will work as you want it to work. At least uModbus is not intended to work that way when I created this package.
piertoni commentedon Aug 28, 2019
Yeah, I agree, that seems odd to me too... but ask Wago producers... 😄
If you think that it is possible to retrieve the length of the request just tell me where to start and eventually I can write the code.
If not I will close the issue, thank you for uModbus, is cool! 😄
OrangeTux commentedon Aug 29, 2019
Assuming you run a Modbus TCP server than you could create your own request handler that extends from the
umodbus.server.tcp.RequestHandler. If you than override than the umodbus.server.AbstractRequestHandler.execute_route() you have access to the info you want.