Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions README-de.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Diese Dokumentation ist auch in 🇬🇧 [englischer Sprache](README.md) verfüg

## Neues in dieser Version

### v0.3.6

* DHCP-Lease-Anzahl und Clientdaten als Sensorattribute hinzugefügt (benötigt api.cgi).
* Kumulative Trafficzähler für die GREEN-, ORANGE- und BLUE-Schnittstellen hinzugefügt (benötigt api.cgi).
* Sensor für erforderlichen Neustart sowie Gesamtzahl verfügbarer Core- und Paket-Updates hinzugefügt (benötigt api.cgi).

### v0.3.5

* Die Entwicklung des IPFire-CGI `api.cgi` wird im eigenständigen Repository [IPFire-API](https://github.com/FMainz/IPFire-API) fortgeführt.
Expand All @@ -65,19 +71,24 @@ Diese Dokumentation ist auch in 🇬🇧 [englischer Sprache](README.md) verfüg

HA-IPFire bietet folgende Funktionen:

* Download-Trafficzähler
* Upload-Trafficzähler
* RED-Download-Trafficzähler
* RED-Upload-Trafficzähler
* Aktuelle Download-Geschwindigkeit
* Aktuelle Upload-Geschwindigkeit
* Status der Internetverbindung
* Dauer der Internetverbindung
* Connect- und Disconnect-Steuerung
* Konfigurierbares Abfrageintervall
* Status der Internetverbindung¹
* Dauer der Internetverbindung¹
* Connect- und Disconnect-Steuerung¹
* Konfigurierbares Abfrageintervall¹
* Abfrageintervall von 5 bis 60 Sekunden
* Optionale SSL-Zertifikatsprüfung
* Authentifizierung mit Benutzername und Passwort
* HACS-kompatibel
* Deutsche und englische Übersetzungen
* DHCP-Lease-Sensor mit Clientdaten¹
* Trafficzähler für einzelne Netzwerkzonen¹
* Neustartstatus und Gesamtzahl verfügbarer Updates¹

¹Benötigt api.cgi aus [IPFire-API](https://github.com/FMainz/IPFire-API)

## IPFire

Expand Down Expand Up @@ -106,11 +117,12 @@ Zusätzlich zum Verbindungsstatus und den Steuerungsaktionen liefert die API unt
* IPFire-, Pakfire- und Kernel-Version sowie Systemhersteller, -modell und Architektur
* CPU-Modell und Anzahl der Kerne
* Arbeitsspeicher und Festplattenbelegung einschließlich I/O-Statistiken und SMART-Status
* Status der Netzwerkschnittstellen und IPFire-Dienste
* Status der Netzwerkschnittstellen, Trafficzähler pro Zone und IPFire-Dienste
* Aktive DHCP-Leases mit Clientdaten
* installierten Add-ons und deren Status
* verfügbaren Core- und Paket-Updates
* Core- und Paket-Updates sowie erforderlicher Neustart

Eine vollständige Beschreibung der JSON-Felder findest du in der [IPFire-API-Dokumentation](https://github.com/FMainz/IPFire-API/blob/main/README-de.md#endpunkt).
Eine vollständige Beschreibung der JSON-Felder findest du in der [IPFire-API-Dokumentation](https://github.com/FMainz/IPFire-API/blob/main/README-de.md#api-zugriff).

### Verbindungssteuerung

Expand Down Expand Up @@ -152,12 +164,29 @@ Die Integration stellt folgende Sensoren bereit:

### Traffic

* **Download** – kumulativer Download-Traffic in Byte.
* **Upload** – kumulativer Upload-Traffic in Byte.
* **Rot empfangen** – kumulativ empfangene Bytes auf der RED-Schnittstelle.
* **Rot gesendet** – kumulativ gesendete Bytes auf der RED-Schnittstelle.
* **Download Speed** – aktuelle Download-Geschwindigkeit.
* **Upload Speed** – aktuelle Upload-Geschwindigkeit.

Die folgenden Sensoren und Funktionen erfordern, dass `api.cgi` auf der IPFire-Firewall [installiert](#installation-des-ipfire-cgi) ist.
Die folgenden zusätzlichen Sensoren und Funktionen erfordern, dass `api.cgi` auf der IPFire-Firewall [installiert](#installation-des-ipfire-cgi) ist.

### Traffic interner Netzwerkschnittstellen

* **Grün empfangen/gesendet** – kumulativ empfangene und gesendete Bytes auf der GREEN-Schnittstelle.
* **Orange empfangen/gesendet** – kumulativ empfangene und gesendete Bytes auf der ORANGE-Schnittstelle.
* **Blau empfangen/gesendet** – kumulativ empfangene und gesendete Bytes auf der BLUE-Schnittstelle.

Sensoren werden nur für interne Schnittstellen angelegt, die auf der IPFire-Firewall konfiguriert sind.

### DHCP-Leases

* **Aktive DHCP-Leases** – Anzahl aktiver DHCP-Leases. Das Attribut `leases` enthält die von IPFire gemeldeten Clientdaten mit IP-Adresse, MAC-Adresse, Hostname, Ablaufzeit und Status. Du findest sie in Home Assistant in der Detailansicht des Sensors unter den Attributen.

### Systemstatus

* **Neustart erforderlich** – zeigt an, wenn IPFire nach einem Update einen Neustart verlangt. Benötigt eine aktuelle Version von `api.cgi`; bei älteren Versionen bleibt der Sensor unbekannt.
* **Updates verfügbar** – Gesamtzahl der verfügbaren Updates, einschließlich Core- und Paket-Updates.

### Internetverbindung

Expand All @@ -178,7 +207,6 @@ Die folgenden Sensoren und Funktionen erfordern, dass `api.cgi` auf der IPFire-F
* **Model**
* **Vendor**
* **Uptime**
* **Package Updates**

### CPU

Expand Down
52 changes: 40 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ This documentation is also available in 🇩🇪 [German](README-de.md).

## What’s New in This Version

### v0.3.6

* Added DHCP lease count and client details as sensor attributes (requires `api.cgi`).
* Added cumulative traffic counters for the GREEN, ORANGE, and BLUE interfaces (requires `api.cgi`).
* Added a reboot-required sensor and a combined count of available core and package updates (requires `api.cgi`).

### v0.3.5

* Development of the IPFire CGI `api.cgi` continues in the standalone [IPFire-API](https://github.com/FMainz/IPFire-API) repository.
Expand All @@ -65,19 +71,24 @@ This documentation is also available in 🇩🇪 [German](README-de.md).

HA-IPFire provides the following features:

* Download traffic counter
* Upload traffic counter
* RED download traffic counter
* RED upload traffic counter
* Current download speed
* Current upload speed
* Internet connection state
* Internet connection duration
* Connect and Disconnect controls
* Configurable polling interval
* Internet connection state¹
* Internet connection duration¹
* Connect and Disconnect controls¹
* Configurable polling interval¹
* Polling interval from 5 to 60 seconds
* Optional SSL certificate verification
* Username/password authentication
* HACS compatible
* German and English translations
* DHCP lease sensor with client details¹
* Traffic counters for individual network zones¹
* Reboot-required status and total available update count¹

¹Requires `api.cgi` from [IPFire-API](https://github.com/FMainz/IPFire-API).

## IPFire

Expand Down Expand Up @@ -108,9 +119,10 @@ In addition to connection status and controls, the API provides information such
* IPFire, Pakfire, and kernel versions, plus system vendor, model, and architecture
* CPU model and number of cores
* Memory and disk usage, including I/O statistics and SMART status
* Network interface and IPFire service states
* Network interface states and per-zone traffic counters, plus IPFire service states
* Active DHCP leases and their client details
* Installed add-ons and their status
* Available core and package updates
* Core and package update status, plus whether a reboot is required

For a complete description of the JSON fields, see the [IPFire-API documentation](https://github.com/FMainz/IPFire-API/blob/main/README.md#endpoint).

Expand Down Expand Up @@ -154,12 +166,29 @@ The integration provides the following sensors:

### Traffic

* **Download** – cumulative download traffic in bytes.
* **Upload** – cumulative upload traffic in bytes.
* **Red Traffic Received** – cumulative received bytes on the RED interface.
* **Red Traffic Sent** – cumulative sent bytes on the RED interface.
* **Download Speed** – current download speed.
* **Upload Speed** – current upload speed.

The following sensors and functions require `api.cgi` to be [installed](#ipfire-cgi-installation) on the IPFire firewall.
The following additional sensors and functions require `api.cgi` to be [installed](#ipfire-cgi-installation) on the IPFire firewall.

### Internal network traffic

* **Green Traffic Received/Sent** – cumulative received and sent bytes on the GREEN interface.
* **Orange Traffic Received/Sent** – cumulative received and sent bytes on the ORANGE interface.
* **Blue Traffic Received/Sent** – cumulative received and sent bytes on the BLUE interface.

Sensors are created only for internal interfaces configured on the IPFire firewall.

### DHCP leases

* **Active DHCP Leases** – number of active DHCP leases. The `leases` attribute contains the client records reported by IPFire, including IP address, MAC address, hostname, expiry, and status. To view them, open the sensor's more-info panel in Home Assistant and inspect its attributes.

### System status

* **Reboot Required** – indicates when IPFire requires a reboot after an update. Requires a current version of `api.cgi`; older versions leave the sensor unknown.
* **Updates Available** – total number of available updates, including core and package updates.

### Internet connection

Expand All @@ -180,7 +209,6 @@ The following sensors and functions require `api.cgi` to be [installed](#ipfire-
* **Model**
* **Vendor**
* **Uptime**
* **Package Updates**

### CPU

Expand Down
9 changes: 5 additions & 4 deletions custom_components/ipfire/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from dataclasses import dataclass

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
Expand Down Expand Up @@ -36,11 +37,11 @@ class IPFireBinarySensorDescription(BinarySensorEntityDescription):
entity_registry_enabled_default=False,
),
IPFireBinarySensorDescription(
key="core_update",
translation_key="core_update",
value_key="core_update",
key="reboot_required",
translation_key="reboot_required",
value_key="reboot_required",
data_group="system",
entity_registry_enabled_default=False,
device_class=BinarySensorDeviceClass.PROBLEM,
),
IPFireBinarySensorDescription(
key="network_blue",
Expand Down
86 changes: 82 additions & 4 deletions custom_components/ipfire/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ class IPFireSystemData:
model: str
vendor: str
virtual: bool
core_update: bool
package_updates: int
core_update: bool | None
reboot_required: bool | None
package_updates: int | None
uptime: int | None
cpu_total: int | None
cpu_idle: int | None
Expand All @@ -50,6 +51,18 @@ class IPFireSystemData:
smart_temperature: int | None
smart_errors: int | None

@property
def updates_available(self) -> int | None:
"""Return the total number of available core and package updates."""
if (
not isinstance(self.core_update, bool)
or not isinstance(self.package_updates, int)
or isinstance(self.package_updates, bool)
):
return None

return self.package_updates + int(self.core_update)


@dataclass(frozen=True, slots=True)
class IPFireNetworkData:
Expand All @@ -59,6 +72,16 @@ class IPFireNetworkData:
green: bool | None
orange: bool | None
red: bool | None
interfaces: dict[str, IPFireInterfaceData | None]


@dataclass(frozen=True, slots=True)
class IPFireInterfaceData:
"""Represent byte counters for one IPFire network interface."""

device: str | None
rx_bytes: int | None
tx_bytes: int | None


@dataclass(frozen=True, slots=True)
Expand All @@ -78,6 +101,7 @@ class IPFireData:
external_hostname: str
system: IPFireSystemData
network: IPFireNetworkData
dhcp_leases: tuple[dict[str, object], ...] | None
services: dict[str, bool]
addons: dict[str, dict[str, bool]]

Expand Down Expand Up @@ -181,6 +205,7 @@ async def _async_update_data(self) -> IPFireData:
traffic = payload["traffic"]
system = payload.get("system", {})
network = payload.get("network", {})
dhcp = payload.get("dhcp", {})
services = payload.get("services", {})
addons = payload.get("addons", {})
if not isinstance(connection, dict):
Expand All @@ -195,11 +220,54 @@ async def _async_update_data(self) -> IPFireData:
if not isinstance(network, dict):
raise ValueError("Invalid network data from IPFire")

if not isinstance(dhcp, dict):
raise ValueError("Invalid DHCP data from IPFire")

if not isinstance(services, dict):
raise ValueError("Invalid services data from IPFire")

if not isinstance(addons, dict):
raise ValueError("Invalid addons data from IPFire")

raw_interfaces = network.get("interfaces", {})
if not isinstance(raw_interfaces, dict):
raise ValueError("Invalid network interface data from IPFire")

interfaces: dict[str, IPFireInterfaceData | None] = {}
for zone in ("red", "green", "orange", "blue"):
raw_interface = raw_interfaces.get(zone)
if raw_interface is None:
interfaces[zone] = None
continue
if not isinstance(raw_interface, dict):
raise ValueError(
f"Invalid {zone.upper()} interface data from IPFire"
)
interfaces[zone] = IPFireInterfaceData(
device=(
str(raw_interface["device"])
if raw_interface.get("device") is not None
else None
),
rx_bytes=self._parse_optional_int(
raw_interface.get("rx_bytes")
),
tx_bytes=self._parse_optional_int(
raw_interface.get("tx_bytes")
),
)

raw_leases = dhcp.get("leases")
if raw_leases is not None and not isinstance(raw_leases, list):
raise ValueError("Invalid DHCP lease data from IPFire")
if isinstance(raw_leases, list) and not all(
isinstance(lease, dict) for lease in raw_leases
):
raise ValueError("Invalid DHCP lease entry from IPFire")
dhcp_leases = (
tuple(raw_leases) if isinstance(raw_leases, list) else None
)

connection_state = str(connection.get("state", "unavailable"))

if "rx_bytes" not in traffic:
Expand Down Expand Up @@ -268,8 +336,15 @@ async def _async_update_data(self) -> IPFireData:
model=system.get("model"),
vendor=system.get("vendor"),
virtual=system.get("virtual"),
core_update=system.get("core_update"),
package_updates=system.get("package_updates"),
core_update=(
system.get("core_update")
if isinstance(system.get("core_update"), bool)
else None
),
reboot_required=system.get("reboot_required"),
package_updates=self._parse_optional_int(
system.get("package_updates")
),
uptime=system.get("uptime"),
cpu_total=cpu_total,
cpu_idle=cpu_idle,
Expand All @@ -291,6 +366,7 @@ async def _async_update_data(self) -> IPFireData:
green=network.get("green"),
orange=network.get("orange"),
red=network.get("red"),
interfaces=interfaces,
)

except (KeyError, TypeError, ValueError) as err:
Expand Down Expand Up @@ -338,6 +414,7 @@ async def _async_update_data(self) -> IPFireData:
external_hostname=external_hostname,
system=system_data,
network=network_data,
dhcp_leases=dhcp_leases,
services=services,
addons=addons,
)
Expand Down Expand Up @@ -419,6 +496,7 @@ def _parse_speed_cgi(payload: str) -> dict:
},
"system": {},
"network": {},
"dhcp": {},
"services": {},
"addons": {},
}
Expand Down
Loading
Loading