Closed aktentasche closed 6 days ago
I decided to implement my own connection class because the codebase seems to be very coupled so a clean implementation made more sense to me.,
If anyone faces the same issue, here is the code:
# windows 1252 encoding
_PI_CONTROLLER_CODEPAGE = "cp1252"
class PiPiezoConnection:
# based on pipython/pidevice/interfaces/pisocket.py
def connect(self, hostname: str, port: int = 50000):
logger.info(f"Connecting to {hostname=} at {port=}")
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.connect((hostname, port))
self._socket.setblocking(False)
self._socket.setsockopt(
socket.SOL_TCP, socket.TCP_NODELAY, 1
) # disable Nagle algorithm
self._flush_input_buffer()
def disconnect(self):
logger.info("Disconnecting..")
self._socket.shutdown(socket.SHUT_RDWR)
self._socket.close()
def send_raw_message(self, msg: str):
msg_encoded = msg.encode(_PI_CONTROLLER_CODEPAGE) + "\n".encode(
_PI_CONTROLLER_CODEPAGE
)
logger.debug(f"Sending message {msg_encoded}")
sent_length = self._socket.send(msg_encoded)
# need to add one because we append \n
if sent_length != len(msg_encoded):
logger.error(f"send_raw_message error for msg: {msg_encoded=}")
def read_raw_message(self, timeout_s: int = 5) -> str:
# note that it is not exactly 5 seconds. Use AcurateSleeper for that.
current_counter_time_s = 0
counter_fraction_s = 0.01
while current_counter_time_s < timeout_s:
try:
received = self._socket.recv(2048)
logger.debug(f"Got raw_message after ~{current_counter_time_s} seconds")
return received.decode(
encoding=_PI_CONTROLLER_CODEPAGE, errors="ignore"
)
# if this exception occurs the input buffer is empty
# keep trying until we hit timeout_s...
except IOError:
pass
finally:
current_counter_time_s = current_counter_time_s + counter_fraction_s
time.sleep(counter_fraction_s)
logger.error(
f"Did not get any messages within {current_counter_time_s} seconds."
)
return "ERROR"
def _flush_input_buffer(self):
# ugly! i guess this is how sockets work...they throw an exception if there is
# nothing to receive
while True:
try:
self._socket.recv(2048)
except IOError:
break
We can confirm this is a bug concerning the cleanup procedure of the connection status callbacks. We are working on this and will let you know as soon as an updated release is available.
The bug was solved with version 2.10.1.1 and is no longer present with the current versions.
Hi,
when running the below code based on https://github.com/PI-PhysikInstrumente/PIPython/blob/master/samples/advanced/connect_socket.py to talk to a E727 I get an
OSError: Bad file descriptor
I also tried to use
this also throws the OSError.
The error originates from line 65 in pidevice/interfaces/pisocket.py but effectively it comes from _downcast_gcscommands_if_necessary() which is some callback and in there when
if isdeviceavailable([GCSBaseCommands, ], self._gcscommands):
is called which in turn propagates to
Can you assist?