Questions regarding pymodbus as an updating server

316 views
Skip to first unread message

cabled

unread,
Nov 22, 2018, 4:57:51 AM11/22/18
to pymodbus
Hi gents,

Am working on pymodbus with some adjustments to the example for the above function (found here). I have a couple of queries I'd like to seek assistance with.

1) In this section: 

def updating_writer(a):
   
""" A worker process that runs every so often and
    updates live values of the context. It should be noted
    that there is a race condition for the update.

What is the race condition that is being warned of? I know what a race condition is but I can't identify one here... probably related to unfamiliarity with python. I may actually have encountered it (update loop seemed to stop being called) but I'm not certain of the cause and/or remedy.

2) Is there a way for the server to read one of its own registers, say a holding register that has been updated, so I can execute a conditional statement based on the vlaue in that particular register?
I can update registers just fine, and they hold the new value, just don't know which example to reference if I want the pymodbus server to react to a value change.

Thanks for the assistance

sanju dhoomakethu

unread,
Nov 23, 2018, 4:45:51 AM11/23/18
to pymodbus
I do not see a race condition here as well, the only problem would be a write request and update_writer being called at the same time might not work out as expected. Re.2 , Have a look at callback_server.py

cabled

unread,
Nov 23, 2018, 10:58:46 PM11/23/18
to pymodbus
Hmm ok so it seems I may have bumped into it...

it seems like the server doesn't accept connections/queries during the updating loop and having incoming read requests during that window seems to somehow throw the loop off (doesn't recover to run subsequent iterations). I'm gonna run a couple of further tests to see if I can isolate the cause.

Does this sound plausible?

sanju dhoomakethu

unread,
Nov 25, 2018, 10:37:13 PM11/25/18
to pymodbus
I tried the example locally (both server and client running on the same machine) and I could not see any such issues you have come across. Would mind sharing more details on your findings.

Here is my simple client code

from pymodbus.client.sync import ModbusTcpClient
client
= ModbusTcpClient(port=502)
while True:
   
try:
       
print(client.read_holding_registers(0x10, 5, unit=1)
   
except Exception as e:
       
print(e)

Galen Collins

unread,
Nov 26, 2018, 12:07:49 PM11/26/18
to pymo...@googlegroups.com
All,

There is no race condition, this documentation was more than likely copied from another example. The updating writer simply gets added to the reactor event queue and events will get processed in order. You are correct that if you are running a large block of code during this loop then now connections will get processed during this time as there is only one thread of control. The solution to this is to use a defer heavy work to a bottom half worker thread or perform the work in another thread and update in this reactor callback. It should be noted that if you are using threads then there _could_ be race conditions depending on how you implement your bottom half. 

Sanju, perhaps try implementing an update block with a thread.sleep in it and you may see the same results.

Galen

--
You received this message because you are subscribed to the Google Groups "pymodbus" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pymodbus+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

cabled

unread,
Nov 26, 2018, 6:52:40 PM11/26/18
to pymodbus
Hi Galen,

Thanks for your reply. I'm going to ask for more assistance from you regarding the following:

1) "You are correct that if you are running a large block of code during this loop then now(no) connections will get processed during this time as there is only one thread of control."
Would you be able to shed a bit more light on why the loop function seems to lock up while the pymodbus server itself continues functioning? i.e. the server doesn't go offline, it just serves stale data

2) "The solution to this is to use a defer heavy work to a bottom half worker thread or perform the work in another thread and update in this reactor callback."
I don't do very much python work and even less of twisted. Would you be able to point me to a few examples? I'm assuming some sort of call by address, with the data refresh function handled elsewhere so the pymodbus only updates registers instead of waiting for the data refresh to be completed before it can update register values?

To give a little more context, I'm actually trying to present values from several API json returns (updating at different intervals) as modbus registers. The total amount of data is about 80 values spread across 4 function calls. Putting them all together in one call locks up very reliably. I've split them into smaller blocks but am still getting stymied on the largest block which generates about 40 data points. 

Galen Collins

unread,
Nov 26, 2018, 7:29:43 PM11/26/18
to pymo...@googlegroups.com
So you are basically using modbus as an API proxy? How out of date can the values be? To answer your questions, I don't really know without seeing your code. I'm guessing it throws, blocks, or something else goody. I. General, it gets weird to mix threads with a reactor based system. If your modbus server is only reading values, I would just start another thread with the server context (the backing modbus data) and just update in that thread. Then modbus is just serving data that is written every so often.

If more complex things are going on, let me know and I can suggest other options.

Galen
Reply all
Reply to author
Forward
0 new messages