venv added, updated
This commit is contained in:
225
myenv/lib/python3.12/site-packages/pymodbus/client/udp.py
Normal file
225
myenv/lib/python3.12/site-packages/pymodbus/client/udp.py
Normal file
@@ -0,0 +1,225 @@
|
||||
"""Modbus client async UDP communication."""
|
||||
from __future__ import annotations
|
||||
|
||||
import socket
|
||||
from collections.abc import Callable
|
||||
|
||||
from pymodbus.client.base import ModbusBaseClient, ModbusBaseSyncClient
|
||||
from pymodbus.exceptions import ConnectionException
|
||||
from pymodbus.framer import FramerType
|
||||
from pymodbus.logging import Log
|
||||
from pymodbus.transport import CommParams, CommType
|
||||
|
||||
|
||||
DGRAM_TYPE = socket.SOCK_DGRAM
|
||||
|
||||
|
||||
class AsyncModbusUdpClient(ModbusBaseClient):
|
||||
"""**AsyncModbusUdpClient**.
|
||||
|
||||
Fixed parameters:
|
||||
|
||||
:param host: Host IP address or host name
|
||||
|
||||
Optional parameters:
|
||||
|
||||
:param framer: Framer name, default FramerType.SOCKET
|
||||
:param port: Port used for communication.
|
||||
:param name: Set communication name, used in logging
|
||||
:param source_address: source address of client,
|
||||
:param reconnect_delay: Minimum delay in seconds.milliseconds before reconnecting.
|
||||
:param reconnect_delay_max: Maximum delay in seconds.milliseconds before reconnecting.
|
||||
:param timeout: Timeout for a connection request, in seconds.
|
||||
:param retries: Max number of retries per request.
|
||||
:param on_reconnect_callback: Function that will be called just before a reconnection attempt.
|
||||
|
||||
.. tip::
|
||||
**reconnect_delay** doubles automatically with each unsuccessful connect, from
|
||||
**reconnect_delay** to **reconnect_delay_max**.
|
||||
Set `reconnect_delay=0` to avoid automatic reconnection.
|
||||
|
||||
Example::
|
||||
|
||||
from pymodbus.client import AsyncModbusUdpClient
|
||||
|
||||
async def run():
|
||||
client = AsyncModbusUdpClient("localhost")
|
||||
|
||||
await client.connect()
|
||||
...
|
||||
client.close()
|
||||
|
||||
Please refer to :ref:`Pymodbus internals` for advanced usage.
|
||||
"""
|
||||
|
||||
def __init__( # pylint: disable=too-many-arguments
|
||||
self,
|
||||
host: str,
|
||||
framer: FramerType = FramerType.SOCKET,
|
||||
port: int = 502,
|
||||
name: str = "comm",
|
||||
source_address: tuple[str, int] | None = None,
|
||||
reconnect_delay: float = 0.1,
|
||||
reconnect_delay_max: float = 300,
|
||||
timeout: float = 3,
|
||||
retries: int = 3,
|
||||
on_connect_callback: Callable[[bool], None] | None = None,
|
||||
) -> None:
|
||||
"""Initialize Asyncio Modbus UDP Client."""
|
||||
self.comm_params = CommParams(
|
||||
comm_type=CommType.UDP,
|
||||
host=host,
|
||||
port=port,
|
||||
comm_name=name,
|
||||
source_address=source_address,
|
||||
reconnect_delay=reconnect_delay,
|
||||
reconnect_delay_max=reconnect_delay_max,
|
||||
timeout_connect=timeout,
|
||||
)
|
||||
ModbusBaseClient.__init__(
|
||||
self,
|
||||
framer,
|
||||
retries,
|
||||
on_connect_callback,
|
||||
)
|
||||
self.source_address = source_address
|
||||
|
||||
@property
|
||||
def connected(self):
|
||||
"""Return true if connected."""
|
||||
return self.ctx.is_active()
|
||||
|
||||
|
||||
class ModbusUdpClient(ModbusBaseSyncClient):
|
||||
"""**ModbusUdpClient**.
|
||||
|
||||
Fixed parameters:
|
||||
|
||||
:param host: Host IP address or host name
|
||||
|
||||
Optional parameters:
|
||||
|
||||
:param framer: Framer name, default FramerType.SOCKET
|
||||
:param port: Port used for communication.
|
||||
:param name: Set communication name, used in logging
|
||||
:param source_address: source address of client,
|
||||
:param reconnect_delay: Minimum delay in seconds.milliseconds before reconnecting.
|
||||
:param reconnect_delay_max: Maximum delay in seconds.milliseconds before reconnecting.
|
||||
:param timeout: Timeout for a connection request, in seconds.
|
||||
:param retries: Max number of retries per request.
|
||||
|
||||
.. tip::
|
||||
**reconnect_delay** doubles automatically with each unsuccessful connect, from
|
||||
**reconnect_delay** to **reconnect_delay_max**.
|
||||
Set `reconnect_delay=0` to avoid automatic reconnection.
|
||||
|
||||
Example::
|
||||
|
||||
from pymodbus.client import ModbusUdpClient
|
||||
|
||||
async def run():
|
||||
client = ModbusUdpClient("localhost")
|
||||
|
||||
client.connect()
|
||||
...
|
||||
client.close()
|
||||
|
||||
Please refer to :ref:`Pymodbus internals` for advanced usage.
|
||||
|
||||
Remark: There are no automatic reconnect as with AsyncModbusUdpClient
|
||||
"""
|
||||
|
||||
socket: socket.socket | None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
host: str,
|
||||
framer: FramerType = FramerType.SOCKET,
|
||||
port: int = 502,
|
||||
name: str = "comm",
|
||||
source_address: tuple[str, int] | None = None,
|
||||
reconnect_delay: float = 0.1,
|
||||
reconnect_delay_max: float = 300,
|
||||
timeout: float = 3,
|
||||
retries: int = 3,
|
||||
) -> None:
|
||||
"""Initialize Modbus UDP Client."""
|
||||
self.comm_params = CommParams(
|
||||
comm_type=CommType.UDP,
|
||||
host=host,
|
||||
port=port,
|
||||
comm_name=name,
|
||||
source_address=source_address,
|
||||
reconnect_delay=reconnect_delay,
|
||||
reconnect_delay_max=reconnect_delay_max,
|
||||
timeout_connect=timeout,
|
||||
)
|
||||
super().__init__(framer, retries)
|
||||
self.socket = None
|
||||
|
||||
@property
|
||||
def connected(self) -> bool:
|
||||
"""Connect internal."""
|
||||
return self.socket is not None
|
||||
|
||||
def connect(self):
|
||||
"""Connect to the modbus tcp server.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
if self.socket:
|
||||
return True
|
||||
try:
|
||||
family = ModbusUdpClient.get_address_family(self.comm_params.host)
|
||||
self.socket = socket.socket(family, socket.SOCK_DGRAM)
|
||||
self.socket.settimeout(self.comm_params.timeout_connect)
|
||||
except OSError as exc:
|
||||
Log.error("Unable to create udp socket {}", exc)
|
||||
self.close()
|
||||
return self.socket is not None
|
||||
|
||||
def close(self):
|
||||
"""Close the underlying socket connection.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
self.socket = None
|
||||
|
||||
def send(self, request: bytes) -> int:
|
||||
"""Send data on the underlying socket.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
super()._start_send()
|
||||
if not self.socket:
|
||||
raise ConnectionException(str(self))
|
||||
if request:
|
||||
return self.socket.sendto(
|
||||
request, (self.comm_params.host, self.comm_params.port)
|
||||
)
|
||||
return 0
|
||||
|
||||
def recv(self, size: int | None) -> bytes:
|
||||
"""Read data from the underlying descriptor.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
if not self.socket:
|
||||
raise ConnectionException(str(self))
|
||||
if size is None:
|
||||
size = 0
|
||||
return self.socket.recvfrom(size)[0]
|
||||
|
||||
def is_socket_open(self):
|
||||
"""Check if socket is open.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
"""Return string representation."""
|
||||
return (
|
||||
f"<{self.__class__.__name__} at {hex(id(self))} socket={self.socket}, "
|
||||
f"ipaddr={self.comm_params.host}, port={self.comm_params.port}, timeout={self.comm_params.timeout_connect}>"
|
||||
)
|
||||
Reference in New Issue
Block a user