From ec642b2e21140ecd6c1d4476222f106f27a7191f Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Tue, 20 Feb 2024 08:11:15 +0000 Subject: [PATCH] Allow setting of CoAP listening IP address --- aioshelly/block_device/coap.py | 16 ++++++++++------ aioshelly/const.py | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/aioshelly/block_device/coap.py b/aioshelly/block_device/coap.py index 534055cb..02352b7a 100644 --- a/aioshelly/block_device/coap.py +++ b/aioshelly/block_device/coap.py @@ -6,10 +6,12 @@ import logging import socket import struct +from collections.abc import Callable from enum import Enum, auto from types import TracebackType -from typing import Callable, cast +from typing import cast +from ..const import DEFAULT_COAP_PORT, DEFAULT_IP_ADDRESS from ..json import JSONDecodeError, json_loads COAP_OPTION_DEVICE_ID = 3332 @@ -111,12 +113,12 @@ def _read_extended_field_value(value: int, raw_data: bytes) -> tuple[int, bytes] raise InvalidMessage("Option contained partial payload marker.") -def socket_init(socket_port: int) -> socket.socket: +def socket_init(socket_ip: str, socket_port: int) -> socket.socket: """Init UDP socket to send/receive data with Shelly devices.""" sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.bind(("", socket_port)) - _LOGGER.debug("Socket initialized on port %s", socket_port) + sock.bind((socket_ip, socket_port)) + _LOGGER.debug("Socket initialized on %s:%s", socket_ip, socket_port) mreq = struct.pack("=4sl", socket.inet_aton("224.0.1.187"), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) sock.setblocking(False) @@ -134,10 +136,12 @@ def __init__(self, message_received: Callable | None = None) -> None: self.subscriptions: dict[str, Callable] = {} self.transport: asyncio.DatagramTransport | None = None - async def initialize(self, socket_port: int = 5683) -> None: + async def initialize( + self, socket_ip: str = DEFAULT_IP_ADDRESS, socket_port: int = DEFAULT_COAP_PORT + ) -> None: """Initialize the COAP manager.""" loop = asyncio.get_running_loop() - self.sock = socket_init(socket_port) + self.sock = socket_init(socket_ip, socket_port) await loop.create_datagram_endpoint(lambda: self, sock=self.sock) async def request(self, ip: str, path: str) -> None: diff --git a/aioshelly/const.py b/aioshelly/const.py index f94de487..2ced165a 100644 --- a/aioshelly/const.py +++ b/aioshelly/const.py @@ -235,6 +235,10 @@ WS_HEARTBEAT = 55 +# Default network settings for gen1 devices ( CoAP ) +DEFAULT_COAP_PORT = 5683 +DEFAULT_IP_ADDRESS = "0.0.0.0" + # Default Gen2 outbound websocket API URL WS_API_URL = "/api/shelly/ws"