simonvetter / modbus

Go modbus stack (client and server)
MIT License
262 stars 83 forks source link

Reading in a loop #7

Closed guydillen closed 2 years ago

guydillen commented 2 years ago

Hi,

When reading at regular intervals values should the client in every iteration be opened/closed, or can I just leave the client open?

Thanks. Guy

simonvetter commented 2 years ago

Hi Guy,

feel free to keep the client open: a client will keep executing requests for as long as the underlying socket/serial port is open.

Keep in mind that TCP devices tend to close inactive connections after a few minutes, so if your poll interval is really long, you may run into issues.

FYI, I usually use something like this in my pollers to detect when to close/re-open a client:

// returns true if the error is a non-modbus (e.g. i/o or network) error, false otherwise.

func shouldReconnect(err error) (yes bool) {     yes = true

    if err == nil ||        err == modbus.ErrIllegalFunction ||        err == modbus.ErrIllegalDataAddress ||        err == modbus.ErrIllegalDataValue ||        err == modbus.ErrServerDeviceFailure ||        err == modbus.ErrMemoryParityError ||        err == modbus.ErrServerDeviceBusy ||        err == modbus.ErrGWPathUnavailable ||        err == modbus.ErrGWTargetFailedToRespond ||        err == modbus.ErrRequestTimedOut {            yes = false        }

    return }

Then you can pass the err value of any client operation to this function. If err is nil or the returned error is a modbus error (i.e. defined in the modbus standard and coming from the target device), there's probably no need to reconnect as the modbus link is operating normally.

Otherwise, it may be a good idea to close and reopen the client to re-establish the connection.

You may want to adjust that logic to your specific use case, obviously.

Hope this helps,

-Simon

guydillen commented 2 years ago

Hi Simon,

Many thanks for the prompt and extensive reply.

Guy