diff --git a/docs/automation.md b/docs/automation.md index 7d9165cb4..c1122b8a7 100644 --- a/docs/automation.md +++ b/docs/automation.md @@ -67,18 +67,3 @@ Example: tcp://192.0.2.5:5025?product_id=hmc804 ``` -### HTTP - -This is a client to the [opennetzteil API](https://github.com/rumpelsepp/opennetzteil/blob/master/man/netzteil-http.7.adoc) which can expose power supplies over HTTP. - -product_id -: `http` - -scheme -: `http` or `https` - -HOST -: IP address - -PORT -: TCP port, most likely `8000` or the http defaults `80`, or `443` diff --git a/poetry.lock b/poetry.lock index 4440290d2..408827096 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiofiles" @@ -51,26 +51,6 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - [[package]] name = "argcomplete" version = "3.5.1" @@ -504,63 +484,6 @@ files = [ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - [[package]] name = "idna" version = "3.10" @@ -1630,17 +1553,6 @@ files = [ {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, ] -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - [[package]] name = "snowballstemmer" version = "2.2.0" @@ -2180,4 +2092,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.13" -content-hash = "cf4a6aacb28f0111c15b288c9d793cc49a7702971b7892f23402ac5e8add6781" +content-hash = "65aac2317a3d7e31527c9dd9a8693407166031988fc642cbd7b5d9434141a694" diff --git a/pyproject.toml b/pyproject.toml index 19fcda9fa..4d40b3b1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,6 @@ msgspec = ">=0.11,<0.19" pydantic = "^2.0" platformdirs = ">=2.6,<5.0" psutil = ">=5.9.4,<7.0.0" -httpx = ">=0.26,<0.28" more-itertools = "^10.3.0" pydantic-argparse = { path = "vendor/pydantic-argparse", develop = true } diff --git a/src/gallia/transports/schemes.py b/src/gallia/transports/schemes.py index 3593f7528..468fcadf0 100644 --- a/src/gallia/transports/schemes.py +++ b/src/gallia/transports/schemes.py @@ -7,7 +7,6 @@ TCP = "tcp" TCP_LINES = "tcp-lines" -HTTP = "http" DOIP = "doip" @@ -17,7 +16,6 @@ class TransportScheme(StrEnum): TCP = TCP TCP_LINES = TCP_LINES - HTTP = HTTP DOIP = DOIP HSFZ = "hsfz" UNIX = "unix" @@ -33,7 +31,6 @@ class TransportScheme(StrEnum): class TransportScheme(StrEnum): TCP = TCP TCP_LINES = TCP_LINES - HTTP = HTTP DOIP = DOIP FLEXRAY_RAW = "fr-raw" diff --git a/src/opennetzteil/__init__.py b/src/opennetzteil/__init__.py index 7aed4015c..ce9680640 100644 --- a/src/opennetzteil/__init__.py +++ b/src/opennetzteil/__init__.py @@ -2,8 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -from opennetzteil.devices.http.client import HTTPNetzteil from opennetzteil.devices.rs.hmc804 import HMC804 from opennetzteil.netzteil import BaseNetzteil -netzteile: list[type[BaseNetzteil]] = [HTTPNetzteil, HMC804] +netzteile: list[type[BaseNetzteil]] = [HMC804] diff --git a/src/opennetzteil/devices/http/__init__.py b/src/opennetzteil/devices/http/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/opennetzteil/devices/http/client.py b/src/opennetzteil/devices/http/client.py deleted file mode 100644 index 1c12da1db..000000000 --- a/src/opennetzteil/devices/http/client.py +++ /dev/null @@ -1,106 +0,0 @@ -# SPDX-FileCopyrightText: AISEC Pentesting Team -# -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from typing import Any, cast -from urllib.parse import urljoin - -import httpx - -from gallia.transports import TargetURI -from opennetzteil.exceptions import OperationNotSupportedError -from opennetzteil.netzteil import BaseNetzteil - - -class HTTPNetzteil(BaseNetzteil): - URL_PREFIX = "/_netzteil/api/" - PRODUCT_ID = "opennetzteil" - - def __init__( - self, - session: httpx.AsyncClient, - host: str, - device: int, - ): - self.host = host - self.baseurl = urljoin(host, self.URL_PREFIX) - self.device_id = device - self.session = session - - @classmethod - async def connect(cls, target: TargetURI, timeout: float | None) -> BaseNetzteil: - if "id" in target.qs: - device_id = int(target.qs["id"][0], 0) - else: - device_id = 1 - - return cls(httpx.AsyncClient(), target.location, device_id) - - async def _put_value(self, endpoint: str, channel: int, val: Any) -> None: - p = f"devices/{self.device_id}/channels/{channel}/{endpoint}" - u = urljoin(self.baseurl, p) - r = await self.session.put(u, json=val) - r.raise_for_status() - - async def _get_value(self, endpoint: str, channel: int) -> Any: - p = f"devices/{self.device_id}/channels/{channel}/{endpoint}" - u = urljoin(self.baseurl, p) - r = await self.session.get(u) - r.raise_for_status() - return await r.json() - - async def get_ident(self) -> str: - u = urljoin(self.baseurl, f"devices/{self.device_id}/ident") - r = await self.session.get(u) - r.raise_for_status() - return cast(str, await r.json()) - - async def get_channels(self) -> int: - u = urljoin(self.baseurl, f"devices/{self.device_id}/channels") - r = await self.session.get(u) - r.raise_for_status() - return cast(int, await r.json()) - - async def set_output(self, channel: int, enabled: bool) -> None: - return await self._put_value("out", channel, enabled) - - async def get_output(self, channel: int) -> bool: - return cast(bool, await self._get_value("out", channel)) - - async def set_master(self, enabled: bool) -> None: - return await self.set_output(0, enabled) - - async def get_master(self) -> bool: - return await self.get_output(0) - - async def set_current(self, channel: int, value: float) -> None: - return await self._put_value("current", channel, value) - - async def get_current(self, channel: int) -> float: - return cast(float, await self._get_value("current", channel)) - - async def set_voltage(self, channel: int, value: float) -> None: - return await self._put_value("voltage", channel, value) - - async def status(self) -> dict[str, Any]: - raise OperationNotSupportedError() - - async def get_voltage(self, channel: int) -> float: - return cast(float, await self._get_value("voltage", channel)) - - async def set_ocp(self, channel: int, enabled: bool) -> None: - return await self._put_value("ocp", channel, enabled) - - async def get_ocp(self, channel: int) -> bool: - return cast(bool, await self._get_value("ocp", channel)) - - async def set_ovp(self, channel: int, enabled: bool) -> None: - return await self._put_value("ovp", channel, enabled) - - async def get_ovp(self, channel: int) -> bool: - return cast(bool, await self._get_value("ovp", channel)) - - async def set_beep(self, enabled: bool) -> None: - raise OperationNotSupportedError()