I am using the fusion 16 relays module.
I am using socket package to send and receive data from the module, sometimes I get timeout exception for the socket.recv, I got to a point that I defined the timeout to be 5 seconds and it still happens.
It does not happen a lot but its not expected.
Thanks, Matan Milrad
Is the fusion set up to do any other processing than computer control currently? For instance is it set up to toggle relays based on sensor input or time schedules?
Just trying to turn to on 3 relays one after the other.
Are you API encoding the packets? i.e. [170, payload_length, [payload], checksum]?
Yes I do, it happens on set relay in bank or get relay in bank state
Those operations run a bit longer, but not that much longer.
Can you share the code that you’re seeing the error in?
Also what is being controlled with the relay?
If its an inductive load then it may be causing delays in the the on-board processor due to voltage spikes.
checksum = np.uint8(170 + 3 + 254 + relay + bank_number)
command = bytearray([170, 3, 254, relay, bank_number, checksum])
time.sleep(0.1) # wait for response
data = self._socket.recv(5)
The timeout is on the recv()
I had the timeout exception without any load
Does the same happen if you use the official python library: https://github.com/ncd-io/NCDEnterpise-Python/tree/master
We just updated some Fusion Compatibility thanks to community members ( @teknix ). Primarily the turn_on/off_relay_by_index functions have a fusion_turn_on/off_relay_by_index function. The rest of the commands should be interchangeable.
Does the controller alter the state of the relays when this timeout exception occurs?
I’m currently working on a more in depth recv timeout that return a false, any received data, and a human readable string outlining the error. I can post it to the dev branch if you’re interested in trying the beta.
It may not solve the issue as its more designed to solve partial return packets if there’s a delay.
This library does not have relay set by bank with API commands.
I am not sure about if the relay state was changed when the timeout exception happened, I will try to reproduce it.
My code works fine its just that sometimes(not so frequently) this exception occurs, I also check my set/get commands and it is the same as in this library https://github.com/ncd-io/Industrial-Relay-Control.
I used to work with the fusion board with Ethernet in C# and did not encounter with that exception, the main difference is that I was using to turn power on/off to devices so was not a lot of relay on/off commands in a row, but now I am using it to control movement so there is much more of on/off commands.
Oh I linked the wrong library above: https://github.com/ncd-io/Industrial-Relay-Control
My main concern is a packet that the controller doesn’t understand 254 119 1 for example. This wouldn’t return anything as its not a valid command.
Honestly with network communications, sometimes packets are lost or sufficient delays between bytes are put in to timeout the command on the controller.
There may not be anything you can do outside of a try/catch to log the error and retry x times.
I am doing a check to get the number of relay 1-8 and adding to the starting value.
relay = 107 + relay_number_in_bank
relay = 99 + relay_number_in_bank
So there is no way that I am sending an invalid command.
Maybe it is something to do with how python’s socket works because when I used TCPClient in C# I never had that problem.
If you will encounter this problem and have a fix whether it is firmware of software please contact me and thanks for the help.
Python sockets definitely have their quirks, although they seem to be better than they were. Many components of the Python socket library call out to the OS to use their components. Back in 2.7 I had some weird issues with timeouts on a Windows machine. I can’t remember the fix, but I think I just brute forced a correct timeout with a retry functionality.
One thing I just noticed is that your .recv is set to 5 while that command should only return 4. This doesn’t explain the timeout, but its a small thing.
Is it a blocking socket or non-blocking?
Are you opening and closing the socket for every send/recv?
I did notice that if I don’t wait a fraction of a second before re-opening a socket i’ll get an error so it may be a situation where the socket is initialized, but its not quite ready for data.
I used timeout of 2 sec and opening the socket only once.
Do you have command to set both banks to different relay states? the command 254, 140, new_bank_state, bank_number can only set the same relay in all banks.
For example in one command set relay 1 in bank 1 to true and relay 1 in bank 2 to false, it will probably need to send 2 new_bank_state bytes in the payload.
Unfortunately there is not a command to alter state of individual relays in different banks outside of targeting all banks to set the status of all relays.
Each bank of relays requires its own callout from the on-board processing unit to drive its relays.
If you needed to do this I might recommend re-wiring if that is feasible to put them on the same bank.
I did a test with C#:
I sent set bank state command every 200ms and 1 sec and I still get timeout exception, so this is not python socket only problem. you need to test max command rate that works.
I implemented with C# as close as possible to my python implementation(used 2sec timeout for socket receive)
I don’t personally run into this issue using the Ethernet modules, but can you send me a screenshot of a couple of Base Station’s windows so I can take a look at a few settings?
Specifically I’m wondering about the Reactor Generation II Automatic Relay Controller Window (https://ncd.io/fusion-reactor-quick-start-guide/) you’ll have to select Step 2, the Taralist Enhanced Event Controller Window (https://ncd.io/fusion-taralist-quick-start-guide/), and the Fusion Master Control Panel. I’m wondering if somehow something was set in there that is eating up processor time somehow.
We do not have the TLEE expension so I can not enter to the Taralist Enhanced Event Controller Window